Merge "Prepare to make origin list mutable" into sc-dev
diff --git a/services/core/java/com/android/server/timedetector/EnvironmentImpl.java b/services/core/java/com/android/server/timedetector/EnvironmentImpl.java
index 4f5e8fa..072cc16f 100644
--- a/services/core/java/com/android/server/timedetector/EnvironmentImpl.java
+++ b/services/core/java/com/android/server/timedetector/EnvironmentImpl.java
@@ -16,26 +16,22 @@
 
 package com.android.server.timedetector;
 
-import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK;
-import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_TELEPHONY;
-import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin;
-
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.app.AlarmManager;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.os.Build;
+import android.database.ContentObserver;
+import android.os.Handler;
 import android.os.PowerManager;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
 import android.util.Slog;
 
-import com.android.internal.R;
-import com.android.server.timedetector.TimeDetectorStrategy.Origin;
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.timezonedetector.ConfigurationChangeListener;
 
 import java.time.Instant;
 import java.util.Objects;
@@ -43,62 +39,71 @@
 /**
  * The real implementation of {@link TimeDetectorStrategyImpl.Environment} used on device.
  */
-public final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environment {
+final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environment {
 
-    private static final String TAG = TimeDetectorService.TAG;
-
-    private static final int SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT = 2 * 1000;
-
-    /**
-     * Time in the past. If automatic time suggestion is before this point, it's
-     * incorrect for sure.
-     */
-    private static final Instant TIME_LOWER_BOUND = Instant.ofEpochMilli(
-            Long.max(android.os.Environment.getRootDirectory().lastModified(), Build.TIME));
-
-    /**
-     * By default telephony and network only suggestions are accepted and telephony takes
-     * precedence over network.
-     */
-    private static final @Origin int[] DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES =
-            { ORIGIN_TELEPHONY, ORIGIN_NETWORK };
-
-    /**
-     * If a newly calculated system clock time and the current system clock time differs by this or
-     * more the system clock will actually be updated. Used to prevent the system clock being set
-     * for only minor differences.
-     */
-    private final int mSystemClockUpdateThresholdMillis;
+    private static final String LOG_TAG = TimeDetectorService.TAG;
 
     @NonNull private final Context mContext;
+    @NonNull private final Handler mHandler;
+    @NonNull private final ServiceConfigAccessor mServiceConfigAccessor;
     @NonNull private final ContentResolver mContentResolver;
     @NonNull private final PowerManager.WakeLock mWakeLock;
     @NonNull private final AlarmManager mAlarmManager;
     @NonNull private final UserManager mUserManager;
-    @NonNull private final int[] mOriginPriorities;
 
-    public EnvironmentImpl(@NonNull Context context) {
+    // @NonNull after setConfigChangeListener() is called.
+    @GuardedBy("this")
+    private ConfigurationChangeListener mConfigChangeListener;
+
+    EnvironmentImpl(@NonNull Context context, @NonNull Handler handler,
+            @NonNull ServiceConfigAccessor serviceConfigAccessor) {
         mContext = Objects.requireNonNull(context);
         mContentResolver = Objects.requireNonNull(context.getContentResolver());
+        mHandler = Objects.requireNonNull(handler);
+        mServiceConfigAccessor = Objects.requireNonNull(serviceConfigAccessor);
 
         PowerManager powerManager = context.getSystemService(PowerManager.class);
         mWakeLock = Objects.requireNonNull(
-                powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG));
+                powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG));
 
         mAlarmManager = Objects.requireNonNull(context.getSystemService(AlarmManager.class));
 
         mUserManager = Objects.requireNonNull(context.getSystemService(UserManager.class));
 
-        mSystemClockUpdateThresholdMillis =
-                SystemProperties.getInt("ro.sys.time_detector_update_diff",
-                        SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT);
+        // Wire up the config change listeners. All invocations are performed on the mHandler
+        // thread.
 
-        mOriginPriorities = getOriginPriorities(context);
+        ContentResolver contentResolver = context.getContentResolver();
+        contentResolver.registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.AUTO_TIME), true,
+                new ContentObserver(mHandler) {
+                    @Override
+                    public void onChange(boolean selfChange) {
+                        handleAutoTimeDetectionChangedOnHandlerThread();
+                    }
+                });
+    }
+
+    /** Internal method for handling the auto time setting being changed. */
+    private void handleAutoTimeDetectionChangedOnHandlerThread() {
+        synchronized (this) {
+            if (mConfigChangeListener == null) {
+                Slog.wtf(LOG_TAG, "mConfigChangeListener is unexpectedly null");
+            }
+            mConfigChangeListener.onChange();
+        }
+    }
+
+    @Override
+    public void setConfigChangeListener(@NonNull ConfigurationChangeListener listener) {
+        synchronized (this) {
+            mConfigChangeListener = Objects.requireNonNull(listener);
+        }
     }
 
     @Override
     public int systemClockUpdateThresholdMillis() {
-        return mSystemClockUpdateThresholdMillis;
+        return mServiceConfigAccessor.systemClockUpdateThresholdMillis();
     }
 
     @Override
@@ -112,12 +117,12 @@
 
     @Override
     public Instant autoTimeLowerBound() {
-        return TIME_LOWER_BOUND;
+        return mServiceConfigAccessor.autoTimeLowerBound();
     }
 
     @Override
     public int[] autoOriginPriorities() {
-        return mOriginPriorities;
+        return mServiceConfigAccessor.getOriginPriorities();
     }
 
     @Override
@@ -131,7 +136,7 @@
     @Override
     public void acquireWakeLock() {
         if (mWakeLock.isHeld()) {
-            Slog.wtf(TAG, "WakeLock " + mWakeLock + " already held");
+            Slog.wtf(LOG_TAG, "WakeLock " + mWakeLock + " already held");
         }
         mWakeLock.acquire();
     }
@@ -160,7 +165,7 @@
 
     private void checkWakeLockHeld() {
         if (!mWakeLock.isHeld()) {
-            Slog.wtf(TAG, "WakeLock " + mWakeLock + " not held");
+            Slog.wtf(LOG_TAG, "WakeLock " + mWakeLock + " not held");
         }
     }
 
@@ -168,20 +173,4 @@
         UserHandle userHandle = UserHandle.of(userId);
         return !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME, userHandle);
     }
-
-    private static int[] getOriginPriorities(@NonNull Context context) {
-        String[] originStrings =
-                context.getResources().getStringArray(R.array.config_autoTimeSourcesPriority);
-        if (originStrings.length == 0) {
-            return DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES;
-        } else {
-            int[] origins = new int[originStrings.length];
-            for (int i = 0; i < originStrings.length; i++) {
-                int origin = stringToOrigin(originStrings[i]);
-                origins[i] = origin;
-            }
-
-            return origins;
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java b/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java
new file mode 100644
index 0000000..be4432a
--- /dev/null
+++ b/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2021 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.timedetector;
+
+import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK;
+import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_TELEPHONY;
+import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.Build;
+import android.os.SystemProperties;
+import android.util.ArraySet;
+
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.timezonedetector.ConfigurationChangeListener;
+
+import java.time.Instant;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A singleton that provides access to service configuration for time detection. This hides how
+ * configuration is split between static, compile-time config and dynamic, server-pushed flags. It
+ * provides a rudimentary mechanism to signal when values have changed.
+ */
+final class ServiceConfigAccessor {
+
+    private static final int SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT = 2 * 1000;
+
+    /**
+     * By default telephony and network only suggestions are accepted and telephony takes
+     * precedence over network.
+     */
+    private static final @TimeDetectorStrategy.Origin int[]
+            DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES = { ORIGIN_TELEPHONY, ORIGIN_NETWORK };
+
+    /**
+     * Time in the past. If an automatic time suggestion is before this point, it is sure to be
+     * incorrect.
+     */
+    private static final Instant TIME_LOWER_BOUND_DEFAULT = Instant.ofEpochMilli(
+            Long.max(android.os.Environment.getRootDirectory().lastModified(), Build.TIME));
+
+    private static final Set<String> SERVER_FLAGS_KEYS_TO_WATCH = Collections.unmodifiableSet(
+            new ArraySet<>(new String[] {
+            }));
+
+    private static final Object SLOCK = new Object();
+
+    /** The singleton instance. Initialized once in {@link #getInstance(Context)}. */
+    @GuardedBy("SLOCK")
+    @Nullable
+    private static ServiceConfigAccessor sInstance;
+
+    @NonNull private final Context mContext;
+    @NonNull private final ServerFlags mServerFlags;
+    @NonNull private final int[] mOriginPriorities;
+
+    /**
+     * If a newly calculated system clock time and the current system clock time differs by this or
+     * more the system clock will actually be updated. Used to prevent the system clock being set
+     * for only minor differences.
+     */
+    private final int mSystemClockUpdateThresholdMillis;
+
+    private ServiceConfigAccessor(@NonNull Context context) {
+        mContext = Objects.requireNonNull(context);
+        mServerFlags = ServerFlags.getInstance(mContext);
+        mOriginPriorities = getOriginPrioritiesInternal();
+        mSystemClockUpdateThresholdMillis =
+                SystemProperties.getInt("ro.sys.time_detector_update_diff",
+                        SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT);
+    }
+
+    /** Returns the singleton instance. */
+    static ServiceConfigAccessor getInstance(Context context) {
+        synchronized (SLOCK) {
+            if (sInstance == null) {
+                sInstance = new ServiceConfigAccessor(context);
+            }
+            return sInstance;
+        }
+    }
+
+    /**
+     * Adds a listener that will be called when server flags related to this class change. The
+     * callbacks are delivered on the main looper thread.
+     *
+     * <p>Note: Only for use by long-lived objects. There is deliberately no associated remove
+     * method.
+     */
+    void addListener(@NonNull ConfigurationChangeListener listener) {
+        mServerFlags.addListener(listener, SERVER_FLAGS_KEYS_TO_WATCH);
+    }
+
+    @NonNull
+    int[] getOriginPriorities() {
+        return mOriginPriorities;
+    }
+
+    int systemClockUpdateThresholdMillis() {
+        return mSystemClockUpdateThresholdMillis;
+    }
+
+    Instant autoTimeLowerBound() {
+        return TIME_LOWER_BOUND_DEFAULT;
+    }
+
+    private int[] getOriginPrioritiesInternal() {
+        String[] originStrings =
+                mContext.getResources().getStringArray(R.array.config_autoTimeSourcesPriority);
+        if (originStrings.length == 0) {
+            return DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES;
+        } else {
+            int[] origins = new int[originStrings.length];
+            for (int i = 0; i < originStrings.length; i++) {
+                int origin = stringToOrigin(originStrings[i]);
+                origins[i] = origin;
+            }
+
+            return origins;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 27e2ee5..20c1c3c 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -27,12 +27,9 @@
 import android.app.timedetector.ManualTimeSuggestion;
 import android.app.timedetector.NetworkTimeSuggestion;
 import android.app.timedetector.TelephonyTimeSuggestion;
-import android.content.ContentResolver;
 import android.content.Context;
-import android.database.ContentObserver;
 import android.os.Binder;
 import android.os.Handler;
-import android.provider.Settings;
 import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -64,7 +61,16 @@
 
         @Override
         public void onStart() {
-            TimeDetectorService service = TimeDetectorService.create(getContext());
+            Context context = getContext();
+            Handler handler = FgThread.getHandler();
+
+            ServiceConfigAccessor serviceConfigAccessor =
+                    ServiceConfigAccessor.getInstance(context);
+            TimeDetectorStrategy timeDetectorStrategy =
+                    TimeDetectorStrategyImpl.create(context, handler, serviceConfigAccessor);
+
+            TimeDetectorService service =
+                    new TimeDetectorService(context, handler, timeDetectorStrategy);
 
             // Publish the binder service so it can be accessed from other (appropriately
             // permissioned) processes.
@@ -77,28 +83,6 @@
     @NonNull private final TimeDetectorStrategy mTimeDetectorStrategy;
     @NonNull private final CallerIdentityInjector mCallerIdentityInjector;
 
-    private static TimeDetectorService create(@NonNull Context context) {
-        TimeDetectorStrategyImpl.Environment environment = new EnvironmentImpl(context);
-        TimeDetectorStrategy timeDetectorStrategy = new TimeDetectorStrategyImpl(environment);
-
-        Handler handler = FgThread.getHandler();
-        TimeDetectorService timeDetectorService =
-                new TimeDetectorService(context, handler, timeDetectorStrategy);
-
-        // Wire up event listening.
-        ContentResolver contentResolver = context.getContentResolver();
-        contentResolver.registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.AUTO_TIME), true,
-                new ContentObserver(handler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        timeDetectorService.handleAutoTimeDetectionChanged();
-                    }
-                });
-
-        return timeDetectorService;
-    }
-
     @VisibleForTesting
     public TimeDetectorService(@NonNull Context context, @NonNull Handler handler,
             @NonNull TimeDetectorStrategy timeDetectorStrategy) {
@@ -185,12 +169,6 @@
         mHandler.post(() -> mTimeDetectorStrategy.suggestExternalTime(timeSignal));
     }
 
-    /** Internal method for handling the auto time setting being changed. */
-    @VisibleForTesting
-    public void handleAutoTimeDetectionChanged() {
-        mHandler.post(mTimeDetectorStrategy::handleAutoTimeConfigChanged);
-    }
-
     @Override
     protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
             @Nullable String[] args) {
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index cde66be..be382f0 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -92,12 +92,6 @@
     /** Returns the configuration that controls time detector behaviour for specified user. */
     ConfigurationInternal getConfigurationInternal(@UserIdInt int userId);
 
-    /**
-     * Handles the auto-time configuration changing For example, when the auto-time setting is
-     * toggled on or off.
-     */
-    void handleAutoTimeConfigChanged();
-
     // Utility methods below are to be moved to a better home when one becomes more obvious.
 
     /**
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index 289d8d6..db8a59e 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -29,6 +29,8 @@
 import android.app.timedetector.ManualTimeSuggestion;
 import android.app.timedetector.NetworkTimeSuggestion;
 import android.app.timedetector.TelephonyTimeSuggestion;
+import android.content.Context;
+import android.os.Handler;
 import android.os.TimestampedValue;
 import android.util.IndentingPrintWriter;
 import android.util.LocalLog;
@@ -37,6 +39,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.timezonedetector.ArrayMapWithHistory;
+import com.android.server.timezonedetector.ConfigurationChangeListener;
 import com.android.server.timezonedetector.ReferenceWithHistory;
 
 import java.time.Instant;
@@ -132,6 +135,12 @@
     public interface Environment {
 
         /**
+         * Sets a {@link ConfigurationChangeListener} that will be invoked when there are any
+         * changes that could affect time detection. This is invoked during system server setup.
+         */
+        void setConfigChangeListener(@NonNull ConfigurationChangeListener listener);
+
+        /**
          * The absolute threshold below which the system clock need not be updated. i.e. if setting
          * the system clock would adjust it by less than this (either backwards or forwards) then it
          * need not be set.
@@ -178,8 +187,19 @@
         void releaseWakeLock();
     }
 
+    static TimeDetectorStrategy create(
+            @NonNull Context context, @NonNull Handler handler,
+            @NonNull ServiceConfigAccessor serviceConfigAccessor) {
+
+        TimeDetectorStrategyImpl.Environment environment =
+                new EnvironmentImpl(context, handler, serviceConfigAccessor);
+        return new TimeDetectorStrategyImpl(environment);
+    }
+
+    @VisibleForTesting
     TimeDetectorStrategyImpl(@NonNull Environment environment) {
         mEnvironment = Objects.requireNonNull(environment);
+        mEnvironment.setConfigChangeListener(this::handleAutoTimeConfigChanged);
     }
 
     @Override
@@ -279,8 +299,7 @@
         return mEnvironment.configurationInternal(userId);
     }
 
-    @Override
-    public synchronized void handleAutoTimeConfigChanged() {
+    private synchronized void handleAutoTimeConfigChanged() {
         boolean enabled = mEnvironment.isAutoTimeDetectionEnabled();
         // When automatic time detection is enabled we update the system clock instantly if we can.
         // Conversely, when automatic time detection is disabled we leave the clock as it is.
diff --git a/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java b/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java
index 0e5f3bf..b84f8a8 100644
--- a/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java
@@ -47,7 +47,7 @@
 /**
  * The real implementation of {@link TimeZoneDetectorStrategyImpl.Environment}.
  */
-public final class EnvironmentImpl implements TimeZoneDetectorStrategyImpl.Environment {
+final class EnvironmentImpl implements TimeZoneDetectorStrategyImpl.Environment {
 
     private static final String LOG_TAG = TimeZoneDetectorService.TAG;
     private static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
index 50d37f4..dddb11b 100644
--- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
+++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
@@ -133,8 +133,8 @@
     }
 
     /**
-     * Adds a listener that will be called server flags related to this class change. The callbacks
-     * are delivered on the main looper thread.
+     * Adds a listener that will be called when server flags related to this class change. The
+     * callbacks are delivered on the main looper thread.
      *
      * <p>Note: Only for use by long-lived objects. There is deliberately no associated remove
      * method.
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 742f503..32fed3b 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -248,21 +248,6 @@
         mStubbedTimeDetectorStrategy.verifyDumpCalled();
     }
 
-    @Test
-    public void testAutoTimeDetectionToggle() throws Exception {
-        mTimeDetectorService.handleAutoTimeDetectionChanged();
-        mTestHandler.assertTotalMessagesEnqueued(1);
-        mTestHandler.waitForMessagesToBeProcessed();
-        mStubbedTimeDetectorStrategy.verifyHandleAutoTimeDetectionChangedCalled();
-
-        mStubbedTimeDetectorStrategy.resetCallTracking();
-
-        mTimeDetectorService.handleAutoTimeDetectionChanged();
-        mTestHandler.assertTotalMessagesEnqueued(2);
-        mTestHandler.waitForMessagesToBeProcessed();
-        mStubbedTimeDetectorStrategy.verifyHandleAutoTimeDetectionChangedCalled();
-    }
-
     private static TelephonyTimeSuggestion createTelephonyTimeSuggestion() {
         int slotIndex = 1234;
         TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
@@ -298,7 +283,6 @@
         private NetworkTimeSuggestion mLastNetworkSuggestion;
         private GnssTimeSuggestion mLastGnssSuggestion;
         private ExternalTimeSuggestion mLastExternalSuggestion;
-        private boolean mHandleAutoTimeDetectionChangedCalled;
         private boolean mDumpCalled;
 
         @Override
@@ -333,11 +317,6 @@
         }
 
         @Override
-        public void handleAutoTimeConfigChanged() {
-            mHandleAutoTimeDetectionChangedCalled = true;
-        }
-
-        @Override
         public void dump(IndentingPrintWriter pw, String[] args) {
             mDumpCalled = true;
         }
@@ -348,7 +327,6 @@
             mLastNetworkSuggestion = null;
             mLastGnssSuggestion = null;
             mLastExternalSuggestion = null;
-            mHandleAutoTimeDetectionChangedCalled = false;
             mDumpCalled = false;
         }
 
@@ -372,10 +350,6 @@
             assertEquals(expectedSuggestion, mLastExternalSuggestion);
         }
 
-        void verifyHandleAutoTimeDetectionChangedCalled() {
-            assertTrue(mHandleAutoTimeDetectionChangedCalled);
-        }
-
         void verifyDumpCalled() {
             assertTrue(mDumpCalled);
         }
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 095703e..0d5b5a5 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
@@ -37,6 +37,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.timedetector.TimeDetectorStrategy.Origin;
+import com.android.server.timezonedetector.ConfigurationChangeListener;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -46,6 +47,7 @@
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
+import java.util.Objects;
 
 @RunWith(AndroidJUnit4.class)
 public class TimeDetectorStrategyImplTest {
@@ -1133,11 +1135,17 @@
         private long mSystemClockMillis;
         private int mSystemClockUpdateThresholdMillis = 2000;
         private int[] mAutoOriginPriorities = PROVIDERS_PRIORITY;
+        private ConfigurationChangeListener mConfigChangeListener;
 
         // Tracking operations.
         private boolean mSystemClockWasSet;
 
         @Override
+        public void setConfigChangeListener(ConfigurationChangeListener listener) {
+            mConfigChangeListener = Objects.requireNonNull(listener);
+        }
+
+        @Override
         public int systemClockUpdateThresholdMillis() {
             return mSystemClockUpdateThresholdMillis;
         }
@@ -1230,6 +1238,7 @@
 
         void simulateAutoTimeZoneDetectionToggle() {
             mAutoTimeDetectionEnabled = !mAutoTimeDetectionEnabled;
+            mConfigChangeListener.onChange();
         }
 
         void verifySystemClockNotSet() {
@@ -1330,7 +1339,6 @@
 
         Script simulateAutoTimeDetectionToggle() {
             mFakeEnvironment.simulateAutoTimeZoneDetectionToggle();
-            mTimeDetectorStrategy.handleAutoTimeConfigChanged();
             return this;
         }