summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/timedetector/ConfigurationInternal.java34
-rw-r--r--services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java10
-rw-r--r--services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java6
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorInternal.java35
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java39
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorService.java29
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java6
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java25
-rw-r--r--services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java25
-rw-r--r--services/core/java/com/android/server/timezonedetector/CurrentUserIdentityInjector.java46
-rw-r--r--services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java12
-rw-r--r--services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java6
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternal.java35
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java39
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java26
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java6
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/ConfigurationInternalTest.java145
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/FakeServiceConfigAccessor.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java67
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java107
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java86
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java78
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java201
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/FakeServiceConfigAccessor.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java57
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/TestCurrentUserIdentityInjector.java34
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorInternalImplTest.java96
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java70
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java90
30 files changed, 938 insertions, 495 deletions
diff --git a/services/core/java/com/android/server/timedetector/ConfigurationInternal.java b/services/core/java/com/android/server/timedetector/ConfigurationInternal.java
index d9a4266e2812..4f221b532b75 100644
--- a/services/core/java/com/android/server/timedetector/ConfigurationInternal.java
+++ b/services/core/java/com/android/server/timedetector/ConfigurationInternal.java
@@ -155,21 +155,33 @@ public final class ConfigurationInternal {
return UserHandle.of(mUserId);
}
- /** Returns true if the user allowed to modify time zone configuration. */
+ /**
+ * Returns true if the user is allowed to modify time configuration, e.g. can be false due
+ * to device policy (enterprise).
+ *
+ * <p>See also {@link #createCapabilitiesAndConfig(boolean)} for situations where this
+ * value are ignored.
+ */
public boolean isUserConfigAllowed() {
return mUserConfigAllowed;
}
- /** Returns a {@link TimeCapabilitiesAndConfig} objects based on configuration values. */
- public TimeCapabilitiesAndConfig capabilitiesAndConfig() {
- return new TimeCapabilitiesAndConfig(timeCapabilities(), timeConfiguration());
+ /**
+ * Returns a {@link TimeCapabilitiesAndConfig} objects based on configuration values.
+ *
+ * @param bypassUserPolicyChecks {@code true} for device policy manager use cases where device
+ * policy restrictions that should apply to actual users can be ignored
+ */
+ public TimeCapabilitiesAndConfig createCapabilitiesAndConfig(boolean bypassUserPolicyChecks) {
+ return new TimeCapabilitiesAndConfig(
+ timeCapabilities(bypassUserPolicyChecks), timeConfiguration());
}
- private TimeCapabilities timeCapabilities() {
+ private TimeCapabilities timeCapabilities(boolean bypassUserPolicyChecks) {
UserHandle userHandle = UserHandle.of(mUserId);
TimeCapabilities.Builder builder = new TimeCapabilities.Builder(userHandle);
- boolean allowConfigDateTime = isUserConfigAllowed();
+ boolean allowConfigDateTime = isUserConfigAllowed() || bypassUserPolicyChecks;
boolean deviceHasAutoTimeDetection = isAutoDetectionSupported();
final @CapabilityState int configureAutoDetectionEnabledCapability;
@@ -186,15 +198,15 @@ public final class ConfigurationInternal {
// current logic above, this could lead to a situation where a device hardware does not
// support auto detection, the device has been forced into "auto" mode by an admin and the
// user is unable to disable auto detection.
- final @CapabilityState int suggestManualTimeZoneCapability;
+ final @CapabilityState int suggestManualTimeCapability;
if (!allowConfigDateTime) {
- suggestManualTimeZoneCapability = CAPABILITY_NOT_ALLOWED;
+ suggestManualTimeCapability = CAPABILITY_NOT_ALLOWED;
} else if (getAutoDetectionEnabledBehavior()) {
- suggestManualTimeZoneCapability = CAPABILITY_NOT_APPLICABLE;
+ suggestManualTimeCapability = CAPABILITY_NOT_APPLICABLE;
} else {
- suggestManualTimeZoneCapability = CAPABILITY_POSSESSED;
+ suggestManualTimeCapability = CAPABILITY_POSSESSED;
}
- builder.setSetManualTimeCapability(suggestManualTimeZoneCapability);
+ builder.setSetManualTimeCapability(suggestManualTimeCapability);
return builder.build();
}
diff --git a/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java b/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java
index 25a74ceeb56d..a39f64c1f82a 100644
--- a/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java
+++ b/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java
@@ -53,11 +53,15 @@ public interface ServiceConfigAccessor {
/**
* Updates the configuration properties that control a device's time behavior.
*
- * <p>This method returns {@code true} if the configuration was changed,
- * {@code false} otherwise.
+ * <p>This method returns {@code true} if the configuration was changed, {@code false}
+ * otherwise.
+ *
+ * @param bypassUserPolicyChecks {@code true} for device policy manager use cases where device
+ * policy restrictions that should apply to actual users can be ignored
*/
boolean updateConfiguration(
- @UserIdInt int userId, @NonNull TimeConfiguration requestedConfiguration);
+ @UserIdInt int userId, @NonNull TimeConfiguration requestedConfiguration,
+ boolean bypassUserPolicyChecks);
/**
* Returns a snapshot of the configuration that controls time zone detector behavior for the
diff --git a/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java b/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java
index 84013a755035..71acf35bd3a2 100644
--- a/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java
+++ b/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java
@@ -194,11 +194,11 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
@Override
public synchronized boolean updateConfiguration(@UserIdInt int userId,
- @NonNull TimeConfiguration requestedConfiguration) {
+ @NonNull TimeConfiguration requestedConfiguration, boolean bypassUserPolicyChecks) {
Objects.requireNonNull(requestedConfiguration);
- TimeCapabilitiesAndConfig capabilitiesAndConfig =
- getCurrentUserConfigurationInternal().capabilitiesAndConfig();
+ TimeCapabilitiesAndConfig capabilitiesAndConfig = getCurrentUserConfigurationInternal()
+ .createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
TimeConfiguration oldConfiguration = capabilitiesAndConfig.getConfiguration();
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java b/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java
index eae12c28d2b9..24533d79fb18 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java
@@ -17,16 +17,47 @@
package com.android.server.timedetector;
import android.annotation.NonNull;
+import android.app.time.TimeCapabilitiesAndConfig;
+import android.app.time.TimeConfiguration;
+import android.app.timedetector.ManualTimeSuggestion;
/**
- * The internal (in-process) system server API for the {@link
- * com.android.server.timedetector.TimeDetectorService}.
+ * The internal (in-process) system server API for the time detector service.
*
* <p>The methods on this class can be called from any thread.
+ *
+ * <p>Methods marked with "[For device policy manager only]" are for use by the device policy
+ * manager to set device state and must not enforce device policy restrictions.
+ *
* @hide
*/
public interface TimeDetectorInternal {
+ /**
+ * [For device policy manager only] Returns a snapshot of the configuration that controls time
+ * detector behavior for the current user.
+ */
+ @NonNull
+ TimeCapabilitiesAndConfig getCapabilitiesAndConfigForDpm();
+
+ /**
+ * [For device policy manager only] Updates the configuration properties that control a device's
+ * time behavior for the current user.
+ *
+ * <p>This method returns {@code true} if the configuration was changed, {@code false}
+ * otherwise.
+ */
+ boolean updateConfigurationForDpm(@NonNull TimeConfiguration configuration);
+
+ /**
+ * [For device policy manager only] Attempts to set the device to a manually entered time.
+ * Returns {@code false} if the suggestion is invalid, or the device configuration prevents the
+ * suggestion being used, {@code true} if the suggestion has been accepted. A suggestion that is
+ * valid but does not change the time because it matches the current device time is considered
+ * accepted.
+ */
+ boolean setManualTimeForDpm(@NonNull ManualTimeSuggestion manualTimeSuggestion);
+
/** Used to pass new network time suggestions to the time detector. */
void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java
index 5a3e20ebd6cd..9839de080690 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java
@@ -17,9 +17,14 @@
package com.android.server.timedetector;
import android.annotation.NonNull;
+import android.app.time.TimeCapabilitiesAndConfig;
+import android.app.time.TimeConfiguration;
+import android.app.timedetector.ManualTimeSuggestion;
import android.content.Context;
import android.os.Handler;
+import com.android.server.timezonedetector.CurrentUserIdentityInjector;
+
import java.util.Objects;
/**
@@ -31,16 +36,50 @@ public class TimeDetectorInternalImpl implements TimeDetectorInternal {
@NonNull private final Context mContext;
@NonNull private final Handler mHandler;
+ @NonNull private final CurrentUserIdentityInjector mCurrentUserIdentityInjector;
+ @NonNull private final ServiceConfigAccessor mServiceConfigAccessor;
@NonNull private final TimeDetectorStrategy mTimeDetectorStrategy;
public TimeDetectorInternalImpl(@NonNull Context context, @NonNull Handler handler,
+ @NonNull CurrentUserIdentityInjector currentUserIdentityInjector,
+ @NonNull ServiceConfigAccessor serviceConfigAccessor,
@NonNull TimeDetectorStrategy timeDetectorStrategy) {
mContext = Objects.requireNonNull(context);
mHandler = Objects.requireNonNull(handler);
+ mCurrentUserIdentityInjector = Objects.requireNonNull(currentUserIdentityInjector);
+ mServiceConfigAccessor = Objects.requireNonNull(serviceConfigAccessor);
mTimeDetectorStrategy = Objects.requireNonNull(timeDetectorStrategy);
}
@Override
+ @NonNull
+ public TimeCapabilitiesAndConfig getCapabilitiesAndConfigForDpm() {
+ int currentUserId = mCurrentUserIdentityInjector.getCurrentUserId();
+ final boolean bypassUserPolicyCheck = true;
+ ConfigurationInternal configurationInternal =
+ mServiceConfigAccessor.getConfigurationInternal(currentUserId);
+ return configurationInternal.createCapabilitiesAndConfig(bypassUserPolicyCheck);
+ }
+
+ @Override
+ public boolean updateConfigurationForDpm(@NonNull TimeConfiguration configuration) {
+ Objects.requireNonNull(configuration);
+
+ int currentUserId = mCurrentUserIdentityInjector.getCurrentUserId();
+ final boolean bypassUserPolicyCheck = true;
+ return mServiceConfigAccessor.updateConfiguration(
+ currentUserId, configuration, bypassUserPolicyCheck);
+ }
+
+ @Override
+ public boolean setManualTimeForDpm(@NonNull ManualTimeSuggestion timeSignal) {
+ Objects.requireNonNull(timeSignal);
+
+ int userId = mCurrentUserIdentityInjector.getCurrentUserId();
+ return mTimeDetectorStrategy.suggestManualTime(userId, timeSignal, false);
+ }
+
+ @Override
public void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal) {
Objects.requireNonNull(timeSignal);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 39672b847f30..64adbb680653 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -49,6 +49,7 @@ import com.android.internal.util.DumpUtils;
import com.android.server.FgThread;
import com.android.server.SystemService;
import com.android.server.timezonedetector.CallerIdentityInjector;
+import com.android.server.timezonedetector.CurrentUserIdentityInjector;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -84,8 +85,11 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
TimeDetectorStrategyImpl.create(context, handler, serviceConfigAccessor);
// Create and publish the local service for use by internal callers.
- TimeDetectorInternal internal =
- new TimeDetectorInternalImpl(context, handler, timeDetectorStrategy);
+ CurrentUserIdentityInjector currentUserIdentityInjector =
+ CurrentUserIdentityInjector.REAL;
+ TimeDetectorInternal internal = new TimeDetectorInternalImpl(
+ context, handler, currentUserIdentityInjector, serviceConfigAccessor,
+ timeDetectorStrategy);
publishLocalService(TimeDetectorInternal.class, internal);
CallerIdentityInjector callerIdentityInjector = CallerIdentityInjector.REAL;
@@ -147,7 +151,8 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
try {
ConfigurationInternal configurationInternal =
mServiceConfigAccessor.getConfigurationInternal(userId);
- return configurationInternal.capabilitiesAndConfig();
+ final boolean bypassUserPolicyCheck = false;
+ return configurationInternal.createCapabilitiesAndConfig(bypassUserPolicyCheck);
} finally {
mCallerIdentityInjector.restoreCallingIdentity(token);
}
@@ -170,7 +175,9 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
final long token = mCallerIdentityInjector.clearCallingIdentity();
try {
- return mServiceConfigAccessor.updateConfiguration(resolvedUserId, configuration);
+ final boolean bypassUserPolicyCheck = false;
+ return mServiceConfigAccessor.updateConfiguration(
+ resolvedUserId, configuration, bypassUserPolicyCheck);
} finally {
mCallerIdentityInjector.restoreCallingIdentity(token);
}
@@ -313,7 +320,9 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
int userId = mCallerIdentityInjector.getCallingUserId();
final long token = Binder.clearCallingIdentity();
try {
- return mTimeDetectorStrategy.suggestManualTime(userId, timeSignal);
+ final boolean bypassUserPolicyChecks = false;
+ return mTimeDetectorStrategy.suggestManualTime(
+ userId, timeSignal, bypassUserPolicyChecks);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -335,7 +344,9 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
int userId = mCallerIdentityInjector.getCallingUserId();
final long token = mCallerIdentityInjector.clearCallingIdentity();
try {
- return mTimeDetectorStrategy.suggestManualTime(userId, timeSignal);
+ final boolean bypassUserPolicyChecks = false;
+ return mTimeDetectorStrategy.suggestManualTime(
+ userId, timeSignal, bypassUserPolicyChecks);
} finally {
mCallerIdentityInjector.restoreCallingIdentity(token);
}
@@ -400,19 +411,19 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
}
private void enforceSuggestManualTimePermission() {
- mContext.enforceCallingOrSelfPermission(
+ mContext.enforceCallingPermission(
android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE,
"suggest manual time and time zone");
}
private void enforceSuggestNetworkTimePermission() {
- mContext.enforceCallingOrSelfPermission(
+ mContext.enforceCallingPermission(
android.Manifest.permission.SET_TIME,
"set time");
}
private void enforceSuggestGnssTimePermission() {
- mContext.enforceCallingOrSelfPermission(
+ mContext.enforceCallingPermission(
android.Manifest.permission.SET_TIME,
"suggest gnss time");
}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index bc86ed057fb6..03f236d9b30d 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -93,8 +93,12 @@ public interface TimeDetectorStrategy extends Dumpable {
* invalid, or the device configuration prevented the suggestion being used, {@code true} if the
* suggestion was accepted. A suggestion that is valid but does not change the time because it
* matches the current device time is considered accepted.
+ *
+ * @param bypassUserPolicyChecks {@code true} for device policy manager use cases where device
+ * policy restrictions that should apply to actual users can be ignored
*/
- boolean suggestManualTime(@UserIdInt int userId, @NonNull ManualTimeSuggestion timeSuggestion);
+ boolean suggestManualTime(@UserIdInt int userId, @NonNull ManualTimeSuggestion timeSuggestion,
+ boolean bypassUserPolicyChecks);
/** Processes the suggested time from network sources. */
void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSuggestion);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index c3f05cc22495..3cee19cbe385 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -16,6 +16,8 @@
package com.android.server.timedetector;
+import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
+
import static com.android.server.SystemClockTime.TIME_CONFIDENCE_HIGH;
import static com.android.server.SystemClockTime.TIME_CONFIDENCE_LOW;
import static com.android.server.timedetector.TimeDetectorStrategy.originToString;
@@ -26,6 +28,8 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.time.ExternalTimeSuggestion;
+import android.app.time.TimeCapabilities;
+import android.app.time.TimeCapabilitiesAndConfig;
import android.app.time.TimeState;
import android.app.time.UnixEpochTime;
import android.app.timedetector.ManualTimeSuggestion;
@@ -244,7 +248,8 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
@Override
public synchronized boolean suggestManualTime(
- @UserIdInt int userId, @NonNull ManualTimeSuggestion suggestion) {
+ @UserIdInt int userId, @NonNull ManualTimeSuggestion suggestion,
+ boolean bypassUserPolicyChecks) {
ConfigurationInternal currentUserConfig = mCurrentConfigurationInternal;
if (currentUserConfig.getUserId() != userId) {
@@ -256,6 +261,18 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
}
Objects.requireNonNull(suggestion);
+ String cause = "Manual time suggestion received: suggestion=" + suggestion;
+
+ TimeCapabilitiesAndConfig capabilitiesAndConfig =
+ currentUserConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
+ TimeCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
+ if (capabilities.getSetManualTimeCapability() != CAPABILITY_POSSESSED) {
+ Slog.i(LOG_TAG, "User does not have the capability needed to set the time manually"
+ + ": capabilities=" + capabilities
+ + ", suggestion=" + suggestion
+ + ", cause=" + cause);
+ return false;
+ }
final UnixEpochTime newUnixEpochTime = suggestion.getUnixEpochTime();
@@ -263,7 +280,6 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
return false;
}
- String cause = "Manual time suggestion received: suggestion=" + suggestion;
return setSystemClockAndConfidenceIfRequired(ORIGIN_MANUAL, newUnixEpochTime, cause);
}
@@ -428,7 +444,10 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
ipw.println("mLastAutoSystemClockTimeSet=" + mLastAutoSystemClockTimeSet);
ipw.println("mCurrentConfigurationInternal=" + mCurrentConfigurationInternal);
- ipw.println("[Capabilities=" + mCurrentConfigurationInternal.capabilitiesAndConfig() + "]");
+ final boolean bypassUserPolicyChecks = false;
+ ipw.println("[Capabilities="
+ + mCurrentConfigurationInternal.createCapabilitiesAndConfig(bypassUserPolicyChecks)
+ + "]");
long elapsedRealtimeMillis = mEnvironment.elapsedRealtimeMillis();
ipw.printf("mEnvironment.elapsedRealtimeMillis()=%s (%s)\n",
Duration.ofMillis(elapsedRealtimeMillis), elapsedRealtimeMillis);
diff --git a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
index d413febdcdb4..8e2a5f472558 100644
--- a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
+++ b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
@@ -147,7 +147,13 @@ public final class ConfigurationInternal {
return UserHandle.of(mUserId);
}
- /** Returns true if the user allowed to modify time zone configuration. */
+ /**
+ * Returns true if the user is allowed to modify time zone configuration, e.g. can be false due
+ * to device policy (enterprise).
+ *
+ * <p>See also {@link #createCapabilitiesAndConfig(boolean)} for situations where this value
+ * are ignored.
+ */
public boolean isUserConfigAllowed() {
return mUserConfigAllowed;
}
@@ -190,17 +196,24 @@ public final class ConfigurationInternal {
|| getGeoDetectionRunInBackgroundEnabled());
}
- /** Creates a {@link TimeZoneCapabilitiesAndConfig} object using the configuration values. */
- public TimeZoneCapabilitiesAndConfig createCapabilitiesAndConfig() {
- return new TimeZoneCapabilitiesAndConfig(asCapabilities(), asConfiguration());
+ /**
+ * Creates a {@link TimeZoneCapabilitiesAndConfig} object using the configuration values.
+ *
+ * @param bypassUserPolicyChecks {@code true} for device policy manager use cases where device
+ * policy restrictions that should apply to actual users can be ignored
+ */
+ public TimeZoneCapabilitiesAndConfig createCapabilitiesAndConfig(
+ boolean bypassUserPolicyChecks) {
+ return new TimeZoneCapabilitiesAndConfig(
+ asCapabilities(bypassUserPolicyChecks), asConfiguration());
}
@NonNull
- private TimeZoneCapabilities asCapabilities() {
+ private TimeZoneCapabilities asCapabilities(boolean bypassUserPolicyChecks) {
UserHandle userHandle = UserHandle.of(mUserId);
TimeZoneCapabilities.Builder builder = new TimeZoneCapabilities.Builder(userHandle);
- boolean allowConfigDateTime = isUserConfigAllowed();
+ boolean allowConfigDateTime = isUserConfigAllowed() || bypassUserPolicyChecks;
// Automatic time zone detection is only supported on devices if there is a telephony
// network available or geolocation time zone detection is possible.
diff --git a/services/core/java/com/android/server/timezonedetector/CurrentUserIdentityInjector.java b/services/core/java/com/android/server/timezonedetector/CurrentUserIdentityInjector.java
new file mode 100644
index 000000000000..f96b76dca929
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/CurrentUserIdentityInjector.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timezonedetector;
+
+import android.annotation.UserIdInt;
+import android.app.ActivityManagerInternal;
+
+import com.android.server.LocalServices;
+
+/**
+ * An interface to access the current user identity in an easy to fake for tests way.
+ */
+public interface CurrentUserIdentityInjector {
+
+ /** A singleton for the real implementation of {@link CurrentUserIdentityInjector}. */
+ CurrentUserIdentityInjector REAL = new Real();
+
+ /** A {@link ActivityManagerInternal#getCurrentUserId()} call. */
+ @UserIdInt int getCurrentUserId();
+
+ /** The real implementation of {@link CurrentUserIdentityInjector}. */
+ class Real implements CurrentUserIdentityInjector {
+
+ protected Real() {
+ }
+
+ @Override
+ public int getCurrentUserId() {
+ return LocalServices.getService(ActivityManagerInternal.class).getCurrentUserId();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
index 692b0cc795f5..8da5d6aefdd6 100644
--- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
+++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
@@ -81,11 +81,15 @@ public interface ServiceConfigAccessor {
/**
* Updates the configuration properties that control a device's time zone behavior.
*
- * <p>This method returns {@code true} if the configuration was changed,
- * {@code false} otherwise.
+ * <p>This method returns {@code true} if the configuration was changed, {@code false}
+ * otherwise.
+ *
+ * @param bypassUserPolicyChecks {@code true} for device policy manager use cases where device
+ * policy restrictions that should apply to actual users can be ignored
*/
- boolean updateConfiguration(@UserIdInt int userId,
- @NonNull TimeZoneConfiguration requestedConfiguration);
+ boolean updateConfiguration(
+ @UserIdInt int userId, @NonNull TimeZoneConfiguration requestedConfiguration,
+ boolean bypassUserPolicyChecks);
/**
* Returns a snapshot of the configuration that controls time zone detector behavior for the
diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
index 7173f6008177..e2f42467c550 100644
--- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
@@ -234,11 +234,11 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
@Override
public synchronized boolean updateConfiguration(@UserIdInt int userId,
- @NonNull TimeZoneConfiguration requestedConfiguration) {
+ @NonNull TimeZoneConfiguration requestedConfiguration, boolean bypassUserPolicyChecks) {
Objects.requireNonNull(requestedConfiguration);
- TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
- getConfigurationInternal(userId).createCapabilitiesAndConfig();
+ TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = getConfigurationInternal(userId)
+ .createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
TimeZoneConfiguration oldConfiguration = capabilitiesAndConfig.getConfiguration();
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternal.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternal.java
index b6ce8026a2dc..80cf1d6b9031 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternal.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternal.java
@@ -17,17 +17,48 @@
package com.android.server.timezonedetector;
import android.annotation.NonNull;
+import android.app.time.TimeZoneCapabilitiesAndConfig;
+import android.app.time.TimeZoneConfiguration;
+import android.app.timezonedetector.ManualTimeZoneSuggestion;
/**
- * The internal (in-process) system server API for the {@link
- * com.android.server.timezonedetector.TimeZoneDetectorService}.
+ * The internal (in-process) system server API for the time zone detector service.
*
* <p>The methods on this class can be called from any thread.
+ *
+ * <p>Methods marked with "[For device policy manager only]" are for use by the device policy
+ * manager to set device state and must not enforce device policy restrictions.
+ *
* @hide
*/
public interface TimeZoneDetectorInternal {
/**
+ * [For device policy manager only] Returns a snapshot of the configuration that controls time
+ * zone detector behavior for the current user.
+ */
+ @NonNull
+ TimeZoneCapabilitiesAndConfig getCapabilitiesAndConfigForDpm();
+
+ /**
+ * [For device policy manager only] Updates the configuration properties that control a device's
+ * time zone behavior for the current user.
+ *
+ * <p>This method returns {@code true} if the configuration was changed,
+ * {@code false} otherwise.
+ */
+ boolean updateConfigurationForDpm(@NonNull TimeZoneConfiguration configuration);
+
+ /**
+ * [For device policy manager only] Attempts to set the device to a manually entered time zone.
+ * Returns {@code false} if the suggestion is invalid, or the device configuration prevents the
+ * suggestion being used, {@code true} if the suggestion has been accepted. A suggestion that is
+ * valid but does not change the time zone because it matches the current device time zone is
+ * considered accepted.
+ */
+ boolean setManualTimeZoneForDpm(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion);
+
+ /**
* Suggests the current time zone, determined using geolocation, to the detector. The
* detector may ignore the signal based on system settings, whether better information is
* available, and so on. This method may be implemented asynchronously.
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
index f61df820c3e0..ce64eaccd98f 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
@@ -17,6 +17,9 @@
package com.android.server.timezonedetector;
import android.annotation.NonNull;
+import android.app.time.TimeZoneCapabilitiesAndConfig;
+import android.app.time.TimeZoneConfiguration;
+import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.content.Context;
import android.os.Handler;
@@ -31,16 +34,52 @@ public final class TimeZoneDetectorInternalImpl implements TimeZoneDetectorInter
@NonNull private final Context mContext;
@NonNull private final Handler mHandler;
+ @NonNull private final CurrentUserIdentityInjector mCurrentUserIdentityInjector;
+ @NonNull private final ServiceConfigAccessor mServiceConfigAccessor;
@NonNull private final TimeZoneDetectorStrategy mTimeZoneDetectorStrategy;
public TimeZoneDetectorInternalImpl(@NonNull Context context, @NonNull Handler handler,
+ @NonNull CurrentUserIdentityInjector currentUserIdentityInjector,
+ @NonNull ServiceConfigAccessor serviceConfigAccessor,
@NonNull TimeZoneDetectorStrategy timeZoneDetectorStrategy) {
mContext = Objects.requireNonNull(context);
mHandler = Objects.requireNonNull(handler);
+ mCurrentUserIdentityInjector = Objects.requireNonNull(currentUserIdentityInjector);
+ mServiceConfigAccessor = Objects.requireNonNull(serviceConfigAccessor);
mTimeZoneDetectorStrategy = Objects.requireNonNull(timeZoneDetectorStrategy);
}
@Override
+ @NonNull
+ public TimeZoneCapabilitiesAndConfig getCapabilitiesAndConfigForDpm() {
+ int currentUserId = mCurrentUserIdentityInjector.getCurrentUserId();
+ ConfigurationInternal configurationInternal =
+ mServiceConfigAccessor.getConfigurationInternal(currentUserId);
+ final boolean bypassUserPolicyChecks = true;
+ return configurationInternal.createCapabilitiesAndConfig(bypassUserPolicyChecks);
+ }
+
+ @Override
+ public boolean updateConfigurationForDpm(@NonNull TimeZoneConfiguration configuration) {
+ Objects.requireNonNull(configuration);
+
+ int currentUserId = mCurrentUserIdentityInjector.getCurrentUserId();
+ final boolean bypassUserPolicyChecks = true;
+ return mServiceConfigAccessor.updateConfiguration(
+ currentUserId, configuration, bypassUserPolicyChecks);
+ }
+
+ @Override
+ public boolean setManualTimeZoneForDpm(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion) {
+ Objects.requireNonNull(timeZoneSuggestion);
+
+ int currentUserId = mCurrentUserIdentityInjector.getCurrentUserId();
+ final boolean bypassUserPolicyChecks = true;
+ return mTimeZoneDetectorStrategy.suggestManualTimeZone(
+ currentUserId, timeZoneSuggestion, bypassUserPolicyChecks);
+ }
+
+ @Override
public void suggestGeolocationTimeZone(
@NonNull GeolocationTimeZoneSuggestion timeZoneSuggestion) {
Objects.requireNonNull(timeZoneSuggestion);
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
index 822cd4124380..13f169461511 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
@@ -96,8 +96,11 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
});
// Create and publish the local service for use by internal callers.
- TimeZoneDetectorInternal internal =
- new TimeZoneDetectorInternalImpl(context, handler, timeZoneDetectorStrategy);
+ CurrentUserIdentityInjector currentUserIdentityInjector =
+ CurrentUserIdentityInjector.REAL;
+ TimeZoneDetectorInternal internal = new TimeZoneDetectorInternalImpl(
+ context, handler, currentUserIdentityInjector, serviceConfigAccessor,
+ timeZoneDetectorStrategy);
publishLocalService(TimeZoneDetectorInternal.class, internal);
// Publish the binder service so it can be accessed from other (appropriately
@@ -175,7 +178,8 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
try {
ConfigurationInternal configurationInternal =
mServiceConfigAccessor.getConfigurationInternal(userId);
- return configurationInternal.createCapabilitiesAndConfig();
+ final boolean bypassUserPolicyChecks = false;
+ return configurationInternal.createCapabilitiesAndConfig(bypassUserPolicyChecks);
} finally {
mCallerIdentityInjector.restoreCallingIdentity(token);
}
@@ -199,7 +203,9 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
final long token = mCallerIdentityInjector.clearCallingIdentity();
try {
- return mServiceConfigAccessor.updateConfiguration(resolvedUserId, configuration);
+ final boolean bypassUserPolicyChecks = false;
+ return mServiceConfigAccessor.updateConfiguration(
+ resolvedUserId, configuration, bypassUserPolicyChecks);
} finally {
mCallerIdentityInjector.restoreCallingIdentity(token);
}
@@ -350,7 +356,9 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
int userId = mCallerIdentityInjector.getCallingUserId();
final long token = mCallerIdentityInjector.clearCallingIdentity();
try {
- return mTimeZoneDetectorStrategy.suggestManualTimeZone(userId, timeZoneSuggestion);
+ final boolean bypassUserPolicyChecks = false;
+ return mTimeZoneDetectorStrategy.suggestManualTimeZone(
+ userId, timeZoneSuggestion, bypassUserPolicyChecks);
} finally {
mCallerIdentityInjector.restoreCallingIdentity(token);
}
@@ -364,7 +372,9 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
int userId = mCallerIdentityInjector.getCallingUserId();
final long token = mCallerIdentityInjector.clearCallingIdentity();
try {
- return mTimeZoneDetectorStrategy.suggestManualTimeZone(userId, timeZoneSuggestion);
+ final boolean bypassUserPolicyChecks = false;
+ return mTimeZoneDetectorStrategy.suggestManualTimeZone(
+ userId, timeZoneSuggestion, bypassUserPolicyChecks);
} finally {
mCallerIdentityInjector.restoreCallingIdentity(token);
}
@@ -449,7 +459,7 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
private void enforceSuggestGeolocationTimeZonePermission() {
// The associated method is only used for the shell command interface, it's not possible to
// call it via Binder, and Shell currently can set the time zone directly anyway.
- mContext.enforceCallingOrSelfPermission(
+ mContext.enforceCallingPermission(
android.Manifest.permission.SET_TIME_ZONE,
"suggest geolocation time zone");
}
@@ -461,7 +471,7 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
}
private void enforceSuggestManualTimeZonePermission() {
- mContext.enforceCallingOrSelfPermission(
+ mContext.enforceCallingPermission(
android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE,
"suggest manual time and time zone");
}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
index e4b2df1460ae..69284e322663 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
@@ -120,9 +120,13 @@ public interface TimeZoneDetectorStrategy extends Dumpable {
/**
* Suggests a time zone for the device using manually-entered (i.e. user sourced) information.
+ *
+ * @param bypassUserPolicyChecks {@code true} for device policy manager use cases where device
+ * policy restrictions that should apply to actual users can be ignored
*/
boolean suggestManualTimeZone(
- @UserIdInt int userId, @NonNull ManualTimeZoneSuggestion suggestion);
+ @UserIdInt int userId, @NonNull ManualTimeZoneSuggestion suggestion,
+ boolean bypassUserPolicyChecks);
/**
* Suggests a time zone for the device, or withdraws a previous suggestion if
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
index 1e88c47e7b30..18c8885ee059 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
@@ -317,7 +317,8 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
@Override
public synchronized boolean suggestManualTimeZone(
- @UserIdInt int userId, @NonNull ManualTimeZoneSuggestion suggestion) {
+ @UserIdInt int userId, @NonNull ManualTimeZoneSuggestion suggestion,
+ boolean bypassUserPolicyChecks) {
ConfigurationInternal currentUserConfig = mCurrentConfigurationInternal;
if (currentUserConfig.getUserId() != userId) {
@@ -334,7 +335,7 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
String cause = "Manual time suggestion received: suggestion=" + suggestion;
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
- currentUserConfig.createCapabilitiesAndConfig();
+ currentUserConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
if (capabilities.getSetManualTimeZoneCapability() != CAPABILITY_POSSESSED) {
Slog.i(LOG_TAG, "User does not have the capability needed to set the time zone manually"
@@ -757,7 +758,9 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
ipw.increaseIndent(); // level 1
ipw.println("mCurrentConfigurationInternal=" + mCurrentConfigurationInternal);
- ipw.println("[Capabilities=" + mCurrentConfigurationInternal.createCapabilitiesAndConfig()
+ final boolean bypassUserPolicyChecks = false;
+ ipw.println("[Capabilities="
+ + mCurrentConfigurationInternal.createCapabilitiesAndConfig(bypassUserPolicyChecks)
+ "]");
ipw.println("mEnvironment.getDeviceTimeZone()=" + mEnvironment.getDeviceTimeZone());
ipw.println("mEnvironment.getDeviceTimeZoneConfidence()="
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/ConfigurationInternalTest.java b/services/tests/servicestests/src/com/android/server/timedetector/ConfigurationInternalTest.java
index a24afe6bc25e..808c1ec2603b 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/ConfigurationInternalTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/ConfigurationInternalTest.java
@@ -31,8 +31,6 @@ import android.app.time.TimeCapabilities;
import android.app.time.TimeCapabilitiesAndConfig;
import android.app.time.TimeConfiguration;
-import androidx.test.runner.AndroidJUnit4;
-
import com.android.server.timedetector.TimeDetectorStrategy.Origin;
import org.junit.Test;
@@ -40,7 +38,14 @@ import org.junit.runner.RunWith;
import java.time.Instant;
-@RunWith(AndroidJUnit4.class)
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
+/**
+ * Tests for {@link ConfigurationInternal} and associated {@link TimeCapabilitiesAndConfig}
+ * behavior.
+ */
+@RunWith(JUnitParamsRunner.class)
public class ConfigurationInternalTest {
private static final int ARBITRARY_USER_ID = 99999;
@@ -51,14 +56,15 @@ public class ConfigurationInternalTest {
private static final @Origin int[] ARBITRARY_ORIGIN_PRIORITIES = { ORIGIN_NETWORK };
/**
- * Tests when {@link ConfigurationInternal#isUserConfigAllowed()} and
- * {@link ConfigurationInternal#isAutoDetectionSupported()} are both true.
+ * Tests {@link TimeCapabilitiesAndConfig} behavior in different scenarios when auto detection
+ * is supported.
*/
@Test
- public void test_unrestricted() {
- ConfigurationInternal
- baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
- .setUserConfigAllowed(true)
+ @Parameters({ "true,true", "true,false", "false,true", "false,false" })
+ public void test_autoDetectionSupported_capabilitiesAndConfiguration(
+ boolean userConfigAllowed, boolean bypassUserPolicyChecks) {
+ ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
+ .setUserConfigAllowed(userConfigAllowed)
.setAutoDetectionSupported(true)
.setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
.setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
@@ -67,58 +73,8 @@ public class ConfigurationInternalTest {
.setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
.setAutoDetectionEnabledSetting(true)
.build();
- {
- ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig)
- .setAutoDetectionEnabledSetting(true)
- .build();
- assertTrue(autoOnConfig.getAutoDetectionEnabledSetting());
- assertTrue(autoOnConfig.getAutoDetectionEnabledBehavior());
-
- TimeCapabilitiesAndConfig capabilitiesAndConfig = autoOnConfig.capabilitiesAndConfig();
-
- TimeCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
- assertEquals(CAPABILITY_POSSESSED,
- capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_NOT_APPLICABLE, capabilities.getSetManualTimeCapability());
-
- TimeConfiguration configuration = capabilitiesAndConfig.getConfiguration();
- assertTrue(configuration.isAutoDetectionEnabled());
- }
- {
- ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig)
- .setAutoDetectionEnabledSetting(false)
- .build();
- assertFalse(autoOffConfig.getAutoDetectionEnabledSetting());
- assertFalse(autoOffConfig.getAutoDetectionEnabledBehavior());
-
- TimeCapabilitiesAndConfig capabilitiesAndConfig = autoOffConfig.capabilitiesAndConfig();
-
- TimeCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
- assertEquals(CAPABILITY_POSSESSED,
- capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_POSSESSED,
- capabilities.getSetManualTimeCapability());
-
- TimeConfiguration configuration = capabilitiesAndConfig.getConfiguration();
- assertFalse(configuration.isAutoDetectionEnabled());
- }
- }
-
- /** Tests when {@link ConfigurationInternal#isUserConfigAllowed()} is false */
- @Test
- public void test_restricted() {
- ConfigurationInternal
- baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
- .setUserConfigAllowed(false)
- .setAutoDetectionSupported(true)
- .setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
- .setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
- .setManualSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
- .setSuggestionUpperBound(ARBITRARY_SUGGESTION_UPPER_BOUND)
- .setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
- .setAutoDetectionEnabledSetting(true)
- .build();
+ boolean userRestrictionsExpected = !(userConfigAllowed || bypassUserPolicyChecks);
{
ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig)
.setAutoDetectionEnabledSetting(true)
@@ -126,12 +82,19 @@ public class ConfigurationInternalTest {
assertTrue(autoOnConfig.getAutoDetectionEnabledSetting());
assertTrue(autoOnConfig.getAutoDetectionEnabledBehavior());
- TimeCapabilitiesAndConfig capabilitiesAndConfig = autoOnConfig.capabilitiesAndConfig();
+ TimeCapabilitiesAndConfig capabilitiesAndConfig =
+ autoOnConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
- assertEquals(CAPABILITY_NOT_ALLOWED,
- capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeCapability());
+ if (userRestrictionsExpected) {
+ assertEquals(CAPABILITY_NOT_ALLOWED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeCapability());
+ } else {
+ assertEquals(CAPABILITY_POSSESSED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_NOT_APPLICABLE, capabilities.getSetManualTimeCapability());
+ }
TimeConfiguration configuration = capabilitiesAndConfig.getConfiguration();
assertTrue(configuration.isAutoDetectionEnabled());
@@ -144,23 +107,35 @@ public class ConfigurationInternalTest {
assertFalse(autoOffConfig.getAutoDetectionEnabledSetting());
assertFalse(autoOffConfig.getAutoDetectionEnabledBehavior());
- TimeCapabilitiesAndConfig capabilitiesAndConfig = autoOffConfig.capabilitiesAndConfig();
+ TimeCapabilitiesAndConfig capabilitiesAndConfig =
+ autoOffConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
- assertEquals(CAPABILITY_NOT_ALLOWED,
- capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeCapability());
-
+ if (userRestrictionsExpected) {
+ assertEquals(CAPABILITY_NOT_ALLOWED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeCapability());
+ } else {
+ assertEquals(CAPABILITY_POSSESSED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_POSSESSED,
+ capabilities.getSetManualTimeCapability());
+ }
TimeConfiguration configuration = capabilitiesAndConfig.getConfiguration();
assertFalse(configuration.isAutoDetectionEnabled());
}
}
- /** Tests when {@link ConfigurationInternal#isAutoDetectionSupported()} is false. */
+ /**
+ * Tests {@link TimeCapabilitiesAndConfig} behavior in different scenarios when auto detection
+ * is not supported.
+ */
@Test
- public void test_autoDetectNotSupported() {
+ @Parameters({ "true,true", "true,false", "false,true", "false,false" })
+ public void test_autoDetectNotSupported_capabilitiesAndConfiguration(
+ boolean userConfigAllowed, boolean bypassUserPolicyChecks) {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
- .setUserConfigAllowed(true)
+ .setUserConfigAllowed(userConfigAllowed)
.setAutoDetectionSupported(false)
.setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
.setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
@@ -169,6 +144,9 @@ public class ConfigurationInternalTest {
.setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
.setAutoDetectionEnabledSetting(true)
.build();
+ boolean userRestrictionsExpected = !(userConfigAllowed || bypassUserPolicyChecks);
+
+ // Auto-detection enabled.
{
ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig)
.setAutoDetectionEnabledSetting(true)
@@ -176,30 +154,41 @@ public class ConfigurationInternalTest {
assertTrue(autoOnConfig.getAutoDetectionEnabledSetting());
assertFalse(autoOnConfig.getAutoDetectionEnabledBehavior());
- TimeCapabilitiesAndConfig capabilitiesAndConfig = autoOnConfig.capabilitiesAndConfig();
+ TimeCapabilitiesAndConfig capabilitiesAndConfig =
+ autoOnConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
assertEquals(CAPABILITY_NOT_SUPPORTED,
capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeCapability());
+ if (userRestrictionsExpected) {
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeCapability());
+ } else {
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeCapability());
+ }
TimeConfiguration configuration = capabilitiesAndConfig.getConfiguration();
assertTrue(configuration.isAutoDetectionEnabled());
}
+
+ // Auto-detection disabled.
{
- ConfigurationInternal
- autoOffConfig = new ConfigurationInternal.Builder(baseConfig)
+ ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig)
.setAutoDetectionEnabledSetting(false)
.build();
assertFalse(autoOffConfig.getAutoDetectionEnabledSetting());
assertFalse(autoOffConfig.getAutoDetectionEnabledBehavior());
- TimeCapabilitiesAndConfig capabilitiesAndConfig = autoOffConfig.capabilitiesAndConfig();
+ TimeCapabilitiesAndConfig capabilitiesAndConfig =
+ autoOffConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
assertEquals(CAPABILITY_NOT_SUPPORTED,
capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeCapability());
+ if (userRestrictionsExpected) {
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeCapability());
+ } else {
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeCapability());
+ }
TimeConfiguration configuration = capabilitiesAndConfig.getConfiguration();
assertFalse(configuration.isAutoDetectionEnabled());
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/FakeServiceConfigAccessor.java b/services/tests/servicestests/src/com/android/server/timedetector/FakeServiceConfigAccessor.java
index 77b319b56acb..a98a43b75d9b 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/FakeServiceConfigAccessor.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/FakeServiceConfigAccessor.java
@@ -31,7 +31,7 @@ import java.util.ArrayList;
import java.util.List;
/** A partially implemented, fake implementation of ServiceConfigAccessor for tests. */
-class FakeServiceConfigAccessor implements ServiceConfigAccessor {
+public class FakeServiceConfigAccessor implements ServiceConfigAccessor {
private final List<ConfigurationChangeListener> mConfigurationInternalChangeListeners =
new ArrayList<>();
@@ -54,7 +54,8 @@ class FakeServiceConfigAccessor implements ServiceConfigAccessor {
@Override
public boolean updateConfiguration(
- @UserIdInt int userID, @NonNull TimeConfiguration requestedChanges) {
+ @UserIdInt int userID, @NonNull TimeConfiguration requestedChanges,
+ boolean bypassUserPolicyChecks) {
assertNotNull(mConfigurationInternal);
assertNotNull(requestedChanges);
@@ -62,7 +63,7 @@ class FakeServiceConfigAccessor implements ServiceConfigAccessor {
// old configuration merged with the new if the user has the capability to up the settings.
// Then, if the configuration changed, the change listener is invoked.
TimeCapabilitiesAndConfig capabilitiesAndConfig =
- mConfigurationInternal.capabilitiesAndConfig();
+ mConfigurationInternal.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
TimeConfiguration configuration = capabilitiesAndConfig.getConfiguration();
TimeConfiguration newConfiguration =
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java b/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java
index 7b38fa014512..856df359b326 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java
@@ -16,9 +16,6 @@
package com.android.server.timedetector;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
import android.annotation.UserIdInt;
import android.app.time.ExternalTimeSuggestion;
import android.app.time.TimeState;
@@ -31,20 +28,10 @@ import android.util.IndentingPrintWriter;
* A fake implementation of {@link com.android.server.timedetector.TimeDetectorStrategy} for use
* in tests.
*/
-class FakeTimeDetectorStrategy implements TimeDetectorStrategy {
+public class FakeTimeDetectorStrategy implements TimeDetectorStrategy {
// State
private TimeState mTimeState;
- // Call tracking.
- private TelephonyTimeSuggestion mLastTelephonySuggestion;
- private @UserIdInt Integer mLastManualSuggestionUserId;
- private ManualTimeSuggestion mLastManualSuggestion;
- private NetworkTimeSuggestion mLastNetworkSuggestion;
- private GnssTimeSuggestion mLastGnssSuggestion;
- private ExternalTimeSuggestion mLastExternalSuggestion;
- private UnixEpochTime mLastConfirmedTime;
- private boolean mDumpCalled;
-
@Override
public TimeState getTimeState() {
return mTimeState;
@@ -57,80 +44,32 @@ class FakeTimeDetectorStrategy implements TimeDetectorStrategy {
@Override
public boolean confirmTime(UnixEpochTime confirmationTime) {
- mLastConfirmedTime = confirmationTime;
return false;
}
@Override
public void suggestTelephonyTime(TelephonyTimeSuggestion timeSuggestion) {
- mLastTelephonySuggestion = timeSuggestion;
}
@Override
- public boolean suggestManualTime(@UserIdInt int userId, ManualTimeSuggestion timeSuggestion) {
- mLastManualSuggestionUserId = userId;
- mLastManualSuggestion = timeSuggestion;
+ public boolean suggestManualTime(@UserIdInt int userId, ManualTimeSuggestion timeSuggestion,
+ boolean bypassUserPolicyChecks) {
return true;
}
@Override
public void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion) {
- mLastNetworkSuggestion = timeSuggestion;
}
@Override
public void suggestGnssTime(GnssTimeSuggestion timeSuggestion) {
- mLastGnssSuggestion = timeSuggestion;
}
@Override
public void suggestExternalTime(ExternalTimeSuggestion timeSuggestion) {
- mLastExternalSuggestion = timeSuggestion;
}
@Override
public void dump(IndentingPrintWriter pw, String[] args) {
- mDumpCalled = true;
- }
-
- void resetCallTracking() {
- mLastTelephonySuggestion = null;
- mLastManualSuggestionUserId = null;
- mLastManualSuggestion = null;
- mLastNetworkSuggestion = null;
- mLastGnssSuggestion = null;
- mLastExternalSuggestion = null;
- mLastConfirmedTime = null;
- mDumpCalled = false;
- }
-
- void verifySuggestTelephonyTimeCalled(TelephonyTimeSuggestion expectedSuggestion) {
- assertEquals(expectedSuggestion, mLastTelephonySuggestion);
- }
-
- void verifySuggestManualTimeCalled(
- @UserIdInt int expectedUserId, ManualTimeSuggestion expectedSuggestion) {
- assertEquals((Integer) expectedUserId, mLastManualSuggestionUserId);
- assertEquals(expectedSuggestion, mLastManualSuggestion);
- }
-
- void verifySuggestNetworkTimeCalled(NetworkTimeSuggestion expectedSuggestion) {
- assertEquals(expectedSuggestion, mLastNetworkSuggestion);
- }
-
- void verifySuggestGnssTimeCalled(GnssTimeSuggestion expectedSuggestion) {
- assertEquals(expectedSuggestion, mLastGnssSuggestion);
- }
-
- void verifySuggestExternalTimeCalled(ExternalTimeSuggestion expectedSuggestion) {
- assertEquals(expectedSuggestion, mLastExternalSuggestion);
- }
-
- void verifyConfirmTimeCalled(UnixEpochTime expectedConfirmationTime) {
- assertEquals(mLastConfirmedTime, expectedConfirmationTime);
- }
-
- void verifyDumpCalled() {
- assertTrue(mDumpCalled);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java
index 5b6175217568..a0845a64757e 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java
@@ -16,14 +16,24 @@
package com.android.server.timedetector;
+import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import android.app.time.TimeCapabilitiesAndConfig;
+import android.app.time.TimeConfiguration;
import android.app.time.UnixEpochTime;
+import android.app.timedetector.ManualTimeSuggestion;
import android.content.Context;
import android.os.HandlerThread;
import androidx.test.runner.AndroidJUnit4;
+import com.android.server.timezonedetector.TestCurrentUserIdentityInjector;
import com.android.server.timezonedetector.TestHandler;
import org.junit.After;
@@ -31,15 +41,25 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.time.Instant;
+
@RunWith(AndroidJUnit4.class)
public class TimeDetectorInternalImplTest {
+ private static final int ARBITRARY_USER_ID = 9999;
+ private static final int ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS = 1234;
+ private static final Instant ARBITRARY_SUGGESTION_LOWER_BOUND = Instant.ofEpochMilli(0);
+ private static final Instant ARBITRARY_SUGGESTION_UPPER_BOUND =
+ Instant.ofEpochMilli(Long.MAX_VALUE);
+ private static final int[] ARBITRARY_ORIGIN_PRIORITIES = { ORIGIN_NETWORK };
private Context mMockContext;
- private FakeTimeDetectorStrategy mFakeTimeDetectorStrategy;
-
- private TimeDetectorInternalImpl mTimeDetectorInternal;
private HandlerThread mHandlerThread;
private TestHandler mTestHandler;
+ private TestCurrentUserIdentityInjector mTestCurrentUserIdentityInjector;
+ private FakeServiceConfigAccessor mFakeServiceConfigAccessorSpy;
+ private FakeTimeDetectorStrategy mFakeTimeDetectorStrategySpy;
+
+ private TimeDetectorInternalImpl mTimeDetectorInternal;
@Before
public void setUp() {
@@ -49,11 +69,14 @@ public class TimeDetectorInternalImplTest {
mHandlerThread = new HandlerThread("TimeDetectorInternalTest");
mHandlerThread.start();
mTestHandler = new TestHandler(mHandlerThread.getLooper());
-
- mFakeTimeDetectorStrategy = new FakeTimeDetectorStrategy();
+ mTestCurrentUserIdentityInjector = new TestCurrentUserIdentityInjector();
+ mTestCurrentUserIdentityInjector.initializeCurrentUserId(ARBITRARY_USER_ID);
+ mFakeServiceConfigAccessorSpy = spy(new FakeServiceConfigAccessor());
+ mFakeTimeDetectorStrategySpy = spy(new FakeTimeDetectorStrategy());
mTimeDetectorInternal = new TimeDetectorInternalImpl(
- mMockContext, mTestHandler, mFakeTimeDetectorStrategy);
+ mMockContext, mTestHandler, mTestCurrentUserIdentityInjector,
+ mFakeServiceConfigAccessorSpy, mFakeTimeDetectorStrategySpy);
}
@After
@@ -63,6 +86,56 @@ public class TimeDetectorInternalImplTest {
}
@Test
+ public void testGetCapabilitiesAndConfigForDpm() throws Exception {
+ final boolean autoDetectionEnabled = true;
+ ConfigurationInternal testConfig = createConfigurationInternal(autoDetectionEnabled);
+ mFakeServiceConfigAccessorSpy.initializeConfiguration(testConfig);
+
+ TimeCapabilitiesAndConfig actualCapabilitiesAndConfig =
+ mTimeDetectorInternal.getCapabilitiesAndConfigForDpm();
+
+ int expectedUserId = mTestCurrentUserIdentityInjector.getCurrentUserId();
+ verify(mFakeServiceConfigAccessorSpy).getConfigurationInternal(expectedUserId);
+
+ final boolean bypassUserPolicyChecks = true;
+ TimeCapabilitiesAndConfig expectedCapabilitiesAndConfig =
+ testConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
+ assertEquals(expectedCapabilitiesAndConfig, actualCapabilitiesAndConfig);
+ }
+
+ @Test
+ public void testUpdateConfigurationForDpm() throws Exception {
+ final boolean autoDetectionEnabled = false;
+ ConfigurationInternal initialConfigurationInternal =
+ createConfigurationInternal(autoDetectionEnabled);
+ mFakeServiceConfigAccessorSpy.initializeConfiguration(initialConfigurationInternal);
+
+ TimeConfiguration timeConfiguration = new TimeConfiguration.Builder()
+ .setAutoDetectionEnabled(true)
+ .build();
+ assertTrue(mTimeDetectorInternal.updateConfigurationForDpm(timeConfiguration));
+
+ final boolean expectedBypassUserPolicyChecks = true;
+ verify(mFakeServiceConfigAccessorSpy).updateConfiguration(
+ mTestCurrentUserIdentityInjector.getCurrentUserId(),
+ timeConfiguration,
+ expectedBypassUserPolicyChecks);
+ }
+
+ @Test
+ public void testSetManualTimeZoneForDpm() throws Exception {
+ ManualTimeSuggestion timeSuggestion = createManualTimeSuggestion();
+
+ // The fake strategy always returns true.
+ assertTrue(mTimeDetectorInternal.setManualTimeForDpm(timeSuggestion));
+
+ int expectedUserId = mTestCurrentUserIdentityInjector.getCurrentUserId();
+ boolean expectedBypassUserPolicyChecks = false;
+ verify(mFakeTimeDetectorStrategySpy).suggestManualTime(
+ expectedUserId, timeSuggestion, expectedBypassUserPolicyChecks);
+ }
+
+ @Test
public void testSuggestNetworkTime() throws Exception {
NetworkTimeSuggestion networkTimeSuggestion = createNetworkTimeSuggestion();
@@ -70,7 +143,7 @@ public class TimeDetectorInternalImplTest {
mTestHandler.assertTotalMessagesEnqueued(1);
mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeDetectorStrategy.verifySuggestNetworkTimeCalled(networkTimeSuggestion);
+ verify(mFakeTimeDetectorStrategySpy).suggestNetworkTime(networkTimeSuggestion);
}
private static NetworkTimeSuggestion createNetworkTimeSuggestion() {
@@ -86,11 +159,29 @@ public class TimeDetectorInternalImplTest {
mTestHandler.assertTotalMessagesEnqueued(1);
mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeDetectorStrategy.verifySuggestGnssTimeCalled(gnssTimeSuggestion);
+ verify(mFakeTimeDetectorStrategySpy).suggestGnssTime(gnssTimeSuggestion);
+ }
+
+ private static ManualTimeSuggestion createManualTimeSuggestion() {
+ UnixEpochTime timeValue = new UnixEpochTime(100L, 1_000_000L);
+ return new ManualTimeSuggestion(timeValue);
}
private static GnssTimeSuggestion createGnssTimeSuggestion() {
UnixEpochTime timeValue = new UnixEpochTime(100L, 1_000_000L);
return new GnssTimeSuggestion(timeValue);
}
+
+ private static ConfigurationInternal createConfigurationInternal(boolean autoDetectionEnabled) {
+ return new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
+ .setUserConfigAllowed(true)
+ .setAutoDetectionSupported(true)
+ .setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
+ .setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
+ .setManualSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
+ .setSuggestionUpperBound(ARBITRARY_SUGGESTION_UPPER_BOUND)
+ .setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
+ .setAutoDetectionEnabledSetting(autoDetectionEnabled)
+ .build();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index f776d3da0e79..4b417ba367ae 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -31,12 +31,14 @@ import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.app.time.ExternalTimeSuggestion;
import android.app.time.ITimeDetectorListener;
+import android.app.time.TimeCapabilitiesAndConfig;
import android.app.time.TimeConfiguration;
import android.app.time.TimeState;
import android.app.time.UnixEpochTime;
@@ -77,14 +79,14 @@ public class TimeDetectorServiceTest {
private Context mMockContext;
- private TimeDetectorService mTimeDetectorService;
private HandlerThread mHandlerThread;
private TestHandler mTestHandler;
private TestCallerIdentityInjector mTestCallerIdentityInjector;
- private FakeServiceConfigAccessor mFakeServiceConfigAccessor;
- private NtpTrustedTime mMockNtpTrustedTime;
- private FakeTimeDetectorStrategy mFakeTimeDetectorStrategy;
+ private FakeServiceConfigAccessor mFakeServiceConfigAccessorSpy;
+ private FakeTimeDetectorStrategy mFakeTimeDetectorStrategySpy;
+ private NtpTrustedTime mMockNtpTrustedTime;
+ private TimeDetectorService mTimeDetectorService;
@Before
public void setUp() {
@@ -98,13 +100,13 @@ public class TimeDetectorServiceTest {
mTestCallerIdentityInjector = new TestCallerIdentityInjector();
mTestCallerIdentityInjector.initializeCallingUserId(ARBITRARY_USER_ID);
- mFakeTimeDetectorStrategy = new FakeTimeDetectorStrategy();
- mFakeServiceConfigAccessor = new FakeServiceConfigAccessor();
+ mFakeServiceConfigAccessorSpy = spy(new FakeServiceConfigAccessor());
+ mFakeTimeDetectorStrategySpy = spy(new FakeTimeDetectorStrategy());
mMockNtpTrustedTime = mock(NtpTrustedTime.class);
mTimeDetectorService = new TimeDetectorService(
- mMockContext, mTestHandler, mTestCallerIdentityInjector, mFakeServiceConfigAccessor,
- mFakeTimeDetectorStrategy, mMockNtpTrustedTime);
+ mMockContext, mTestHandler, mTestCallerIdentityInjector,
+ mFakeServiceConfigAccessorSpy, mFakeTimeDetectorStrategySpy, mMockNtpTrustedTime);
}
@After
@@ -129,13 +131,19 @@ public class TimeDetectorServiceTest {
ConfigurationInternal configuration =
createConfigurationInternal(true /* autoDetectionEnabled*/);
- mFakeServiceConfigAccessor.initializeConfiguration(configuration);
-
- assertEquals(configuration.capabilitiesAndConfig(),
- mTimeDetectorService.getCapabilitiesAndConfig());
+ mFakeServiceConfigAccessorSpy.initializeConfiguration(configuration);
+ TimeCapabilitiesAndConfig actualCapabilitiesAndConfig =
+ mTimeDetectorService.getCapabilitiesAndConfig();
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION), anyString());
+ int expectedUserId = mTestCallerIdentityInjector.getCallingUserId();
+ verify(mFakeServiceConfigAccessorSpy).getConfigurationInternal(expectedUserId);
+
+ boolean bypassUserPolicyChecks = false;
+ TimeCapabilitiesAndConfig expectedCapabilitiesAndConfig =
+ configuration.createCapabilitiesAndConfig(bypassUserPolicyChecks);
+ assertEquals(expectedCapabilitiesAndConfig, actualCapabilitiesAndConfig);
}
@Test
@@ -165,7 +173,7 @@ public class TimeDetectorServiceTest {
public void testListenerRegistrationAndCallbacks() throws Exception {
ConfigurationInternal initialConfiguration =
createConfigurationInternal(false /* autoDetectionEnabled */);
- mFakeServiceConfigAccessor.initializeConfiguration(initialConfiguration);
+ mFakeServiceConfigAccessorSpy.initializeConfiguration(initialConfiguration);
IBinder mockListenerBinder = mock(IBinder.class);
ITimeDetectorListener mockListener = mock(ITimeDetectorListener.class);
@@ -258,32 +266,34 @@ public class TimeDetectorServiceTest {
eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE), anyString());
mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeDetectorStrategy.verifySuggestTelephonyTimeCalled(timeSuggestion);
+ verify(mFakeTimeDetectorStrategySpy).suggestTelephonyTime(timeSuggestion);
}
@Test
public void testSuggestManualTime_withoutPermission() {
doThrow(new SecurityException("Mock"))
- .when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ .when(mMockContext).enforceCallingPermission(anyString(), any());
ManualTimeSuggestion manualTimeSuggestion = createManualTimeSuggestion();
assertThrows(SecurityException.class,
() -> mTimeDetectorService.suggestManualTime(manualTimeSuggestion));
- verify(mMockContext).enforceCallingOrSelfPermission(
+ verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE), anyString());
}
@Test
public void testSuggestManualTime() throws Exception {
- doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
ManualTimeSuggestion manualTimeSuggestion = createManualTimeSuggestion();
assertTrue(mTimeDetectorService.suggestManualTime(manualTimeSuggestion));
- mFakeTimeDetectorStrategy.verifySuggestManualTimeCalled(
- mTestCallerIdentityInjector.getCallingUserId(), manualTimeSuggestion);
+ int expectedUserId = mTestCallerIdentityInjector.getCallingUserId();
+ boolean expectedBypassUserPolicyChecks = false;
+ verify(mFakeTimeDetectorStrategySpy).suggestManualTime(
+ expectedUserId, manualTimeSuggestion, expectedBypassUserPolicyChecks);
- verify(mMockContext).enforceCallingOrSelfPermission(
+ verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE), anyString());
}
@@ -291,55 +301,55 @@ public class TimeDetectorServiceTest {
@Test
public void testSuggestNetworkTime_withoutPermission() {
doThrow(new SecurityException("Mock"))
- .when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ .when(mMockContext).enforceCallingPermission(anyString(), any());
NetworkTimeSuggestion networkTimeSuggestion = createNetworkTimeSuggestion();
assertThrows(SecurityException.class,
() -> mTimeDetectorService.suggestNetworkTime(networkTimeSuggestion));
- verify(mMockContext).enforceCallingOrSelfPermission(
+ verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SET_TIME), anyString());
}
@Test
public void testSuggestNetworkTime() throws Exception {
- doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
NetworkTimeSuggestion networkTimeSuggestion = createNetworkTimeSuggestion();
mTimeDetectorService.suggestNetworkTime(networkTimeSuggestion);
mTestHandler.assertTotalMessagesEnqueued(1);
- verify(mMockContext).enforceCallingOrSelfPermission(
+ verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SET_TIME), anyString());
mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeDetectorStrategy.verifySuggestNetworkTimeCalled(networkTimeSuggestion);
+ verify(mFakeTimeDetectorStrategySpy).suggestNetworkTime(networkTimeSuggestion);
}
@Test
public void testSuggestGnssTime_withoutPermission() {
doThrow(new SecurityException("Mock"))
- .when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ .when(mMockContext).enforceCallingPermission(anyString(), any());
GnssTimeSuggestion gnssTimeSuggestion = createGnssTimeSuggestion();
assertThrows(SecurityException.class,
() -> mTimeDetectorService.suggestGnssTime(gnssTimeSuggestion));
- verify(mMockContext).enforceCallingOrSelfPermission(
+ verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SET_TIME), anyString());
}
@Test
public void testSuggestGnssTime() throws Exception {
- doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
GnssTimeSuggestion gnssTimeSuggestion = createGnssTimeSuggestion();
mTimeDetectorService.suggestGnssTime(gnssTimeSuggestion);
mTestHandler.assertTotalMessagesEnqueued(1);
- verify(mMockContext).enforceCallingOrSelfPermission(
+ verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SET_TIME), anyString());
mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeDetectorStrategy.verifySuggestGnssTimeCalled(gnssTimeSuggestion);
+ verify(mFakeTimeDetectorStrategySpy).suggestGnssTime(gnssTimeSuggestion);
}
@Test
@@ -366,7 +376,7 @@ public class TimeDetectorServiceTest {
eq(android.Manifest.permission.SUGGEST_EXTERNAL_TIME), anyString());
mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeDetectorStrategy.verifySuggestExternalTimeCalled(externalTimeSuggestion);
+ verify(mFakeTimeDetectorStrategySpy).suggestExternalTime(externalTimeSuggestion);
}
@Test
@@ -390,7 +400,7 @@ public class TimeDetectorServiceTest {
public void testGetTimeState() {
doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
TimeState fakeState = new TimeState(new UnixEpochTime(12345L, 98765L), true);
- mFakeTimeDetectorStrategy.setTimeState(fakeState);
+ mFakeTimeDetectorStrategySpy.setTimeState(fakeState);
TimeState actualState = mTimeDetectorService.getTimeState();
@@ -418,7 +428,7 @@ public class TimeDetectorServiceTest {
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION), anyString());
- assertEquals(mFakeTimeDetectorStrategy.getTimeState(), state);
+ assertEquals(mFakeTimeDetectorStrategySpy.getTimeState(), state);
}
@Test
@@ -442,7 +452,7 @@ public class TimeDetectorServiceTest {
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION), anyString());
- mFakeTimeDetectorStrategy.verifyConfirmTimeCalled(confirmationTime);
+ verify(mFakeTimeDetectorStrategySpy).confirmTime(confirmationTime);
}
@Test
@@ -467,8 +477,10 @@ public class TimeDetectorServiceTest {
mTimeDetectorService.setManualTime(timeSuggestion));
// The service calls "suggestManualTime()" because the logic is the same.
- mFakeTimeDetectorStrategy.verifySuggestManualTimeCalled(
- mTestCallerIdentityInjector.getCallingUserId(), timeSuggestion);
+ int expectedUserId = mTestCallerIdentityInjector.getCallingUserId();
+ boolean expectedBypassUserPolicyChecks = false;
+ verify(mFakeTimeDetectorStrategySpy).suggestManualTime(
+ expectedUserId, timeSuggestion, expectedBypassUserPolicyChecks);
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION), anyString());
@@ -495,7 +507,7 @@ public class TimeDetectorServiceTest {
mTimeDetectorService.dump(null, pw, null);
verify(mMockContext).checkCallingOrSelfPermission(eq(android.Manifest.permission.DUMP));
- mFakeTimeDetectorStrategy.verifyDumpCalled();
+ verify(mFakeTimeDetectorStrategySpy).dump(any(), any());
}
private static TimeConfiguration createTimeConfiguration(boolean autoDetectionEnabled) {
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
index 08632284cfc8..62dae481ac0b 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
@@ -38,8 +38,6 @@ import android.app.timedetector.ManualTimeSuggestion;
import android.app.timedetector.TelephonyTimeSuggestion;
import android.os.TimestampedValue;
-import androidx.test.runner.AndroidJUnit4;
-
import com.android.server.SystemClockTime.TimeConfidence;
import com.android.server.timedetector.TimeDetectorStrategy.Origin;
import com.android.server.timezonedetector.ConfigurationChangeListener;
@@ -55,7 +53,10 @@ import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Objects;
-@RunWith(AndroidJUnit4.class)
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
+@RunWith(JUnitParamsRunner.class)
public class TimeDetectorStrategyImplTest {
private static final @UserIdInt int ARBITRARY_USER_ID = 9876;
@@ -656,12 +657,45 @@ public class TimeDetectorStrategyImplTest {
long expectedSystemClockMillis =
script.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime());
+ boolean bypassUserPolicyChecks = false;
+ boolean expectedResult = true;
script.simulateManualTimeSuggestion(
- ARBITRARY_USER_ID, timeSuggestion, true /* expectedResult */)
+ ARBITRARY_USER_ID, timeSuggestion, bypassUserPolicyChecks, expectedResult)
.verifySystemClockConfidence(TIME_CONFIDENCE_HIGH)
.verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
}
+ /** Confirms the effect of user policy restrictions on being able to set the time. */
+ @Test
+ @Parameters({ "true,true", "true,false", "false,true", "false,false" })
+ public void testSuggestManualTime_autoTimeDisabled_userRestrictions(
+ boolean userConfigAllowed, boolean bypassUserPolicyChecks) {
+ ConfigurationInternal configAutoDisabled =
+ new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
+ .setUserConfigAllowed(userConfigAllowed)
+ .build();
+ Script script = new Script().simulateConfigurationInternalChange(configAutoDisabled)
+ .verifySystemClockConfidence(TIME_CONFIDENCE_LOW);
+
+ ManualTimeSuggestion timeSuggestion =
+ script.generateManualTimeSuggestion(ARBITRARY_TEST_TIME);
+
+ script.simulateTimePassing();
+
+ long expectedSystemClockMillis =
+ script.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime());
+ boolean expectedResult = userConfigAllowed || bypassUserPolicyChecks;
+ script.simulateManualTimeSuggestion(
+ ARBITRARY_USER_ID, timeSuggestion, bypassUserPolicyChecks, expectedResult);
+ if (expectedResult) {
+ script.verifySystemClockConfidence(TIME_CONFIDENCE_HIGH)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
+ } else {
+ script.verifySystemClockConfidence(TIME_CONFIDENCE_LOW)
+ .verifySystemClockWasNotSetAndResetCallTracking();
+ }
+ }
+
@Test
public void testSuggestManualTime_retainsAutoSignal() {
Script script = new Script().simulateConfigurationInternalChange(CONFIG_AUTO_ENABLED)
@@ -704,8 +738,10 @@ public class TimeDetectorStrategyImplTest {
long expectedManualClockMillis =
script.calculateTimeInMillisForNow(manualTimeSuggestion.getUnixEpochTime());
+ boolean bypassUserPolicyChecks = false;
+ boolean expectedResult = true;
script.simulateManualTimeSuggestion(
- ARBITRARY_USER_ID, manualTimeSuggestion, true /* expectedResult */)
+ ARBITRARY_USER_ID, manualTimeSuggestion, bypassUserPolicyChecks, expectedResult)
.verifySystemClockConfidence(TIME_CONFIDENCE_HIGH)
.verifySystemClockWasSetAndResetCallTracking(expectedManualClockMillis)
.assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion);
@@ -737,9 +773,10 @@ public class TimeDetectorStrategyImplTest {
ManualTimeSuggestion timeSuggestion =
script.generateManualTimeSuggestion(ARBITRARY_TEST_TIME);
- script.simulateTimePassing()
- .simulateManualTimeSuggestion(
- ARBITRARY_USER_ID, timeSuggestion, false /* expectedResult */)
+ boolean bypassUserPolicyChecks = false;
+ boolean expectedResult = false;
+ script.simulateTimePassing().simulateManualTimeSuggestion(
+ ARBITRARY_USER_ID, timeSuggestion, bypassUserPolicyChecks, expectedResult)
.verifySystemClockConfidence(TIME_CONFIDENCE_LOW)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@@ -755,8 +792,10 @@ public class TimeDetectorStrategyImplTest {
Instant aboveUpperBound = TEST_SUGGESTION_UPPER_BOUND.plusSeconds(1);
ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(aboveUpperBound);
+ boolean bypassUserPolicyChecks = false;
+ boolean expectedResult = false;
script.simulateManualTimeSuggestion(
- ARBITRARY_USER_ID, timeSuggestion, false /* expectedResult */)
+ ARBITRARY_USER_ID, timeSuggestion, bypassUserPolicyChecks, expectedResult)
.verifySystemClockConfidence(TIME_CONFIDENCE_LOW)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@@ -772,8 +811,10 @@ public class TimeDetectorStrategyImplTest {
Instant belowUpperBound = TEST_SUGGESTION_UPPER_BOUND.minusSeconds(1);
ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(belowUpperBound);
+ boolean bypassUserPolicyChecks = false;
+ boolean expectedResult = true;
script.simulateManualTimeSuggestion(
- ARBITRARY_USER_ID, timeSuggestion, true /* expectedResult */)
+ ARBITRARY_USER_ID, timeSuggestion, bypassUserPolicyChecks, expectedResult)
.verifySystemClockConfidence(TIME_CONFIDENCE_HIGH)
.verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
}
@@ -789,8 +830,10 @@ public class TimeDetectorStrategyImplTest {
Instant belowLowerBound = TEST_SUGGESTION_LOWER_BOUND.minusSeconds(1);
ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(belowLowerBound);
+ boolean bypassUserPolicyChecks = false;
+ boolean expectedResult = false;
script.simulateManualTimeSuggestion(
- ARBITRARY_USER_ID, timeSuggestion, false /* expectedResult */)
+ ARBITRARY_USER_ID, timeSuggestion, bypassUserPolicyChecks, expectedResult)
.verifySystemClockConfidence(TIME_CONFIDENCE_LOW)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@@ -806,8 +849,10 @@ public class TimeDetectorStrategyImplTest {
Instant aboveLowerBound = TEST_SUGGESTION_LOWER_BOUND.plusSeconds(1);
ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(aboveLowerBound);
+ boolean bypassUserPolicyChecks = false;
+ boolean expectedResult = true;
script.simulateManualTimeSuggestion(
- ARBITRARY_USER_ID, timeSuggestion, true /* expectedResult */)
+ ARBITRARY_USER_ID, timeSuggestion, bypassUserPolicyChecks, expectedResult)
.verifySystemClockConfidence(TIME_CONFIDENCE_HIGH)
.verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
}
@@ -1758,8 +1803,10 @@ public class TimeDetectorStrategyImplTest {
ManualTimeSuggestion timeSuggestion =
script.generateManualTimeSuggestion(ARBITRARY_TEST_TIME);
+ boolean bypassUserPolicyChecks = false;
+ boolean expectedResult = true;
script.simulateManualTimeSuggestion(
- ARBITRARY_USER_ID, timeSuggestion, true /* expectedResult */)
+ ARBITRARY_USER_ID, timeSuggestion, bypassUserPolicyChecks, expectedResult)
.verifySystemClockWasSetAndResetCallTracking(ARBITRARY_TEST_TIME.toEpochMilli());
}
@@ -1951,14 +1998,15 @@ public class TimeDetectorStrategyImplTest {
Script simulateManualTimeSuggestion(
@UserIdInt int userId, ManualTimeSuggestion timeSuggestion,
- boolean expectedResult) {
+ boolean bypassUserPolicyChecks, boolean expectedResult) {
String errorMessage = expectedResult
? "Manual time suggestion was ignored, but expected to be accepted."
: "Manual time suggestion was accepted, but expected to be ignored.";
assertEquals(
errorMessage,
expectedResult,
- mTimeDetectorStrategy.suggestManualTime(userId, timeSuggestion));
+ mTimeDetectorStrategy.suggestManualTime(
+ userId, timeSuggestion, bypassUserPolicyChecks));
return this;
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java
index 810bd82f4431..7140097bb6c0 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java
@@ -29,27 +29,36 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import android.app.time.TimeCapabilitiesAndConfig;
import android.app.time.TimeZoneCapabilities;
import android.app.time.TimeZoneCapabilitiesAndConfig;
import android.app.time.TimeZoneConfiguration;
import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
/**
- * Tests for {@link ConfigurationInternal} and the {@link TimeZoneCapabilitiesAndConfig}.
+ * Tests for {@link ConfigurationInternal} and associated {@link TimeZoneCapabilitiesAndConfig}
+ * behavior.
*/
+@RunWith(JUnitParamsRunner.class)
public class ConfigurationInternalTest {
private static final int ARBITRARY_USER_ID = 99999;
/**
- * Tests when {@link ConfigurationInternal#isUserConfigAllowed()} and
- * {@link ConfigurationInternal#isAutoDetectionSupported()} are both true.
+ * Tests {@link TimeCapabilitiesAndConfig} behavior in different scenarios when auto detection
+ * is supported (and geo detection is supported)
*/
@Test
- public void test_unrestricted() {
+ @Parameters({ "true,true", "true,false", "false,true", "false,false" })
+ public void test_autoDetectionSupported_capabilitiesAndConfiguration(
+ boolean userConfigAllowed, boolean bypassUserPolicyChecks) {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
- .setUserConfigAllowed(true)
+ .setUserConfigAllowed(userConfigAllowed)
.setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setGeoDetectionRunInBackgroundEnabled(false)
@@ -59,73 +68,10 @@ public class ConfigurationInternalTest {
.setLocationEnabledSetting(true)
.setGeoDetectionEnabledSetting(true)
.build();
- {
- ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig)
- .setAutoDetectionEnabledSetting(true)
- .build();
- assertTrue(autoOnConfig.getAutoDetectionEnabledSetting());
- assertTrue(autoOnConfig.getGeoDetectionEnabledSetting());
- assertTrue(autoOnConfig.getAutoDetectionEnabledBehavior());
- assertTrue(autoOnConfig.isGeoDetectionExecutionEnabled());
- assertEquals(DETECTION_MODE_GEO, autoOnConfig.getDetectionMode());
-
- TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
- autoOnConfig.createCapabilitiesAndConfig();
- TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
- assertEquals(CAPABILITY_POSSESSED,
- capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_NOT_APPLICABLE,
- capabilities.getSetManualTimeZoneCapability());
- assertEquals(CAPABILITY_POSSESSED,
- capabilities.getConfigureGeoDetectionEnabledCapability());
-
- TimeZoneConfiguration configuration = capabilitiesAndConfig.getConfiguration();
- assertTrue(configuration.isAutoDetectionEnabled());
- assertTrue(configuration.isGeoDetectionEnabled());
- }
+ boolean userRestrictionsExpected = !(userConfigAllowed || bypassUserPolicyChecks);
- {
- ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig)
- .setAutoDetectionEnabledSetting(false)
- .build();
- assertFalse(autoOffConfig.getAutoDetectionEnabledSetting());
- assertTrue(autoOffConfig.getGeoDetectionEnabledSetting());
- assertFalse(autoOffConfig.getAutoDetectionEnabledBehavior());
- assertFalse(autoOffConfig.isGeoDetectionExecutionEnabled());
- assertEquals(DETECTION_MODE_MANUAL, autoOffConfig.getDetectionMode());
-
- TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
- autoOffConfig.createCapabilitiesAndConfig();
-
- TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
- assertEquals(CAPABILITY_POSSESSED,
- capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_POSSESSED,
- capabilities.getSetManualTimeZoneCapability());
- assertEquals(CAPABILITY_NOT_APPLICABLE,
- capabilities.getConfigureGeoDetectionEnabledCapability());
-
- TimeZoneConfiguration configuration = capabilitiesAndConfig.getConfiguration();
- assertFalse(configuration.isAutoDetectionEnabled());
- assertTrue(configuration.isGeoDetectionEnabled());
- }
- }
-
- /** Tests when {@link ConfigurationInternal#isUserConfigAllowed()} is false */
- @Test
- public void test_restricted() {
- ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
- .setUserConfigAllowed(false)
- .setTelephonyDetectionFeatureSupported(true)
- .setGeoDetectionFeatureSupported(true)
- .setTelephonyFallbackSupported(false)
- .setGeoDetectionRunInBackgroundEnabled(false)
- .setEnhancedMetricsCollectionEnabled(false)
- .setAutoDetectionEnabledSetting(true)
- .setLocationEnabledSetting(true)
- .setGeoDetectionEnabledSetting(true)
- .build();
+ // Auto-detection enabled.
{
ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig)
.setAutoDetectionEnabledSetting(true)
@@ -137,13 +83,20 @@ public class ConfigurationInternalTest {
assertEquals(DETECTION_MODE_GEO, autoOnConfig.getDetectionMode());
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
- autoOnConfig.createCapabilitiesAndConfig();
+ autoOnConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
- assertEquals(CAPABILITY_NOT_ALLOWED,
- capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_NOT_ALLOWED,
- capabilities.getSetManualTimeZoneCapability());
+ if (userRestrictionsExpected) {
+ assertEquals(CAPABILITY_NOT_ALLOWED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_NOT_ALLOWED,
+ capabilities.getSetManualTimeZoneCapability());
+ } else {
+ assertEquals(CAPABILITY_POSSESSED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_NOT_APPLICABLE,
+ capabilities.getSetManualTimeZoneCapability());
+ }
// This has user privacy implications so it is not restricted in the same way as others.
assertEquals(CAPABILITY_POSSESSED,
capabilities.getConfigureGeoDetectionEnabledCapability());
@@ -153,6 +106,7 @@ public class ConfigurationInternalTest {
assertTrue(configuration.isGeoDetectionEnabled());
}
+ // Auto-detection disabled.
{
ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig)
.setAutoDetectionEnabledSetting(false)
@@ -164,13 +118,20 @@ public class ConfigurationInternalTest {
assertEquals(DETECTION_MODE_MANUAL, autoOffConfig.getDetectionMode());
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
- autoOffConfig.createCapabilitiesAndConfig();
+ autoOffConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
- assertEquals(CAPABILITY_NOT_ALLOWED,
- capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_NOT_ALLOWED,
- capabilities.getSetManualTimeZoneCapability());
+ if (userRestrictionsExpected) {
+ assertEquals(CAPABILITY_NOT_ALLOWED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_NOT_ALLOWED,
+ capabilities.getSetManualTimeZoneCapability());
+ } else {
+ assertEquals(CAPABILITY_POSSESSED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_POSSESSED,
+ capabilities.getSetManualTimeZoneCapability());
+ }
// This has user privacy implications so it is not restricted in the same way as others.
assertEquals(CAPABILITY_NOT_APPLICABLE,
capabilities.getConfigureGeoDetectionEnabledCapability());
@@ -181,11 +142,16 @@ public class ConfigurationInternalTest {
}
}
- /** Tests when {@link ConfigurationInternal#isAutoDetectionSupported()} is false. */
+ /**
+ * Tests {@link TimeCapabilitiesAndConfig} behavior in different scenarios when auto detection
+ * is not supported.
+ */
@Test
- public void test_autoDetectNotSupported() {
+ @Parameters({ "true,true", "true,false", "false,true", "false,false" })
+ public void test_autoDetectNotSupported_capabilitiesAndConfiguration(
+ boolean userConfigAllowed, boolean bypassUserPolicyChecks) {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
- .setUserConfigAllowed(true)
+ .setUserConfigAllowed(userConfigAllowed)
.setTelephonyDetectionFeatureSupported(false)
.setGeoDetectionFeatureSupported(false)
.setGeoDetectionRunInBackgroundEnabled(false)
@@ -195,6 +161,10 @@ public class ConfigurationInternalTest {
.setLocationEnabledSetting(true)
.setGeoDetectionEnabledSetting(true)
.build();
+
+ boolean userRestrictionsExpected = !(userConfigAllowed || bypassUserPolicyChecks);
+
+ // Auto-detection enabled.
{
ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig)
.setAutoDetectionEnabledSetting(true)
@@ -206,12 +176,16 @@ public class ConfigurationInternalTest {
assertEquals(DETECTION_MODE_MANUAL, autoOnConfig.getDetectionMode());
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
- autoOnConfig.createCapabilitiesAndConfig();
+ autoOnConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
assertEquals(CAPABILITY_NOT_SUPPORTED,
capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability());
+ if (userRestrictionsExpected) {
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeZoneCapability());
+ } else {
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability());
+ }
assertEquals(CAPABILITY_NOT_SUPPORTED,
capabilities.getConfigureGeoDetectionEnabledCapability());
@@ -219,6 +193,8 @@ public class ConfigurationInternalTest {
assertTrue(configuration.isAutoDetectionEnabled());
assertTrue(configuration.isGeoDetectionEnabled());
}
+
+ // Auto-detection disabled.
{
ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig)
.setAutoDetectionEnabledSetting(false)
@@ -230,12 +206,16 @@ public class ConfigurationInternalTest {
assertEquals(DETECTION_MODE_MANUAL, autoOffConfig.getDetectionMode());
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
- autoOffConfig.createCapabilitiesAndConfig();
+ autoOffConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
assertEquals(CAPABILITY_NOT_SUPPORTED,
capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability());
+ if (userRestrictionsExpected) {
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeZoneCapability());
+ } else {
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability());
+ }
assertEquals(CAPABILITY_NOT_SUPPORTED,
capabilities.getConfigureGeoDetectionEnabledCapability());
@@ -246,13 +226,15 @@ public class ConfigurationInternalTest {
}
/**
- * Tests when {@link ConfigurationInternal#isAutoDetectionSupported()} is true, but
- * {@link ConfigurationInternal#isGeoDetectionSupported()} is false.
+ * Tests {@link TimeCapabilitiesAndConfig} behavior in different scenarios when auto detection
+ * is supported (and geo detection is not supported).
*/
@Test
- public void test_geoDetectNotSupported() {
+ @Parameters({ "true,true", "true,false", "false,true", "false,false" })
+ public void test_geoDetectNotSupported_capabilitiesAndConfiguration(
+ boolean userConfigAllowed, boolean bypassUserPolicyChecks) {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
- .setUserConfigAllowed(true)
+ .setUserConfigAllowed(userConfigAllowed)
.setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(false)
.setGeoDetectionRunInBackgroundEnabled(false)
@@ -262,6 +244,10 @@ public class ConfigurationInternalTest {
.setLocationEnabledSetting(true)
.setGeoDetectionEnabledSetting(true)
.build();
+
+ boolean userRestrictionsExpected = !(userConfigAllowed || bypassUserPolicyChecks);
+
+ // Auto-detection enabled.
{
ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig)
.setAutoDetectionEnabledSetting(true)
@@ -273,13 +259,20 @@ public class ConfigurationInternalTest {
assertEquals(DETECTION_MODE_TELEPHONY, autoOnConfig.getDetectionMode());
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
- autoOnConfig.createCapabilitiesAndConfig();
+ autoOnConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
- assertEquals(CAPABILITY_POSSESSED,
- capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_NOT_APPLICABLE,
- capabilities.getSetManualTimeZoneCapability());
+ if (userRestrictionsExpected) {
+ assertEquals(CAPABILITY_NOT_ALLOWED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_NOT_ALLOWED,
+ capabilities.getSetManualTimeZoneCapability());
+ } else {
+ assertEquals(CAPABILITY_POSSESSED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_NOT_APPLICABLE,
+ capabilities.getSetManualTimeZoneCapability());
+ }
assertEquals(CAPABILITY_NOT_SUPPORTED,
capabilities.getConfigureGeoDetectionEnabledCapability());
@@ -287,6 +280,8 @@ public class ConfigurationInternalTest {
assertTrue(configuration.isAutoDetectionEnabled());
assertTrue(configuration.isGeoDetectionEnabled());
}
+
+ // Auto-detection disabled.
{
ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig)
.setAutoDetectionEnabledSetting(false)
@@ -298,12 +293,18 @@ public class ConfigurationInternalTest {
assertEquals(DETECTION_MODE_MANUAL, autoOffConfig.getDetectionMode());
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
- autoOffConfig.createCapabilitiesAndConfig();
+ autoOffConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
- assertEquals(CAPABILITY_POSSESSED,
- capabilities.getConfigureAutoDetectionEnabledCapability());
- assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability());
+ if (userRestrictionsExpected) {
+ assertEquals(CAPABILITY_NOT_ALLOWED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeZoneCapability());
+ } else {
+ assertEquals(CAPABILITY_POSSESSED,
+ capabilities.getConfigureAutoDetectionEnabledCapability());
+ assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability());
+ }
assertEquals(CAPABILITY_NOT_SUPPORTED,
capabilities.getConfigureGeoDetectionEnabledCapability());
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/FakeServiceConfigAccessor.java b/services/tests/servicestests/src/com/android/server/timezonedetector/FakeServiceConfigAccessor.java
index a97ad8c57a0d..fdee86ea1285 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/FakeServiceConfigAccessor.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/FakeServiceConfigAccessor.java
@@ -32,7 +32,7 @@ import java.util.List;
import java.util.Optional;
/** A partially implemented, fake implementation of ServiceConfigAccessor for tests. */
-class FakeServiceConfigAccessor implements ServiceConfigAccessor {
+public class FakeServiceConfigAccessor implements ServiceConfigAccessor {
private final List<ConfigurationChangeListener> mConfigurationInternalChangeListeners =
new ArrayList<>();
@@ -55,7 +55,8 @@ class FakeServiceConfigAccessor implements ServiceConfigAccessor {
@Override
public boolean updateConfiguration(
- @UserIdInt int userID, @NonNull TimeZoneConfiguration requestedChanges) {
+ @UserIdInt int userID, @NonNull TimeZoneConfiguration requestedChanges,
+ boolean bypassUserPolicyChecks) {
assertNotNull(mConfigurationInternal);
assertNotNull(requestedChanges);
@@ -63,7 +64,7 @@ class FakeServiceConfigAccessor implements ServiceConfigAccessor {
// old configuration merged with the new if the user has the capability to up the settings.
// Then, if the configuration changed, the change listener is invoked.
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
- mConfigurationInternal.createCapabilitiesAndConfig();
+ mConfigurationInternal.createCapabilitiesAndConfig(bypassUserPolicyChecks);
TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
TimeZoneConfiguration configuration = capabilitiesAndConfig.getConfiguration();
TimeZoneConfiguration newConfiguration =
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java b/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java
index 339e5b23cd9a..228dc952356a 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java
@@ -15,9 +15,6 @@
*/
package com.android.server.timezonedetector;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.time.TimeZoneState;
@@ -25,21 +22,12 @@ import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
import android.util.IndentingPrintWriter;
-class FakeTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
+public class FakeTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
private TimeZoneState mTimeZoneState;
- // Call tracking.
- private GeolocationTimeZoneSuggestion mLastGeolocationSuggestion;
- private ManualTimeZoneSuggestion mLastManualSuggestion;
- private Integer mLastManualSuggestionUserId;
- private TelephonyTimeZoneSuggestion mLastTelephonySuggestion;
- private String mLastConfirmedTimeZone;
- private boolean mDumpCalled;
-
@Override
public boolean confirmTimeZone(String timeZoneId) {
- mLastConfirmedTimeZone = timeZoneId;
return false;
}
@@ -55,21 +43,17 @@ class FakeTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
@Override
public void suggestGeolocationTimeZone(GeolocationTimeZoneSuggestion timeZoneSuggestion) {
- mLastGeolocationSuggestion = timeZoneSuggestion;
}
@Override
public boolean suggestManualTimeZone(
- @UserIdInt int userId, @NonNull ManualTimeZoneSuggestion timeZoneSuggestion) {
- mLastManualSuggestionUserId = userId;
- mLastManualSuggestion = timeZoneSuggestion;
+ @UserIdInt int userId, @NonNull ManualTimeZoneSuggestion timeZoneSuggestion,
+ boolean bypassUserPolicyChecks) {
return true;
}
@Override
- public void suggestTelephonyTimeZone(
- @NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion) {
- mLastTelephonySuggestion = timeZoneSuggestion;
+ public void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion) {
}
@Override
@@ -94,38 +78,5 @@ class FakeTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
@Override
public void dump(IndentingPrintWriter pw, String[] args) {
- mDumpCalled = true;
- }
-
- void resetCallTracking() {
- mLastGeolocationSuggestion = null;
- mLastManualSuggestion = null;
- mLastManualSuggestionUserId = null;
- mLastTelephonySuggestion = null;
- mDumpCalled = false;
- mLastConfirmedTimeZone = null;
- }
-
- void verifySuggestGeolocationTimeZoneCalled(
- GeolocationTimeZoneSuggestion expectedSuggestion) {
- assertEquals(expectedSuggestion, mLastGeolocationSuggestion);
- }
-
- void verifySuggestManualTimeZoneCalled(
- @UserIdInt int expectedUserId, ManualTimeZoneSuggestion expectedSuggestion) {
- assertEquals((Integer) expectedUserId, mLastManualSuggestionUserId);
- assertEquals(expectedSuggestion, mLastManualSuggestion);
- }
-
- void verifySuggestTelephonyTimeZoneCalled(TelephonyTimeZoneSuggestion expectedSuggestion) {
- assertEquals(expectedSuggestion, mLastTelephonySuggestion);
- }
-
- void verifyDumpCalled() {
- assertTrue(mDumpCalled);
- }
-
- void verifyConfirmTimeZoneCalled(String expectedTimeZoneId) {
- assertEquals(expectedTimeZoneId, mLastConfirmedTimeZone);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TestCurrentUserIdentityInjector.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TestCurrentUserIdentityInjector.java
new file mode 100644
index 000000000000..aad06d87f111
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TestCurrentUserIdentityInjector.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timezonedetector;
+
+import android.annotation.UserIdInt;
+
+/** A fake {@link CurrentUserIdentityInjector} used in tests. */
+public class TestCurrentUserIdentityInjector implements CurrentUserIdentityInjector {
+
+ private Integer mCurrentUserId;
+
+ public void initializeCurrentUserId(@UserIdInt int userId) {
+ mCurrentUserId = userId;
+ }
+
+ @Override
+ public int getCurrentUserId() {
+ return mCurrentUserId;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorInternalImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorInternalImplTest.java
index c5bab760fcfe..276fdb971172 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorInternalImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorInternalImplTest.java
@@ -16,8 +16,15 @@
package com.android.server.timezonedetector;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import android.app.time.TimeZoneCapabilitiesAndConfig;
+import android.app.time.TimeZoneConfiguration;
+import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.content.Context;
import android.os.HandlerThread;
@@ -35,15 +42,18 @@ import java.util.List;
public class TimeZoneDetectorInternalImplTest {
private static final long ARBITRARY_ELAPSED_REALTIME_MILLIS = 1234L;
- private static final List<String> ARBITRARY_ZONE_IDS = Arrays.asList("TestZoneId");
+ private static final String ARBITRARY_ZONE_ID = "TestZoneId";
+ private static final List<String> ARBITRARY_ZONE_IDS = Arrays.asList(ARBITRARY_ZONE_ID);
+ private static final int ARBITRARY_USER_ID = 9999;
private Context mMockContext;
- private FakeTimeZoneDetectorStrategy mFakeTimeZoneDetectorStrategy;
-
- private TimeZoneDetectorInternalImpl mTimeZoneDetectorInternal;
private HandlerThread mHandlerThread;
private TestHandler mTestHandler;
+ private TestCurrentUserIdentityInjector mTestCurrentUserIdentityInjector;
+ private FakeServiceConfigAccessor mFakeServiceConfigAccessorSpy;
+ private FakeTimeZoneDetectorStrategy mFakeTimeZoneDetectorStrategySpy;
+ private TimeZoneDetectorInternalImpl mTimeZoneDetectorInternal;
@Before
public void setUp() {
@@ -53,11 +63,14 @@ public class TimeZoneDetectorInternalImplTest {
mHandlerThread = new HandlerThread("TimeZoneDetectorInternalTest");
mHandlerThread.start();
mTestHandler = new TestHandler(mHandlerThread.getLooper());
-
- mFakeTimeZoneDetectorStrategy = new FakeTimeZoneDetectorStrategy();
+ mTestCurrentUserIdentityInjector = new TestCurrentUserIdentityInjector();
+ mTestCurrentUserIdentityInjector.initializeCurrentUserId(ARBITRARY_USER_ID);
+ mFakeServiceConfigAccessorSpy = spy(new FakeServiceConfigAccessor());
+ mFakeTimeZoneDetectorStrategySpy = spy(new FakeTimeZoneDetectorStrategy());
mTimeZoneDetectorInternal = new TimeZoneDetectorInternalImpl(
- mMockContext, mTestHandler, mFakeTimeZoneDetectorStrategy);
+ mMockContext, mTestHandler, mTestCurrentUserIdentityInjector,
+ mFakeServiceConfigAccessorSpy, mFakeTimeZoneDetectorStrategySpy);
}
@After
@@ -67,17 +80,84 @@ public class TimeZoneDetectorInternalImplTest {
}
@Test
+ public void testGetCapabilitiesAndConfigForDpm() throws Exception {
+ final boolean autoDetectionEnabled = true;
+ ConfigurationInternal testConfig = createConfigurationInternal(autoDetectionEnabled);
+ mFakeServiceConfigAccessorSpy.initializeConfiguration(testConfig);
+
+ TimeZoneCapabilitiesAndConfig actualCapabilitiesAndConfig =
+ mTimeZoneDetectorInternal.getCapabilitiesAndConfigForDpm();
+
+ int expectedUserId = mTestCurrentUserIdentityInjector.getCurrentUserId();
+ verify(mFakeServiceConfigAccessorSpy).getConfigurationInternal(expectedUserId);
+
+ final boolean bypassUserPolicyChecks = true;
+ TimeZoneCapabilitiesAndConfig expectedCapabilitiesAndConfig =
+ testConfig.createCapabilitiesAndConfig(bypassUserPolicyChecks);
+ assertEquals(expectedCapabilitiesAndConfig, actualCapabilitiesAndConfig);
+ }
+
+ @Test
+ public void testUpdateConfigurationForDpm() throws Exception {
+ final boolean autoDetectionEnabled = false;
+ ConfigurationInternal initialConfigurationInternal =
+ createConfigurationInternal(autoDetectionEnabled);
+ mFakeServiceConfigAccessorSpy.initializeConfiguration(initialConfigurationInternal);
+
+ TimeZoneConfiguration timeConfiguration = new TimeZoneConfiguration.Builder()
+ .setAutoDetectionEnabled(true)
+ .build();
+ assertTrue(mTimeZoneDetectorInternal.updateConfigurationForDpm(timeConfiguration));
+
+ final boolean expectedBypassUserPolicyChecks = true;
+ verify(mFakeServiceConfigAccessorSpy).updateConfiguration(
+ mTestCurrentUserIdentityInjector.getCurrentUserId(),
+ timeConfiguration,
+ expectedBypassUserPolicyChecks);
+ }
+
+ @Test
+ public void testSetManualTimeZoneForDpm() throws Exception {
+ ManualTimeZoneSuggestion timeZoneSuggestion = createManualTimeZoneSuggestion();
+
+ // The fake strategy always returns true.
+ assertTrue(mTimeZoneDetectorInternal.setManualTimeZoneForDpm(timeZoneSuggestion));
+
+ int expectedUserId = mTestCurrentUserIdentityInjector.getCurrentUserId();
+ boolean expectedBypassUserPolicyChecks = true;
+ verify(mFakeTimeZoneDetectorStrategySpy).suggestManualTimeZone(
+ expectedUserId, timeZoneSuggestion, expectedBypassUserPolicyChecks);
+ }
+
+ @Test
public void testSuggestGeolocationTimeZone() throws Exception {
GeolocationTimeZoneSuggestion timeZoneSuggestion = createGeolocationTimeZoneSuggestion();
mTimeZoneDetectorInternal.suggestGeolocationTimeZone(timeZoneSuggestion);
mTestHandler.assertTotalMessagesEnqueued(1);
mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeZoneDetectorStrategy.verifySuggestGeolocationTimeZoneCalled(timeZoneSuggestion);
+ verify(mFakeTimeZoneDetectorStrategySpy).suggestGeolocationTimeZone(timeZoneSuggestion);
+ }
+ private static ManualTimeZoneSuggestion createManualTimeZoneSuggestion() {
+ return new ManualTimeZoneSuggestion(ARBITRARY_ZONE_ID);
}
private static GeolocationTimeZoneSuggestion createGeolocationTimeZoneSuggestion() {
return GeolocationTimeZoneSuggestion.createCertainSuggestion(
ARBITRARY_ELAPSED_REALTIME_MILLIS, ARBITRARY_ZONE_IDS);
}
+
+ private static ConfigurationInternal createConfigurationInternal(boolean autoDetectionEnabled) {
+ return new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
+ .setTelephonyDetectionFeatureSupported(true)
+ .setGeoDetectionFeatureSupported(true)
+ .setTelephonyFallbackSupported(false)
+ .setGeoDetectionRunInBackgroundEnabled(false)
+ .setEnhancedMetricsCollectionEnabled(false)
+ .setUserConfigAllowed(true)
+ .setAutoDetectionEnabledSetting(autoDetectionEnabled)
+ .setLocationEnabledSetting(false)
+ .setGeoDetectionEnabledSetting(false)
+ .build();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
index fc6459725978..bb9d564b5aad 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
@@ -28,11 +28,13 @@ import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.app.time.ITimeZoneDetectorListener;
+import android.app.time.TimeZoneCapabilitiesAndConfig;
import android.app.time.TimeZoneConfiguration;
import android.app.time.TimeZoneState;
import android.app.timezonedetector.ManualTimeZoneSuggestion;
@@ -67,8 +69,8 @@ public class TimeZoneDetectorServiceTest {
private HandlerThread mHandlerThread;
private TestHandler mTestHandler;
private TestCallerIdentityInjector mTestCallerIdentityInjector;
- private FakeServiceConfigAccessor mFakeServiceConfigAccessor;
- private FakeTimeZoneDetectorStrategy mFakeTimeZoneDetectorStrategy;
+ private FakeServiceConfigAccessor mFakeServiceConfigAccessorSpy;
+ private FakeTimeZoneDetectorStrategy mFakeTimeZoneDetectorStrategySpy;
@Before
@@ -83,12 +85,12 @@ public class TimeZoneDetectorServiceTest {
mTestCallerIdentityInjector = new TestCallerIdentityInjector();
mTestCallerIdentityInjector.initializeCallingUserId(ARBITRARY_USER_ID);
- mFakeTimeZoneDetectorStrategy = new FakeTimeZoneDetectorStrategy();
- mFakeServiceConfigAccessor = new FakeServiceConfigAccessor();
+ mFakeServiceConfigAccessorSpy = spy(new FakeServiceConfigAccessor());
+ mFakeTimeZoneDetectorStrategySpy = spy(new FakeTimeZoneDetectorStrategy());
mTimeZoneDetectorService = new TimeZoneDetectorService(
mMockContext, mTestHandler, mTestCallerIdentityInjector,
- mFakeServiceConfigAccessor, mFakeTimeZoneDetectorStrategy);
+ mFakeServiceConfigAccessorSpy, mFakeTimeZoneDetectorStrategySpy);
}
@After
@@ -113,13 +115,21 @@ public class TimeZoneDetectorServiceTest {
ConfigurationInternal configuration =
createConfigurationInternal(true /* autoDetectionEnabled*/);
- mFakeServiceConfigAccessor.initializeConfiguration(configuration);
+ mFakeServiceConfigAccessorSpy.initializeConfiguration(configuration);
- assertEquals(configuration.createCapabilitiesAndConfig(),
- mTimeZoneDetectorService.getCapabilitiesAndConfig());
+ TimeZoneCapabilitiesAndConfig actualCapabilitiesAndConfig =
+ mTimeZoneDetectorService.getCapabilitiesAndConfig();
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION), anyString());
+
+ int expectedUserId = mTestCallerIdentityInjector.getCallingUserId();
+ verify(mFakeServiceConfigAccessorSpy).getConfigurationInternal(expectedUserId);
+
+ boolean expectedBypassUserPolicyChecks = false;
+ TimeZoneCapabilitiesAndConfig expectedCapabilitiesAndConfig =
+ configuration.createCapabilitiesAndConfig(expectedBypassUserPolicyChecks);
+ assertEquals(expectedCapabilitiesAndConfig, actualCapabilitiesAndConfig);
}
@Test
@@ -150,7 +160,7 @@ public class TimeZoneDetectorServiceTest {
public void testListenerRegistrationAndCallbacks() throws Exception {
ConfigurationInternal initialConfiguration =
createConfigurationInternal(false /* autoDetectionEnabled */);
- mFakeServiceConfigAccessor.initializeConfiguration(initialConfiguration);
+ mFakeServiceConfigAccessorSpy.initializeConfiguration(initialConfiguration);
IBinder mockListenerBinder = mock(IBinder.class);
ITimeZoneDetectorListener mockListener = mock(ITimeZoneDetectorListener.class);
@@ -222,46 +232,46 @@ public class TimeZoneDetectorServiceTest {
@Test
public void testSuggestGeolocationTimeZone_withoutPermission() {
doThrow(new SecurityException("Mock"))
- .when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ .when(mMockContext).enforceCallingPermission(anyString(), any());
GeolocationTimeZoneSuggestion timeZoneSuggestion = createGeolocationTimeZoneSuggestion();
assertThrows(SecurityException.class,
() -> mTimeZoneDetectorService.suggestGeolocationTimeZone(timeZoneSuggestion));
- verify(mMockContext).enforceCallingOrSelfPermission(
+ verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SET_TIME_ZONE), anyString());
}
@Test
public void testSuggestGeolocationTimeZone() throws Exception {
- doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
GeolocationTimeZoneSuggestion timeZoneSuggestion = createGeolocationTimeZoneSuggestion();
mTimeZoneDetectorService.suggestGeolocationTimeZone(timeZoneSuggestion);
mTestHandler.assertTotalMessagesEnqueued(1);
- verify(mMockContext).enforceCallingOrSelfPermission(
+ verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SET_TIME_ZONE), anyString());
mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeZoneDetectorStrategy.verifySuggestGeolocationTimeZoneCalled(timeZoneSuggestion);
+ verify(mFakeTimeZoneDetectorStrategySpy).suggestGeolocationTimeZone(timeZoneSuggestion);
}
@Test
public void testSuggestManualTimeZone_withoutPermission() {
doThrow(new SecurityException("Mock"))
- .when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ .when(mMockContext).enforceCallingPermission(anyString(), any());
ManualTimeZoneSuggestion timeZoneSuggestion = createManualTimeZoneSuggestion();
assertThrows(SecurityException.class,
() -> mTimeZoneDetectorService.suggestManualTimeZone(timeZoneSuggestion));
- verify(mMockContext).enforceCallingOrSelfPermission(
+ verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE), anyString());
}
@Test
public void testSuggestManualTimeZone() throws Exception {
- doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
ManualTimeZoneSuggestion timeZoneSuggestion = createManualTimeZoneSuggestion();
@@ -269,10 +279,12 @@ public class TimeZoneDetectorServiceTest {
assertEquals(expectedResult,
mTimeZoneDetectorService.suggestManualTimeZone(timeZoneSuggestion));
- mFakeTimeZoneDetectorStrategy.verifySuggestManualTimeZoneCalled(
- mTestCallerIdentityInjector.getCallingUserId(), timeZoneSuggestion);
+ int expectedUserId = mTestCallerIdentityInjector.getCallingUserId();
+ boolean expectedBypassUserPolicyChecks = false;
+ verify(mFakeTimeZoneDetectorStrategySpy).suggestManualTimeZone(
+ expectedUserId, timeZoneSuggestion, expectedBypassUserPolicyChecks);
- verify(mMockContext).enforceCallingOrSelfPermission(
+ verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE), anyString());
}
@@ -312,20 +324,20 @@ public class TimeZoneDetectorServiceTest {
eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE), anyString());
mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeZoneDetectorStrategy.verifySuggestTelephonyTimeZoneCalled(timeZoneSuggestion);
+ verify(mFakeTimeZoneDetectorStrategySpy).suggestTelephonyTimeZone(timeZoneSuggestion);
}
@Test
public void testGetTimeZoneState() {
doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
TimeZoneState fakeState = new TimeZoneState("Europe/Narnia", true);
- mFakeTimeZoneDetectorStrategy.setTimeZoneState(fakeState);
+ mFakeTimeZoneDetectorStrategySpy.setTimeZoneState(fakeState);
TimeZoneState actualState = mTimeZoneDetectorService.getTimeZoneState();
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION), anyString());
- assertEquals(actualState, fakeState);
+ assertEquals(fakeState, actualState);
}
@Test
@@ -347,7 +359,7 @@ public class TimeZoneDetectorServiceTest {
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION), anyString());
- assertEquals(mFakeTimeZoneDetectorStrategy.getTimeZoneState(), state);
+ assertEquals(state, mFakeTimeZoneDetectorStrategySpy.getTimeZoneState());
}
@Test
@@ -371,7 +383,7 @@ public class TimeZoneDetectorServiceTest {
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION), anyString());
- mFakeTimeZoneDetectorStrategy.verifyConfirmTimeZoneCalled("Europe/Narnia");
+ verify(mFakeTimeZoneDetectorStrategySpy).confirmTimeZone("Europe/Narnia");
}
@Test
@@ -396,8 +408,10 @@ public class TimeZoneDetectorServiceTest {
mTimeZoneDetectorService.setManualTimeZone(timeZoneSuggestion));
// The service calls "suggestManualTimeZone()" because the logic is the same.
- mFakeTimeZoneDetectorStrategy.verifySuggestManualTimeZoneCalled(
- mTestCallerIdentityInjector.getCallingUserId(), timeZoneSuggestion);
+ int expectedUserId = mTestCallerIdentityInjector.getCallingUserId();
+ boolean expectedBypassUserPolicyChecks = false;
+ verify(mFakeTimeZoneDetectorStrategySpy).suggestManualTimeZone(
+ expectedUserId, timeZoneSuggestion, expectedBypassUserPolicyChecks);
verify(mMockContext).enforceCallingPermission(
eq(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION), anyString());
@@ -427,7 +441,7 @@ public class TimeZoneDetectorServiceTest {
mTimeZoneDetectorService.dump(null, pw, null);
verify(mMockContext).checkCallingOrSelfPermission(eq(android.Manifest.permission.DUMP));
- mFakeTimeZoneDetectorStrategy.verifyDumpCalled();
+ verify(mFakeTimeZoneDetectorStrategySpy).dump(any(), any());
verify(dumpable).dump(any(), any());
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
index 77d8b8bf9687..d0a7c92b0436 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
@@ -53,6 +53,7 @@ import com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.Qualifie
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -60,9 +61,13 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Function;
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
/**
* White-box unit tests for {@link TimeZoneDetectorStrategyImpl}.
*/
+@RunWith(JUnitParamsRunner.class)
public class TimeZoneDetectorStrategyImplTest {
private static final @UserIdInt int USER_ID = 9876;
@@ -561,74 +566,79 @@ public class TimeZoneDetectorStrategyImplTest {
.resetConfigurationTracking();
// Auto time zone detection is enabled so the manual suggestion should be ignored.
- script.simulateManualTimeZoneSuggestion(
- USER_ID, createManualSuggestion("Europe/Paris"), false /* expectedResult */)
+ boolean bypassUserPolicyChecks = false;
+ boolean expectedResult = false;
+ script.simulateManualTimeZoneSuggestion(USER_ID, createManualSuggestion("Europe/Paris"),
+ bypassUserPolicyChecks, expectedResult)
.verifyTimeZoneNotChanged();
assertNull(mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
- public void testManualSuggestion_restricted_simulateAutoTimeZoneEnabled() {
- Script script = new Script()
- .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID, TIME_ZONE_CONFIDENCE_LOW)
- .simulateConfigurationInternalChange(CONFIG_USER_RESTRICTED_AUTO_ENABLED)
- .resetConfigurationTracking();
-
- // User is restricted so the manual suggestion should be ignored.
- script.simulateManualTimeZoneSuggestion(
- USER_ID, createManualSuggestion("Europe/Paris"), false /* expectedResult */)
- .verifyTimeZoneNotChanged();
-
- assertNull(mTimeZoneDetectorStrategy.getLatestManualSuggestion());
- }
-
- @Test
- public void testManualSuggestion_unrestricted_autoTimeZoneDetectionDisabled() {
+ public void testManualSuggestion_autoDetectNotSupported() {
Script script = new Script()
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID, TIME_ZONE_CONFIDENCE_LOW)
- .simulateConfigurationInternalChange(CONFIG_AUTO_DISABLED_GEO_DISABLED)
+ .simulateConfigurationInternalChange(CONFIG_AUTO_DETECT_NOT_SUPPORTED)
.resetConfigurationTracking();
- // Auto time zone detection is disabled so the manual suggestion should be used.
+ // Unrestricted users have the capability.
ManualTimeZoneSuggestion manualSuggestion = createManualSuggestion("Europe/Paris");
+ boolean bypassUserPolicyChecks = false;
+ boolean expectedResult = true;
script.simulateManualTimeZoneSuggestion(
- USER_ID, manualSuggestion, true /* expectedResult */)
- .verifyTimeZoneChangedAndReset(manualSuggestion);
+ USER_ID, manualSuggestion, bypassUserPolicyChecks, expectedResult)
+ .verifyTimeZoneChangedAndReset(manualSuggestion);
assertEquals(manualSuggestion, mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
- public void testManualSuggestion_restricted_autoTimeZoneDetectionDisabled() {
+ @Parameters({ "true,true", "true,false", "false,true", "false,false" })
+ public void testManualSuggestion_autoTimeEnabled_userRestrictions(
+ boolean userConfigAllowed, boolean bypassUserPolicyChecks) {
+ ConfigurationInternal config =
+ new ConfigurationInternal.Builder(CONFIG_USER_RESTRICTED_AUTO_ENABLED)
+ .setUserConfigAllowed(userConfigAllowed)
+ .build();
Script script = new Script()
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID, TIME_ZONE_CONFIDENCE_LOW)
- .simulateConfigurationInternalChange(CONFIG_USER_RESTRICTED_AUTO_DISABLED)
+ .simulateConfigurationInternalChange(config)
.resetConfigurationTracking();
- // Restricted users do not have the capability.
- ManualTimeZoneSuggestion manualSuggestion = createManualSuggestion("Europe/Paris");
- script.simulateManualTimeZoneSuggestion(
- USER_ID, manualSuggestion, false /* expectedResult */)
+ // User is restricted so the manual suggestion should be ignored.
+ boolean expectedResult = false;
+ script.simulateManualTimeZoneSuggestion(USER_ID, createManualSuggestion("Europe/Paris"),
+ bypassUserPolicyChecks, expectedResult)
.verifyTimeZoneNotChanged();
assertNull(mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
- public void testManualSuggestion_autoDetectNotSupported() {
+ @Parameters({ "true,true", "true,false", "false,true", "false,false" })
+ public void testManualSuggestion_autoTimeDisabled_userRestrictions(
+ boolean userConfigAllowed, boolean bypassUserPolicyChecks) {
+ ConfigurationInternal config =
+ new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED_GEO_DISABLED)
+ .setUserConfigAllowed(userConfigAllowed)
+ .build();
Script script = new Script()
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID, TIME_ZONE_CONFIDENCE_LOW)
- .simulateConfigurationInternalChange(CONFIG_AUTO_DETECT_NOT_SUPPORTED)
+ .simulateConfigurationInternalChange(config)
.resetConfigurationTracking();
- // Unrestricted users have the capability.
ManualTimeZoneSuggestion manualSuggestion = createManualSuggestion("Europe/Paris");
+ boolean expectedResult = userConfigAllowed || bypassUserPolicyChecks;
script.simulateManualTimeZoneSuggestion(
- USER_ID, manualSuggestion, true /* expectedResult */)
- .verifyTimeZoneChangedAndReset(manualSuggestion);
-
- assertEquals(manualSuggestion, mTimeZoneDetectorStrategy.getLatestManualSuggestion());
+ USER_ID, manualSuggestion, bypassUserPolicyChecks, expectedResult);
+ if (expectedResult) {
+ script.verifyTimeZoneChangedAndReset(manualSuggestion);
+ assertEquals(manualSuggestion, mTimeZoneDetectorStrategy.getLatestManualSuggestion());
+ } else {
+ script.verifyTimeZoneNotChanged();
+ assertNull(mTimeZoneDetectorStrategy.getLatestManualSuggestion());
+ }
}
@Test
@@ -1071,8 +1081,10 @@ public class TimeZoneDetectorStrategyImplTest {
// Make sure the manual suggestion is recorded.
ManualTimeZoneSuggestion manualSuggestion = createManualSuggestion("Zone1");
- script.simulateManualTimeZoneSuggestion(USER_ID, manualSuggestion,
- true /* expectedResult */)
+ boolean bypassUserPolicyChecks = false;
+ boolean expectedResult = true;
+ script.simulateManualTimeZoneSuggestion(
+ USER_ID, manualSuggestion, bypassUserPolicyChecks, expectedResult)
.verifyTimeZoneChangedAndReset(manualSuggestion);
expectedDeviceTimeZoneId = manualSuggestion.getZoneId();
assertMetricsState(expectedInternalConfig, expectedDeviceTimeZoneId,
@@ -1350,9 +1362,9 @@ public class TimeZoneDetectorStrategyImplTest {
/** Simulates the time zone detection strategy receiving a user-originated suggestion. */
Script simulateManualTimeZoneSuggestion(
@UserIdInt int userId, ManualTimeZoneSuggestion manualTimeZoneSuggestion,
- boolean expectedResult) {
+ boolean bypassUserPolicyChecks, boolean expectedResult) {
boolean actualResult = mTimeZoneDetectorStrategy.suggestManualTimeZone(
- userId, manualTimeZoneSuggestion);
+ userId, manualTimeZoneSuggestion, bypassUserPolicyChecks);
assertEquals(expectedResult, actualResult);
return this;
}