Merge "Adjust geotz feature config logic" into sc-dev
This commit is contained in:
@@ -49,31 +49,6 @@ public final class LocationTimeZoneManager {
|
||||
*/
|
||||
public static final String SHELL_COMMAND_STOP = "stop";
|
||||
|
||||
/**
|
||||
* A shell command that can put providers into different modes. Takes effect next time the
|
||||
* service is started.
|
||||
*/
|
||||
public static final String SHELL_COMMAND_SET_PROVIDER_MODE_OVERRIDE =
|
||||
"set_provider_mode_override";
|
||||
|
||||
/**
|
||||
* The default provider mode.
|
||||
* For use with {@link #SHELL_COMMAND_SET_PROVIDER_MODE_OVERRIDE}.
|
||||
*/
|
||||
public static final String PROVIDER_MODE_OVERRIDE_NONE = "none";
|
||||
|
||||
/**
|
||||
* The "simulated" provider mode.
|
||||
* For use with {@link #SHELL_COMMAND_SET_PROVIDER_MODE_OVERRIDE}.
|
||||
*/
|
||||
public static final String PROVIDER_MODE_OVERRIDE_SIMULATED = "simulated";
|
||||
|
||||
/**
|
||||
* The "disabled" provider mode (equivalent to there being no provider configured).
|
||||
* For use with {@link #SHELL_COMMAND_SET_PROVIDER_MODE_OVERRIDE}.
|
||||
*/
|
||||
public static final String PROVIDER_MODE_OVERRIDE_DISABLED = "disabled";
|
||||
|
||||
/**
|
||||
* A shell command that tells the service to record state information during tests. The next
|
||||
* argument value is "true" or "false".
|
||||
|
||||
@@ -1637,32 +1637,22 @@
|
||||
config_timeZoneRulesUpdateTrackingEnabled are true.] -->
|
||||
<integer name="config_timeZoneRulesCheckRetryCount">5</integer>
|
||||
|
||||
<!-- Whether the geolocation time zone detection feature is enabled. -->
|
||||
<!-- Whether the geolocation time zone detection feature is enabled. Setting this to false means
|
||||
the feature cannot be used. Setting this to true means it may be used if other
|
||||
configuration allows (see provider configuration below, also compile time overlays). -->
|
||||
<bool name="config_enableGeolocationTimeZoneDetection" translatable="false">true</bool>
|
||||
|
||||
<!-- Whether the primary LocationTimeZoneProvider is enabled device.
|
||||
<!-- Whether the primary LocationTimeZoneProvider is enabled.
|
||||
Ignored if config_enableGeolocationTimeZoneDetection is false -->
|
||||
<bool name="config_enablePrimaryLocationTimeZoneProvider" translatable="false">false</bool>
|
||||
<!-- Used when enablePrimaryLocationTimeZoneProvider is true. Controls whether to enable primary
|
||||
location time zone provider overlay which allows the primary location time zone provider to
|
||||
be replaced by an app at run-time. When disabled, only the
|
||||
config_primaryLocationTimeZoneProviderPackageName package will be searched for the primary
|
||||
location time zone provider, otherwise any system package is eligible. Anyone who wants to
|
||||
disable the runtime overlay mechanism can set it to false. -->
|
||||
<bool name="config_enablePrimaryLocationTimeZoneOverlay" translatable="false">false</bool>
|
||||
<!-- Package name providing the primary location time zone provider. Used only when
|
||||
config_enablePrimaryLocationTimeZoneOverlay is false. -->
|
||||
<!-- The package name providing the primary location time zone provider.
|
||||
Only used when config_enableGeolocationTimeZoneDetection and
|
||||
enablePrimaryLocationTimeZoneProvider are true. -->
|
||||
<string name="config_primaryLocationTimeZoneProviderPackageName" translatable="false">@null</string>
|
||||
|
||||
<!-- Whether the secondary LocationTimeZoneProvider is enabled device.
|
||||
<!-- Whether the secondary LocationTimeZoneProvider is enabled.
|
||||
Ignored if config_enableGeolocationTimeZoneDetection is false -->
|
||||
<bool name="config_enableSecondaryLocationTimeZoneProvider" translatable="false">true</bool>
|
||||
<!-- Used when enableSecondaryLocationTimeZoneProvider is true. Controls whether to enable
|
||||
secondary location time zone provider overlay which allows the primary location time zone
|
||||
provider to config_secondaryLocationTimeZoneProviderPackageName package will be searched
|
||||
for the secondary location time zone provider, otherwise any system package is eligible.
|
||||
Anyone who wants to disable the runtime overlay mechanism can set it to false. -->
|
||||
<bool name="config_enableSecondaryLocationTimeZoneOverlay" translatable="false">false</bool>
|
||||
<!-- Package name providing the secondary location time zone provider. Used only when
|
||||
config_enableSecondaryLocationTimeZoneOverlay is false.
|
||||
|
||||
|
||||
@@ -2180,10 +2180,8 @@
|
||||
<java-symbol type="bool" name="config_enableGnssTimeUpdateService" />
|
||||
<java-symbol type="bool" name="config_enableGeolocationTimeZoneDetection" />
|
||||
<java-symbol type="bool" name="config_enablePrimaryLocationTimeZoneProvider" />
|
||||
<java-symbol type="bool" name="config_enablePrimaryLocationTimeZoneOverlay" />
|
||||
<java-symbol type="string" name="config_primaryLocationTimeZoneProviderPackageName" />
|
||||
<java-symbol type="bool" name="config_enableSecondaryLocationTimeZoneProvider" />
|
||||
<java-symbol type="bool" name="config_enableSecondaryLocationTimeZoneOverlay" />
|
||||
<java-symbol type="string" name="config_secondaryLocationTimeZoneProviderPackageName" />
|
||||
|
||||
<java-symbol type="layout" name="resolver_list" />
|
||||
|
||||
@@ -28,6 +28,8 @@ import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.server.timezonedetector.ConfigurationChangeListener;
|
||||
import com.android.server.timezonedetector.ServiceConfigAccessor;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -53,14 +55,15 @@ public final class ServerFlags {
|
||||
*/
|
||||
@StringDef(prefix = "KEY_", value = {
|
||||
KEY_LOCATION_TIME_ZONE_DETECTION_FEATURE_SUPPORTED,
|
||||
KEY_PRIMARY_LOCATION_TIME_ZONE_PROVIDER_ENABLED_OVERRIDE,
|
||||
KEY_SECONDARY_LOCATION_TIME_ZONE_PROVIDER_ENABLED_OVERRIDE,
|
||||
KEY_PRIMARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE,
|
||||
KEY_SECONDARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE,
|
||||
KEY_LOCATION_TIME_ZONE_PROVIDER_INITIALIZATION_TIMEOUT_FUZZ_MILLIS,
|
||||
KEY_LOCATION_TIME_ZONE_PROVIDER_INITIALIZATION_TIMEOUT_MILLIS,
|
||||
KEY_LOCATION_TIME_ZONE_DETECTION_UNCERTAINTY_DELAY_MILLIS,
|
||||
KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_OVERRIDE,
|
||||
KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface DeviceConfigKey {}
|
||||
|
||||
/**
|
||||
@@ -75,19 +78,19 @@ public final class ServerFlags {
|
||||
|
||||
/**
|
||||
* The key for the server flag that can override the device config for whether the primary
|
||||
* location time zone provider is enabled or disabled.
|
||||
* location time zone provider is enabled, disabled, or (for testing) in simulation mode.
|
||||
*/
|
||||
@DeviceConfigKey
|
||||
public static final String KEY_PRIMARY_LOCATION_TIME_ZONE_PROVIDER_ENABLED_OVERRIDE =
|
||||
"primary_location_time_zone_provider_enabled_override";
|
||||
public static final String KEY_PRIMARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE =
|
||||
"primary_location_time_zone_provider_mode_override";
|
||||
|
||||
/**
|
||||
* The key for the server flag that can override the device config for whether the secondary
|
||||
* location time zone provider is enabled or disabled.
|
||||
* location time zone provider is enabled or disabled, or (for testing) in simulation mode.
|
||||
*/
|
||||
@DeviceConfigKey
|
||||
public static final String KEY_SECONDARY_LOCATION_TIME_ZONE_PROVIDER_ENABLED_OVERRIDE =
|
||||
"secondary_location_time_zone_provider_enabled_override";
|
||||
public static final String KEY_SECONDARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE =
|
||||
"secondary_location_time_zone_provider_mode_override";
|
||||
|
||||
/**
|
||||
* The key for the minimum delay after location time zone detection has been enabled before the
|
||||
@@ -195,6 +198,16 @@ public final class ServerFlags {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an optional string value from {@link DeviceConfig} from the system_time
|
||||
* namespace, returns {@link Optional#empty()} if there is no explicit value set.
|
||||
*/
|
||||
@NonNull
|
||||
public Optional<String> getOptionalString(@DeviceConfigKey String key) {
|
||||
String value = DeviceConfig.getProperty(NAMESPACE_SYSTEM_TIME, key);
|
||||
return Optional.ofNullable(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an optional boolean value from {@link DeviceConfig} from the system_time
|
||||
* namespace, returns {@link Optional#empty()} if there is no explicit value set.
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.android.server.timezonedetector;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.StringDef;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
@@ -27,6 +28,10 @@ import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.server.timedetector.ServerFlags;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
@@ -40,13 +45,38 @@ import java.util.Set;
|
||||
*/
|
||||
public final class ServiceConfigAccessor {
|
||||
|
||||
@StringDef(prefix = "PROVIDER_MODE_",
|
||||
value = { PROVIDER_MODE_SIMULATED, PROVIDER_MODE_DISABLED, PROVIDER_MODE_ENABLED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface ProviderMode {}
|
||||
|
||||
/**
|
||||
* The "simulated" provider mode.
|
||||
* For use with {@link #getPrimaryLocationTimeZoneProviderMode()} and {@link
|
||||
* #getSecondaryLocationTimeZoneProviderMode()}.
|
||||
*/
|
||||
public static final @ProviderMode String PROVIDER_MODE_SIMULATED = "simulated";
|
||||
|
||||
/**
|
||||
* The "disabled" provider mode. For use with {@link #getPrimaryLocationTimeZoneProviderMode()}
|
||||
* and {@link #getSecondaryLocationTimeZoneProviderMode()}.
|
||||
*/
|
||||
public static final @ProviderMode String PROVIDER_MODE_DISABLED = "disabled";
|
||||
|
||||
/**
|
||||
* The "enabled" provider mode. For use with {@link #getPrimaryLocationTimeZoneProviderMode()}
|
||||
* and {@link #getSecondaryLocationTimeZoneProviderMode()}.
|
||||
*/
|
||||
public static final @ProviderMode String PROVIDER_MODE_ENABLED = "enabled";
|
||||
|
||||
private static final Set<String> SERVER_FLAGS_KEYS_TO_WATCH = Collections.unmodifiableSet(
|
||||
new ArraySet<>(new String[] {
|
||||
ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_FEATURE_SUPPORTED,
|
||||
ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT,
|
||||
ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_OVERRIDE,
|
||||
ServerFlags.KEY_PRIMARY_LOCATION_TIME_ZONE_PROVIDER_ENABLED_OVERRIDE,
|
||||
ServerFlags.KEY_SECONDARY_LOCATION_TIME_ZONE_PROVIDER_ENABLED_OVERRIDE,
|
||||
ServerFlags.KEY_PRIMARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE,
|
||||
ServerFlags.KEY_SECONDARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE,
|
||||
ServerFlags.KEY_LOCATION_TIME_ZONE_PROVIDER_INITIALIZATION_TIMEOUT_MILLIS,
|
||||
ServerFlags.KEY_LOCATION_TIME_ZONE_PROVIDER_INITIALIZATION_TIMEOUT_FUZZ_MILLIS,
|
||||
ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_UNCERTAINTY_DELAY_MILLIS
|
||||
@@ -139,14 +169,28 @@ public final class ServiceConfigAccessor {
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the location-based time zone detection feature is supported on the
|
||||
* device. This can be used during feature testing on builds that are capable of location time
|
||||
* zone detection to enable / disable the feature for some users.
|
||||
* device.
|
||||
*/
|
||||
public boolean isGeoTimeZoneDetectionFeatureSupported() {
|
||||
// For the feature to be enabled it must:
|
||||
// 1) Be turned on in config.
|
||||
// 2) Not be turned off via a server flag.
|
||||
// 3) There must be at least one location time zone provider enabled / configured.
|
||||
return mGeoDetectionFeatureSupportedInConfig
|
||||
&& isGeoTimeZoneDetectionFeatureSupportedInternal();
|
||||
&& isGeoTimeZoneDetectionFeatureSupportedInternal()
|
||||
&& atLeastOneProviderIsEnabled();
|
||||
}
|
||||
|
||||
private boolean atLeastOneProviderIsEnabled() {
|
||||
return !(Objects.equals(getPrimaryLocationTimeZoneProviderMode(), PROVIDER_MODE_DISABLED)
|
||||
&& Objects.equals(getSecondaryLocationTimeZoneProviderMode(),
|
||||
PROVIDER_MODE_DISABLED));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the location-based time zone detection feature is not explicitly
|
||||
* disabled by a server flag.
|
||||
*/
|
||||
private boolean isGeoTimeZoneDetectionFeatureSupportedInternal() {
|
||||
final boolean defaultEnabled = true;
|
||||
return mServerFlags.getBoolean(
|
||||
@@ -154,42 +198,49 @@ public final class ServiceConfigAccessor {
|
||||
defaultEnabled);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getPrimaryLocationTimeZoneProviderPackageName() {
|
||||
return mContext.getResources().getString(
|
||||
R.string.config_primaryLocationTimeZoneProviderPackageName);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getSecondaryLocationTimeZoneProviderPackageName() {
|
||||
return mContext.getResources().getString(
|
||||
R.string.config_secondaryLocationTimeZoneProviderPackageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the primary location time zone provider can be used.
|
||||
*/
|
||||
public boolean isPrimaryLocationTimeZoneProviderEnabled() {
|
||||
return getPrimaryLocationTimeZoneProviderEnabledOverride()
|
||||
.orElse(isPrimaryLocationTimeZoneProviderEnabledInConfig());
|
||||
}
|
||||
|
||||
private boolean isPrimaryLocationTimeZoneProviderEnabledInConfig() {
|
||||
int providerEnabledConfigId = R.bool.config_enablePrimaryLocationTimeZoneProvider;
|
||||
return getConfigBoolean(providerEnabledConfigId);
|
||||
@NonNull
|
||||
public @ProviderMode String getPrimaryLocationTimeZoneProviderMode() {
|
||||
return mServerFlags.getOptionalString(
|
||||
ServerFlags.KEY_PRIMARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE)
|
||||
.orElse(getPrimaryLocationTimeZoneProviderModeFromConfig());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Optional<Boolean> getPrimaryLocationTimeZoneProviderEnabledOverride() {
|
||||
return mServerFlags.getOptionalBoolean(
|
||||
ServerFlags.KEY_PRIMARY_LOCATION_TIME_ZONE_PROVIDER_ENABLED_OVERRIDE);
|
||||
private @ProviderMode String getPrimaryLocationTimeZoneProviderModeFromConfig() {
|
||||
int providerEnabledConfigId = R.bool.config_enablePrimaryLocationTimeZoneProvider;
|
||||
return getConfigBoolean(providerEnabledConfigId)
|
||||
? PROVIDER_MODE_ENABLED : PROVIDER_MODE_DISABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the secondary location time zone provider can be used.
|
||||
* Returns the mode for the secondary location time zone provider can be used.
|
||||
*/
|
||||
public boolean isSecondaryLocationTimeZoneProviderEnabled() {
|
||||
return getSecondaryLocationTimeZoneProviderEnabledOverride()
|
||||
.orElse(isSecondaryLocationTimeZoneProviderEnabledInConfig());
|
||||
}
|
||||
|
||||
private boolean isSecondaryLocationTimeZoneProviderEnabledInConfig() {
|
||||
int providerEnabledConfigId = R.bool.config_enableSecondaryLocationTimeZoneProvider;
|
||||
return getConfigBoolean(providerEnabledConfigId);
|
||||
public @ProviderMode String getSecondaryLocationTimeZoneProviderMode() {
|
||||
return mServerFlags.getOptionalString(
|
||||
ServerFlags.KEY_SECONDARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE)
|
||||
.orElse(getSecondaryLocationTimeZoneProviderModeFromConfig());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Optional<Boolean> getSecondaryLocationTimeZoneProviderEnabledOverride() {
|
||||
return mServerFlags.getOptionalBoolean(
|
||||
ServerFlags.KEY_SECONDARY_LOCATION_TIME_ZONE_PROVIDER_ENABLED_OVERRIDE);
|
||||
private @ProviderMode String getSecondaryLocationTimeZoneProviderModeFromConfig() {
|
||||
int providerEnabledConfigId = R.bool.config_enableSecondaryLocationTimeZoneProvider;
|
||||
return getConfigBoolean(providerEnabledConfigId)
|
||||
? PROVIDER_MODE_ENABLED : PROVIDER_MODE_DISABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,7 @@ import static com.android.server.timezonedetector.location.TimeZoneProviderEvent
|
||||
import static com.android.server.timezonedetector.location.TimeZoneProviderEvent.EVENT_TYPE_UNCERTAIN;
|
||||
|
||||
import android.annotation.DurationMillisLong;
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.RemoteCallback;
|
||||
@@ -604,14 +605,14 @@ class ControllerImpl extends LocationTimeZoneProviderController {
|
||||
* known provider, then the command is logged and discarded.
|
||||
*/
|
||||
void handleProviderTestCommand(
|
||||
@NonNull String providerName, @NonNull TestCommand testCommand,
|
||||
@IntRange(from = 0, to = 1) int providerIndex, @NonNull TestCommand testCommand,
|
||||
@Nullable RemoteCallback callback) {
|
||||
mThreadingDomain.assertCurrentThread();
|
||||
|
||||
LocationTimeZoneProvider targetProvider = getLocationTimeZoneProvider(providerName);
|
||||
LocationTimeZoneProvider targetProvider = getLocationTimeZoneProvider(providerIndex);
|
||||
if (targetProvider == null) {
|
||||
warnLog("Unable to process test command:"
|
||||
+ " providerName=" + providerName + ", testCommand=" + testCommand);
|
||||
+ " providerIndex=" + providerIndex + ", testCommand=" + testCommand);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -620,7 +621,7 @@ class ControllerImpl extends LocationTimeZoneProviderController {
|
||||
targetProvider.handleTestCommand(testCommand, callback);
|
||||
} catch (Exception e) {
|
||||
warnLog("Unable to process test command:"
|
||||
+ " providerName=" + providerName + ", testCommand=" + testCommand, e);
|
||||
+ " providerIndex=" + providerIndex + ", testCommand=" + testCommand, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -658,14 +659,15 @@ class ControllerImpl extends LocationTimeZoneProviderController {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private LocationTimeZoneProvider getLocationTimeZoneProvider(@NonNull String providerName) {
|
||||
private LocationTimeZoneProvider getLocationTimeZoneProvider(
|
||||
@IntRange(from = 0, to = 1) int providerIndex) {
|
||||
LocationTimeZoneProvider targetProvider;
|
||||
if (Objects.equals(mPrimaryProvider.getName(), providerName)) {
|
||||
if (providerIndex == 0) {
|
||||
targetProvider = mPrimaryProvider;
|
||||
} else if (Objects.equals(mSecondaryProvider.getName(), providerName)) {
|
||||
} else if (providerIndex == 1) {
|
||||
targetProvider = mSecondaryProvider;
|
||||
} else {
|
||||
warnLog("Bad providerName=" + providerName);
|
||||
warnLog("Bad providerIndex=" + providerIndex);
|
||||
targetProvider = null;
|
||||
}
|
||||
return targetProvider;
|
||||
|
||||
@@ -16,13 +16,12 @@
|
||||
|
||||
package com.android.server.timezonedetector.location;
|
||||
|
||||
import static android.app.time.LocationTimeZoneManager.PRIMARY_PROVIDER_NAME;
|
||||
import static android.app.time.LocationTimeZoneManager.PROVIDER_MODE_OVERRIDE_DISABLED;
|
||||
import static android.app.time.LocationTimeZoneManager.PROVIDER_MODE_OVERRIDE_NONE;
|
||||
import static android.app.time.LocationTimeZoneManager.PROVIDER_MODE_OVERRIDE_SIMULATED;
|
||||
import static android.app.time.LocationTimeZoneManager.SECONDARY_PROVIDER_NAME;
|
||||
import static android.app.time.LocationTimeZoneManager.SERVICE_NAME;
|
||||
|
||||
import static com.android.server.timezonedetector.ServiceConfigAccessor.PROVIDER_MODE_DISABLED;
|
||||
import static com.android.server.timezonedetector.ServiceConfigAccessor.PROVIDER_MODE_SIMULATED;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
@@ -37,12 +36,12 @@ import android.util.IndentingPrintWriter;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.DumpUtils;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.server.FgThread;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.timezonedetector.Dumpable;
|
||||
import com.android.server.timezonedetector.ServiceConfigAccessor;
|
||||
import com.android.server.timezonedetector.TimeZoneDetectorInternal;
|
||||
import com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderMetricsLogger;
|
||||
@@ -131,11 +130,15 @@ public class LocationTimeZoneManagerService extends Binder {
|
||||
|
||||
private static final String ATTRIBUTION_TAG = "LocationTimeZoneService";
|
||||
|
||||
private static final String PRIMARY_LOCATION_TIME_ZONE_SERVICE_ACTION =
|
||||
TimeZoneProviderService.PRIMARY_LOCATION_TIME_ZONE_PROVIDER_SERVICE_INTERFACE;
|
||||
private static final String SECONDARY_LOCATION_TIME_ZONE_SERVICE_ACTION =
|
||||
TimeZoneProviderService.SECONDARY_LOCATION_TIME_ZONE_PROVIDER_SERVICE_INTERFACE;
|
||||
@GuardedBy("mSharedLock")
|
||||
private final ProviderConfig mPrimaryProviderConfig = new ProviderConfig(
|
||||
0 /* index */, "primary",
|
||||
TimeZoneProviderService.PRIMARY_LOCATION_TIME_ZONE_PROVIDER_SERVICE_INTERFACE);
|
||||
|
||||
@GuardedBy("mSharedLock")
|
||||
private final ProviderConfig mSecondaryProviderConfig = new ProviderConfig(
|
||||
1 /* index */, "secondary",
|
||||
TimeZoneProviderService.SECONDARY_LOCATION_TIME_ZONE_PROVIDER_SERVICE_INTERFACE);
|
||||
|
||||
@NonNull private final Context mContext;
|
||||
|
||||
@@ -165,14 +168,6 @@ public class LocationTimeZoneManagerService extends Binder {
|
||||
@GuardedBy("mSharedLock")
|
||||
private ControllerEnvironmentImpl mEnvironment;
|
||||
|
||||
@GuardedBy("mSharedLock")
|
||||
@NonNull
|
||||
private String mPrimaryProviderModeOverride = PROVIDER_MODE_OVERRIDE_NONE;
|
||||
|
||||
@GuardedBy("mSharedLock")
|
||||
@NonNull
|
||||
private String mSecondaryProviderModeOverride = PROVIDER_MODE_OVERRIDE_NONE;
|
||||
|
||||
LocationTimeZoneManagerService(Context context) {
|
||||
mContext = context.createAttributionContext(ATTRIBUTION_TAG);
|
||||
mHandler = FgThread.getHandler();
|
||||
@@ -200,9 +195,14 @@ public class LocationTimeZoneManagerService extends Binder {
|
||||
mThreadingDomain.assertCurrentThread();
|
||||
|
||||
synchronized (mSharedLock) {
|
||||
// Stop and start the service, waiting until completion.
|
||||
stopOnDomainThread();
|
||||
startOnDomainThread();
|
||||
// Avoid starting the service if it is currently stopped. This is required because
|
||||
// server flags are used by tests to set behavior with the service stopped, and we don't
|
||||
// want the service being restarted after each flag is set.
|
||||
if (mLocationTimeZoneDetectorController != null) {
|
||||
// Stop and start the service, waiting until completion.
|
||||
stopOnDomainThread();
|
||||
startOnDomainThread();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,8 +257,8 @@ public class LocationTimeZoneManagerService extends Binder {
|
||||
}
|
||||
|
||||
if (mLocationTimeZoneDetectorController == null) {
|
||||
LocationTimeZoneProvider primary = createPrimaryProvider();
|
||||
LocationTimeZoneProvider secondary = createSecondaryProvider();
|
||||
LocationTimeZoneProvider primary = mPrimaryProviderConfig.createProvider();
|
||||
LocationTimeZoneProvider secondary = mSecondaryProviderConfig.createProvider();
|
||||
|
||||
ControllerImpl controller =
|
||||
new ControllerImpl(mThreadingDomain, primary, secondary);
|
||||
@@ -273,88 +273,6 @@ public class LocationTimeZoneManagerService extends Binder {
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private LocationTimeZoneProvider createPrimaryProvider() {
|
||||
LocationTimeZoneProviderProxy proxy;
|
||||
if (isProviderInSimulationMode(PRIMARY_PROVIDER_NAME)) {
|
||||
proxy = new SimulatedLocationTimeZoneProviderProxy(mContext, mThreadingDomain);
|
||||
} else if (!isProviderEnabled(PRIMARY_PROVIDER_NAME)) {
|
||||
proxy = new NullLocationTimeZoneProviderProxy(mContext, mThreadingDomain);
|
||||
} else {
|
||||
proxy = new RealLocationTimeZoneProviderProxy(
|
||||
mContext,
|
||||
mHandler,
|
||||
mThreadingDomain,
|
||||
PRIMARY_LOCATION_TIME_ZONE_SERVICE_ACTION,
|
||||
R.bool.config_enablePrimaryLocationTimeZoneOverlay,
|
||||
R.string.config_primaryLocationTimeZoneProviderPackageName
|
||||
);
|
||||
}
|
||||
ProviderMetricsLogger providerMetricsLogger = new RealProviderMetricsLogger(0);
|
||||
return new BinderLocationTimeZoneProvider(
|
||||
providerMetricsLogger, mThreadingDomain, PRIMARY_PROVIDER_NAME, proxy);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private LocationTimeZoneProvider createSecondaryProvider() {
|
||||
LocationTimeZoneProviderProxy proxy;
|
||||
if (isProviderInSimulationMode(SECONDARY_PROVIDER_NAME)) {
|
||||
proxy = new SimulatedLocationTimeZoneProviderProxy(mContext, mThreadingDomain);
|
||||
} else if (!isProviderEnabled(SECONDARY_PROVIDER_NAME)) {
|
||||
proxy = new NullLocationTimeZoneProviderProxy(mContext, mThreadingDomain);
|
||||
} else {
|
||||
proxy = new RealLocationTimeZoneProviderProxy(
|
||||
mContext,
|
||||
mHandler,
|
||||
mThreadingDomain,
|
||||
SECONDARY_LOCATION_TIME_ZONE_SERVICE_ACTION,
|
||||
R.bool.config_enableSecondaryLocationTimeZoneOverlay,
|
||||
R.string.config_secondaryLocationTimeZoneProviderPackageName
|
||||
);
|
||||
}
|
||||
ProviderMetricsLogger providerMetricsLogger = new RealProviderMetricsLogger(1);
|
||||
return new BinderLocationTimeZoneProvider(
|
||||
providerMetricsLogger, mThreadingDomain, SECONDARY_PROVIDER_NAME, proxy);
|
||||
}
|
||||
|
||||
/** Used for bug triage and in tests to simulate provider events. */
|
||||
private boolean isProviderInSimulationMode(@NonNull String providerName) {
|
||||
return isProviderModeOverrideSet(providerName, PROVIDER_MODE_OVERRIDE_SIMULATED);
|
||||
}
|
||||
|
||||
/** Used for bug triage, and by tests and experiments to remove a provider. */
|
||||
private boolean isProviderEnabled(@NonNull String providerName) {
|
||||
if (isProviderModeOverrideSet(providerName, PROVIDER_MODE_OVERRIDE_DISABLED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (providerName) {
|
||||
case PRIMARY_PROVIDER_NAME: {
|
||||
return mServiceConfigAccessor.isPrimaryLocationTimeZoneProviderEnabled();
|
||||
}
|
||||
case SECONDARY_PROVIDER_NAME: {
|
||||
return mServiceConfigAccessor.isSecondaryLocationTimeZoneProviderEnabled();
|
||||
}
|
||||
default: {
|
||||
throw new IllegalArgumentException(providerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isProviderModeOverrideSet(@NonNull String providerName, @NonNull String mode) {
|
||||
switch (providerName) {
|
||||
case PRIMARY_PROVIDER_NAME: {
|
||||
return Objects.equals(mPrimaryProviderModeOverride, mode);
|
||||
}
|
||||
case SECONDARY_PROVIDER_NAME: {
|
||||
return Objects.equals(mSecondaryProviderModeOverride, mode);
|
||||
}
|
||||
default: {
|
||||
throw new IllegalArgumentException(providerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the service for tests and other rare cases. To avoid tests needing to sleep, this
|
||||
* method will not return until all the system server components have stopped.
|
||||
@@ -389,33 +307,6 @@ public class LocationTimeZoneManagerService extends Binder {
|
||||
this, in, out, err, args, callback, resultReceiver);
|
||||
}
|
||||
|
||||
/** Sets this service into provider state recording mode for tests. */
|
||||
void setProviderModeOverride(@NonNull String providerName, @NonNull String mode) {
|
||||
enforceManageTimeZoneDetectorPermission();
|
||||
|
||||
Preconditions.checkArgument(
|
||||
PRIMARY_PROVIDER_NAME.equals(providerName)
|
||||
|| SECONDARY_PROVIDER_NAME.equals(providerName));
|
||||
Preconditions.checkArgument(PROVIDER_MODE_OVERRIDE_DISABLED.equals(mode)
|
||||
|| PROVIDER_MODE_OVERRIDE_SIMULATED.equals(mode)
|
||||
|| PROVIDER_MODE_OVERRIDE_NONE.equals(mode));
|
||||
|
||||
mThreadingDomain.postAndWait(() -> {
|
||||
synchronized (mSharedLock) {
|
||||
switch (providerName) {
|
||||
case PRIMARY_PROVIDER_NAME: {
|
||||
mPrimaryProviderModeOverride = mode;
|
||||
break;
|
||||
}
|
||||
case SECONDARY_PROVIDER_NAME: {
|
||||
mSecondaryProviderModeOverride = mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, BLOCKING_OP_WAIT_DURATION_MILLIS);
|
||||
}
|
||||
|
||||
/** Sets this service into provider state recording mode for tests. */
|
||||
void setProviderStateRecordingEnabled(boolean enabled) {
|
||||
enforceManageTimeZoneDetectorPermission();
|
||||
@@ -457,8 +348,8 @@ public class LocationTimeZoneManagerService extends Binder {
|
||||
* Passes a {@link TestCommand} to the specified provider and waits for the response.
|
||||
*/
|
||||
@NonNull
|
||||
Bundle handleProviderTestCommand(
|
||||
@NonNull String providerName, @NonNull TestCommand testCommand) {
|
||||
Bundle handleProviderTestCommand(@IntRange(from = 0, to = 1) int providerIndex,
|
||||
@NonNull TestCommand testCommand) {
|
||||
enforceManageTimeZoneDetectorPermission();
|
||||
|
||||
// Because this method blocks and posts work to the threading domain thread, it would cause
|
||||
@@ -479,7 +370,7 @@ public class LocationTimeZoneManagerService extends Binder {
|
||||
return;
|
||||
}
|
||||
mLocationTimeZoneDetectorController.handleProviderTestCommand(
|
||||
providerName, testCommand, remoteCallback);
|
||||
providerIndex, testCommand, remoteCallback);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -505,6 +396,17 @@ public class LocationTimeZoneManagerService extends Binder {
|
||||
synchronized (mSharedLock) {
|
||||
ipw.println("LocationTimeZoneManagerService:");
|
||||
ipw.increaseIndent();
|
||||
|
||||
ipw.println("Primary provider config:");
|
||||
ipw.increaseIndent();
|
||||
mPrimaryProviderConfig.dump(ipw, args);
|
||||
ipw.decreaseIndent();
|
||||
|
||||
ipw.println("Secondary provider config:");
|
||||
ipw.increaseIndent();
|
||||
mSecondaryProviderConfig.dump(ipw, args);
|
||||
ipw.decreaseIndent();
|
||||
|
||||
if (mLocationTimeZoneDetectorController == null) {
|
||||
ipw.println("{Stopped}");
|
||||
} else {
|
||||
@@ -541,4 +443,75 @@ public class LocationTimeZoneManagerService extends Binder {
|
||||
android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION,
|
||||
"manage time and time zone detection");
|
||||
}
|
||||
|
||||
/** An inner class for managing a provider's config. */
|
||||
private final class ProviderConfig implements Dumpable {
|
||||
@IntRange(from = 0, to = 1) private final int mIndex;
|
||||
@NonNull private final String mName;
|
||||
@NonNull private final String mServiceAction;
|
||||
|
||||
ProviderConfig(@IntRange(from = 0, to = 1) int index, @NonNull String name,
|
||||
@NonNull String serviceAction) {
|
||||
Preconditions.checkArgument(index >= 0 && index <= 1);
|
||||
mIndex = index;
|
||||
mName = Objects.requireNonNull(name);
|
||||
mServiceAction = Objects.requireNonNull(serviceAction);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
LocationTimeZoneProvider createProvider() {
|
||||
LocationTimeZoneProviderProxy proxy = createProxy();
|
||||
ProviderMetricsLogger providerMetricsLogger = new RealProviderMetricsLogger(mIndex);
|
||||
return new BinderLocationTimeZoneProvider(
|
||||
providerMetricsLogger, mThreadingDomain, mName, proxy);
|
||||
}
|
||||
|
||||
@GuardedBy("mSharedLock")
|
||||
@Override
|
||||
public void dump(IndentingPrintWriter ipw, String[] args) {
|
||||
ipw.printf("getMode()=%s\n", getMode());
|
||||
ipw.printf("getPackageName()=%s\n", getPackageName());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private LocationTimeZoneProviderProxy createProxy() {
|
||||
String mode = getMode();
|
||||
if (Objects.equals(mode, PROVIDER_MODE_SIMULATED)) {
|
||||
return new SimulatedLocationTimeZoneProviderProxy(mContext, mThreadingDomain);
|
||||
} else if (Objects.equals(mode, PROVIDER_MODE_DISABLED)) {
|
||||
return new NullLocationTimeZoneProviderProxy(mContext, mThreadingDomain);
|
||||
} else {
|
||||
// mode == PROVIDER_MODE_OVERRIDE_ENABLED (or unknown).
|
||||
return createRealProxy();
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the mode of the provider. */
|
||||
@NonNull
|
||||
private String getMode() {
|
||||
if (mIndex == 0) {
|
||||
return mServiceConfigAccessor.getPrimaryLocationTimeZoneProviderMode();
|
||||
} else {
|
||||
return mServiceConfigAccessor.getSecondaryLocationTimeZoneProviderMode();
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private RealLocationTimeZoneProviderProxy createRealProxy() {
|
||||
String providerServiceAction = mServiceAction;
|
||||
String providerPackageName = getPackageName();
|
||||
return new RealLocationTimeZoneProviderProxy(
|
||||
mContext, mHandler, mThreadingDomain, providerServiceAction,
|
||||
providerPackageName);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getPackageName() {
|
||||
if (mIndex == 0) {
|
||||
return mServiceConfigAccessor.getPrimaryLocationTimeZoneProviderPackageName();
|
||||
} else {
|
||||
return mServiceConfigAccessor.getSecondaryLocationTimeZoneProviderPackageName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,19 +16,25 @@
|
||||
package com.android.server.timezonedetector.location;
|
||||
|
||||
import static android.app.time.LocationTimeZoneManager.DUMP_STATE_OPTION_PROTO;
|
||||
import static android.app.time.LocationTimeZoneManager.PRIMARY_PROVIDER_NAME;
|
||||
import static android.app.time.LocationTimeZoneManager.PROVIDER_MODE_OVERRIDE_DISABLED;
|
||||
import static android.app.time.LocationTimeZoneManager.PROVIDER_MODE_OVERRIDE_NONE;
|
||||
import static android.app.time.LocationTimeZoneManager.PROVIDER_MODE_OVERRIDE_SIMULATED;
|
||||
import static android.app.time.LocationTimeZoneManager.SECONDARY_PROVIDER_NAME;
|
||||
import static android.app.time.LocationTimeZoneManager.SERVICE_NAME;
|
||||
import static android.app.time.LocationTimeZoneManager.SHELL_COMMAND_DUMP_STATE;
|
||||
import static android.app.time.LocationTimeZoneManager.SHELL_COMMAND_RECORD_PROVIDER_STATES;
|
||||
import static android.app.time.LocationTimeZoneManager.SHELL_COMMAND_SEND_PROVIDER_TEST_COMMAND;
|
||||
import static android.app.time.LocationTimeZoneManager.SHELL_COMMAND_SET_PROVIDER_MODE_OVERRIDE;
|
||||
import static android.app.time.LocationTimeZoneManager.SHELL_COMMAND_START;
|
||||
import static android.app.time.LocationTimeZoneManager.SHELL_COMMAND_STOP;
|
||||
import static android.provider.DeviceConfig.NAMESPACE_SYSTEM_TIME;
|
||||
|
||||
import static com.android.server.timedetector.ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_FEATURE_SUPPORTED;
|
||||
import static com.android.server.timedetector.ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT;
|
||||
import static com.android.server.timedetector.ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_OVERRIDE;
|
||||
import static com.android.server.timedetector.ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_UNCERTAINTY_DELAY_MILLIS;
|
||||
import static com.android.server.timedetector.ServerFlags.KEY_LOCATION_TIME_ZONE_PROVIDER_INITIALIZATION_TIMEOUT_FUZZ_MILLIS;
|
||||
import static com.android.server.timedetector.ServerFlags.KEY_LOCATION_TIME_ZONE_PROVIDER_INITIALIZATION_TIMEOUT_MILLIS;
|
||||
import static com.android.server.timedetector.ServerFlags.KEY_PRIMARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE;
|
||||
import static com.android.server.timedetector.ServerFlags.KEY_SECONDARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE;
|
||||
import static com.android.server.timezonedetector.ServiceConfigAccessor.PROVIDER_MODE_DISABLED;
|
||||
import static com.android.server.timezonedetector.ServiceConfigAccessor.PROVIDER_MODE_ENABLED;
|
||||
import static com.android.server.timezonedetector.ServiceConfigAccessor.PROVIDER_MODE_SIMULATED;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_DESTROYED;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_PERM_FAILED;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STARTED_CERTAIN;
|
||||
@@ -53,16 +59,12 @@ import com.android.server.timezonedetector.location.LocationTimeZoneProvider.Pro
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/** Implements the shell command interface for {@link LocationTimeZoneManagerService}. */
|
||||
class LocationTimeZoneManagerShellCommand extends ShellCommand {
|
||||
|
||||
private static final List<String> VALID_PROVIDER_NAMES =
|
||||
Arrays.asList(PRIMARY_PROVIDER_NAME, SECONDARY_PROVIDER_NAME);
|
||||
|
||||
private final LocationTimeZoneManagerService mService;
|
||||
|
||||
LocationTimeZoneManagerShellCommand(LocationTimeZoneManagerService service) {
|
||||
@@ -82,9 +84,6 @@ class LocationTimeZoneManagerShellCommand extends ShellCommand {
|
||||
case SHELL_COMMAND_STOP: {
|
||||
return runStop();
|
||||
}
|
||||
case SHELL_COMMAND_SET_PROVIDER_MODE_OVERRIDE: {
|
||||
return runSetProviderModeOverride();
|
||||
}
|
||||
case SHELL_COMMAND_SEND_PROVIDER_TEST_COMMAND: {
|
||||
return runSendProviderTestCommand();
|
||||
}
|
||||
@@ -110,10 +109,6 @@ class LocationTimeZoneManagerShellCommand extends ShellCommand {
|
||||
pw.println(" Starts the location_time_zone_manager, creating time zone providers.");
|
||||
pw.printf(" %s\n", SHELL_COMMAND_STOP);
|
||||
pw.println(" Stops the location_time_zone_manager, destroying time zone providers.");
|
||||
pw.printf(" %s <provider name> <mode>\n", SHELL_COMMAND_SET_PROVIDER_MODE_OVERRIDE);
|
||||
pw.println(" Sets a provider into a test mode next time the service started.");
|
||||
pw.printf(" Values: %s|%s|%s\n", PROVIDER_MODE_OVERRIDE_NONE,
|
||||
PROVIDER_MODE_OVERRIDE_DISABLED, PROVIDER_MODE_OVERRIDE_SIMULATED);
|
||||
pw.printf(" %s (true|false)\n", SHELL_COMMAND_RECORD_PROVIDER_STATES);
|
||||
pw.printf(" Enables / disables provider state recording mode. See also %s. The default"
|
||||
+ " state is always \"false\".\n", SHELL_COMMAND_DUMP_STATE);
|
||||
@@ -126,11 +121,11 @@ class LocationTimeZoneManagerShellCommand extends ShellCommand {
|
||||
pw.println(" Dumps Location Time Zone Manager state for tests as text or binary proto"
|
||||
+ " form.");
|
||||
pw.println(" See the LocationTimeZoneManagerServiceStateProto definition for details.");
|
||||
pw.printf(" %s <provider name> <test command>\n",
|
||||
pw.printf(" %s <provider index> <test command>\n",
|
||||
SHELL_COMMAND_SEND_PROVIDER_TEST_COMMAND);
|
||||
pw.println(" Passes a test command to the named provider.");
|
||||
pw.println();
|
||||
pw.printf("<provider name> = One of %s\n", VALID_PROVIDER_NAMES);
|
||||
pw.println("<provider index> = 0 (primary), 1 (secondary)");
|
||||
pw.println();
|
||||
pw.printf("%s details:\n", SHELL_COMMAND_SEND_PROVIDER_TEST_COMMAND);
|
||||
pw.println();
|
||||
@@ -146,6 +141,47 @@ class LocationTimeZoneManagerShellCommand extends ShellCommand {
|
||||
pw.println();
|
||||
pw.println("Test commands cannot currently be passed to real provider implementations.");
|
||||
pw.println();
|
||||
pw.printf("This service is also affected by the following device_config flags in the"
|
||||
+ " %s namespace:\n", NAMESPACE_SYSTEM_TIME);
|
||||
pw.printf(" %s - [default=true], only observed if the feature is enabled in config,"
|
||||
+ "set this to false to disable the feature\n",
|
||||
KEY_LOCATION_TIME_ZONE_DETECTION_FEATURE_SUPPORTED);
|
||||
pw.printf(" %s - [default=false]. Only used if the device does not have an explicit"
|
||||
+ " 'location time zone detection enabled' setting configured [*].\n",
|
||||
KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT);
|
||||
pw.printf(" %s - [default=<unset>]. Used to override the device's 'location time zone"
|
||||
+ " detection enabled' setting [*]\n",
|
||||
KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_OVERRIDE);
|
||||
pw.printf(" %s - Overrides the mode of the primary provider. Values=%s|%s|%s\n",
|
||||
KEY_PRIMARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE,
|
||||
PROVIDER_MODE_DISABLED, PROVIDER_MODE_ENABLED, PROVIDER_MODE_SIMULATED);
|
||||
pw.printf(" %s - Overrides the mode of the secondary provider. Values=%s|%s|%s\n",
|
||||
KEY_SECONDARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE,
|
||||
PROVIDER_MODE_DISABLED, PROVIDER_MODE_ENABLED, PROVIDER_MODE_SIMULATED);
|
||||
pw.printf(" %s - \n",
|
||||
KEY_SECONDARY_LOCATION_TIME_ZONE_PROVIDER_MODE_OVERRIDE);
|
||||
pw.printf(" %s - Sets the amount of time the service waits when uncertain before making"
|
||||
+ " an 'uncertain' suggestion to the time zone detector.\n",
|
||||
KEY_LOCATION_TIME_ZONE_DETECTION_UNCERTAINTY_DELAY_MILLIS);
|
||||
pw.printf(" %s - Sets the initialization time passed to the location time zone providers"
|
||||
+ "\n",
|
||||
KEY_LOCATION_TIME_ZONE_PROVIDER_INITIALIZATION_TIMEOUT_MILLIS);
|
||||
pw.printf(" %s - Sets the amount of extra time added to the location time zone providers"
|
||||
+ " initialization time\n",
|
||||
KEY_LOCATION_TIME_ZONE_PROVIDER_INITIALIZATION_TIMEOUT_FUZZ_MILLIS);
|
||||
pw.println();
|
||||
pw.println("[*] The user must still have location = on / auto time zone detection = on");
|
||||
pw.println();
|
||||
pw.printf("Typically, use '%s' to stop the service before setting individual"
|
||||
+ " flags and '%s' after to restart it.\n",
|
||||
SHELL_COMMAND_STOP, SHELL_COMMAND_START);
|
||||
pw.println();
|
||||
pw.println("Example:");
|
||||
pw.printf(" $ adb shell cmd device_config put %s %s %s\n",
|
||||
NAMESPACE_SYSTEM_TIME, KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT,
|
||||
"true");
|
||||
pw.println("See adb shell cmd device_config for more information.");
|
||||
pw.println();
|
||||
}
|
||||
|
||||
private int runStart() {
|
||||
@@ -172,21 +208,6 @@ class LocationTimeZoneManagerShellCommand extends ShellCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runSetProviderModeOverride() {
|
||||
PrintWriter outPrintWriter = getOutPrintWriter();
|
||||
try {
|
||||
String providerName = getNextArgRequired();
|
||||
String modeOverride = getNextArgRequired();
|
||||
outPrintWriter.println("Setting provider mode override for " + providerName
|
||||
+ " to " + modeOverride);
|
||||
mService.setProviderModeOverride(providerName, modeOverride);
|
||||
} catch (RuntimeException e) {
|
||||
reportError(e);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runRecordProviderStates() {
|
||||
PrintWriter outPrintWriter = getOutPrintWriter();
|
||||
boolean enabled;
|
||||
@@ -293,10 +314,10 @@ class LocationTimeZoneManagerShellCommand extends ShellCommand {
|
||||
private int runSendProviderTestCommand() {
|
||||
PrintWriter outPrintWriter = getOutPrintWriter();
|
||||
|
||||
String providerName;
|
||||
int providerIndex;
|
||||
TestCommand testCommand;
|
||||
try {
|
||||
providerName = validateProviderName(getNextArgRequired());
|
||||
providerIndex = parseProviderIndex(getNextArgRequired());
|
||||
testCommand = createTestCommandFromNextShellArg();
|
||||
} catch (RuntimeException e) {
|
||||
reportError(e);
|
||||
@@ -304,9 +325,9 @@ class LocationTimeZoneManagerShellCommand extends ShellCommand {
|
||||
}
|
||||
|
||||
outPrintWriter.println("Injecting testCommand=" + testCommand
|
||||
+ " to providerName=" + providerName);
|
||||
+ " to providerIndex=" + providerIndex);
|
||||
try {
|
||||
Bundle result = mService.handleProviderTestCommand(providerName, testCommand);
|
||||
Bundle result = mService.handleProviderTestCommand(providerIndex, testCommand);
|
||||
outPrintWriter.println(result);
|
||||
} catch (RuntimeException e) {
|
||||
reportError(e);
|
||||
@@ -326,11 +347,11 @@ class LocationTimeZoneManagerShellCommand extends ShellCommand {
|
||||
e.printStackTrace(errPrintWriter);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
static String validateProviderName(@NonNull String value) {
|
||||
if (!VALID_PROVIDER_NAMES.contains(value)) {
|
||||
throw new IllegalArgumentException("Unknown provider name=" + value);
|
||||
private static int parseProviderIndex(@NonNull String providerIndexString) {
|
||||
int providerIndex = Integer.parseInt(providerIndexString);
|
||||
if (providerIndex < 0 || providerIndex > 1) {
|
||||
throw new IllegalArgumentException(providerIndexString);
|
||||
}
|
||||
return value;
|
||||
return providerIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,15 +62,17 @@ class RealLocationTimeZoneProviderProxy extends LocationTimeZoneProviderProxy im
|
||||
RealLocationTimeZoneProviderProxy(
|
||||
@NonNull Context context, @NonNull Handler handler,
|
||||
@NonNull ThreadingDomain threadingDomain, @NonNull String action,
|
||||
int enableOverlayResId, int nonOverlayPackageResId) {
|
||||
@NonNull String providerPackageName) {
|
||||
super(context, threadingDomain);
|
||||
mManagerProxy = null;
|
||||
mRequest = TimeZoneProviderRequest.createStopUpdatesRequest();
|
||||
|
||||
Objects.requireNonNull(providerPackageName);
|
||||
mServiceWatcher = ServiceWatcher.create(context,
|
||||
handler,
|
||||
"RealLocationTimeZoneProviderProxy",
|
||||
new CurrentUserServiceSupplier(context, action, enableOverlayResId,
|
||||
nonOverlayPackageResId, BIND_TIME_ZONE_PROVIDER_SERVICE,
|
||||
new CurrentUserServiceSupplier(context, action,
|
||||
providerPackageName, BIND_TIME_ZONE_PROVIDER_SERVICE,
|
||||
INSTALL_LOCATION_TIME_ZONE_PROVIDER_SERVICE),
|
||||
this);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user