1 /*
2  * Copyright 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.timezonedetector;
17 
18 import android.annotation.NonNull;
19 import android.annotation.Nullable;
20 import android.annotation.StringDef;
21 import android.annotation.UserIdInt;
22 import android.app.time.TimeZoneConfiguration;
23 
24 import java.lang.annotation.ElementType;
25 import java.lang.annotation.Retention;
26 import java.lang.annotation.RetentionPolicy;
27 import java.lang.annotation.Target;
28 import java.time.Duration;
29 import java.util.Optional;
30 
31 /**
32  * An interface that provides access to service configuration for time zone detection. This hides
33  * how configuration is split between static, compile-time config, dynamic server-pushed flags and
34  * user settings. It provides listeners to signal when values that affect different components have
35  * changed.
36  */
37 public interface ServiceConfigAccessor {
38 
39     @StringDef(prefix = "PROVIDER_MODE_",
40             value = { PROVIDER_MODE_DISABLED, PROVIDER_MODE_ENABLED })
41     @Retention(RetentionPolicy.SOURCE)
42     @Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER })
43     @interface ProviderMode {
44     }
45 
46     /**
47      * The "disabled" provider mode. For use with {@link #getPrimaryLocationTimeZoneProviderMode()}
48      * and {@link #getSecondaryLocationTimeZoneProviderMode()}.
49      */
50     @ProviderMode String PROVIDER_MODE_DISABLED = "disabled";
51 
52     /**
53      * The "enabled" provider mode. For use with {@link #getPrimaryLocationTimeZoneProviderMode()}
54      * and {@link #getSecondaryLocationTimeZoneProviderMode()}.
55      */
56     @ProviderMode String PROVIDER_MODE_ENABLED = "enabled";
57 
58     /**
59      * Adds a listener that will be invoked when {@link ConfigurationInternal} may have changed.
60      * The listener is invoked on the main thread.
61      */
addConfigurationInternalChangeListener(@onNull StateChangeListener listener)62     void addConfigurationInternalChangeListener(@NonNull StateChangeListener listener);
63 
64     /**
65      * Removes a listener previously added via {@link
66      * #addConfigurationInternalChangeListener(StateChangeListener)}.
67      */
removeConfigurationInternalChangeListener(@onNull StateChangeListener listener)68     void removeConfigurationInternalChangeListener(@NonNull StateChangeListener listener);
69 
70     /**
71      * Returns a snapshot of the {@link ConfigurationInternal} for the current user. This is only a
72      * snapshot so callers must use {@link
73      * #addConfigurationInternalChangeListener(StateChangeListener)} to be notified when it
74      * changes.
75      */
76     @NonNull
getCurrentUserConfigurationInternal()77     ConfigurationInternal getCurrentUserConfigurationInternal();
78 
79     /**
80      * Updates the configuration properties that control a device's time zone behavior.
81      *
82      * <p>This method returns {@code true} if the configuration was changed, {@code false}
83      * otherwise.
84      *
85      * @param bypassUserPolicyChecks {@code true} for device policy manager use cases where device
86      *   policy restrictions that should apply to actual users can be ignored
87      */
updateConfiguration( @serIdInt int userId, @NonNull TimeZoneConfiguration requestedConfiguration, boolean bypassUserPolicyChecks)88     boolean updateConfiguration(
89             @UserIdInt int userId, @NonNull TimeZoneConfiguration requestedConfiguration,
90             boolean bypassUserPolicyChecks);
91 
92     /**
93      * Returns a snapshot of the configuration that controls time zone detector behavior for the
94      * specified user.
95      */
96     @NonNull
getConfigurationInternal(@serIdInt int userId)97     ConfigurationInternal getConfigurationInternal(@UserIdInt int userId);
98 
99     /**
100      * Adds a listener that will be called when server flags related to location_time_zone_manager
101      * change. The callbacks are delivered on the main looper thread.
102      *
103      * <p>Note: Currently only for use by long-lived objects; there is no associated remove method.
104      */
addLocationTimeZoneManagerConfigListener(@onNull StateChangeListener listener)105     void addLocationTimeZoneManagerConfigListener(@NonNull StateChangeListener listener);
106 
107     /**
108      * Returns {@code true} if the telephony-based time zone detection feature is supported on the
109      * device.
110      */
isTelephonyTimeZoneDetectionFeatureSupported()111     boolean isTelephonyTimeZoneDetectionFeatureSupported();
112 
113     /**
114      * Returns {@code true} if the location-based time zone detection feature can be supported on
115      * this device at all according to config. When {@code false}, implies that various other
116      * location-based services and settings will be turned off or rendered meaningless.
117      *
118      * <p>This is the ultimate "feature switch" for location-based time zone detection. If this is
119      * {@code false}, the device cannot support the feature without a config change or a reboot:
120      * This affects what services are started on boot to minimize expense when the feature is not
121      * wanted.
122      *
123      * Typically {@link #isGeoTimeZoneDetectionFeatureSupported()} should be used except during
124      * boot.
125      */
isGeoTimeZoneDetectionFeatureSupportedInConfig()126     boolean isGeoTimeZoneDetectionFeatureSupportedInConfig();
127 
128     /**
129      * Returns {@code true} if the location-based time zone detection feature is supported on the
130      * device.
131      */
isGeoTimeZoneDetectionFeatureSupported()132     boolean isGeoTimeZoneDetectionFeatureSupported();
133 
134     /** Returns the package name of the app hosting the primary location time zone provider. */
135     @NonNull
getPrimaryLocationTimeZoneProviderPackageName()136     String getPrimaryLocationTimeZoneProviderPackageName();
137 
138     /**
139      * Sets the package name of the app hosting the primary location time zone provider for tests.
140      * Setting a {@code null} value means the provider is to be disabled.
141      * The values are reset with {@link #resetVolatileTestConfig()}.
142      */
setTestPrimaryLocationTimeZoneProviderPackageName( @ullable String testPrimaryLocationTimeZoneProviderPackageName)143     void setTestPrimaryLocationTimeZoneProviderPackageName(
144             @Nullable String testPrimaryLocationTimeZoneProviderPackageName);
145 
146     /**
147      * Returns {@code true} if the usual permission checks are to be bypassed for the primary
148      * provider. Returns {@code true} only if {@link
149      * #setTestPrimaryLocationTimeZoneProviderPackageName} has been called.
150      */
isTestPrimaryLocationTimeZoneProvider()151     boolean isTestPrimaryLocationTimeZoneProvider();
152 
153     /** Returns the package name of the app hosting the secondary location time zone provider. */
154     @NonNull
getSecondaryLocationTimeZoneProviderPackageName()155     String getSecondaryLocationTimeZoneProviderPackageName();
156 
157     /**
158      * Sets the package name of the app hosting the secondary location time zone provider for tests.
159      * Setting a {@code null} value means the provider is to be disabled.
160      * The values are reset with {@link #resetVolatileTestConfig()}.
161      */
setTestSecondaryLocationTimeZoneProviderPackageName( @ullable String testSecondaryLocationTimeZoneProviderPackageName)162     void setTestSecondaryLocationTimeZoneProviderPackageName(
163             @Nullable String testSecondaryLocationTimeZoneProviderPackageName);
164 
165     /**
166      * Returns {@code true} if the usual permission checks are to be bypassed for the secondary
167      * provider. Returns {@code true} only if {@link
168      * #setTestSecondaryLocationTimeZoneProviderPackageName} has been called.
169      */
isTestSecondaryLocationTimeZoneProvider()170     boolean isTestSecondaryLocationTimeZoneProvider();
171 
172     /**
173      * Enables/disables the state recording mode for tests. The value is reset with {@link
174      * #resetVolatileTestConfig()}.
175      */
setRecordStateChangesForTests(boolean enabled)176     void setRecordStateChangesForTests(boolean enabled);
177 
178     /**
179      * Returns {@code true} if the controller / providers are expected to record their state changes
180      * for tests.
181      */
getRecordStateChangesForTests()182     boolean getRecordStateChangesForTests();
183 
184     /**
185      * Returns the mode for the primary location time zone provider.
186      */
187     @NonNull
getPrimaryLocationTimeZoneProviderMode()188     @ProviderMode String getPrimaryLocationTimeZoneProviderMode();
189 
190     /**
191      * Returns the mode for the secondary location time zone provider.
192      */
getSecondaryLocationTimeZoneProviderMode()193     @ProviderMode String getSecondaryLocationTimeZoneProviderMode();
194 
195     /**
196      * Returns whether location time zone detection is enabled for users when there's no setting
197      * value. Intended for use during feature release testing to "opt-in" users that haven't shown
198      * an explicit preference.
199      */
isGeoDetectionEnabledForUsersByDefault()200     boolean isGeoDetectionEnabledForUsersByDefault();
201 
202     /**
203      * Returns whether location time zone detection is force enabled/disabled for users. Intended
204      * for use during feature release testing to force a given state.
205      */
206     @NonNull
getGeoDetectionSettingEnabledOverride()207     Optional<Boolean> getGeoDetectionSettingEnabledOverride();
208 
209     /**
210      * Returns the time to send to a location time zone provider that informs it how long it has
211      * to return its first time zone suggestion.
212      */
213     @NonNull
getLocationTimeZoneProviderInitializationTimeout()214     Duration getLocationTimeZoneProviderInitializationTimeout();
215 
216     /**
217      * Returns the time added to {@link #getLocationTimeZoneProviderInitializationTimeout()} by the
218      * server before unilaterally declaring the provider is uncertain.
219      */
220     @NonNull
getLocationTimeZoneProviderInitializationTimeoutFuzz()221     Duration getLocationTimeZoneProviderInitializationTimeoutFuzz();
222 
223     /**
224      * Returns the time after uncertainty is detected by providers before the location time zone
225      * manager makes a suggestion to the time zone detector.
226      */
227     @NonNull
getLocationTimeZoneUncertaintyDelay()228     Duration getLocationTimeZoneUncertaintyDelay();
229 
230     /**
231      * Returns the time between equivalent events before the provider process will send the event
232      * to the system server.
233      */
234     @NonNull
getLocationTimeZoneProviderEventFilteringAgeThreshold()235     Duration getLocationTimeZoneProviderEventFilteringAgeThreshold();
236 
237     /** Clears all in-memory test config. */
resetVolatileTestConfig()238     void resetVolatileTestConfig();
239 }
240