Merge changes from topic "update_profile_api"

* changes:
  Use new bt api to set active device
  Update LocalBluetoothProfile api
  Update connect/disconnect Bluetooth api
diff --git a/api/system-current.txt b/api/system-current.txt
index e24ed55..1c43e09 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -979,6 +979,16 @@
 
 }
 
+package android.app.compat {
+
+  public final class CompatChanges {
+    method public static boolean isChangeEnabled(long);
+    method public static boolean isChangeEnabled(long, @NonNull String, @NonNull android.os.UserHandle);
+    method public static boolean isChangeEnabled(long, int);
+  }
+
+}
+
 package android.app.contentsuggestions {
 
   public final class ClassificationsRequest implements android.os.Parcelable {
@@ -1293,9 +1303,9 @@
 
   public final class BluetoothAdapter {
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean connectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
     method public boolean disableBLE();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean disconnectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
     method public boolean enableBLE();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean factoryReset();
@@ -9601,6 +9611,7 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int);
     method public boolean isCurrentSimOperator(@NonNull String, int, @Nullable String);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionEnabled();
     method public boolean isDataConnectivityPossible();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index d1fb2db..6cd34ae 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -351,6 +351,10 @@
             228 [(allow_from_any_uid) = true];
         PerfettoUploaded perfetto_uploaded =
             229 [(log_from_module) = "perfetto"];
+        BootTimeEventDuration boot_time_event_duration_reported = 239;
+        BootTimeEventElapsedTime boot_time_event_elapsed_time_reported = 240;
+        BootTimeEventUtcTime boot_time_event_utc_time_reported = 241;
+        BootTimeEventErrorCode boot_time_event_error_code_reported = 242;
         UserspaceRebootReported userspace_reboot_reported = 243;
     }
 
@@ -3739,6 +3743,210 @@
     optional Result result = 9;
 }
 
+/**
+ * Represents boot time event with duration in ms.
+ *
+ * Logged from: bootstat and various system server components. Check each enums for details.
+ */
+message BootTimeEventDuration {
+    enum DurationEvent {
+        UNKNOWN = 0;
+        // Bootloader time excluding BOOTLOADER_UI_WAIT + boot complete time. Logged from bootstat.
+        ABSOLUTE_BOOT_TIME = 1;
+        // Bootloader's 1st stage execution time.
+        // Logged from bootstat.
+        BOOTLOADER_FIRST_STAGE_EXEC = 2;
+        // Bootloader's 1st stage loading time.
+        // Logged from bootstat.
+        BOOTLOADER_FIRST_STAGE_LOAD = 3;
+        // Bootloader's kernel loading time.
+        // Logged from bootstat.
+        BOOTLOADER_KERNEL_LOAD = 4;
+        // Bootloader's 2nd stage execution time.
+        // Logged from bootstat.
+        BOOTLOADER_SECOND_STAGE_EXEC = 5;
+        // Bootloader's 2nd stage loading time.
+        // Logged from bootstat.
+        BOOTLOADER_SECOND_STAGE_LOAD = 6;
+        // Duration for Bootloader to show unlocked device's warning UI. This should not happen
+        // for locked device.
+        // Logged from bootstat.
+        BOOTLOADER_UI_WAIT = 7;
+        // Total time spend in bootloader. This is the sum of all BOOTLOADER_* listed above.
+        // Logged from bootstat.
+        BOOTLOADER_TOTAL = 8;
+        // Shutdown duration inside init for the reboot before the current boot up.
+        // Logged from f/b/services/.../BootReceiver.java.
+        SHUTDOWN_DURATION = 9;
+        // Total time for mounting of disk devices during bootup.
+        // Logged from f/b/services/.../BootReceiver.java.
+        MOUNT_DEFAULT_DURATION = 10;
+        // Total time for early stage mounting of disk devices during bootup.
+        // Logged from f/b/services/.../BootReceiver.java.
+        MOUNT_EARLY_DURATION = 11;
+        // Total time for late stage mounting of disk devices during bootup.
+        // Logged from f/b/services/.../BootReceiver.java.
+        MOUNT_LATE_DURATION = 12;
+        // Average time to scan non-system app after OTA
+        // Logged from f/b/services/.../PackageManagerService.java
+        OTA_PACKAGE_MANAGER_INIT_TIME = 13;
+        // Time to initialize Package manager after OTA
+        // Logged from f/b/services/.../PackageManagerService.java
+        OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME = 14;
+        // Time to scan all system app from Package manager after OTA
+        // Logged from f/b/services/.../PackageManagerService.java
+        OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME = 15;
+        // Init's total time for cold boot stage.
+        // Logged from bootstat.
+        COLDBOOT_WAIT = 16;
+        // Init's total time for initializing selinux.
+        // Logged from bootstat.
+        SELINUX_INIT = 17;
+        // Time since last factory reset.
+        // Logged from bootstat.
+        FACTORY_RESET_TIME_SINCE_RESET = 18;
+        // Init's total time spent for completing the 1st stage.
+        // Logged from bootstat.
+        ANDROID_INIT_STAGE_1 = 19;
+    }
+
+    // Type of the event.
+    optional DurationEvent event = 1;
+    // Duration of the event in ms.
+    optional int64 duration_millis = 2;
+}
+
+/**
+ * Represents the start of specific boot time event during bootup in ms. This is usually a time
+ * since boot-up.
+ *
+ * Logged from: bootstat and various system server components. Check each enums for details.
+ */
+message BootTimeEventElapsedTime {
+    enum ElapsedTimeEvent {
+        UNKNOWN = 0;
+        // Time when init starts 1st stage. Logged from bootstat.
+        ANDROID_INIT_STAGE_1 = 1;
+        // Time when sys.boot_completed prop is set.
+        // Logged from bootstat.
+        BOOT_COMPLETE = 2;
+        // BOOT_COMPLETE for encrypted device.
+        BOOT_COMPLETE_ENCRYPTION = 3;
+        // BOOT_COMPLETE for device with no encryption.
+        BOOT_COMPLETE_NO_ENCRYPTION = 4;
+        // Adjusted BOOT_COMPLETE for encrypted device extracting decryption time.
+        BOOT_COMPLETE_POST_DECRYPT = 5;
+        // BOOT_COMPLETE after factory reset.
+        FACTORY_RESET_BOOT_COMPLETE = 6;
+        // BOOT_COMPLETE_NO_ENCRYPTION after factory reset.
+        FACTORY_RESET_BOOT_COMPLETE_NO_ENCRYPTION = 7;
+        // BOOT_COMPLETE_POST_DECRYPT after factory reset.
+        FACTORY_RESET_BOOT_COMPLETE_POST_DECRYPT = 8;
+        // BOOT_COMPLETE after OTA.
+        OTA_BOOT_COMPLETE = 9;
+        // BOOT_COMPLETE_NO_ENCRYPTION after OTA.
+        OTA_BOOT_COMPLETE_NO_ENCRYPTION = 10;
+        // BOOT_COMPLETE_POST_DECRYPT after OTA.
+        OTA_BOOT_COMPLETE_POST_DECRYPT = 11;
+        // Time when the system starts sending LOCKED_BOOT_COMPLETED broadcast.
+        // Logged from  f/b/services/.../UserController.java
+        FRAMEWORK_LOCKED_BOOT_COMPLETED = 12;
+        // Time when the system starts sending BOOT_COMPLETED broadcast.
+        // Logged from  f/b/services/.../UserController.java
+        FRAMEWORK_BOOT_COMPLETED = 13;
+        // Time when the package manager starts init.
+        // Logged from f/b/services/.../SystemServer.java
+        PACKAGE_MANAGER_INIT_START = 14;
+        // Time when package manager is ready
+        // Logged from f/b/services/.../SystemServer.java
+        PACKAGE_MANAGER_INIT_READY = 15;
+        // Represents the time when user has entered unlock credential for system with user pin.
+        // Logged from bootstat.
+        POST_DECRYPT = 16;
+        // Represents the start of zygote's init.
+        // Logged from zygote itself.
+        ZYGOTE_INIT_START = 17;
+        // Represents the start of secondary zygote's init.
+        // TODO: add logging to zygote
+        SECONDARY_ZYGOTE_INIT_START = 18;
+        // Represents the start of system server's init.
+        // Logged from f/b/services/.../SystemServer.java
+        SYSTEM_SERVER_INIT_START = 19;
+        // Represents the completion of system server's init.
+        // Logged from f/b/services/.../SystemServer.java
+        SYSTEM_SERVER_READY = 20;
+        // Represents the start of launcher during boot-up.
+        // TODO: add logging
+        LAUNCHER_START = 21;
+        // Represents the completion of launcher's initial rendering. User can use other apps from
+        // launcher from this point.
+        // TODO: add logging
+        LAUNCHER_SHOWN = 22;
+    }
+
+    // Type of the event.
+    optional ElapsedTimeEvent event = 1;
+    // Time since bootup for the event.
+    // It should be acquired from SystemClock elapsedRealtime() call or equivalent.
+    optional int64 time_millis = 2;
+}
+
+/**
+ * Boot time events with UTC time.
+ *
+ * Logged from: bootstat and various system server components. Check each enums for details.
+ */
+message BootTimeEventUtcTime {
+    enum UtcTimeEvent {
+        UNKNOWN = 0;
+        // Time of the bootstat's marking of 1st boot after the last factory reset.
+        // Logged from bootstat.
+        FACTORY_RESET_RESET_TIME = 1;
+        // The time when bootstat records FACTORY_RESET_* events. This is close to
+        // BOOT_COMPLETE time for the current bootup.
+        // Logged from bootstat.
+        FACTORY_RESET_CURRENT_TIME = 2;
+        // DUplicate of FACTORY_RESET_RESET_TIME added for debugging purpose.
+        // Logged from bootstat.
+        FACTORY_RESET_RECORD_VALUE = 3;
+    }
+
+    // Type of the event.
+    optional UtcTimeEvent event = 1;
+    // UTC time for the event.
+    optional int64 utc_time_secs = 2;
+}
+
+/**
+ * Boot time events representing specific error code during bootup.
+ * Meaning of error code can be different per each event type.
+ *
+ * Logged from: bootstat and various system server components. Check each enums for details.
+ */
+message BootTimeEventErrorCode {
+    enum ErrorCodeEvent {
+        UNKNOWN = 0;
+        // Linux error code for time() call to get the current UTC time.
+        // Logged from bootstat.
+        FACTORY_RESET_CURRENT_TIME_FAILURE = 1;
+        // Represents UmountStat before the reboot for the current boot up. Error codes defined
+        // as UMOUNT_STAT_* from init/reboot.cpp.
+        // Logged from f/b/services/.../BootReceiver.java.
+        SHUTDOWN_UMOUNT_STAT = 2;
+        // Reprepsents fie system mounting error code of /data partition for the current boot.
+        // Error codes defined as combination of FsStatFlags from system/core/fs_mgr/fs_mgr.cpp.
+        // Logged from f/b/services/.../BootReceiver.java.
+        FS_MGR_FS_STAT_DATA_PARTITION = 3;
+    }
+
+    // Type of the event.
+    optional ErrorCodeEvent event = 1;
+    // error code defined per each event type.
+    // For example, this can have a value of FsStatFlags.FS_STAT_FULL_MOUNT_FAILED for the event of
+    // FS_MGR_FS_STAT.
+    optional int32 error_code = 2;
+}
+
 //////////////////////////////////////////////////////////////////////
 // Pulled atoms below this line //
 //////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/app/compat/CompatChanges.java b/core/java/android/app/compat/CompatChanges.java
new file mode 100644
index 0000000..5b36789
--- /dev/null
+++ b/core/java/android/app/compat/CompatChanges.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2020 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 android.app.compat;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.compat.Compatibility;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+
+import com.android.internal.compat.IPlatformCompat;
+
+/**
+ * CompatChanges APIs - to be used by platform code only (including mainline
+ * modules).
+ *
+ * @hide
+ */
+@SystemApi
+public final class CompatChanges {
+    private CompatChanges() {}
+
+    /**
+     * Query if a given compatibility change is enabled for the current process. This method is
+     * intended to be called by code running inside a process of the affected app only.
+     *
+     * <p>If this method returns {@code true}, the calling code should implement the compatibility
+     * change, resulting in differing behaviour compared to earlier releases. If this method returns
+     * {@code false}, the calling code should behave as it did in earlier releases.
+     *
+     * @param changeId The ID of the compatibility change in question.
+     * @return {@code true} if the change is enabled for the current app.
+     */
+    public static boolean isChangeEnabled(long changeId) {
+        return Compatibility.isChangeEnabled(changeId);
+    }
+
+    /**
+     * Same as {@code #isChangeEnabled(long)}, except this version should be called on behalf of an
+     * app from a different process that's performing work for the app.
+     *
+     * <p> Note that this involves a binder call to the system server (unless running in the system
+     * server). If the binder call fails, a {@code RuntimeException} will be thrown.
+     *
+     * <p> Caller must have android.permission.READ_COMPAT_CHANGE_CONFIG permission. If it
+     * doesn't, a {@code RuntimeException} will be thrown.
+     *
+     * @param changeId    The ID of the compatibility change in question.
+     * @param packageName The package name of the app in question.
+     * @param user        The user that the operation is done for.
+     * @return {@code true} if the change is enabled for the current app.
+     */
+    public static boolean isChangeEnabled(long changeId, @NonNull String packageName,
+            @NonNull UserHandle user) {
+        IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
+                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+        try {
+            return platformCompat.isChangeEnabledByPackageName(changeId, packageName,
+                    user.getIdentifier());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Same as {@code #isChangeEnabled(long)}, except this version should be called on behalf of an
+     * app from a different process that's performing work for the app.
+     *
+     * <p> Note that this involves a binder call to the system server (unless running in the system
+     * server). If the binder call fails, {@code RuntimeException}  will be thrown.
+     *
+     * <p> Caller must have android.permission.READ_COMPAT_CHANGE_CONFIG permission. If it
+     * doesn't, a {@code RuntimeException} will be thrown.
+     *
+     * <p> Returns {@code true} if there are no installed packages for the required UID, or if the
+     * change is enabled for ALL of the installed packages associated with the provided UID. Please
+     * use a more specific API if you want a different behaviour for multi-package UIDs.
+     *
+     * @param changeId The ID of the compatibility change in question.
+     * @param uid      The UID of the app in question.
+     * @return {@code true} if the change is enabled for the current app.
+     */
+    public static boolean isChangeEnabled(long changeId, int uid) {
+        IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
+                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+        try {
+            return platformCompat.isChangeEnabledByUid(changeId, uid);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/core/java/android/app/timedetector/ITimeDetectorService.aidl b/core/java/android/app/timedetector/ITimeDetectorService.aidl
index de8f470..5ead0c9 100644
--- a/core/java/android/app/timedetector/ITimeDetectorService.aidl
+++ b/core/java/android/app/timedetector/ITimeDetectorService.aidl
@@ -18,7 +18,7 @@
 
 import android.app.timedetector.ManualTimeSuggestion;
 import android.app.timedetector.NetworkTimeSuggestion;
-import android.app.timedetector.PhoneTimeSuggestion;
+import android.app.timedetector.TelephonyTimeSuggestion;
 
 /**
  * System private API to communicate with time detector service.
@@ -34,7 +34,7 @@
  * {@hide}
  */
 interface ITimeDetectorService {
-  void suggestPhoneTime(in PhoneTimeSuggestion timeSuggestion);
   void suggestManualTime(in ManualTimeSuggestion timeSuggestion);
   void suggestNetworkTime(in NetworkTimeSuggestion timeSuggestion);
+  void suggestTelephonyTime(in TelephonyTimeSuggestion timeSuggestion);
 }
diff --git a/core/java/android/app/timedetector/PhoneTimeSuggestion.aidl b/core/java/android/app/timedetector/TelephonyTimeSuggestion.aidl
similarity index 94%
rename from core/java/android/app/timedetector/PhoneTimeSuggestion.aidl
rename to core/java/android/app/timedetector/TelephonyTimeSuggestion.aidl
index f5e2405..d9b0386 100644
--- a/core/java/android/app/timedetector/PhoneTimeSuggestion.aidl
+++ b/core/java/android/app/timedetector/TelephonyTimeSuggestion.aidl
@@ -16,4 +16,4 @@
 
 package android.app.timedetector;
 
-parcelable PhoneTimeSuggestion;
+parcelable TelephonyTimeSuggestion;
diff --git a/core/java/android/app/timedetector/PhoneTimeSuggestion.java b/core/java/android/app/timedetector/TelephonyTimeSuggestion.java
similarity index 79%
rename from core/java/android/app/timedetector/PhoneTimeSuggestion.java
rename to core/java/android/app/timedetector/TelephonyTimeSuggestion.java
index 0133a44..c0e8957 100644
--- a/core/java/android/app/timedetector/PhoneTimeSuggestion.java
+++ b/core/java/android/app/timedetector/TelephonyTimeSuggestion.java
@@ -50,17 +50,17 @@
  *
  * @hide
  */
-public final class PhoneTimeSuggestion implements Parcelable {
+public final class TelephonyTimeSuggestion implements Parcelable {
 
     /** @hide */
-    public static final @NonNull Parcelable.Creator<PhoneTimeSuggestion> CREATOR =
-            new Parcelable.Creator<PhoneTimeSuggestion>() {
-                public PhoneTimeSuggestion createFromParcel(Parcel in) {
-                    return PhoneTimeSuggestion.createFromParcel(in);
+    public static final @NonNull Parcelable.Creator<TelephonyTimeSuggestion> CREATOR =
+            new Parcelable.Creator<TelephonyTimeSuggestion>() {
+                public TelephonyTimeSuggestion createFromParcel(Parcel in) {
+                    return TelephonyTimeSuggestion.createFromParcel(in);
                 }
 
-                public PhoneTimeSuggestion[] newArray(int size) {
-                    return new PhoneTimeSuggestion[size];
+                public TelephonyTimeSuggestion[] newArray(int size) {
+                    return new TelephonyTimeSuggestion[size];
                 }
             };
 
@@ -68,15 +68,15 @@
     @Nullable private final TimestampedValue<Long> mUtcTime;
     @Nullable private ArrayList<String> mDebugInfo;
 
-    private PhoneTimeSuggestion(Builder builder) {
+    private TelephonyTimeSuggestion(Builder builder) {
         mSlotIndex = builder.mSlotIndex;
         mUtcTime = builder.mUtcTime;
         mDebugInfo = builder.mDebugInfo != null ? new ArrayList<>(builder.mDebugInfo) : null;
     }
 
-    private static PhoneTimeSuggestion createFromParcel(Parcel in) {
+    private static TelephonyTimeSuggestion createFromParcel(Parcel in) {
         int slotIndex = in.readInt();
-        PhoneTimeSuggestion suggestion = new PhoneTimeSuggestion.Builder(slotIndex)
+        TelephonyTimeSuggestion suggestion = new TelephonyTimeSuggestion.Builder(slotIndex)
                 .setUtcTime(in.readParcelable(null /* classLoader */))
                 .build();
         @SuppressWarnings("unchecked")
@@ -102,7 +102,7 @@
     /**
      * Returns an identifier for the source of this suggestion.
      *
-     * <p>See {@link PhoneTimeSuggestion} for more information about {@code slotIndex}.
+     * <p>See {@link TelephonyTimeSuggestion} for more information about {@code slotIndex}.
      */
     public int getSlotIndex() {
         return mSlotIndex;
@@ -111,7 +111,7 @@
     /**
      * Returns the suggested time or {@code null} if there isn't one.
      *
-     * <p>See {@link PhoneTimeSuggestion} for more information about {@code utcTime}.
+     * <p>See {@link TelephonyTimeSuggestion} for more information about {@code utcTime}.
      */
     @Nullable
     public TimestampedValue<Long> getUtcTime() {
@@ -121,7 +121,7 @@
     /**
      * Returns debug metadata for the suggestion.
      *
-     * <p>See {@link PhoneTimeSuggestion} for more information about {@code debugInfo}.
+     * <p>See {@link TelephonyTimeSuggestion} for more information about {@code debugInfo}.
      */
     @NonNull
     public List<String> getDebugInfo() {
@@ -132,7 +132,7 @@
     /**
      * Associates information with the instance that can be useful for debugging / logging.
      *
-     * <p>See {@link PhoneTimeSuggestion} for more information about {@code debugInfo}.
+     * <p>See {@link TelephonyTimeSuggestion} for more information about {@code debugInfo}.
      */
     public void addDebugInfo(@NonNull String debugInfo) {
         if (mDebugInfo == null) {
@@ -144,7 +144,7 @@
     /**
      * Associates information with the instance that can be useful for debugging / logging.
      *
-     * <p>See {@link PhoneTimeSuggestion} for more information about {@code debugInfo}.
+     * <p>See {@link TelephonyTimeSuggestion} for more information about {@code debugInfo}.
      */
     public void addDebugInfo(@NonNull List<String> debugInfo) {
         if (mDebugInfo == null) {
@@ -161,7 +161,7 @@
         if (o == null || getClass() != o.getClass()) {
             return false;
         }
-        PhoneTimeSuggestion that = (PhoneTimeSuggestion) o;
+        TelephonyTimeSuggestion that = (TelephonyTimeSuggestion) o;
         return mSlotIndex == that.mSlotIndex
                 && Objects.equals(mUtcTime, that.mUtcTime);
     }
@@ -173,7 +173,7 @@
 
     @Override
     public String toString() {
-        return "PhoneTimeSuggestion{"
+        return "TelephonyTimeSuggestion{"
                 + "mSlotIndex='" + mSlotIndex + '\''
                 + ", mUtcTime=" + mUtcTime
                 + ", mDebugInfo=" + mDebugInfo
@@ -181,7 +181,7 @@
     }
 
     /**
-     * Builds {@link PhoneTimeSuggestion} instances.
+     * Builds {@link TelephonyTimeSuggestion} instances.
      *
      * @hide
      */
@@ -193,7 +193,7 @@
         /**
          * Creates a builder with the specified {@code slotIndex}.
          *
-         * <p>See {@link PhoneTimeSuggestion} for more information about {@code slotIndex}.
+         * <p>See {@link TelephonyTimeSuggestion} for more information about {@code slotIndex}.
          */
         public Builder(int slotIndex) {
             mSlotIndex = slotIndex;
@@ -202,7 +202,7 @@
         /**
          * Returns the builder for call chaining.
          *
-         * <p>See {@link PhoneTimeSuggestion} for more information about {@code utcTime}.
+         * <p>See {@link TelephonyTimeSuggestion} for more information about {@code utcTime}.
          */
         @NonNull
         public Builder setUtcTime(@Nullable TimestampedValue<Long> utcTime) {
@@ -218,7 +218,7 @@
         /**
          * Returns the builder for call chaining.
          *
-         * <p>See {@link PhoneTimeSuggestion} for more information about {@code debugInfo}.
+         * <p>See {@link TelephonyTimeSuggestion} for more information about {@code debugInfo}.
          */
         @NonNull
         public Builder addDebugInfo(@NonNull String debugInfo) {
@@ -229,10 +229,10 @@
             return this;
         }
 
-        /** Returns the {@link PhoneTimeSuggestion}. */
+        /** Returns the {@link TelephonyTimeSuggestion}. */
         @NonNull
-        public PhoneTimeSuggestion build() {
-            return new PhoneTimeSuggestion(this);
+        public TelephonyTimeSuggestion build() {
+            return new TelephonyTimeSuggestion(this);
         }
     }
 }
diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java
index df4f513..84ad495 100644
--- a/core/java/android/app/timedetector/TimeDetector.java
+++ b/core/java/android/app/timedetector/TimeDetector.java
@@ -45,12 +45,12 @@
     }
 
     /**
-     * Suggests the current phone-signal derived time to the detector. The detector may ignore the
-     * signal if better signals are available such as those that come from more reliable sources or
-     * were determined more recently.
+     * Suggests a telephony-signal derived time to the detector. The detector may ignore the signal
+     * if better signals are available such as those that come from more reliable sources or were
+     * determined more recently.
      */
-    @RequiresPermission(android.Manifest.permission.SUGGEST_PHONE_TIME_AND_ZONE)
-    void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSuggestion);
+    @RequiresPermission(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE)
+    void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSuggestion);
 
     /**
      * Suggests the user's manually entered current time to the detector.
diff --git a/core/java/android/app/timedetector/TimeDetectorImpl.java b/core/java/android/app/timedetector/TimeDetectorImpl.java
index 1683817..c1d6667 100644
--- a/core/java/android/app/timedetector/TimeDetectorImpl.java
+++ b/core/java/android/app/timedetector/TimeDetectorImpl.java
@@ -40,12 +40,12 @@
     }
 
     @Override
-    public void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSuggestion) {
+    public void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSuggestion) {
         if (DEBUG) {
-            Log.d(TAG, "suggestPhoneTime called: " + timeSuggestion);
+            Log.d(TAG, "suggestTelephonyTime called: " + timeSuggestion);
         }
         try {
-            mITimeDetectorService.suggestPhoneTime(timeSuggestion);
+            mITimeDetectorService.suggestTelephonyTime(timeSuggestion);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl b/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl
index df643831..b06f4b8 100644
--- a/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl
+++ b/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl
@@ -17,7 +17,7 @@
 package android.app.timezonedetector;
 
 import android.app.timezonedetector.ManualTimeZoneSuggestion;
-import android.app.timezonedetector.PhoneTimeZoneSuggestion;
+import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
 
 /**
  * System private API to communicate with time zone detector service.
@@ -34,5 +34,5 @@
  */
 interface ITimeZoneDetectorService {
   void suggestManualTimeZone(in ManualTimeZoneSuggestion timeZoneSuggestion);
-  void suggestPhoneTimeZone(in PhoneTimeZoneSuggestion timeZoneSuggestion);
+  void suggestTelephonyTimeZone(in TelephonyTimeZoneSuggestion timeZoneSuggestion);
 }
diff --git a/core/java/android/app/timezonedetector/PhoneTimeZoneSuggestion.aidl b/core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.aidl
similarity index 94%
rename from core/java/android/app/timezonedetector/PhoneTimeZoneSuggestion.aidl
rename to core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.aidl
index 3ad903b..b57ad20 100644
--- a/core/java/android/app/timezonedetector/PhoneTimeZoneSuggestion.aidl
+++ b/core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.aidl
@@ -16,4 +16,4 @@
 
 package android.app.timezonedetector;
 
-parcelable PhoneTimeZoneSuggestion;
+parcelable TelephonyTimeZoneSuggestion;
diff --git a/core/java/android/app/timezonedetector/PhoneTimeZoneSuggestion.java b/core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.java
similarity index 84%
rename from core/java/android/app/timezonedetector/PhoneTimeZoneSuggestion.java
rename to core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.java
index 9147b44..150c01d 100644
--- a/core/java/android/app/timezonedetector/PhoneTimeZoneSuggestion.java
+++ b/core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.java
@@ -56,18 +56,18 @@
  *
  * @hide
  */
-public final class PhoneTimeZoneSuggestion implements Parcelable {
+public final class TelephonyTimeZoneSuggestion implements Parcelable {
 
     /** @hide */
     @NonNull
-    public static final Creator<PhoneTimeZoneSuggestion> CREATOR =
-            new Creator<PhoneTimeZoneSuggestion>() {
-                public PhoneTimeZoneSuggestion createFromParcel(Parcel in) {
-                    return PhoneTimeZoneSuggestion.createFromParcel(in);
+    public static final Creator<TelephonyTimeZoneSuggestion> CREATOR =
+            new Creator<TelephonyTimeZoneSuggestion>() {
+                public TelephonyTimeZoneSuggestion createFromParcel(Parcel in) {
+                    return TelephonyTimeZoneSuggestion.createFromParcel(in);
                 }
 
-                public PhoneTimeZoneSuggestion[] newArray(int size) {
-                    return new PhoneTimeZoneSuggestion[size];
+                public TelephonyTimeZoneSuggestion[] newArray(int size) {
+                    return new TelephonyTimeZoneSuggestion[size];
                 }
             };
 
@@ -76,7 +76,7 @@
      * the same {@code slotIndex}.
      */
     @NonNull
-    public static PhoneTimeZoneSuggestion createEmptySuggestion(
+    public static TelephonyTimeZoneSuggestion createEmptySuggestion(
             int slotIndex, @NonNull String debugInfo) {
         return new Builder(slotIndex).addDebugInfo(debugInfo).build();
     }
@@ -144,7 +144,7 @@
     @Quality private final int mQuality;
     @Nullable private List<String> mDebugInfo;
 
-    private PhoneTimeZoneSuggestion(Builder builder) {
+    private TelephonyTimeZoneSuggestion(Builder builder) {
         mSlotIndex = builder.mSlotIndex;
         mZoneId = builder.mZoneId;
         mMatchType = builder.mMatchType;
@@ -153,15 +153,16 @@
     }
 
     @SuppressWarnings("unchecked")
-    private static PhoneTimeZoneSuggestion createFromParcel(Parcel in) {
+    private static TelephonyTimeZoneSuggestion createFromParcel(Parcel in) {
         // Use the Builder so we get validation during build().
         int slotIndex = in.readInt();
-        PhoneTimeZoneSuggestion suggestion = new Builder(slotIndex)
+        TelephonyTimeZoneSuggestion suggestion = new Builder(slotIndex)
                 .setZoneId(in.readString())
                 .setMatchType(in.readInt())
                 .setQuality(in.readInt())
                 .build();
-        List<String> debugInfo = in.readArrayList(PhoneTimeZoneSuggestion.class.getClassLoader());
+        List<String> debugInfo =
+                in.readArrayList(TelephonyTimeZoneSuggestion.class.getClassLoader());
         if (debugInfo != null) {
             suggestion.addDebugInfo(debugInfo);
         }
@@ -185,7 +186,7 @@
     /**
      * Returns an identifier for the source of this suggestion.
      *
-     * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code slotIndex}.
+     * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code slotIndex}.
      */
     public int getSlotIndex() {
         return mSlotIndex;
@@ -195,7 +196,7 @@
      * Returns the suggested time zone Olson ID, e.g. "America/Los_Angeles". {@code null} means that
      * the caller is no longer sure what the current time zone is.
      *
-     * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code zoneId}.
+     * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code zoneId}.
      */
     @Nullable
     public String getZoneId() {
@@ -206,7 +207,7 @@
      * Returns information about how the suggestion was determined which could be used to rank
      * suggestions when several are available from different sources.
      *
-     * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code matchType}.
+     * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code matchType}.
      */
     @MatchType
     public int getMatchType() {
@@ -216,7 +217,7 @@
     /**
      * Returns information about the likelihood of the suggested zone being correct.
      *
-     * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code quality}.
+     * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code quality}.
      */
     @Quality
     public int getQuality() {
@@ -226,7 +227,7 @@
     /**
      * Returns debug metadata for the suggestion.
      *
-     * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code debugInfo}.
+     * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code debugInfo}.
      */
     @NonNull
     public List<String> getDebugInfo() {
@@ -237,7 +238,7 @@
     /**
      * Associates information with the instance that can be useful for debugging / logging.
      *
-     * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code debugInfo}.
+     * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code debugInfo}.
      */
     public void addDebugInfo(@NonNull String debugInfo) {
         if (mDebugInfo == null) {
@@ -249,7 +250,7 @@
     /**
      * Associates information with the instance that can be useful for debugging / logging.
      *
-     * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code debugInfo}.
+     * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code debugInfo}.
      */
     public void addDebugInfo(@NonNull List<String> debugInfo) {
         if (mDebugInfo == null) {
@@ -266,7 +267,7 @@
         if (o == null || getClass() != o.getClass()) {
             return false;
         }
-        PhoneTimeZoneSuggestion that = (PhoneTimeZoneSuggestion) o;
+        TelephonyTimeZoneSuggestion that = (TelephonyTimeZoneSuggestion) o;
         return mSlotIndex == that.mSlotIndex
                 && mMatchType == that.mMatchType
                 && mQuality == that.mQuality
@@ -280,7 +281,7 @@
 
     @Override
     public String toString() {
-        return "PhoneTimeZoneSuggestion{"
+        return "TelephonyTimeZoneSuggestion{"
                 + "mSlotIndex=" + mSlotIndex
                 + ", mZoneId='" + mZoneId + '\''
                 + ", mMatchType=" + mMatchType
@@ -290,7 +291,7 @@
     }
 
     /**
-     * Builds {@link PhoneTimeZoneSuggestion} instances.
+     * Builds {@link TelephonyTimeZoneSuggestion} instances.
      *
      * @hide
      */
@@ -304,7 +305,7 @@
         /**
          * Creates a builder with the specified {@code slotIndex}.
          *
-         * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code slotIndex}.
+         * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code slotIndex}.
          */
         public Builder(int slotIndex) {
             mSlotIndex = slotIndex;
@@ -313,7 +314,7 @@
         /**
          * Returns the builder for call chaining.
          *
-         * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code zoneId}.
+         * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code zoneId}.
          */
         @NonNull
         public Builder setZoneId(@Nullable String zoneId) {
@@ -324,7 +325,7 @@
         /**
          * Returns the builder for call chaining.
          *
-         * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code matchType}.
+         * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code matchType}.
          */
         @NonNull
         public Builder setMatchType(@MatchType int matchType) {
@@ -335,7 +336,7 @@
         /**
          * Returns the builder for call chaining.
          *
-         * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code quality}.
+         * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code quality}.
          */
         @NonNull
         public Builder setQuality(@Quality int quality) {
@@ -346,7 +347,7 @@
         /**
          * Returns the builder for call chaining.
          *
-         * <p>See {@link PhoneTimeZoneSuggestion} for more information about {@code debugInfo}.
+         * <p>See {@link TelephonyTimeZoneSuggestion} for more information about {@code debugInfo}.
          */
         @NonNull
         public Builder addDebugInfo(@NonNull String debugInfo) {
@@ -384,11 +385,11 @@
             }
         }
 
-        /** Returns the {@link PhoneTimeZoneSuggestion}. */
+        /** Returns the {@link TelephonyTimeZoneSuggestion}. */
         @NonNull
-        public PhoneTimeZoneSuggestion build() {
+        public TelephonyTimeZoneSuggestion build() {
             validate();
-            return new PhoneTimeZoneSuggestion(this);
+            return new TelephonyTimeZoneSuggestion(this);
         }
     }
 }
diff --git a/core/java/android/app/timezonedetector/TimeZoneDetector.java b/core/java/android/app/timezonedetector/TimeZoneDetector.java
index 6a3953e..20761ad 100644
--- a/core/java/android/app/timezonedetector/TimeZoneDetector.java
+++ b/core/java/android/app/timezonedetector/TimeZoneDetector.java
@@ -47,8 +47,8 @@
      *
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.SUGGEST_PHONE_TIME_AND_ZONE)
-    void suggestPhoneTimeZone(@NonNull PhoneTimeZoneSuggestion timeZoneSuggestion);
+    @RequiresPermission(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE)
+    void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion);
 
     /**
      * Suggests the current time zone, determined for the user's manually information, to the
diff --git a/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java b/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
index 27b8374..0ada885 100644
--- a/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
+++ b/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
@@ -40,12 +40,12 @@
     }
 
     @Override
-    public void suggestPhoneTimeZone(@NonNull PhoneTimeZoneSuggestion timeZoneSuggestion) {
+    public void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion) {
         if (DEBUG) {
-            Log.d(TAG, "suggestPhoneTimeZone called: " + timeZoneSuggestion);
+            Log.d(TAG, "suggestTelephonyTimeZone called: " + timeZoneSuggestion);
         }
         try {
-            mITimeZoneDetectorService.suggestPhoneTimeZone(timeZoneSuggestion);
+            mITimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 56424c9..0a9dbb6 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1861,15 +1861,19 @@
     }
 
     /**
-     * Connects all enabled and supported bluetooth profiles between the local and remote device
+     * Connects all enabled and supported bluetooth profiles between the local and remote device.
+     * Connection is asynchronous and you should listen to each profile's broadcast intent
+     * ACTION_CONNECTION_STATE_CHANGED to verify whether connection was successful. For example,
+     * to verify a2dp is connected, you would listen for
+     * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
      *
      * @param device is the remote device with which to connect these profiles
-     * @return true if all profiles successfully connected, false if an error occurred
+     * @return true if message sent to try to connect all profiles, false if an error occurred
      *
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean connectAllEnabledProfiles(@NonNull BluetoothDevice device) {
         try {
             mServiceLock.readLock().lock();
@@ -1886,15 +1890,19 @@
     }
 
     /**
-     * Disconnects all enabled and supported bluetooth profiles between the local and remote device
+     * Disconnects all enabled and supported bluetooth profiles between the local and remote device.
+     * Disconnection is asynchronous and you should listen to each profile's broadcast intent
+     * ACTION_CONNECTION_STATE_CHANGED to verify whether disconnection was successful. For example,
+     * to verify a2dp is disconnected, you would listen for
+     * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
      *
      * @param device is the remote device with which to disconnect these profiles
-     * @return true if all profiles successfully disconnected, false if an error occurred
+     * @return true if message sent to try to disconnect all profiles, false if an error occurred
      *
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean disconnectAllEnabledProfiles(@NonNull BluetoothDevice device) {
         try {
             mServiceLock.readLock().lock();
diff --git a/core/java/android/timezone/CountryTimeZones.java b/core/java/android/timezone/CountryTimeZones.java
index ab2c4fc..ee3a8a7 100644
--- a/core/java/android/timezone/CountryTimeZones.java
+++ b/core/java/android/timezone/CountryTimeZones.java
@@ -18,7 +18,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SuppressLint;
 import android.icu.util.TimeZone;
 
 import java.util.ArrayList;
@@ -206,27 +205,47 @@
     }
 
     /**
-     * Returns a time zone for the country, if there is one, that matches the desired properties. If
-     * there are multiple matches and the {@code bias} is one of them then it is returned, otherwise
-     * an arbitrary match is returned based on the {@link #getEffectiveTimeZoneMappingsAt(long)}
-     * ordering.
+     * Returns a time zone for the country, if there is one, that matches the supplied properties.
+     * If there are multiple matches and the {@code bias} is one of them then it is returned,
+     * otherwise an arbitrary match is returned based on the {@link
+     * #getEffectiveTimeZoneMappingsAt(long)} ordering.
      *
+     * @param whenMillis the UTC time to match against
+     * @param bias the time zone to prefer, can be {@code null} to indicate there is no preference
      * @param totalOffsetMillis the offset from UTC at {@code whenMillis}
      * @param isDst the Daylight Savings Time state at {@code whenMillis}. {@code true} means DST,
-     *     {@code false} means not DST, {@code null} means unknown
-     * @param dstOffsetMillis the part of {@code totalOffsetMillis} contributed by DST, only used if
-     *     {@code isDst} is {@code true}. The value can be {@code null} if the DST offset is
-     *     unknown
-     * @param whenMillis the UTC time to match against
-     * @param bias the time zone to prefer, can be {@code null}
+     *     {@code false} means not DST
+     * @return an {@link OffsetResult} with information about a matching zone, or {@code null} if
+     *     there is no match
      */
     @Nullable
-    public OffsetResult lookupByOffsetWithBias(int totalOffsetMillis, @Nullable Boolean isDst,
-            @SuppressLint("AutoBoxing") @Nullable Integer dstOffsetMillis, long whenMillis,
-            @Nullable TimeZone bias) {
+    public OffsetResult lookupByOffsetWithBias(long whenMillis, @Nullable TimeZone bias,
+            int totalOffsetMillis, boolean isDst) {
         libcore.timezone.CountryTimeZones.OffsetResult delegateOffsetResult =
                 mDelegate.lookupByOffsetWithBias(
-                        totalOffsetMillis, isDst, dstOffsetMillis, whenMillis, bias);
+                        whenMillis, bias, totalOffsetMillis, isDst);
+        return delegateOffsetResult == null ? null :
+                new OffsetResult(
+                        delegateOffsetResult.getTimeZone(), delegateOffsetResult.isOnlyMatch());
+    }
+
+    /**
+     * Returns a time zone for the country, if there is one, that matches the supplied properties.
+     * If there are multiple matches and the {@code bias} is one of them then it is returned,
+     * otherwise an arbitrary match is returned based on the {@link
+     * #getEffectiveTimeZoneMappingsAt(long)} ordering.
+     *
+     * @param whenMillis the UTC time to match against
+     * @param bias the time zone to prefer, can be {@code null} to indicate there is no preference
+     * @param totalOffsetMillis the offset from UTC at {@code whenMillis}
+     * @return an {@link OffsetResult} with information about a matching zone, or {@code null} if
+     *     there is no match
+     */
+    @Nullable
+    public OffsetResult lookupByOffsetWithBias(long whenMillis, @Nullable TimeZone bias,
+            int totalOffsetMillis) {
+        libcore.timezone.CountryTimeZones.OffsetResult delegateOffsetResult =
+                mDelegate.lookupByOffsetWithBias(whenMillis, bias, totalOffsetMillis);
         return delegateOffsetResult == null ? null :
                 new OffsetResult(
                         delegateOffsetResult.getTimeZone(), delegateOffsetResult.isOnlyMatch());
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index de5b027f..6e41fc8 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -79,7 +79,7 @@
             return null;
         }
         CountryTimeZones.OffsetResult offsetResult = countryTimeZones.lookupByOffsetWithBias(
-                offsetMillis, isDst, null /* dstOffsetMillis */, whenMillis, bias);
+                whenMillis, bias, offsetMillis, isDst);
         return offsetResult != null ? offsetResult.getTimeZone() : null;
     }
 
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index f68fd57..43df2e4 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -233,6 +233,7 @@
 
     static_libs: [
         "libasync_safe",
+        "libbinderthreadstateutils",
         "libdmabufinfo",
         "libgif",
         "libseccomp_policy",
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 079c265..1da022c 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -37,6 +37,7 @@
 #include <binder/Parcel.h>
 #include <binder/ProcessState.h>
 #include <binder/Stability.h>
+#include <binderthreadstate/CallerUtils.h>
 #include <cutils/atomic.h>
 #include <log/log.h>
 #include <utils/KeyedVector.h>
@@ -946,7 +947,7 @@
 
 static jboolean android_os_Binder_isHandlingTransaction()
 {
-    return IPCThreadState::self()->isServingCall();
+    return getCurrentServingCall() == BinderCallType::BINDER;
 }
 
 static jlong android_os_Binder_clearCallingIdentity()
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d6097d8..e7539ba 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2559,7 +2559,7 @@
          <p>Not for use by third-party applications.
          @hide
      -->
-    <permission android:name="android.permission.SUGGEST_PHONE_TIME_AND_ZONE"
+    <permission android:name="android.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE"
         android:protectionLevel="signature|telephony" />
 
     <!-- Allows applications like settings to suggest the user's manually chosen time / time zone.
@@ -4699,6 +4699,19 @@
     <permission android:name="android.permission.ACCESS_SHARED_LIBRARIES"
                 android:protectionLevel="signature|installer" />
 
+    <!-- Allows an app to log compat change usage.
+         @hide  <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.LOG_COMPAT_CHANGE"
+                android:protectionLevel="signature|privileged" />
+    <!-- Allows an app to read compat change config.
+         @hide  <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"
+                android:protectionLevel="signature|privileged" />
+    <!-- Allows an app to override compat change config.
+         @hide  <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"
+                android:protectionLevel="signature|privileged" />
+
     <!-- Allows input events to be monitored. Very dangerous!  @hide -->
     <permission android:name="android.permission.MONITOR_INPUT"
                 android:protectionLevel="signature" />
diff --git a/core/res/res/values-mcc334/config.xml b/core/res/res/values-mcc334/config.xml
new file mode 100644
index 0000000..e99c9a0
--- /dev/null
+++ b/core/res/res/values-mcc334/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2020, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc732/config.xml b/core/res/res/values-mcc732/config.xml
new file mode 100644
index 0000000..e99c9a0
--- /dev/null
+++ b/core/res/res/values-mcc732/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2020, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc740/config.xml b/core/res/res/values-mcc740/config.xml
new file mode 100644
index 0000000..e99c9a0
--- /dev/null
+++ b/core/res/res/values-mcc740/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2020, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 268d6f1..204d827 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -263,6 +263,10 @@
          before automatically restore the default connection.  Set -1 if the connection
          does not require auto-restore. -->
     <!-- the 6th element indicates boot-time dependency-met value. -->
+    <!-- NOTE: The telephony module is no longer reading the configuration below for available
+         APN types.  The set of APN types and relevant settings are specified within the telephony
+         module and are non-configurable.  Whether or not data connectivity over a cellular network
+         is available at all is controlled by the flag: config_moble_data_capable. -->
     <string-array translatable="false" name="networkAttributes">
         <item>"wifi,1,1,1,-1,true"</item>
         <item>"mobile,0,0,0,-1,true"</item>
@@ -2026,6 +2030,12 @@
          Note: This config is deprecated, please use config_defaultSms instead. -->
     <string name="default_sms_application" translatable="false">com.android.messaging</string>
 
+    <!-- Flag indicating whether the current device allows data.
+         If true, this means that the device supports data connectivity through
+         the telephony network.
+         This can be overridden to false for devices that support voice and/or sms . -->
+    <bool name="config_mobile_data_capable">true</bool>
+
     <!-- Default web browser.  This is the package name of the application that will
          be the default browser when the device first boots.  Afterwards the user
          can select whatever browser app they wish to use as the default.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 95e133f..76d5715 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -310,6 +310,7 @@
   <java-symbol type="bool" name="config_sip_wifi_only" />
   <java-symbol type="bool" name="config_sms_capable" />
   <java-symbol type="bool" name="config_sms_utf8_support" />
+  <java-symbol type="bool" name="config_mobile_data_capable" />
   <java-symbol type="bool" name="config_suspendWhenScreenOffDueToProximity" />
   <java-symbol type="bool" name="config_swipeDisambiguation" />
   <java-symbol type="bool" name="config_syncstorageengine_masterSyncAutomatically" />
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 0d7ac08..70917e7 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -34,7 +34,7 @@
          http://smscoin.net/software/engine/WordPress/Paid+SMS-registration/ -->
 
     <!-- Arab Emirates -->
-    <shortcode country="ae" pattern="\\d{1,5}" free="3214|1017" />
+    <shortcode country="ae" pattern="\\d{1,5}" free="1017|1355|3214" />
 
     <!-- Albania: 5 digits, known short codes listed -->
     <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" />
@@ -184,7 +184,7 @@
     <shortcode country="mk" pattern="\\d{1,6}" free="129005|122" />
 
     <!-- Mexico: 4-5 digits (not confirmed), known premium codes listed -->
-    <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" free="46645|5050|26259|50025|50052|9963|76551" />
+    <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" free="26259|46645|50025|50052|5050|76551|88778|9963" />
 
     <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf -->
     <shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288" />
@@ -199,7 +199,7 @@
     <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" free="2171" />
 
     <!-- New Zealand: 3-4 digits, known premium codes listed -->
-    <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" free="1737|2141|3067|3068|3110|4006|4053|4061|4062|4202|4300|4334|4412|4575|5626|8006|8681" />
+    <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" free="1737|176|2141|3067|3068|3110|4006|4053|4061|4062|4202|4300|4334|4412|4575|5626|8006|8681" />
 
     <!-- Peru: 4-5 digits (not confirmed), known premium codes listed -->
     <shortcode country="pe" pattern="\\d{4,5}" free="9963" />
@@ -267,4 +267,7 @@
     <!-- Mayotte (French Territory): 1-5 digits (not confirmed) -->
     <shortcode country="yt" pattern="\\d{1,5}" free="38600,36300,36303,959" />
 
+    <!-- South Africa -->
+    <shortcode country="za" pattern="\d{1,5}" free="44136" />
+
 </shortcodes>
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 4d4f447..02b8d7d 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -37,6 +37,7 @@
         "mockito-target-minus-junit4",
         "ub-uiautomator",
         "platform-test-annotations",
+        "platform-compat-test-rules",
         "truth-prebuilt",
         "print-test-util-lib",
         "testng",
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index a9e0a77..98f887e 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -110,6 +110,10 @@
     <uses-permission android:name="android.permission.MOVE_PACKAGE" />
     <uses-permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT" />
 
+    <!-- gating and logging permissions -->
+    <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
+    <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
+
     <!-- os storage test permissions -->
     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
     <uses-permission android:name="android.permission.ASEC_ACCESS" />
diff --git a/core/tests/coretests/src/android/app/compat/CompatChangesTest.java b/core/tests/coretests/src/android/app/compat/CompatChangesTest.java
new file mode 100644
index 0000000..fbd02ed
--- /dev/null
+++ b/core/tests/coretests/src/android/app/compat/CompatChangesTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 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 android.app.compat;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Instrumentation;
+import android.compat.testing.PlatformCompatChangeRule;
+import android.os.Process;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+/**
+ * {@link CompatChanges} tests.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class CompatChangesTest {
+    static final long CHANGE_ID = 1L;
+
+    private Instrumentation mInstrumentation;
+
+    @Rule
+    public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
+    @Before
+    public void setup() {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+    }
+
+
+    private String getPackageName() {
+        return mInstrumentation.getTargetContext().getPackageName();
+    }
+
+    @Test
+    @EnableCompatChanges(CHANGE_ID)
+    public void testEnabledChange() {
+        assertThat(CompatChanges.isChangeEnabled(CHANGE_ID)).isTrue();
+        assertThat(CompatChanges.isChangeEnabled(CHANGE_ID, Process.myUid())).isTrue();
+        assertThat(CompatChanges.isChangeEnabled(CHANGE_ID, getPackageName(),
+                UserHandle.of(UserHandle.myUserId()))).isTrue();
+    }
+
+    @Test
+    @DisableCompatChanges(CHANGE_ID)
+    public void testDisabledChange() {
+        assertThat(CompatChanges.isChangeEnabled(CHANGE_ID)).isFalse();
+        assertThat(CompatChanges.isChangeEnabled(CHANGE_ID, Process.myUid())).isFalse();
+        assertThat(CompatChanges.isChangeEnabled(CHANGE_ID, getPackageName(),
+                UserHandle.of(UserHandle.myUserId()))).isFalse();
+    }
+}
diff --git a/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java
similarity index 66%
rename from core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java
rename to core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java
index d17b635..4b64dfc 100644
--- a/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java
+++ b/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java
@@ -26,44 +26,45 @@
 
 import org.junit.Test;
 
-public class PhoneTimeSuggestionTest {
+public class TelephonyTimeSuggestionTest {
     private static final int SLOT_INDEX = 99999;
 
     @Test
     public void testEquals() {
-        PhoneTimeSuggestion.Builder builder1 = new PhoneTimeSuggestion.Builder(SLOT_INDEX);
+        TelephonyTimeSuggestion.Builder builder1 = new TelephonyTimeSuggestion.Builder(SLOT_INDEX);
         {
-            PhoneTimeSuggestion one = builder1.build();
+            TelephonyTimeSuggestion one = builder1.build();
             assertEquals(one, one);
         }
 
-        PhoneTimeSuggestion.Builder builder2 = new PhoneTimeSuggestion.Builder(SLOT_INDEX);
+        TelephonyTimeSuggestion.Builder builder2 = new TelephonyTimeSuggestion.Builder(SLOT_INDEX);
         {
-            PhoneTimeSuggestion one = builder1.build();
-            PhoneTimeSuggestion two = builder2.build();
+            TelephonyTimeSuggestion one = builder1.build();
+            TelephonyTimeSuggestion two = builder2.build();
             assertEquals(one, two);
             assertEquals(two, one);
         }
 
         builder1.setUtcTime(new TimestampedValue<>(1111L, 2222L));
         {
-            PhoneTimeSuggestion one = builder1.build();
+            TelephonyTimeSuggestion one = builder1.build();
             assertEquals(one, one);
         }
 
         builder2.setUtcTime(new TimestampedValue<>(1111L, 2222L));
         {
-            PhoneTimeSuggestion one = builder1.build();
-            PhoneTimeSuggestion two = builder2.build();
+            TelephonyTimeSuggestion one = builder1.build();
+            TelephonyTimeSuggestion two = builder2.build();
             assertEquals(one, two);
             assertEquals(two, one);
         }
 
-        PhoneTimeSuggestion.Builder builder3 = new PhoneTimeSuggestion.Builder(SLOT_INDEX + 1);
+        TelephonyTimeSuggestion.Builder builder3 =
+                new TelephonyTimeSuggestion.Builder(SLOT_INDEX + 1);
         builder3.setUtcTime(new TimestampedValue<>(1111L, 2222L));
         {
-            PhoneTimeSuggestion one = builder1.build();
-            PhoneTimeSuggestion three = builder3.build();
+            TelephonyTimeSuggestion one = builder1.build();
+            TelephonyTimeSuggestion three = builder3.build();
             assertNotEquals(one, three);
             assertNotEquals(three, one);
         }
@@ -72,15 +73,15 @@
         builder1.addDebugInfo("Debug info 1");
         builder2.addDebugInfo("Debug info 2");
         {
-            PhoneTimeSuggestion one = builder1.build();
-            PhoneTimeSuggestion two = builder2.build();
+            TelephonyTimeSuggestion one = builder1.build();
+            TelephonyTimeSuggestion two = builder2.build();
             assertEquals(one, two);
         }
     }
 
     @Test
     public void testParcelable() {
-        PhoneTimeSuggestion.Builder builder = new PhoneTimeSuggestion.Builder(SLOT_INDEX);
+        TelephonyTimeSuggestion.Builder builder = new TelephonyTimeSuggestion.Builder(SLOT_INDEX);
         assertRoundTripParcelable(builder.build());
 
         builder.setUtcTime(new TimestampedValue<>(1111L, 2222L));
@@ -88,9 +89,9 @@
 
         // DebugInfo should also be stored (but is not checked by equals()
         {
-            PhoneTimeSuggestion suggestion1 = builder.build();
+            TelephonyTimeSuggestion suggestion1 = builder.build();
             builder.addDebugInfo("This is debug info");
-            PhoneTimeSuggestion rtSuggestion1 = roundTripParcelable(suggestion1);
+            TelephonyTimeSuggestion rtSuggestion1 = roundTripParcelable(suggestion1);
             assertEquals(suggestion1.getDebugInfo(), rtSuggestion1.getDebugInfo());
         }
     }
diff --git a/core/tests/coretests/src/android/app/timezonedetector/PhoneTimeZoneSuggestionTest.java b/core/tests/coretests/src/android/app/timezonedetector/PhoneTimeZoneSuggestionTest.java
deleted file mode 100644
index 384dbf9..0000000
--- a/core/tests/coretests/src/android/app/timezonedetector/PhoneTimeZoneSuggestionTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2019 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 android.app.timezonedetector;
-
-import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
-import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-public class PhoneTimeZoneSuggestionTest {
-    private static final int SLOT_INDEX = 99999;
-
-    @Test
-    public void testEquals() {
-        PhoneTimeZoneSuggestion.Builder builder1 = new PhoneTimeZoneSuggestion.Builder(SLOT_INDEX);
-        {
-            PhoneTimeZoneSuggestion one = builder1.build();
-            assertEquals(one, one);
-        }
-
-        PhoneTimeZoneSuggestion.Builder builder2 = new PhoneTimeZoneSuggestion.Builder(SLOT_INDEX);
-        {
-            PhoneTimeZoneSuggestion one = builder1.build();
-            PhoneTimeZoneSuggestion two = builder2.build();
-            assertEquals(one, two);
-            assertEquals(two, one);
-        }
-
-        PhoneTimeZoneSuggestion.Builder builder3 =
-                new PhoneTimeZoneSuggestion.Builder(SLOT_INDEX + 1);
-        {
-            PhoneTimeZoneSuggestion one = builder1.build();
-            PhoneTimeZoneSuggestion three = builder3.build();
-            assertNotEquals(one, three);
-            assertNotEquals(three, one);
-        }
-
-        builder1.setZoneId("Europe/London");
-        builder1.setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY);
-        builder1.setQuality(PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE);
-        {
-            PhoneTimeZoneSuggestion one = builder1.build();
-            PhoneTimeZoneSuggestion two = builder2.build();
-            assertNotEquals(one, two);
-        }
-
-        builder2.setZoneId("Europe/Paris");
-        builder2.setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY);
-        builder2.setQuality(PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE);
-        {
-            PhoneTimeZoneSuggestion one = builder1.build();
-            PhoneTimeZoneSuggestion two = builder2.build();
-            assertNotEquals(one, two);
-        }
-
-        builder1.setZoneId("Europe/Paris");
-        {
-            PhoneTimeZoneSuggestion one = builder1.build();
-            PhoneTimeZoneSuggestion two = builder2.build();
-            assertEquals(one, two);
-        }
-
-        builder1.setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID);
-        builder2.setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY);
-        {
-            PhoneTimeZoneSuggestion one = builder1.build();
-            PhoneTimeZoneSuggestion two = builder2.build();
-            assertNotEquals(one, two);
-        }
-
-        builder1.setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY);
-        {
-            PhoneTimeZoneSuggestion one = builder1.build();
-            PhoneTimeZoneSuggestion two = builder2.build();
-            assertEquals(one, two);
-        }
-
-        builder1.setQuality(PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE);
-        builder2.setQuality(PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS);
-        {
-            PhoneTimeZoneSuggestion one = builder1.build();
-            PhoneTimeZoneSuggestion two = builder2.build();
-            assertNotEquals(one, two);
-        }
-
-        builder1.setQuality(PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS);
-        {
-            PhoneTimeZoneSuggestion one = builder1.build();
-            PhoneTimeZoneSuggestion two = builder2.build();
-            assertEquals(one, two);
-        }
-
-        // DebugInfo must not be considered in equals().
-        {
-            PhoneTimeZoneSuggestion one = builder1.build();
-            PhoneTimeZoneSuggestion two = builder2.build();
-            one.addDebugInfo("Debug info 1");
-            two.addDebugInfo("Debug info 2");
-            assertEquals(one, two);
-        }
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void testBuilderValidates_emptyZone_badMatchType() {
-        PhoneTimeZoneSuggestion.Builder builder = new PhoneTimeZoneSuggestion.Builder(SLOT_INDEX);
-        // No zone ID, so match type should be left unset.
-        builder.setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET);
-        builder.build();
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void testBuilderValidates_zoneSet_badMatchType() {
-        PhoneTimeZoneSuggestion.Builder builder = new PhoneTimeZoneSuggestion.Builder(SLOT_INDEX);
-        builder.setZoneId("Europe/London");
-        builder.setQuality(PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE);
-        builder.build();
-    }
-
-    @Test
-    public void testParcelable() {
-        PhoneTimeZoneSuggestion.Builder builder = new PhoneTimeZoneSuggestion.Builder(SLOT_INDEX);
-        assertRoundTripParcelable(builder.build());
-
-        builder.setZoneId("Europe/London");
-        builder.setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID);
-        builder.setQuality(PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE);
-        PhoneTimeZoneSuggestion suggestion1 = builder.build();
-        assertRoundTripParcelable(suggestion1);
-
-        // DebugInfo should also be stored (but is not checked by equals()
-        String debugString = "This is debug info";
-        suggestion1.addDebugInfo(debugString);
-        PhoneTimeZoneSuggestion suggestion1_2 = roundTripParcelable(suggestion1);
-        assertEquals(suggestion1, suggestion1_2);
-        assertTrue(suggestion1_2.getDebugInfo().contains(debugString));
-    }
-}
diff --git a/core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java b/core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java
new file mode 100644
index 0000000..59d55b7
--- /dev/null
+++ b/core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2019 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 android.app.timezonedetector;
+
+import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
+import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class TelephonyTimeZoneSuggestionTest {
+    private static final int SLOT_INDEX = 99999;
+
+    @Test
+    public void testEquals() {
+        TelephonyTimeZoneSuggestion.Builder builder1 =
+                new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX);
+        {
+            TelephonyTimeZoneSuggestion one = builder1.build();
+            assertEquals(one, one);
+        }
+
+        TelephonyTimeZoneSuggestion.Builder builder2 =
+                new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX);
+        {
+            TelephonyTimeZoneSuggestion one = builder1.build();
+            TelephonyTimeZoneSuggestion two = builder2.build();
+            assertEquals(one, two);
+            assertEquals(two, one);
+        }
+
+        TelephonyTimeZoneSuggestion.Builder builder3 =
+                new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX + 1);
+        {
+            TelephonyTimeZoneSuggestion one = builder1.build();
+            TelephonyTimeZoneSuggestion three = builder3.build();
+            assertNotEquals(one, three);
+            assertNotEquals(three, one);
+        }
+
+        builder1.setZoneId("Europe/London");
+        builder1.setMatchType(TelephonyTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY);
+        builder1.setQuality(TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE);
+        {
+            TelephonyTimeZoneSuggestion one = builder1.build();
+            TelephonyTimeZoneSuggestion two = builder2.build();
+            assertNotEquals(one, two);
+        }
+
+        builder2.setZoneId("Europe/Paris");
+        builder2.setMatchType(TelephonyTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY);
+        builder2.setQuality(TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE);
+        {
+            TelephonyTimeZoneSuggestion one = builder1.build();
+            TelephonyTimeZoneSuggestion two = builder2.build();
+            assertNotEquals(one, two);
+        }
+
+        builder1.setZoneId("Europe/Paris");
+        {
+            TelephonyTimeZoneSuggestion one = builder1.build();
+            TelephonyTimeZoneSuggestion two = builder2.build();
+            assertEquals(one, two);
+        }
+
+        builder1.setMatchType(TelephonyTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID);
+        builder2.setMatchType(TelephonyTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY);
+        {
+            TelephonyTimeZoneSuggestion one = builder1.build();
+            TelephonyTimeZoneSuggestion two = builder2.build();
+            assertNotEquals(one, two);
+        }
+
+        builder1.setMatchType(TelephonyTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY);
+        {
+            TelephonyTimeZoneSuggestion one = builder1.build();
+            TelephonyTimeZoneSuggestion two = builder2.build();
+            assertEquals(one, two);
+        }
+
+        builder1.setQuality(TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE);
+        builder2.setQuality(
+                TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS);
+        {
+            TelephonyTimeZoneSuggestion one = builder1.build();
+            TelephonyTimeZoneSuggestion two = builder2.build();
+            assertNotEquals(one, two);
+        }
+
+        builder1.setQuality(
+                TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS);
+        {
+            TelephonyTimeZoneSuggestion one = builder1.build();
+            TelephonyTimeZoneSuggestion two = builder2.build();
+            assertEquals(one, two);
+        }
+
+        // DebugInfo must not be considered in equals().
+        {
+            TelephonyTimeZoneSuggestion one = builder1.build();
+            TelephonyTimeZoneSuggestion two = builder2.build();
+            one.addDebugInfo("Debug info 1");
+            two.addDebugInfo("Debug info 2");
+            assertEquals(one, two);
+        }
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testBuilderValidates_emptyZone_badMatchType() {
+        TelephonyTimeZoneSuggestion.Builder builder =
+                new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX);
+        // No zone ID, so match type should be left unset.
+        builder.setMatchType(TelephonyTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET);
+        builder.build();
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testBuilderValidates_zoneSet_badMatchType() {
+        TelephonyTimeZoneSuggestion.Builder builder =
+                new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX);
+        builder.setZoneId("Europe/London");
+        builder.setQuality(TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE);
+        builder.build();
+    }
+
+    @Test
+    public void testParcelable() {
+        TelephonyTimeZoneSuggestion.Builder builder =
+                new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX);
+        assertRoundTripParcelable(builder.build());
+
+        builder.setZoneId("Europe/London");
+        builder.setMatchType(TelephonyTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID);
+        builder.setQuality(TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE);
+        TelephonyTimeZoneSuggestion suggestion1 = builder.build();
+        assertRoundTripParcelable(suggestion1);
+
+        // DebugInfo should also be stored (but is not checked by equals()
+        String debugString = "This is debug info";
+        suggestion1.addDebugInfo(debugString);
+        TelephonyTimeZoneSuggestion suggestion1_2 = roundTripParcelable(suggestion1);
+        assertEquals(suggestion1, suggestion1_2);
+        assertTrue(suggestion1_2.getDebugInfo().contains(debugString));
+    }
+}
diff --git a/data/etc/com.android.settings.xml b/data/etc/com.android.settings.xml
index cc1ce9b..ed5abe3 100644
--- a/data/etc/com.android.settings.xml
+++ b/data/etc/com.android.settings.xml
@@ -26,6 +26,7 @@
         <permission name="android.permission.DELETE_PACKAGES"/>
         <permission name="android.permission.FORCE_STOP_PACKAGES"/>
         <permission name="android.permission.LOCAL_MAC_ADDRESS"/>
+        <permission name="android.permission.LOG_COMPAT_CHANGE" />
         <permission name="android.permission.MANAGE_DEBUGGING"/>
         <permission name="android.permission.MANAGE_DEVICE_ADMINS"/>
         <permission name="android.permission.MANAGE_FINGERPRINT"/>
@@ -37,8 +38,10 @@
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
         <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
         <permission name="android.permission.MOVE_PACKAGE"/>
+        <permission name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG" />
         <permission name="android.permission.OVERRIDE_WIFI_CONFIG"/>
         <permission name="android.permission.PACKAGE_USAGE_STATS"/>
+        <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
         <permission name="android.permission.REBOOT"/>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 65f784d..b1fc817 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -72,6 +72,11 @@
         <group gid="net_admin" />
     </permission>
 
+    <permission name="android.permission.MAINLINE_NETWORK_STACK" >
+        <group gid="net_admin" />
+        <group gid="net_raw" />
+    </permission>
+
     <!-- The group that /cache belongs to, linked to the permission
          set on the applications that can access /cache -->
     <permission name="android.permission.ACCESS_CACHE_FILESYSTEM" >
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 03f31ae..1bc5924 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -159,7 +159,7 @@
         <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
         <permission name="android.permission.STATUS_BAR"/>
         <permission name="android.permission.STOP_APP_SWITCHES"/>
-        <permission name="android.permission.SUGGEST_PHONE_TIME_AND_ZONE"/>
+        <permission name="android.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE"/>
         <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
         <permission name="android.permission.UPDATE_DEVICE_STATS"/>
         <permission name="android.permission.UPDATE_LOCK"/>
@@ -343,6 +343,10 @@
         <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
         <!-- Permission required for Tethering CTS tests. -->
         <permission name="android.permission.TETHER_PRIVILEGED"/>
+        <!-- Permissions required for ganting and logging -->
+        <permission name="android.permission.LOG_COMPAT_CHANGE" />
+        <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
+        <permission name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG" />
         <!-- Permissions required to test ambient display. -->
         <permission name="android.permission.READ_DREAM_STATE" />
         <permission name="android.permission.WRITE_DREAM_STATE" />
@@ -373,4 +377,7 @@
         <permission name="android.permission.MANAGE_DYNAMIC_SYSTEM"/>
     </privapp-permissions>
 
+    <privapp-permissions package="com.android.settings">
+        <permission name="android.permission.BIND_CELL_BROADCAST_SERVICE"/>
+    </privapp-permissions>
 </permissions>
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 3c4577a..b997f85 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -215,6 +215,11 @@
     <!-- permissions required for CTS test - PhoneStateListenerTest -->
     <uses-permission android:name="android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH" />
 
+    <!-- Permissions required for ganting and logging -->
+    <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
+    <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
+    <uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"/>
+
     <!-- Permission required for CTS test - UiModeManagerTest -->
     <uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 1c646b2..b73aff4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -661,7 +661,7 @@
     }
 
     boolean isDataDisabled() {
-        return !mPhone.isDataCapable();
+        return !mPhone.isDataConnectionEnabled();
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 59270d8..6b34c3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -173,7 +173,7 @@
     protected void setupNetworkController() {
         // For now just pretend to be the data sim, so we can test that too.
         mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
-        when(mMockTm.isDataCapable()).thenReturn(true);
+        when(mMockTm.isDataConnectionEnabled()).thenReturn(true);
         setDefaultSubId(mSubId);
         setSubscriptions(mSubId);
         mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 47e0c3c..70ebfff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -124,7 +124,7 @@
     @Test
     public void testNoInternetIcon_withDefaultSub() {
         setupNetworkController();
-        when(mMockTm.isDataCapable()).thenReturn(false);
+        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
         setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -138,7 +138,7 @@
     @Test
     public void testDataDisabledIcon_withDefaultSub() {
         setupNetworkController();
-        when(mMockTm.isDataCapable()).thenReturn(false);
+        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
         setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -152,7 +152,7 @@
     @Test
     public void testNonDefaultSIM_showsFullSignal_connected() {
         setupNetworkController();
-        when(mMockTm.isDataCapable()).thenReturn(false);
+        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
         setupDefaultSignal();
         setDefaultSubId(mSubId + 1);
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
@@ -167,7 +167,7 @@
     @Test
     public void testNonDefaultSIM_showsFullSignal_disconnected() {
         setupNetworkController();
-        when(mMockTm.isDataCapable()).thenReturn(false);
+        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
         setupDefaultSignal();
         setDefaultSubId(mSubId + 1);
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
@@ -438,7 +438,7 @@
     @Test
     public void testDataDisabledIcon_UserNotSetup() {
         setupNetworkController();
-        when(mMockTm.isDataCapable()).thenReturn(false);
+        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
         setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -453,7 +453,7 @@
     @Test
     public void testAlwaysShowDataRatIcon() {
         setupDefaultSignal();
-        when(mMockTm.isDataCapable()).thenReturn(false);
+        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED,
                 TelephonyManager.NETWORK_TYPE_GSM);
 
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
index 5b35bb6..19e4c10 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
@@ -272,13 +272,6 @@
 
         mStateReceiver = new StateReceiver();
 
-        mNetdCallback = new NetdCallback();
-        try {
-            mNetd.registerUnsolicitedEventListener(mNetdCallback);
-        } catch (RemoteException e) {
-            mLog.e("Unable to register netd UnsolicitedEventListener");
-        }
-
         final UserManager userManager = (UserManager) mContext.getSystemService(
                 Context.USER_SERVICE);
         mTetheringRestriction = new UserRestrictionActionListener(userManager, this);
@@ -287,6 +280,14 @@
 
         // Load tethering configuration.
         updateConfiguration();
+        // NetdCallback should be registered after updateConfiguration() to ensure
+        // TetheringConfiguration is created.
+        mNetdCallback = new NetdCallback();
+        try {
+            mNetd.registerUnsolicitedEventListener(mNetdCallback);
+        } catch (RemoteException e) {
+            mLog.e("Unable to register netd UnsolicitedEventListener");
+        }
 
         startStateMachineUpdaters(mHandler);
         startTrackDefaultNetwork();
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 71f751c..d304152 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -68,6 +68,7 @@
 import android.net.CaptivePortal;
 import android.net.ConnectionInfo;
 import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
+import android.net.ConnectivityDiagnosticsManager.DataStallReport;
 import android.net.ConnectivityManager;
 import android.net.ICaptivePortal;
 import android.net.IConnectivityDiagnosticsCallback;
@@ -3009,6 +3010,21 @@
         }
 
         @Override
+        public void notifyDataStallSuspected(
+                long timestampMillis, int detectionMethod, PersistableBundle extras) {
+            final Message msg =
+                    mConnectivityDiagnosticsHandler.obtainMessage(
+                            ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED,
+                            detectionMethod, mNetId, timestampMillis);
+            msg.setData(new Bundle(extras));
+
+            // NetworkStateTrackerHandler currently doesn't take any actions based on data
+            // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid
+            // the cost of going through two handlers.
+            mConnectivityDiagnosticsHandler.sendMessage(msg);
+        }
+
+        @Override
         public int getInterfaceVersion() {
             return this.VERSION;
         }
@@ -4182,6 +4198,19 @@
         final int connectivityInfo = encodeBool(hasConnectivity);
         mHandler.sendMessage(
                 mHandler.obtainMessage(EVENT_REVALIDATE_NETWORK, uid, connectivityInfo, network));
+
+        final NetworkAgentInfo nai;
+        if (network == null) {
+            nai = getDefaultNetwork();
+        } else {
+            nai = getNetworkAgentInfoForNetwork(network);
+        }
+        if (nai != null) {
+            mConnectivityDiagnosticsHandler.sendMessage(
+                    mConnectivityDiagnosticsHandler.obtainMessage(
+                            ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED,
+                            connectivityInfo, 0, nai));
+        }
     }
 
     private void handleReportNetworkConnectivity(
@@ -6561,6 +6590,7 @@
     }
 
     private ArrayMap<NetworkRequestInfo, NetworkAgentInfo> computeRequestReassignmentForNetwork(
+            @NonNull final NetworkReassignment changes,
             @NonNull final NetworkAgentInfo newNetwork) {
         final int score = newNetwork.getCurrentScore();
         final ArrayMap<NetworkRequestInfo, NetworkAgentInfo> reassignedRequests = new ArrayMap<>();
@@ -6571,7 +6601,10 @@
             // requests or not, and doesn't affect the network's score.
             if (nri.request.isListen()) continue;
 
-            final NetworkAgentInfo currentNetwork = nri.mSatisfier;
+            // The reassignment has been seeded with the initial assignment, therefore
+            // getReassignment can't be null and mNewNetwork is only null if there was no
+            // satisfier in the first place or there was an explicit reassignment to null.
+            final NetworkAgentInfo currentNetwork = changes.getReassignment(nri).mNewNetwork;
             final boolean satisfies = newNetwork.satisfies(nri.request);
             if (newNetwork == currentNetwork && satisfies) continue;
 
@@ -6621,7 +6654,7 @@
         if (VDBG || DDBG) log("rematching " + newNetwork.name());
 
         final ArrayMap<NetworkRequestInfo, NetworkAgentInfo> reassignedRequests =
-                computeRequestReassignmentForNetwork(newNetwork);
+                computeRequestReassignmentForNetwork(changes, newNetwork);
 
         // Find and migrate to this Network any NetworkRequests for
         // which this network is now the best.
@@ -7528,6 +7561,8 @@
      */
     @VisibleForTesting
     class ConnectivityDiagnosticsHandler extends Handler {
+        private final String mTag = ConnectivityDiagnosticsHandler.class.getSimpleName();
+
         /**
          * Used to handle ConnectivityDiagnosticsCallback registration events from {@link
          * android.net.ConnectivityDiagnosticsManager}.
@@ -7555,6 +7590,26 @@
          */
         private static final int EVENT_NETWORK_TESTED = ConnectivityService.EVENT_NETWORK_TESTED;
 
+        /**
+         * Event for NetworkMonitor to inform ConnectivityService that a potential data stall has
+         * been detected on the network.
+         * obj = Long the timestamp (in millis) for when the suspected data stall was detected.
+         * arg1 = {@link DataStallReport#DetectionMethod} indicating the detection method.
+         * arg2 = NetID.
+         * data = PersistableBundle of extras passed from NetworkMonitor.
+         */
+        private static final int EVENT_DATA_STALL_SUSPECTED = 4;
+
+        /**
+         * Event for ConnectivityDiagnosticsHandler to handle network connectivity being reported to
+         * the platform. This event will invoke {@link
+         * IConnectivityDiagnosticsCallback#onNetworkConnectivityReported} for permissioned
+         * callbacks.
+         * obj = Network that was reported on
+         * arg1 = boolint for the quality reported
+         */
+        private static final int EVENT_NETWORK_CONNECTIVITY_REPORTED = 5;
+
         private ConnectivityDiagnosticsHandler(Looper looper) {
             super(looper);
         }
@@ -7585,6 +7640,24 @@
                     handleNetworkTestedWithExtras(reportEvent, extras);
                     break;
                 }
+                case EVENT_DATA_STALL_SUSPECTED: {
+                    final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
+                    if (nai == null) break;
+
+                    // This is safe because NetworkMonitorCallbacks#notifyDataStallSuspected
+                    // receives a PersistableBundle and converts it to the Bundle in the incoming
+                    // Message.
+                    final PersistableBundle extras = new PersistableBundle(msg.getData());
+                    handleDataStallSuspected(nai, (long) msg.obj, msg.arg1, extras);
+                    break;
+                }
+                case EVENT_NETWORK_CONNECTIVITY_REPORTED: {
+                    handleNetworkConnectivityReported((NetworkAgentInfo) msg.obj, toBool(msg.arg1));
+                    break;
+                }
+                default: {
+                    Log.e(mTag, "Unrecognized event in ConnectivityDiagnostics: " + msg.what);
+                }
             }
         }
     }
@@ -7714,6 +7787,35 @@
         }
     }
 
+    private void handleDataStallSuspected(
+            @NonNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod,
+            @NonNull PersistableBundle extras) {
+        final DataStallReport report =
+                new DataStallReport(nai.network, timestampMillis, detectionMethod, extras);
+        final List<IConnectivityDiagnosticsCallback> results =
+                getMatchingPermissionedCallbacks(nai);
+        for (final IConnectivityDiagnosticsCallback cb : results) {
+            try {
+                cb.onDataStallSuspected(report);
+            } catch (RemoteException ex) {
+                loge("Error invoking onDataStallSuspected", ex);
+            }
+        }
+    }
+
+    private void handleNetworkConnectivityReported(
+            @NonNull NetworkAgentInfo nai, boolean connectivity) {
+        final List<IConnectivityDiagnosticsCallback> results =
+                getMatchingPermissionedCallbacks(nai);
+        for (final IConnectivityDiagnosticsCallback cb : results) {
+            try {
+                cb.onNetworkConnectivityReported(nai.network, connectivity);
+            } catch (RemoteException ex) {
+                loge("Error invoking onNetworkConnectivityReported", ex);
+            }
+        }
+    }
+
     private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks(
             @NonNull NetworkAgentInfo nai) {
         final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>();
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 3c6ae9d..a5d9aa2 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -16,6 +16,12 @@
 
 package com.android.server.compat;
 
+import static android.Manifest.permission.LOG_COMPAT_CHANGE;
+import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
+import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.content.Context;
@@ -66,12 +72,14 @@
 
     @Override
     public void reportChange(long changeId, ApplicationInfo appInfo) {
+        checkCompatChangeLogPermission();
         reportChange(changeId, appInfo.uid,
                 ChangeReporter.STATE_LOGGED);
     }
 
     @Override
     public void reportChangeByPackageName(long changeId, String packageName, int userId) {
+        checkCompatChangeLogPermission();
         ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
         if (appInfo == null) {
             return;
@@ -81,11 +89,13 @@
 
     @Override
     public void reportChangeByUid(long changeId, int uid) {
+        checkCompatChangeLogPermission();
         reportChange(changeId, uid, ChangeReporter.STATE_LOGGED);
     }
 
     @Override
     public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
+        checkCompatChangeReadAndLogPermission();
         if (mCompatConfig.isChangeEnabled(changeId, appInfo)) {
             reportChange(changeId, appInfo.uid,
                     ChangeReporter.STATE_ENABLED);
@@ -97,7 +107,9 @@
     }
 
     @Override
-    public boolean isChangeEnabledByPackageName(long changeId, String packageName, int userId) {
+    public boolean isChangeEnabledByPackageName(long changeId, String packageName,
+            @UserIdInt int userId) {
+        checkCompatChangeReadAndLogPermission();
         ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
         if (appInfo == null) {
             return true;
@@ -107,6 +119,7 @@
 
     @Override
     public boolean isChangeEnabledByUid(long changeId, int uid) {
+        checkCompatChangeReadAndLogPermission();
         String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
         if (packages == null || packages.length == 0) {
             return true;
@@ -139,6 +152,7 @@
     @Override
     public void setOverrides(CompatibilityChangeConfig overrides, String packageName)
             throws RemoteException, SecurityException {
+        checkCompatChangeOverridePermission();
         mCompatConfig.addOverrides(overrides, packageName);
         killPackage(packageName);
     }
@@ -146,11 +160,13 @@
     @Override
     public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName)
             throws RemoteException, SecurityException {
+        checkCompatChangeOverridePermission();
         mCompatConfig.addOverrides(overrides, packageName);
     }
 
     @Override
     public void clearOverrides(String packageName) throws RemoteException, SecurityException {
+        checkCompatChangeOverridePermission();
         mCompatConfig.removePackageOverrides(packageName);
         killPackage(packageName);
     }
@@ -158,12 +174,14 @@
     @Override
     public void clearOverridesForTest(String packageName)
             throws RemoteException, SecurityException {
+        checkCompatChangeOverridePermission();
         mCompatConfig.removePackageOverrides(packageName);
     }
 
     @Override
     public boolean clearOverride(long changeId, String packageName)
             throws RemoteException, SecurityException {
+        checkCompatChangeOverridePermission();
         boolean existed = mCompatConfig.removeOverride(changeId, packageName);
         killPackage(packageName);
         return existed;
@@ -171,11 +189,13 @@
 
     @Override
     public CompatibilityChangeConfig getAppConfig(ApplicationInfo appInfo) {
+        checkCompatChangeReadAndLogPermission();
         return mCompatConfig.getAppConfig(appInfo);
     }
 
     @Override
     public CompatibilityChangeInfo[] listAllChanges() {
+        checkCompatChangeReadPermission();
         return mCompatConfig.dumpChanges();
     }
 
@@ -214,6 +234,7 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        checkCompatChangeReadAndLogPermission();
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
         mCompatConfig.dumpConfig(pw);
     }
@@ -275,4 +296,30 @@
             Binder.restoreCallingIdentity(identity);
         }
     }
+
+    private void checkCompatChangeLogPermission() throws SecurityException {
+        if (mContext.checkCallingOrSelfPermission(LOG_COMPAT_CHANGE)
+                != PERMISSION_GRANTED) {
+            throw new SecurityException("Cannot log compat change usage");
+        }
+    }
+
+    private void checkCompatChangeReadPermission() throws SecurityException {
+        if (mContext.checkCallingOrSelfPermission(READ_COMPAT_CHANGE_CONFIG)
+                != PERMISSION_GRANTED) {
+            throw new SecurityException("Cannot read compat change");
+        }
+    }
+
+    private void checkCompatChangeOverridePermission() throws SecurityException {
+        if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
+                != PERMISSION_GRANTED) {
+            throw new SecurityException("Cannot override compat change");
+        }
+    }
+
+    private void checkCompatChangeReadAndLogPermission() throws SecurityException {
+        checkCompatChangeReadPermission();
+        checkCompatChangeLogPermission();
+    }
 }
diff --git a/services/core/java/com/android/server/compat/PlatformCompatNative.java b/services/core/java/com/android/server/compat/PlatformCompatNative.java
index 85dfbf4..5d7af65 100644
--- a/services/core/java/com/android/server/compat/PlatformCompatNative.java
+++ b/services/core/java/com/android/server/compat/PlatformCompatNative.java
@@ -16,6 +16,8 @@
 
 package com.android.server.compat;
 
+import android.annotation.UserIdInt;
+
 import com.android.internal.compat.IPlatformCompatNative;
 
 /**
@@ -39,7 +41,8 @@
     }
 
     @Override
-    public boolean isChangeEnabledByPackageName(long changeId, String packageName, int userId) {
+    public boolean isChangeEnabledByPackageName(long changeId, String packageName,
+            @UserIdInt int userId) {
         return mPlatformCompat.isChangeEnabledByPackageName(changeId, packageName, userId);
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 609a415..35e9ba9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -2601,6 +2601,8 @@
                 case "--staged":
                     sessionParams.setStaged();
                     break;
+                case "--force-queryable":
+                    break;
                 case "--enable-rollback":
                     if (params.installerPackageName == null) {
                         // com.android.shell has the TEST_MANAGE_ROLLBACKS
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 0bb0f94..ed6424c 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -21,7 +21,7 @@
 import android.app.timedetector.ITimeDetectorService;
 import android.app.timedetector.ManualTimeSuggestion;
 import android.app.timedetector.NetworkTimeSuggestion;
-import android.app.timedetector.PhoneTimeSuggestion;
+import android.app.timedetector.TelephonyTimeSuggestion;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
@@ -94,11 +94,11 @@
     }
 
     @Override
-    public void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSignal) {
-        enforceSuggestPhoneTimePermission();
+    public void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSignal) {
+        enforceSuggestTelephonyTimePermission();
         Objects.requireNonNull(timeSignal);
 
-        mHandler.post(() -> mTimeDetectorStrategy.suggestPhoneTime(timeSignal));
+        mHandler.post(() -> mTimeDetectorStrategy.suggestTelephonyTime(timeSignal));
     }
 
     @Override
@@ -131,10 +131,10 @@
         mTimeDetectorStrategy.dump(pw, args);
     }
 
-    private void enforceSuggestPhoneTimePermission() {
+    private void enforceSuggestTelephonyTimePermission() {
         mContext.enforceCallingPermission(
-                android.Manifest.permission.SUGGEST_PHONE_TIME_AND_ZONE,
-                "suggest phone time and time zone");
+                android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE,
+                "suggest telephony time and time zone");
     }
 
     private void enforceSuggestManualTimePermission() {
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index a7c3b4d..a5fba4e 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -20,7 +20,7 @@
 import android.annotation.Nullable;
 import android.app.timedetector.ManualTimeSuggestion;
 import android.app.timedetector.NetworkTimeSuggestion;
-import android.app.timedetector.PhoneTimeSuggestion;
+import android.app.timedetector.TelephonyTimeSuggestion;
 import android.os.TimestampedValue;
 
 import java.io.PrintWriter;
@@ -78,7 +78,7 @@
     void initialize(@NonNull Callback callback);
 
     /** Process the suggested time from telephony sources. */
-    void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSuggestion);
+    void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSuggestion);
 
     /** Process the suggested manually entered time. */
     void suggestManualTime(@NonNull ManualTimeSuggestion timeSuggestion);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index 19435ee..8c54fa9 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -22,7 +22,7 @@
 import android.app.AlarmManager;
 import android.app.timedetector.ManualTimeSuggestion;
 import android.app.timedetector.NetworkTimeSuggestion;
-import android.app.timedetector.PhoneTimeSuggestion;
+import android.app.timedetector.TelephonyTimeSuggestion;
 import android.os.TimestampedValue;
 import android.util.LocalLog;
 import android.util.Slog;
@@ -38,9 +38,9 @@
 import java.lang.annotation.RetentionPolicy;
 
 /**
- * An implementation of {@link TimeDetectorStrategy} that passes phone and manual suggestions to
- * {@link AlarmManager}. When there are multiple phone sources, the one with the lowest ID is used
- * unless the data becomes too stale.
+ * An implementation of {@link TimeDetectorStrategy} that passes telephony and manual suggestions to
+ * {@link AlarmManager}. When there are multiple telephony sources, the one with the lowest ID is
+ * used unless the data becomes too stale.
  *
  * <p>Most public methods are marked synchronized to ensure thread safety around internal state.
  */
@@ -50,23 +50,26 @@
     private static final String LOG_TAG = "SimpleTimeDetectorStrategy";
 
     /** A score value used to indicate "no score", either due to validation failure or age. */
-    private static final int PHONE_INVALID_SCORE = -1;
-    /** The number of buckets phone suggestions can be put in by age. */
-    private static final int PHONE_BUCKET_COUNT = 24;
+    private static final int TELEPHONY_INVALID_SCORE = -1;
+    /** The number of buckets telephony suggestions can be put in by age. */
+    private static final int TELEPHONY_BUCKET_COUNT = 24;
     /** Each bucket is this size. All buckets are equally sized. */
     @VisibleForTesting
-    static final int PHONE_BUCKET_SIZE_MILLIS = 60 * 60 * 1000;
-    /** Phone and network suggestions older than this value are considered too old to be used. */
+    static final int TELEPHONY_BUCKET_SIZE_MILLIS = 60 * 60 * 1000;
+    /**
+     * Telephony and network suggestions older than this value are considered too old to be used.
+     */
     @VisibleForTesting
-    static final long MAX_UTC_TIME_AGE_MILLIS = PHONE_BUCKET_COUNT * PHONE_BUCKET_SIZE_MILLIS;
+    static final long MAX_UTC_TIME_AGE_MILLIS =
+            TELEPHONY_BUCKET_COUNT * TELEPHONY_BUCKET_SIZE_MILLIS;
 
-    @IntDef({ ORIGIN_PHONE, ORIGIN_MANUAL, ORIGIN_NETWORK })
+    @IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL, ORIGIN_NETWORK })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Origin {}
 
     /** Used when a time value originated from a telephony signal. */
     @Origin
-    private static final int ORIGIN_PHONE = 1;
+    private static final int ORIGIN_TELEPHONY = 1;
 
     /** Used when a time value originated from a user / manual settings. */
     @Origin
@@ -83,7 +86,9 @@
      */
     private static final long SYSTEM_CLOCK_PARANOIA_THRESHOLD_MILLIS = 2 * 1000;
 
-    /** The number of previous phone suggestions to keep for each ID (for use during debugging). */
+    /**
+     * The number of previous telephony suggestions to keep for each ID (for use during debugging).
+     */
     private static final int KEEP_SUGGESTION_HISTORY_SIZE = 30;
 
     // A log for changes made to the system clock and why.
@@ -106,7 +111,7 @@
      * stable.
      */
     @GuardedBy("this")
-    private final ArrayMapWithHistory<Integer, PhoneTimeSuggestion> mSuggestionBySlotIndex =
+    private final ArrayMapWithHistory<Integer, TelephonyTimeSuggestion> mSuggestionBySlotIndex =
             new ArrayMapWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
 
     @GuardedBy("this")
@@ -144,7 +149,7 @@
     }
 
     @Override
-    public synchronized void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSuggestion) {
+    public synchronized void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSuggestion) {
         // Empty time suggestion means that telephony network connectivity has been lost.
         // The passage of time is relentless, and we don't expect our users to use a time machine,
         // so we can continue relying on previous suggestions when we lose connectivity. This is
@@ -157,13 +162,13 @@
 
         // Perform validation / input filtering and record the validated suggestion against the
         // slotIndex.
-        if (!validateAndStorePhoneSuggestion(timeSuggestion)) {
+        if (!validateAndStoreTelephonySuggestion(timeSuggestion)) {
             return;
         }
 
         // Now perform auto time detection. The new suggestion may be used to modify the system
         // clock.
-        String reason = "New phone time suggested. timeSuggestion=" + timeSuggestion;
+        String reason = "New telephony time suggested. timeSuggestion=" + timeSuggestion;
         doAutoTimeDetection(reason);
     }
 
@@ -201,7 +206,7 @@
         mTimeChangesLog.dump(ipw);
         ipw.decreaseIndent(); // level 2
 
-        ipw.println("Phone suggestion history:");
+        ipw.println("Telephony suggestion history:");
         ipw.increaseIndent(); // level 2
         mSuggestionBySlotIndex.dump(ipw);
         ipw.decreaseIndent(); // level 2
@@ -216,7 +221,8 @@
     }
 
     @GuardedBy("this")
-    private boolean validateAndStorePhoneSuggestion(@NonNull PhoneTimeSuggestion suggestion) {
+    private boolean validateAndStoreTelephonySuggestion(
+            @NonNull TelephonyTimeSuggestion suggestion) {
         TimestampedValue<Long> newUtcTime = suggestion.getUtcTime();
         if (!validateSuggestionTime(newUtcTime, suggestion)) {
             // There's probably nothing useful we can do: elsewhere we assume that reference
@@ -225,7 +231,7 @@
         }
 
         int slotIndex = suggestion.getSlotIndex();
-        PhoneTimeSuggestion previousSuggestion = mSuggestionBySlotIndex.get(slotIndex);
+        TelephonyTimeSuggestion previousSuggestion = mSuggestionBySlotIndex.get(slotIndex);
         if (previousSuggestion != null) {
             // We can log / discard suggestions with obvious issues with the reference time clock.
             if (previousSuggestion.getUtcTime() == null
@@ -241,7 +247,7 @@
                     newUtcTime, previousSuggestion.getUtcTime());
             if (referenceTimeDifference < 0) {
                 // The reference time is before the previously received suggestion. Ignore it.
-                Slog.w(LOG_TAG, "Out of order phone suggestion received."
+                Slog.w(LOG_TAG, "Out of order telephony suggestion received."
                         + " referenceTimeDifference=" + referenceTimeDifference
                         + " previousSuggestion=" + previousSuggestion
                         + " suggestion=" + suggestion);
@@ -282,18 +288,18 @@
 
         // Android devices currently prioritize any telephony over network signals. There are
         // carrier compliance tests that would need to be changed before we could ignore NITZ or
-        // prefer NTP generally. This check is cheap on devices without phone hardware.
-        PhoneTimeSuggestion bestPhoneSuggestion = findBestPhoneSuggestion();
-        if (bestPhoneSuggestion != null) {
-            final TimestampedValue<Long> newUtcTime = bestPhoneSuggestion.getUtcTime();
-            String cause = "Found good phone suggestion."
-                    + ", bestPhoneSuggestion=" + bestPhoneSuggestion
+        // prefer NTP generally. This check is cheap on devices without telephony hardware.
+        TelephonyTimeSuggestion bestTelephonySuggestion = findBestTelephonySuggestion();
+        if (bestTelephonySuggestion != null) {
+            final TimestampedValue<Long> newUtcTime = bestTelephonySuggestion.getUtcTime();
+            String cause = "Found good telephony suggestion."
+                    + ", bestTelephonySuggestion=" + bestTelephonySuggestion
                     + ", detectionReason=" + detectionReason;
-            setSystemClockIfRequired(ORIGIN_PHONE, newUtcTime, cause);
+            setSystemClockIfRequired(ORIGIN_TELEPHONY, newUtcTime, cause);
             return;
         }
 
-        // There is no good phone suggestion, try network.
+        // There is no good telephony suggestion, try network.
         NetworkTimeSuggestion networkSuggestion = findLatestValidNetworkSuggestion();
         if (networkSuggestion != null) {
             final TimestampedValue<Long> newUtcTime = networkSuggestion.getUtcTime();
@@ -305,18 +311,18 @@
         }
 
         if (DBG) {
-            Slog.d(LOG_TAG, "Could not determine time: No best phone or network suggestion."
+            Slog.d(LOG_TAG, "Could not determine time: No best telephony or network suggestion."
                     + " detectionReason=" + detectionReason);
         }
     }
 
     @GuardedBy("this")
     @Nullable
-    private PhoneTimeSuggestion findBestPhoneSuggestion() {
+    private TelephonyTimeSuggestion findBestTelephonySuggestion() {
         long elapsedRealtimeMillis = mCallback.elapsedRealtimeMillis();
 
-        // Phone time suggestions are assumed to be derived from NITZ or NITZ-like signals. These
-        // have a number of limitations:
+        // Telephony time suggestions are assumed to be derived from NITZ or NITZ-like signals.
+        // These have a number of limitations:
         // 1) No guarantee of accuracy ("accuracy of the time information is in the order of
         // minutes") [1]
         // 2) No guarantee of regular signals ("dependent on the handset crossing radio network
@@ -335,8 +341,8 @@
         // For simplicity, we try to value recency, then consistency of slotIndex.
         //
         // The heuristic works as follows:
-        // Recency: The most recent suggestion from each phone is scored. The score is based on a
-        // discrete age bucket, i.e. so signals received around the same time will be in the same
+        // Recency: The most recent suggestion from each slotIndex is scored. The score is based on
+        // a discrete age bucket, i.e. so signals received around the same time will be in the same
         // bucket, thus applying a loose reference time ordering. The suggestion with the highest
         // score is used.
         // Consistency: If there a multiple suggestions with the same score, the suggestion with the
@@ -345,11 +351,11 @@
         // In the trivial case with a single ID this will just mean that the latest received
         // suggestion is used.
 
-        PhoneTimeSuggestion bestSuggestion = null;
-        int bestScore = PHONE_INVALID_SCORE;
+        TelephonyTimeSuggestion bestSuggestion = null;
+        int bestScore = TELEPHONY_INVALID_SCORE;
         for (int i = 0; i < mSuggestionBySlotIndex.size(); i++) {
             Integer slotIndex = mSuggestionBySlotIndex.keyAt(i);
-            PhoneTimeSuggestion candidateSuggestion = mSuggestionBySlotIndex.valueAt(i);
+            TelephonyTimeSuggestion candidateSuggestion = mSuggestionBySlotIndex.valueAt(i);
             if (candidateSuggestion == null) {
                 // Unexpected - null suggestions should never be stored.
                 Slog.w(LOG_TAG, "Latest suggestion unexpectedly null for slotIndex."
@@ -362,8 +368,9 @@
                 continue;
             }
 
-            int candidateScore = scorePhoneSuggestion(elapsedRealtimeMillis, candidateSuggestion);
-            if (candidateScore == PHONE_INVALID_SCORE) {
+            int candidateScore =
+                    scoreTelephonySuggestion(elapsedRealtimeMillis, candidateSuggestion);
+            if (candidateScore == TELEPHONY_INVALID_SCORE) {
                 // Expected: This means the suggestion is obviously invalid or just too old.
                 continue;
             }
@@ -384,8 +391,8 @@
         return bestSuggestion;
     }
 
-    private static int scorePhoneSuggestion(
-            long elapsedRealtimeMillis, @NonNull PhoneTimeSuggestion timeSuggestion) {
+    private static int scoreTelephonySuggestion(
+            long elapsedRealtimeMillis, @NonNull TelephonyTimeSuggestion timeSuggestion) {
 
         // Validate first.
         TimestampedValue<Long> utcTime = timeSuggestion.getUtcTime();
@@ -393,21 +400,21 @@
             Slog.w(LOG_TAG, "Existing suggestion found to be invalid "
                     + " elapsedRealtimeMillis=" + elapsedRealtimeMillis
                     + ", timeSuggestion=" + timeSuggestion);
-            return PHONE_INVALID_SCORE;
+            return TELEPHONY_INVALID_SCORE;
         }
 
         // The score is based on the age since receipt. Suggestions are bucketed so two
         // suggestions in the same bucket from different slotIndexs are scored the same.
         long ageMillis = elapsedRealtimeMillis - utcTime.getReferenceTimeMillis();
 
-        // Turn the age into a discrete value: 0 <= bucketIndex < PHONE_BUCKET_COUNT.
-        int bucketIndex = (int) (ageMillis / PHONE_BUCKET_SIZE_MILLIS);
-        if (bucketIndex >= PHONE_BUCKET_COUNT) {
-            return PHONE_INVALID_SCORE;
+        // Turn the age into a discrete value: 0 <= bucketIndex < TELEPHONY_BUCKET_COUNT.
+        int bucketIndex = (int) (ageMillis / TELEPHONY_BUCKET_SIZE_MILLIS);
+        if (bucketIndex >= TELEPHONY_BUCKET_COUNT) {
+            return TELEPHONY_INVALID_SCORE;
         }
 
         // We want the lowest bucket index to have the highest score. 0 > score >= BUCKET_COUNT.
-        return PHONE_BUCKET_COUNT - bucketIndex;
+        return TELEPHONY_BUCKET_COUNT - bucketIndex;
     }
 
     /** Returns the latest, valid, network suggestion. Returns {@code null} if there isn't one. */
@@ -537,13 +544,13 @@
     }
 
     /**
-     * Returns the current best phone suggestion. Not intended for general use: it is used during
-     * tests to check strategy behavior.
+     * Returns the current best telephony suggestion. Not intended for general use: it is used
+     * during tests to check strategy behavior.
      */
     @VisibleForTesting
     @Nullable
-    public synchronized PhoneTimeSuggestion findBestPhoneSuggestionForTests() {
-        return findBestPhoneSuggestion();
+    public synchronized TelephonyTimeSuggestion findBestTelephonySuggestionForTests() {
+        return findBestTelephonySuggestion();
     }
 
     /**
@@ -561,7 +568,7 @@
      */
     @VisibleForTesting
     @Nullable
-    public synchronized PhoneTimeSuggestion getLatestPhoneSuggestion(int slotIndex) {
+    public synchronized TelephonyTimeSuggestion getLatestTelephonySuggestion(int slotIndex) {
         return mSuggestionBySlotIndex.get(slotIndex);
     }
 
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
index 381ee10..57b6ec9 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
@@ -20,7 +20,7 @@
 import android.annotation.Nullable;
 import android.app.timezonedetector.ITimeZoneDetectorService;
 import android.app.timezonedetector.ManualTimeZoneSuggestion;
-import android.app.timezonedetector.PhoneTimeZoneSuggestion;
+import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
@@ -101,11 +101,11 @@
     }
 
     @Override
-    public void suggestPhoneTimeZone(@NonNull PhoneTimeZoneSuggestion timeZoneSuggestion) {
-        enforceSuggestPhoneTimeZonePermission();
+    public void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion) {
+        enforceSuggestTelephonyTimeZonePermission();
         Objects.requireNonNull(timeZoneSuggestion);
 
-        mHandler.post(() -> mTimeZoneDetectorStrategy.suggestPhoneTimeZone(timeZoneSuggestion));
+        mHandler.post(() -> mTimeZoneDetectorStrategy.suggestTelephonyTimeZone(timeZoneSuggestion));
     }
 
     @Override
@@ -122,10 +122,10 @@
         mHandler.post(mTimeZoneDetectorStrategy::handleAutoTimeZoneDetectionChanged);
     }
 
-    private void enforceSuggestPhoneTimeZonePermission() {
+    private void enforceSuggestTelephonyTimeZonePermission() {
         mContext.enforceCallingPermission(
-                android.Manifest.permission.SUGGEST_PHONE_TIME_AND_ZONE,
-                "suggest phone time and time zone");
+                android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE,
+                "suggest telephony time and time zone");
     }
 
     private void enforceSuggestManualTimeZonePermission() {
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
index 1d439e9..0eb27cc 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
@@ -17,7 +17,7 @@
 
 import android.annotation.NonNull;
 import android.app.timezonedetector.ManualTimeZoneSuggestion;
-import android.app.timezonedetector.PhoneTimeZoneSuggestion;
+import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
 
 import java.io.PrintWriter;
 
@@ -38,13 +38,13 @@
 
     /**
      * Suggests a time zone for the device, or withdraws a previous suggestion if
-     * {@link PhoneTimeZoneSuggestion#getZoneId()} is {@code null}. The suggestion is scoped to a
-     * specific {@link PhoneTimeZoneSuggestion#getSlotIndex() phone}.
-     * See {@link PhoneTimeZoneSuggestion} for an explanation of the metadata associated with a
+     * {@link TelephonyTimeZoneSuggestion#getZoneId()} is {@code null}. The suggestion is scoped to
+     * a specific {@link TelephonyTimeZoneSuggestion#getSlotIndex() slotIndex}.
+     * See {@link TelephonyTimeZoneSuggestion} for an explanation of the metadata associated with a
      * suggestion. The strategy uses suggestions to decide whether to modify the device's time zone
      * setting and what to set it to.
      */
-    void suggestPhoneTimeZone(@NonNull PhoneTimeZoneSuggestion suggestion);
+    void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion suggestion);
 
     /**
      * Called when there has been a change to the automatic time zone detection setting.
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
index f85f9fe..652dbe15 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
@@ -15,17 +15,17 @@
  */
 package com.android.server.timezonedetector;
 
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID;
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY;
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS;
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.timezonedetector.ManualTimeZoneSuggestion;
-import android.app.timezonedetector.PhoneTimeZoneSuggestion;
+import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
 import android.content.Context;
 import android.util.LocalLog;
 import android.util.Slog;
@@ -44,11 +44,11 @@
  * suggestions. Suggestions are acted on or ignored as needed, dependent on the current "auto time
  * zone detection" setting.
  *
- * <p>For automatic detection it keeps track of the most recent suggestion from each phone it uses
- * the best suggestion based on a scoring algorithm. If several phones provide the same score then
- * the phone with the lowest numeric ID "wins". If the situation changes and it is no longer
- * possible to be confident about the time zone, phones must submit an empty suggestion in order to
- * "withdraw" their previous suggestion.
+ * <p>For automatic detection, it keeps track of the most recent telephony suggestion from each
+ * slotIndex and it uses the best suggestion based on a scoring algorithm. If several slotIndexes
+ * provide the same score then the slotIndex with the lowest numeric value "wins". If the situation
+ * changes and it is no longer possible to be confident about the time zone, slotIndexes must have
+ * an empty suggestion submitted in order to "withdraw" their previous suggestion.
  *
  * <p>Most public methods are marked synchronized to ensure thread safety around internal state.
  */
@@ -91,28 +91,28 @@
     private static final String LOG_TAG = "TimeZoneDetectorStrategy";
     private static final boolean DBG = false;
 
-    @IntDef({ ORIGIN_PHONE, ORIGIN_MANUAL })
+    @IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Origin {}
 
     /** Used when a time value originated from a telephony signal. */
     @Origin
-    private static final int ORIGIN_PHONE = 1;
+    private static final int ORIGIN_TELEPHONY = 1;
 
     /** Used when a time value originated from a user / manual settings. */
     @Origin
     private static final int ORIGIN_MANUAL = 2;
 
     /**
-     * The abstract score for an empty or invalid phone suggestion.
+     * The abstract score for an empty or invalid telephony suggestion.
      *
-     * Used to score phone suggestions where there is no zone.
+     * Used to score telephony suggestions where there is no zone.
      */
     @VisibleForTesting
-    public static final int PHONE_SCORE_NONE = 0;
+    public static final int TELEPHONY_SCORE_NONE = 0;
 
     /**
-     * The abstract score for a low quality phone suggestion.
+     * The abstract score for a low quality telephony suggestion.
      *
      * Used to score suggestions where:
      * The suggested zone ID is one of several possibilities, and the possibilities have different
@@ -121,10 +121,10 @@
      * You would have to be quite desperate to want to use this choice.
      */
     @VisibleForTesting
-    public static final int PHONE_SCORE_LOW = 1;
+    public static final int TELEPHONY_SCORE_LOW = 1;
 
     /**
-     * The abstract score for a medium quality phone suggestion.
+     * The abstract score for a medium quality telephony suggestion.
      *
      * Used for:
      * The suggested zone ID is one of several possibilities but at least the possibilities have the
@@ -132,36 +132,38 @@
      * switch to DST at the wrong time and (for example) their calendar events.
      */
     @VisibleForTesting
-    public static final int PHONE_SCORE_MEDIUM = 2;
+    public static final int TELEPHONY_SCORE_MEDIUM = 2;
 
     /**
-     * The abstract score for a high quality phone suggestion.
+     * The abstract score for a high quality telephony suggestion.
      *
      * Used for:
      * The suggestion was for one zone ID and the answer was unambiguous and likely correct given
      * the info available.
      */
     @VisibleForTesting
-    public static final int PHONE_SCORE_HIGH = 3;
+    public static final int TELEPHONY_SCORE_HIGH = 3;
 
     /**
-     * The abstract score for a highest quality phone suggestion.
+     * The abstract score for a highest quality telephony suggestion.
      *
      * Used for:
      * Suggestions that must "win" because they constitute test or emulator zone ID.
      */
     @VisibleForTesting
-    public static final int PHONE_SCORE_HIGHEST = 4;
+    public static final int TELEPHONY_SCORE_HIGHEST = 4;
 
     /**
-     * The threshold at which phone suggestions are good enough to use to set the device's time
+     * The threshold at which telephony suggestions are good enough to use to set the device's time
      * zone.
      */
     @VisibleForTesting
-    public static final int PHONE_SCORE_USAGE_THRESHOLD = PHONE_SCORE_MEDIUM;
+    public static final int TELEPHONY_SCORE_USAGE_THRESHOLD = TELEPHONY_SCORE_MEDIUM;
 
-    /** The number of previous phone suggestions to keep for each ID (for use during debugging). */
-    private static final int KEEP_PHONE_SUGGESTION_HISTORY_SIZE = 30;
+    /**
+     * The number of previous telephony suggestions to keep for each ID (for use during debugging).
+     */
+    private static final int KEEP_TELEPHONY_SUGGESTION_HISTORY_SIZE = 30;
 
     @NonNull
     private final Callback mCallback;
@@ -174,13 +176,14 @@
     private final LocalLog mTimeZoneChangesLog = new LocalLog(30, false /* useLocalTimestamps */);
 
     /**
-     * A mapping from slotIndex to a phone time zone suggestion. We typically expect one or two
-     * mappings: devices will have a small number of telephony devices and slotIndexs are assumed to
-     * be stable.
+     * A mapping from slotIndex to a telephony time zone suggestion. We typically expect one or two
+     * mappings: devices will have a small number of telephony devices and slotIndexes are assumed
+     * to be stable.
      */
     @GuardedBy("this")
-    private ArrayMapWithHistory<Integer, QualifiedPhoneTimeZoneSuggestion> mSuggestionBySlotIndex =
-            new ArrayMapWithHistory<>(KEEP_PHONE_SUGGESTION_HISTORY_SIZE);
+    private ArrayMapWithHistory<Integer, QualifiedTelephonyTimeZoneSuggestion>
+            mSuggestionBySlotIndex =
+            new ArrayMapWithHistory<>(KEEP_TELEPHONY_SUGGESTION_HISTORY_SIZE);
 
     /**
      * Creates a new instance of {@link TimeZoneDetectorStrategyImpl}.
@@ -205,42 +208,43 @@
     }
 
     @Override
-    public synchronized void suggestPhoneTimeZone(@NonNull PhoneTimeZoneSuggestion suggestion) {
+    public synchronized void suggestTelephonyTimeZone(
+            @NonNull TelephonyTimeZoneSuggestion suggestion) {
         if (DBG) {
-            Slog.d(LOG_TAG, "Phone suggestion received. newSuggestion=" + suggestion);
+            Slog.d(LOG_TAG, "Telephony suggestion received. newSuggestion=" + suggestion);
         }
         Objects.requireNonNull(suggestion);
 
         // Score the suggestion.
-        int score = scorePhoneSuggestion(suggestion);
-        QualifiedPhoneTimeZoneSuggestion scoredSuggestion =
-                new QualifiedPhoneTimeZoneSuggestion(suggestion, score);
+        int score = scoreTelephonySuggestion(suggestion);
+        QualifiedTelephonyTimeZoneSuggestion scoredSuggestion =
+                new QualifiedTelephonyTimeZoneSuggestion(suggestion, score);
 
         // Store the suggestion against the correct slotIndex.
         mSuggestionBySlotIndex.put(suggestion.getSlotIndex(), scoredSuggestion);
 
         // Now perform auto time zone detection. The new suggestion may be used to modify the time
         // zone setting.
-        String reason = "New phone time suggested. suggestion=" + suggestion;
+        String reason = "New telephony time suggested. suggestion=" + suggestion;
         doAutoTimeZoneDetection(reason);
     }
 
-    private static int scorePhoneSuggestion(@NonNull PhoneTimeZoneSuggestion suggestion) {
+    private static int scoreTelephonySuggestion(@NonNull TelephonyTimeZoneSuggestion suggestion) {
         int score;
         if (suggestion.getZoneId() == null) {
-            score = PHONE_SCORE_NONE;
+            score = TELEPHONY_SCORE_NONE;
         } else if (suggestion.getMatchType() == MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY
                 || suggestion.getMatchType() == MATCH_TYPE_EMULATOR_ZONE_ID) {
             // Handle emulator / test cases : These suggestions should always just be used.
-            score = PHONE_SCORE_HIGHEST;
+            score = TELEPHONY_SCORE_HIGHEST;
         } else if (suggestion.getQuality() == QUALITY_SINGLE_ZONE) {
-            score = PHONE_SCORE_HIGH;
+            score = TELEPHONY_SCORE_HIGH;
         } else if (suggestion.getQuality() == QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET) {
             // The suggestion may be wrong, but at least the offset should be correct.
-            score = PHONE_SCORE_MEDIUM;
+            score = TELEPHONY_SCORE_MEDIUM;
         } else if (suggestion.getQuality() == QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS) {
             // The suggestion has a good chance of being wrong.
-            score = PHONE_SCORE_LOW;
+            score = TELEPHONY_SCORE_LOW;
         } else {
             throw new AssertionError();
         }
@@ -248,9 +252,9 @@
     }
 
     /**
-     * Finds the best available time zone suggestion from all phones. If it is high-enough quality
-     * and automatic time zone detection is enabled then it will be set on the device. The outcome
-     * can be that this strategy becomes / remains un-opinionated and nothing is set.
+     * Finds the best available time zone suggestion from all slotIndexes. If it is high-enough
+     * quality and automatic time zone detection is enabled then it will be set on the device. The
+     * outcome can be that this strategy becomes / remains un-opinionated and nothing is set.
      */
     @GuardedBy("this")
     private void doAutoTimeZoneDetection(@NonNull String detectionReason) {
@@ -259,35 +263,37 @@
             return;
         }
 
-        QualifiedPhoneTimeZoneSuggestion bestPhoneSuggestion = findBestPhoneSuggestion();
+        QualifiedTelephonyTimeZoneSuggestion bestTelephonySuggestion =
+                findBestTelephonySuggestion();
 
         // Work out what to do with the best suggestion.
-        if (bestPhoneSuggestion == null) {
-            // There is no phone suggestion available at all. Become un-opinionated.
+        if (bestTelephonySuggestion == null) {
+            // There is no telephony suggestion available at all. Become un-opinionated.
             if (DBG) {
-                Slog.d(LOG_TAG, "Could not determine time zone: No best phone suggestion."
+                Slog.d(LOG_TAG, "Could not determine time zone: No best telephony suggestion."
                         + " detectionReason=" + detectionReason);
             }
             return;
         }
 
         // Special case handling for uninitialized devices. This should only happen once.
-        String newZoneId = bestPhoneSuggestion.suggestion.getZoneId();
+        String newZoneId = bestTelephonySuggestion.suggestion.getZoneId();
         if (newZoneId != null && !mCallback.isDeviceTimeZoneInitialized()) {
             String cause = "Device has no time zone set. Attempting to set the device to the best"
                     + " available suggestion."
-                    + " bestPhoneSuggestion=" + bestPhoneSuggestion
+                    + " bestTelephonySuggestion=" + bestTelephonySuggestion
                     + ", detectionReason=" + detectionReason;
             Slog.i(LOG_TAG, cause);
-            setDeviceTimeZoneIfRequired(ORIGIN_PHONE, newZoneId, cause);
+            setDeviceTimeZoneIfRequired(ORIGIN_TELEPHONY, newZoneId, cause);
             return;
         }
 
-        boolean suggestionGoodEnough = bestPhoneSuggestion.score >= PHONE_SCORE_USAGE_THRESHOLD;
+        boolean suggestionGoodEnough =
+                bestTelephonySuggestion.score >= TELEPHONY_SCORE_USAGE_THRESHOLD;
         if (!suggestionGoodEnough) {
             if (DBG) {
                 Slog.d(LOG_TAG, "Best suggestion not good enough."
-                        + " bestPhoneSuggestion=" + bestPhoneSuggestion
+                        + " bestTelephonySuggestion=" + bestTelephonySuggestion
                         + ", detectionReason=" + detectionReason);
             }
             return;
@@ -297,16 +303,16 @@
         // zone ID.
         if (newZoneId == null) {
             Slog.w(LOG_TAG, "Empty zone suggestion scored higher than expected. This is an error:"
-                    + " bestPhoneSuggestion=" + bestPhoneSuggestion
+                    + " bestTelephonySuggestion=" + bestTelephonySuggestion
                     + " detectionReason=" + detectionReason);
             return;
         }
 
-        String zoneId = bestPhoneSuggestion.suggestion.getZoneId();
+        String zoneId = bestTelephonySuggestion.suggestion.getZoneId();
         String cause = "Found good suggestion."
-                + ", bestPhoneSuggestion=" + bestPhoneSuggestion
+                + ", bestTelephonySuggestion=" + bestTelephonySuggestion
                 + ", detectionReason=" + detectionReason;
-        setDeviceTimeZoneIfRequired(ORIGIN_PHONE, zoneId, cause);
+        setDeviceTimeZoneIfRequired(ORIGIN_TELEPHONY, zoneId, cause);
     }
 
     @GuardedBy("this")
@@ -372,15 +378,15 @@
 
     @GuardedBy("this")
     @Nullable
-    private QualifiedPhoneTimeZoneSuggestion findBestPhoneSuggestion() {
-        QualifiedPhoneTimeZoneSuggestion bestSuggestion = null;
+    private QualifiedTelephonyTimeZoneSuggestion findBestTelephonySuggestion() {
+        QualifiedTelephonyTimeZoneSuggestion bestSuggestion = null;
 
-        // Iterate over the latest QualifiedPhoneTimeZoneSuggestion objects received for each phone
-        // and find the best. Note that we deliberately do not look at age: the caller can
+        // Iterate over the latest QualifiedTelephonyTimeZoneSuggestion objects received for each
+        // slotIndex and find the best. Note that we deliberately do not look at age: the caller can
         // rate-limit so age is not a strong indicator of confidence. Instead, the callers are
         // expected to withdraw suggestions they no longer have confidence in.
         for (int i = 0; i < mSuggestionBySlotIndex.size(); i++) {
-            QualifiedPhoneTimeZoneSuggestion candidateSuggestion =
+            QualifiedTelephonyTimeZoneSuggestion candidateSuggestion =
                     mSuggestionBySlotIndex.valueAt(i);
             if (candidateSuggestion == null) {
                 // Unexpected
@@ -404,13 +410,13 @@
     }
 
     /**
-     * Returns the current best phone suggestion. Not intended for general use: it is used during
-     * tests to check strategy behavior.
+     * Returns the current best telephony suggestion. Not intended for general use: it is used
+     * during tests to check strategy behavior.
      */
     @VisibleForTesting
     @Nullable
-    public synchronized QualifiedPhoneTimeZoneSuggestion findBestPhoneSuggestionForTests() {
-        return findBestPhoneSuggestion();
+    public synchronized QualifiedTelephonyTimeZoneSuggestion findBestTelephonySuggestionForTests() {
+        return findBestTelephonySuggestion();
     }
 
     @Override
@@ -447,7 +453,7 @@
         mTimeZoneChangesLog.dump(ipw);
         ipw.decreaseIndent(); // level 2
 
-        ipw.println("Phone suggestion history:");
+        ipw.println("Telephony suggestion history:");
         ipw.increaseIndent(); // level 2
         mSuggestionBySlotIndex.dump(ipw);
         ipw.decreaseIndent(); // level 2
@@ -459,18 +465,19 @@
      * A method used to inspect strategy state during tests. Not intended for general use.
      */
     @VisibleForTesting
-    public synchronized QualifiedPhoneTimeZoneSuggestion getLatestPhoneSuggestion(int slotIndex) {
+    public synchronized QualifiedTelephonyTimeZoneSuggestion getLatestTelephonySuggestion(
+            int slotIndex) {
         return mSuggestionBySlotIndex.get(slotIndex);
     }
 
     /**
-     * A {@link PhoneTimeZoneSuggestion} with additional qualifying metadata.
+     * A {@link TelephonyTimeZoneSuggestion} with additional qualifying metadata.
      */
     @VisibleForTesting
-    public static class QualifiedPhoneTimeZoneSuggestion {
+    public static class QualifiedTelephonyTimeZoneSuggestion {
 
         @VisibleForTesting
-        public final PhoneTimeZoneSuggestion suggestion;
+        public final TelephonyTimeZoneSuggestion suggestion;
 
         /**
          * The score the suggestion has been given. This can be used to rank against other
@@ -480,7 +487,8 @@
         public final int score;
 
         @VisibleForTesting
-        public QualifiedPhoneTimeZoneSuggestion(PhoneTimeZoneSuggestion suggestion, int score) {
+        public QualifiedTelephonyTimeZoneSuggestion(
+                TelephonyTimeZoneSuggestion suggestion, int score) {
             this.suggestion = suggestion;
             this.score = score;
         }
@@ -493,7 +501,7 @@
             if (o == null || getClass() != o.getClass()) {
                 return false;
             }
-            QualifiedPhoneTimeZoneSuggestion that = (QualifiedPhoneTimeZoneSuggestion) o;
+            QualifiedTelephonyTimeZoneSuggestion that = (QualifiedTelephonyTimeZoneSuggestion) o;
             return score == that.score
                     && suggestion.equals(that.suggestion);
         }
@@ -505,7 +513,7 @@
 
         @Override
         public String toString() {
-            return "QualifiedPhoneTimeZoneSuggestion{"
+            return "QualifiedTelephonyTimeZoneSuggestion{"
                     + "suggestion=" + suggestion
                     + ", score=" + score
                     + '}';
diff --git a/services/tests/mockingservicestests/AndroidManifest.xml b/services/tests/mockingservicestests/AndroidManifest.xml
index 1200c0c..66b775f 100644
--- a/services/tests/mockingservicestests/AndroidManifest.xml
+++ b/services/tests/mockingservicestests/AndroidManifest.xml
@@ -17,6 +17,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.frameworks.mockingservicestests">
 
+    <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
+    <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
     <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
     <uses-permission android:name="android.permission.HARDWARE_TEST"/>
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 61fe01f..e1d31eb 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -64,6 +64,8 @@
     <uses-permission android:name="android.permission.WATCH_APPOPS" />
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.SUSPEND_APPS"/>
+    <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
+    <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
     <uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
     <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
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 218f43c..2eeeb3e 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -30,7 +30,7 @@
 
 import android.app.timedetector.ManualTimeSuggestion;
 import android.app.timedetector.NetworkTimeSuggestion;
-import android.app.timedetector.PhoneTimeSuggestion;
+import android.app.timedetector.TelephonyTimeSuggestion;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.HandlerThread;
@@ -80,35 +80,35 @@
     }
 
     @Test(expected = SecurityException.class)
-    public void testSuggestPhoneTime_withoutPermission() {
+    public void testSuggestTelephonyTime_withoutPermission() {
         doThrow(new SecurityException("Mock"))
                 .when(mMockContext).enforceCallingPermission(anyString(), any());
-        PhoneTimeSuggestion phoneTimeSuggestion = createPhoneTimeSuggestion();
+        TelephonyTimeSuggestion timeSuggestion = createTelephonyTimeSuggestion();
 
         try {
-            mTimeDetectorService.suggestPhoneTime(phoneTimeSuggestion);
+            mTimeDetectorService.suggestTelephonyTime(timeSuggestion);
             fail();
         } finally {
             verify(mMockContext).enforceCallingPermission(
-                    eq(android.Manifest.permission.SUGGEST_PHONE_TIME_AND_ZONE),
+                    eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE),
                     anyString());
         }
     }
 
     @Test
-    public void testSuggestPhoneTime() throws Exception {
+    public void testSuggestTelephonyTime() throws Exception {
         doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
 
-        PhoneTimeSuggestion phoneTimeSuggestion = createPhoneTimeSuggestion();
-        mTimeDetectorService.suggestPhoneTime(phoneTimeSuggestion);
+        TelephonyTimeSuggestion timeSuggestion = createTelephonyTimeSuggestion();
+        mTimeDetectorService.suggestTelephonyTime(timeSuggestion);
         mTestHandler.assertTotalMessagesEnqueued(1);
 
         verify(mMockContext).enforceCallingPermission(
-                eq(android.Manifest.permission.SUGGEST_PHONE_TIME_AND_ZONE),
+                eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE),
                 anyString());
 
         mTestHandler.waitForMessagesToBeProcessed();
-        mStubbedTimeDetectorStrategy.verifySuggestPhoneTimeCalled(phoneTimeSuggestion);
+        mStubbedTimeDetectorStrategy.verifySuggestTelephonyTimeCalled(timeSuggestion);
     }
 
     @Test(expected = SecurityException.class)
@@ -199,10 +199,10 @@
         mStubbedTimeDetectorStrategy.verifyHandleAutoTimeDetectionChangedCalled();
     }
 
-    private static PhoneTimeSuggestion createPhoneTimeSuggestion() {
+    private static TelephonyTimeSuggestion createTelephonyTimeSuggestion() {
         int slotIndex = 1234;
         TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
-        return new PhoneTimeSuggestion.Builder(slotIndex)
+        return new TelephonyTimeSuggestion.Builder(slotIndex)
                 .setUtcTime(timeValue)
                 .build();
     }
@@ -220,7 +220,7 @@
     private static class StubbedTimeDetectorStrategy implements TimeDetectorStrategy {
 
         // Call tracking.
-        private PhoneTimeSuggestion mLastPhoneSuggestion;
+        private TelephonyTimeSuggestion mLastTelephonySuggestion;
         private ManualTimeSuggestion mLastManualSuggestion;
         private NetworkTimeSuggestion mLastNetworkSuggestion;
         private boolean mHandleAutoTimeDetectionChangedCalled;
@@ -231,8 +231,8 @@
         }
 
         @Override
-        public void suggestPhoneTime(PhoneTimeSuggestion timeSuggestion) {
-            mLastPhoneSuggestion = timeSuggestion;
+        public void suggestTelephonyTime(TelephonyTimeSuggestion timeSuggestion) {
+            mLastTelephonySuggestion = timeSuggestion;
         }
 
         @Override
@@ -256,15 +256,15 @@
         }
 
         void resetCallTracking() {
-            mLastPhoneSuggestion = null;
+            mLastTelephonySuggestion = null;
             mLastManualSuggestion = null;
             mLastNetworkSuggestion = null;
             mHandleAutoTimeDetectionChangedCalled = false;
             mDumpCalled = false;
         }
 
-        void verifySuggestPhoneTimeCalled(PhoneTimeSuggestion expectedSuggestion) {
-            assertEquals(expectedSuggestion, mLastPhoneSuggestion);
+        void verifySuggestTelephonyTimeCalled(TelephonyTimeSuggestion expectedSuggestion) {
+            assertEquals(expectedSuggestion, mLastTelephonySuggestion);
         }
 
         public void verifySuggestManualTimeCalled(ManualTimeSuggestion expectedSuggestion) {
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 d940a6a..803b245 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
@@ -24,7 +24,7 @@
 
 import android.app.timedetector.ManualTimeSuggestion;
 import android.app.timedetector.NetworkTimeSuggestion;
-import android.app.timedetector.PhoneTimeSuggestion;
+import android.app.timedetector.TelephonyTimeSuggestion;
 import android.icu.util.Calendar;
 import android.icu.util.GregorianCalendar;
 import android.icu.util.TimeZone;
@@ -52,7 +52,7 @@
      */
     private static final long ARBITRARY_TEST_TIME_MILLIS = createUtcTime(2018, 1, 1, 12, 0, 0);
 
-    private static final int ARBITRARY_PHONE_ID = 123456;
+    private static final int ARBITRARY_SLOT_INDEX = 123456;
 
     private Script mScript;
 
@@ -62,51 +62,51 @@
     }
 
     @Test
-    public void testSuggestPhoneTime_autoTimeEnabled() {
+    public void testSuggestTelephonyTime_autoTimeEnabled() {
         mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
                 .pokeAutoTimeDetectionEnabled(true);
 
-        int phoneId = ARBITRARY_PHONE_ID;
+        int slotIndex = ARBITRARY_SLOT_INDEX;
         long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS;
 
-        PhoneTimeSuggestion timeSuggestion =
-                mScript.generatePhoneTimeSuggestion(phoneId, testTimeMillis);
+        TelephonyTimeSuggestion timeSuggestion =
+                mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis);
         mScript.simulateTimePassing()
-                .simulatePhoneTimeSuggestion(timeSuggestion);
+                .simulateTelephonyTimeSuggestion(timeSuggestion);
 
         long expectedSystemClockMillis =
                 mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime());
         mScript.verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
-                .assertLatestPhoneSuggestion(phoneId, timeSuggestion);
+                .assertLatestTelephonySuggestion(slotIndex, timeSuggestion);
     }
 
     @Test
-    public void testSuggestPhoneTime_emptySuggestionIgnored() {
+    public void testSuggestTelephonyTime_emptySuggestionIgnored() {
         mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
                 .pokeAutoTimeDetectionEnabled(true);
 
-        int phoneId = ARBITRARY_PHONE_ID;
-        PhoneTimeSuggestion timeSuggestion =
-                mScript.generatePhoneTimeSuggestion(phoneId, null);
-        mScript.simulatePhoneTimeSuggestion(timeSuggestion)
+        int slotIndex = ARBITRARY_SLOT_INDEX;
+        TelephonyTimeSuggestion timeSuggestion =
+                mScript.generateTelephonyTimeSuggestion(slotIndex, null);
+        mScript.simulateTelephonyTimeSuggestion(timeSuggestion)
                 .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestPhoneSuggestion(phoneId, null);
+                .assertLatestTelephonySuggestion(slotIndex, null);
     }
 
     @Test
-    public void testSuggestPhoneTime_systemClockThreshold() {
+    public void testSuggestTelephonyTime_systemClockThreshold() {
         final int systemClockUpdateThresholdMillis = 1000;
         final int clockIncrementMillis = 100;
         mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
                 .pokeThresholds(systemClockUpdateThresholdMillis)
                 .pokeAutoTimeDetectionEnabled(true);
 
-        int phoneId = ARBITRARY_PHONE_ID;
+        int slotIndex = ARBITRARY_SLOT_INDEX;
 
         // Send the first time signal. It should be used.
         {
-            PhoneTimeSuggestion timeSuggestion1 =
-                    mScript.generatePhoneTimeSuggestion(phoneId, ARBITRARY_TEST_TIME_MILLIS);
+            TelephonyTimeSuggestion timeSuggestion1 =
+                    mScript.generateTelephonyTimeSuggestion(slotIndex, ARBITRARY_TEST_TIME_MILLIS);
 
             // Increment the the device clocks to simulate the passage of time.
             mScript.simulateTimePassing(clockIncrementMillis);
@@ -114,151 +114,151 @@
             long expectedSystemClockMillis1 =
                     mScript.calculateTimeInMillisForNow(timeSuggestion1.getUtcTime());
 
-            mScript.simulatePhoneTimeSuggestion(timeSuggestion1)
+            mScript.simulateTelephonyTimeSuggestion(timeSuggestion1)
                     .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1)
-                    .assertLatestPhoneSuggestion(phoneId, timeSuggestion1);
+                    .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1);
         }
 
         // Now send another time signal, but one that is too similar to the last one and should be
         // stored, but not used to set the system clock.
         {
             int underThresholdMillis = systemClockUpdateThresholdMillis - 1;
-            PhoneTimeSuggestion timeSuggestion2 = mScript.generatePhoneTimeSuggestion(
-                    phoneId, mScript.peekSystemClockMillis() + underThresholdMillis);
+            TelephonyTimeSuggestion timeSuggestion2 = mScript.generateTelephonyTimeSuggestion(
+                    slotIndex, mScript.peekSystemClockMillis() + underThresholdMillis);
             mScript.simulateTimePassing(clockIncrementMillis)
-                    .simulatePhoneTimeSuggestion(timeSuggestion2)
+                    .simulateTelephonyTimeSuggestion(timeSuggestion2)
                     .verifySystemClockWasNotSetAndResetCallTracking()
-                    .assertLatestPhoneSuggestion(phoneId, timeSuggestion2);
+                    .assertLatestTelephonySuggestion(slotIndex, timeSuggestion2);
         }
 
         // Now send another time signal, but one that is on the threshold and so should be used.
         {
-            PhoneTimeSuggestion timeSuggestion3 = mScript.generatePhoneTimeSuggestion(
-                    phoneId,
+            TelephonyTimeSuggestion timeSuggestion3 = mScript.generateTelephonyTimeSuggestion(
+                    slotIndex,
                     mScript.peekSystemClockMillis() + systemClockUpdateThresholdMillis);
             mScript.simulateTimePassing(clockIncrementMillis);
 
             long expectedSystemClockMillis3 =
                     mScript.calculateTimeInMillisForNow(timeSuggestion3.getUtcTime());
 
-            mScript.simulatePhoneTimeSuggestion(timeSuggestion3)
+            mScript.simulateTelephonyTimeSuggestion(timeSuggestion3)
                     .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis3)
-                    .assertLatestPhoneSuggestion(phoneId, timeSuggestion3);
+                    .assertLatestTelephonySuggestion(slotIndex, timeSuggestion3);
         }
     }
 
     @Test
-    public void testSuggestPhoneTime_multiplePhoneIdsAndBucketing() {
+    public void testSuggestTelephonyTime_multipleSlotIndexsAndBucketing() {
         mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
                 .pokeAutoTimeDetectionEnabled(true);
 
-        // There are 2 phones in this test. Phone 2 has a different idea of the current time.
-        // phone1Id < phone2Id (which is important because the strategy uses the lowest ID when
-        // multiple phone suggestions are available.
-        int phone1Id = ARBITRARY_PHONE_ID;
-        int phone2Id = ARBITRARY_PHONE_ID + 1;
-        long phone1TimeMillis = ARBITRARY_TEST_TIME_MILLIS;
-        long phone2TimeMillis = ARBITRARY_TEST_TIME_MILLIS + Duration.ofDays(1).toMillis();
+        // There are 2 slotIndexes in this test. slotIndex1 and slotIndex2 have different opinions
+        // about the current time. slotIndex1 < slotIndex2 (which is important because the strategy
+        // uses the lowest slotIndex when multiple telephony suggestions are available.
+        int slotIndex1 = ARBITRARY_SLOT_INDEX;
+        int slotIndex2 = ARBITRARY_SLOT_INDEX + 1;
+        long slotIndex1TimeMillis = ARBITRARY_TEST_TIME_MILLIS;
+        long slotIndex2TimeMillis = ARBITRARY_TEST_TIME_MILLIS + Duration.ofDays(1).toMillis();
 
-        // Make a suggestion with phone2Id.
+        // Make a suggestion with slotIndex2.
         {
-            PhoneTimeSuggestion phone2TimeSuggestion =
-                    mScript.generatePhoneTimeSuggestion(phone2Id, phone2TimeMillis);
+            TelephonyTimeSuggestion slotIndex2TimeSuggestion =
+                    mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2TimeMillis);
             mScript.simulateTimePassing();
 
             long expectedSystemClockMillis =
-                    mScript.calculateTimeInMillisForNow(phone2TimeSuggestion.getUtcTime());
+                    mScript.calculateTimeInMillisForNow(slotIndex2TimeSuggestion.getUtcTime());
 
-            mScript.simulatePhoneTimeSuggestion(phone2TimeSuggestion)
+            mScript.simulateTelephonyTimeSuggestion(slotIndex2TimeSuggestion)
                     .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
-                    .assertLatestPhoneSuggestion(phone1Id, null)
-                    .assertLatestPhoneSuggestion(phone2Id, phone2TimeSuggestion);
+                    .assertLatestTelephonySuggestion(slotIndex1, null)
+                    .assertLatestTelephonySuggestion(slotIndex2, slotIndex2TimeSuggestion);
         }
 
         mScript.simulateTimePassing();
 
-        // Now make a different suggestion with phone1Id.
+        // Now make a different suggestion with slotIndex1.
         {
-            PhoneTimeSuggestion phone1TimeSuggestion =
-                    mScript.generatePhoneTimeSuggestion(phone1Id, phone1TimeMillis);
+            TelephonyTimeSuggestion slotIndex1TimeSuggestion =
+                    mScript.generateTelephonyTimeSuggestion(slotIndex1, slotIndex1TimeMillis);
             mScript.simulateTimePassing();
 
             long expectedSystemClockMillis =
-                    mScript.calculateTimeInMillisForNow(phone1TimeSuggestion.getUtcTime());
+                    mScript.calculateTimeInMillisForNow(slotIndex1TimeSuggestion.getUtcTime());
 
-            mScript.simulatePhoneTimeSuggestion(phone1TimeSuggestion)
+            mScript.simulateTelephonyTimeSuggestion(slotIndex1TimeSuggestion)
                     .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
-                    .assertLatestPhoneSuggestion(phone1Id, phone1TimeSuggestion);
+                    .assertLatestTelephonySuggestion(slotIndex1, slotIndex1TimeSuggestion);
 
         }
 
         mScript.simulateTimePassing();
 
-        // Make another suggestion with phone2Id. It should be stored but not used because the
-        // phone1Id suggestion will still "win".
+        // Make another suggestion with slotIndex2. It should be stored but not used because the
+        // slotIndex1 suggestion will still "win".
         {
-            PhoneTimeSuggestion phone2TimeSuggestion =
-                    mScript.generatePhoneTimeSuggestion(phone2Id, phone2TimeMillis);
+            TelephonyTimeSuggestion slotIndex2TimeSuggestion =
+                    mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2TimeMillis);
             mScript.simulateTimePassing();
 
-            mScript.simulatePhoneTimeSuggestion(phone2TimeSuggestion)
+            mScript.simulateTelephonyTimeSuggestion(slotIndex2TimeSuggestion)
                     .verifySystemClockWasNotSetAndResetCallTracking()
-                    .assertLatestPhoneSuggestion(phone2Id, phone2TimeSuggestion);
+                    .assertLatestTelephonySuggestion(slotIndex2, slotIndex2TimeSuggestion);
         }
 
-        // Let enough time pass that phone1Id's suggestion should now be too old.
-        mScript.simulateTimePassing(TimeDetectorStrategyImpl.PHONE_BUCKET_SIZE_MILLIS);
+        // Let enough time pass that slotIndex1's suggestion should now be too old.
+        mScript.simulateTimePassing(TimeDetectorStrategyImpl.TELEPHONY_BUCKET_SIZE_MILLIS);
 
-        // Make another suggestion with phone2Id. It should be used because the phoneId1
+        // Make another suggestion with slotIndex2. It should be used because the slotIndex1
         // is in an older "bucket".
         {
-            PhoneTimeSuggestion phone2TimeSuggestion =
-                    mScript.generatePhoneTimeSuggestion(phone2Id, phone2TimeMillis);
+            TelephonyTimeSuggestion slotIndex2TimeSuggestion =
+                    mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2TimeMillis);
             mScript.simulateTimePassing();
 
             long expectedSystemClockMillis =
-                    mScript.calculateTimeInMillisForNow(phone2TimeSuggestion.getUtcTime());
+                    mScript.calculateTimeInMillisForNow(slotIndex2TimeSuggestion.getUtcTime());
 
-            mScript.simulatePhoneTimeSuggestion(phone2TimeSuggestion)
+            mScript.simulateTelephonyTimeSuggestion(slotIndex2TimeSuggestion)
                     .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
-                    .assertLatestPhoneSuggestion(phone2Id, phone2TimeSuggestion);
+                    .assertLatestTelephonySuggestion(slotIndex2, slotIndex2TimeSuggestion);
         }
     }
 
     @Test
-    public void testSuggestPhoneTime_autoTimeDisabled() {
+    public void testSuggestTelephonyTime_autoTimeDisabled() {
         mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
                 .pokeAutoTimeDetectionEnabled(false);
 
-        int phoneId = ARBITRARY_PHONE_ID;
-        PhoneTimeSuggestion timeSuggestion =
-                mScript.generatePhoneTimeSuggestion(phoneId, ARBITRARY_TEST_TIME_MILLIS);
+        int slotIndex = ARBITRARY_SLOT_INDEX;
+        TelephonyTimeSuggestion timeSuggestion =
+                mScript.generateTelephonyTimeSuggestion(slotIndex, ARBITRARY_TEST_TIME_MILLIS);
         mScript.simulateTimePassing()
-                .simulatePhoneTimeSuggestion(timeSuggestion)
+                .simulateTelephonyTimeSuggestion(timeSuggestion)
                 .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestPhoneSuggestion(phoneId, timeSuggestion);
+                .assertLatestTelephonySuggestion(slotIndex, timeSuggestion);
     }
 
     @Test
-    public void testSuggestPhoneTime_invalidNitzReferenceTimesIgnored() {
+    public void testSuggestTelephonyTime_invalidNitzReferenceTimesIgnored() {
         final int systemClockUpdateThreshold = 2000;
         mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
                 .pokeThresholds(systemClockUpdateThreshold)
                 .pokeAutoTimeDetectionEnabled(true);
 
         long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS;
-        int phoneId = ARBITRARY_PHONE_ID;
+        int slotIndex = ARBITRARY_SLOT_INDEX;
 
-        PhoneTimeSuggestion timeSuggestion1 =
-                mScript.generatePhoneTimeSuggestion(phoneId, testTimeMillis);
+        TelephonyTimeSuggestion timeSuggestion1 =
+                mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis);
         TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime();
 
-        // Initialize the strategy / device with a time set from a phone suggestion.
+        // Initialize the strategy / device with a time set from a telephony suggestion.
         mScript.simulateTimePassing();
         long expectedSystemClockMillis1 = mScript.calculateTimeInMillisForNow(utcTime1);
-        mScript.simulatePhoneTimeSuggestion(timeSuggestion1)
+        mScript.simulateTelephonyTimeSuggestion(timeSuggestion1)
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1)
-                .assertLatestPhoneSuggestion(phoneId, timeSuggestion1);
+                .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1);
 
         // The UTC time increment should be larger than the system clock update threshold so we
         // know it shouldn't be ignored for other reasons.
@@ -269,11 +269,11 @@
         long referenceTimeBeforeLastSignalMillis = utcTime1.getReferenceTimeMillis() - 1;
         TimestampedValue<Long> utcTime2 = new TimestampedValue<>(
                 referenceTimeBeforeLastSignalMillis, validUtcTimeMillis);
-        PhoneTimeSuggestion timeSuggestion2 =
-                createPhoneTimeSuggestion(phoneId, utcTime2);
-        mScript.simulatePhoneTimeSuggestion(timeSuggestion2)
+        TelephonyTimeSuggestion timeSuggestion2 =
+                createTelephonyTimeSuggestion(slotIndex, utcTime2);
+        mScript.simulateTelephonyTimeSuggestion(timeSuggestion2)
                 .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestPhoneSuggestion(phoneId, timeSuggestion1);
+                .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1);
 
         // Now supply a new signal that has an obviously bogus reference time : substantially in the
         // future.
@@ -281,36 +281,36 @@
                 utcTime1.getReferenceTimeMillis() + Integer.MAX_VALUE + 1;
         TimestampedValue<Long> utcTime3 = new TimestampedValue<>(
                 referenceTimeInFutureMillis, validUtcTimeMillis);
-        PhoneTimeSuggestion timeSuggestion3 =
-                createPhoneTimeSuggestion(phoneId, utcTime3);
-        mScript.simulatePhoneTimeSuggestion(timeSuggestion3)
+        TelephonyTimeSuggestion timeSuggestion3 =
+                createTelephonyTimeSuggestion(slotIndex, utcTime3);
+        mScript.simulateTelephonyTimeSuggestion(timeSuggestion3)
                 .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestPhoneSuggestion(phoneId, timeSuggestion1);
+                .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1);
 
         // Just to prove validUtcTimeMillis is valid.
         long validReferenceTimeMillis = utcTime1.getReferenceTimeMillis() + 100;
         TimestampedValue<Long> utcTime4 = new TimestampedValue<>(
                 validReferenceTimeMillis, validUtcTimeMillis);
         long expectedSystemClockMillis4 = mScript.calculateTimeInMillisForNow(utcTime4);
-        PhoneTimeSuggestion timeSuggestion4 =
-                createPhoneTimeSuggestion(phoneId, utcTime4);
-        mScript.simulatePhoneTimeSuggestion(timeSuggestion4)
+        TelephonyTimeSuggestion timeSuggestion4 =
+                createTelephonyTimeSuggestion(slotIndex, utcTime4);
+        mScript.simulateTelephonyTimeSuggestion(timeSuggestion4)
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis4)
-                .assertLatestPhoneSuggestion(phoneId, timeSuggestion4);
+                .assertLatestTelephonySuggestion(slotIndex, timeSuggestion4);
     }
 
     @Test
-    public void testSuggestPhoneTime_timeDetectionToggled() {
+    public void testSuggestTelephonyTime_timeDetectionToggled() {
         final int clockIncrementMillis = 100;
         final int systemClockUpdateThreshold = 2000;
         mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
                 .pokeThresholds(systemClockUpdateThreshold)
                 .pokeAutoTimeDetectionEnabled(false);
 
-        int phoneId = ARBITRARY_PHONE_ID;
+        int slotIndex = ARBITRARY_SLOT_INDEX;
         long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS;
-        PhoneTimeSuggestion timeSuggestion1 =
-                mScript.generatePhoneTimeSuggestion(phoneId, testTimeMillis);
+        TelephonyTimeSuggestion timeSuggestion1 =
+                mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis);
         TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime();
 
         // Simulate time passing.
@@ -318,9 +318,9 @@
 
         // Simulate the time signal being received. It should not be used because auto time
         // detection is off but it should be recorded.
-        mScript.simulatePhoneTimeSuggestion(timeSuggestion1)
+        mScript.simulateTelephonyTimeSuggestion(timeSuggestion1)
                 .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestPhoneSuggestion(phoneId, timeSuggestion1);
+                .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1);
 
         // Simulate more time passing.
         mScript.simulateTimePassing(clockIncrementMillis);
@@ -330,17 +330,17 @@
         // Turn on auto time detection.
         mScript.simulateAutoTimeDetectionToggle()
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1)
-                .assertLatestPhoneSuggestion(phoneId, timeSuggestion1);
+                .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1);
 
         // Turn off auto time detection.
         mScript.simulateAutoTimeDetectionToggle()
                 .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestPhoneSuggestion(phoneId, timeSuggestion1);
+                .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1);
 
         // Receive another valid time signal.
         // It should be on the threshold and accounting for the clock increments.
-        PhoneTimeSuggestion timeSuggestion2 = mScript.generatePhoneTimeSuggestion(
-                phoneId, mScript.peekSystemClockMillis() + systemClockUpdateThreshold);
+        TelephonyTimeSuggestion timeSuggestion2 = mScript.generateTelephonyTimeSuggestion(
+                slotIndex, mScript.peekSystemClockMillis() + systemClockUpdateThreshold);
 
         // Simulate more time passing.
         mScript.simulateTimePassing(clockIncrementMillis);
@@ -350,45 +350,45 @@
 
         // The new time, though valid, should not be set in the system clock because auto time is
         // disabled.
-        mScript.simulatePhoneTimeSuggestion(timeSuggestion2)
+        mScript.simulateTelephonyTimeSuggestion(timeSuggestion2)
                 .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestPhoneSuggestion(phoneId, timeSuggestion2);
+                .assertLatestTelephonySuggestion(slotIndex, timeSuggestion2);
 
         // Turn on auto time detection.
         mScript.simulateAutoTimeDetectionToggle()
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis2)
-                .assertLatestPhoneSuggestion(phoneId, timeSuggestion2);
+                .assertLatestTelephonySuggestion(slotIndex, timeSuggestion2);
     }
 
     @Test
-    public void testSuggestPhoneTime_maxSuggestionAge() {
+    public void testSuggestTelephonyTime_maxSuggestionAge() {
         mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
                 .pokeAutoTimeDetectionEnabled(true);
 
-        int phoneId = ARBITRARY_PHONE_ID;
+        int slotIndex = ARBITRARY_SLOT_INDEX;
         long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS;
-        PhoneTimeSuggestion phoneSuggestion =
-                mScript.generatePhoneTimeSuggestion(phoneId, testTimeMillis);
+        TelephonyTimeSuggestion telephonySuggestion =
+                mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis);
 
         mScript.simulateTimePassing();
 
         long expectedSystemClockMillis =
-                mScript.calculateTimeInMillisForNow(phoneSuggestion.getUtcTime());
-        mScript.simulatePhoneTimeSuggestion(phoneSuggestion)
+                mScript.calculateTimeInMillisForNow(telephonySuggestion.getUtcTime());
+        mScript.simulateTelephonyTimeSuggestion(telephonySuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(
                         expectedSystemClockMillis  /* expectedNetworkBroadcast */)
-                .assertLatestPhoneSuggestion(phoneId, phoneSuggestion);
+                .assertLatestTelephonySuggestion(slotIndex, telephonySuggestion);
 
-        // Look inside and check what the strategy considers the current best phone suggestion.
-        assertEquals(phoneSuggestion, mScript.peekBestPhoneSuggestion());
+        // Look inside and check what the strategy considers the current best telephony suggestion.
+        assertEquals(telephonySuggestion, mScript.peekBestTelephonySuggestion());
 
-        // Simulate time passing, long enough that phoneSuggestion is now too old.
+        // Simulate time passing, long enough that telephonySuggestion is now too old.
         mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS);
 
-        // Look inside and check what the strategy considers the current best phone suggestion. It
-        // should still be the, it's just no longer used.
-        assertNull(mScript.peekBestPhoneSuggestion());
-        mScript.assertLatestPhoneSuggestion(phoneId, phoneSuggestion);
+        // Look inside and check what the strategy considers the current best telephony suggestion.
+        // It should still be the, it's just no longer used.
+        assertNull(mScript.peekBestTelephonySuggestion());
+        mScript.assertLatestTelephonySuggestion(slotIndex, telephonySuggestion);
     }
 
     @Test
@@ -413,21 +413,21 @@
         mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
                 .pokeAutoTimeDetectionEnabled(true);
 
-        int phoneId = ARBITRARY_PHONE_ID;
+        int slotIndex = ARBITRARY_SLOT_INDEX;
 
-        // Simulate a phone suggestion.
+        // Simulate a telephony suggestion.
         long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS;
-        PhoneTimeSuggestion phoneTimeSuggestion =
-                mScript.generatePhoneTimeSuggestion(phoneId, testTimeMillis);
+        TelephonyTimeSuggestion telephonyTimeSuggestion =
+                mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis);
 
         // Simulate the passage of time.
         mScript.simulateTimePassing();
 
         long expectedAutoClockMillis =
-                mScript.calculateTimeInMillisForNow(phoneTimeSuggestion.getUtcTime());
-        mScript.simulatePhoneTimeSuggestion(phoneTimeSuggestion)
+                mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUtcTime());
+        mScript.simulateTelephonyTimeSuggestion(telephonyTimeSuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(expectedAutoClockMillis)
-                .assertLatestPhoneSuggestion(phoneId, phoneTimeSuggestion);
+                .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion);
 
         // Simulate the passage of time.
         mScript.simulateTimePassing();
@@ -435,7 +435,7 @@
         // Switch to manual.
         mScript.simulateAutoTimeDetectionToggle()
                 .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestPhoneSuggestion(phoneId, phoneTimeSuggestion);
+                .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion);
 
         // Simulate the passage of time.
         mScript.simulateTimePassing();
@@ -450,7 +450,7 @@
                 mScript.calculateTimeInMillisForNow(manualTimeSuggestion.getUtcTime());
         mScript.simulateManualTimeSuggestion(manualTimeSuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(expectedManualClockMillis)
-                .assertLatestPhoneSuggestion(phoneId, phoneTimeSuggestion);
+                .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion);
 
         // Simulate the passage of time.
         mScript.simulateTimePassing();
@@ -459,14 +459,14 @@
         mScript.simulateAutoTimeDetectionToggle();
 
         expectedAutoClockMillis =
-                mScript.calculateTimeInMillisForNow(phoneTimeSuggestion.getUtcTime());
+                mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUtcTime());
         mScript.verifySystemClockWasSetAndResetCallTracking(expectedAutoClockMillis)
-                .assertLatestPhoneSuggestion(phoneId, phoneTimeSuggestion);
+                .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion);
 
         // Switch back to manual - nothing should happen to the clock.
         mScript.simulateAutoTimeDetectionToggle()
                 .verifySystemClockWasNotSetAndResetCallTracking()
-                .assertLatestPhoneSuggestion(phoneId, phoneTimeSuggestion);
+                .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion);
     }
 
     /**
@@ -515,19 +515,19 @@
     }
 
     @Test
-    public void testSuggestNetworkTime_phoneSuggestionsBeatNetworkSuggestions() {
+    public void testSuggestNetworkTime_telephonySuggestionsBeatNetworkSuggestions() {
         mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
                 .pokeAutoTimeDetectionEnabled(true);
 
         // Three obviously different times that could not be mistaken for each other.
         long networkTimeMillis1 = ARBITRARY_TEST_TIME_MILLIS;
         long networkTimeMillis2 = ARBITRARY_TEST_TIME_MILLIS + Duration.ofDays(30).toMillis();
-        long phoneTimeMillis = ARBITRARY_TEST_TIME_MILLIS + Duration.ofDays(60).toMillis();
+        long telephonyTimeMillis = ARBITRARY_TEST_TIME_MILLIS + Duration.ofDays(60).toMillis();
         // A small increment used to simulate the passage of time, but not enough to interfere with
         // macro-level time changes associated with suggestion age.
         final long smallTimeIncrementMillis = 101;
 
-        // A network suggestion is made. It should be used because there is no phone suggestion.
+        // A network suggestion is made. It should be used because there is no telephony suggestion.
         NetworkTimeSuggestion networkTimeSuggestion1 =
                 mScript.generateNetworkTimeSuggestion(networkTimeMillis1);
         mScript.simulateTimePassing(smallTimeIncrementMillis)
@@ -536,37 +536,37 @@
                         mScript.calculateTimeInMillisForNow(networkTimeSuggestion1.getUtcTime()));
 
         // Check internal state.
-        mScript.assertLatestPhoneSuggestion(ARBITRARY_PHONE_ID, null)
+        mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, null)
                 .assertLatestNetworkSuggestion(networkTimeSuggestion1);
         assertEquals(networkTimeSuggestion1, mScript.peekLatestValidNetworkSuggestion());
-        assertNull(mScript.peekBestPhoneSuggestion());
+        assertNull(mScript.peekBestTelephonySuggestion());
 
         // Simulate a little time passing.
         mScript.simulateTimePassing(smallTimeIncrementMillis)
                 .verifySystemClockWasNotSetAndResetCallTracking();
 
-        // Now a phone suggestion is made. Phone suggestions are prioritized over network
+        // Now a telephony suggestion is made. Telephony suggestions are prioritized over network
         // suggestions so it should "win".
-        PhoneTimeSuggestion phoneTimeSuggestion =
-                mScript.generatePhoneTimeSuggestion(ARBITRARY_PHONE_ID, phoneTimeMillis);
+        TelephonyTimeSuggestion telephonyTimeSuggestion =
+                mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeMillis);
         mScript.simulateTimePassing(smallTimeIncrementMillis)
-                .simulatePhoneTimeSuggestion(phoneTimeSuggestion)
+                .simulateTelephonyTimeSuggestion(telephonyTimeSuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(
-                        mScript.calculateTimeInMillisForNow(phoneTimeSuggestion.getUtcTime()));
+                        mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUtcTime()));
 
         // Check internal state.
-        mScript.assertLatestPhoneSuggestion(ARBITRARY_PHONE_ID, phoneTimeSuggestion)
+        mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
                 .assertLatestNetworkSuggestion(networkTimeSuggestion1);
         assertEquals(networkTimeSuggestion1, mScript.peekLatestValidNetworkSuggestion());
-        assertEquals(phoneTimeSuggestion, mScript.peekBestPhoneSuggestion());
+        assertEquals(telephonyTimeSuggestion, mScript.peekBestTelephonySuggestion());
 
         // Simulate some significant time passing: half the time allowed before a time signal
         // becomes "too old to use".
         mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2)
                 .verifySystemClockWasNotSetAndResetCallTracking();
 
-        // Now another network suggestion is made. Phone suggestions are prioritized over network
-        // suggestions so the latest phone suggestion should still "win".
+        // Now another network suggestion is made. Telephony suggestions are prioritized over
+        // network suggestions so the latest telephony suggestion should still "win".
         NetworkTimeSuggestion networkTimeSuggestion2 =
                 mScript.generateNetworkTimeSuggestion(networkTimeMillis2);
         mScript.simulateTimePassing(smallTimeIncrementMillis)
@@ -574,14 +574,14 @@
                 .verifySystemClockWasNotSetAndResetCallTracking();
 
         // Check internal state.
-        mScript.assertLatestPhoneSuggestion(ARBITRARY_PHONE_ID, phoneTimeSuggestion)
+        mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
                 .assertLatestNetworkSuggestion(networkTimeSuggestion2);
         assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion());
-        assertEquals(phoneTimeSuggestion, mScript.peekBestPhoneSuggestion());
+        assertEquals(telephonyTimeSuggestion, mScript.peekBestTelephonySuggestion());
 
         // Simulate some significant time passing: half the time allowed before a time signal
-        // becomes "too old to use". This should mean that phoneTimeSuggestion is now too old to be
-        // used but networkTimeSuggestion2 is not.
+        // becomes "too old to use". This should mean that telephonyTimeSuggestion is now too old to
+        // be used but networkTimeSuggestion2 is not.
         mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2);
 
         // NOTE: The TimeDetectorStrategyImpl doesn't set an alarm for the point when the last
@@ -591,10 +591,10 @@
         mScript.verifySystemClockWasNotSetAndResetCallTracking();
 
         // Check internal state.
-        mScript.assertLatestPhoneSuggestion(ARBITRARY_PHONE_ID, phoneTimeSuggestion)
+        mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
                 .assertLatestNetworkSuggestion(networkTimeSuggestion2);
         assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion());
-        assertNull(mScript.peekBestPhoneSuggestion());
+        assertNull(mScript.peekBestTelephonySuggestion());
 
         // Toggle auto-time off and on to force the detection logic to run.
         mScript.simulateAutoTimeDetectionToggle()
@@ -606,10 +606,10 @@
                 mScript.calculateTimeInMillisForNow(networkTimeSuggestion2.getUtcTime()));
 
         // Check internal state.
-        mScript.assertLatestPhoneSuggestion(ARBITRARY_PHONE_ID, phoneTimeSuggestion)
+        mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
                 .assertLatestNetworkSuggestion(networkTimeSuggestion2);
         assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion());
-        assertNull(mScript.peekBestPhoneSuggestion());
+        assertNull(mScript.peekBestTelephonySuggestion());
     }
 
     /**
@@ -760,8 +760,8 @@
             return mFakeCallback.peekSystemClockMillis();
         }
 
-        Script simulatePhoneTimeSuggestion(PhoneTimeSuggestion timeSuggestion) {
-            mTimeDetectorStrategy.suggestPhoneTime(timeSuggestion);
+        Script simulateTelephonyTimeSuggestion(TelephonyTimeSuggestion timeSuggestion) {
+            mTimeDetectorStrategy.suggestTelephonyTime(timeSuggestion);
             return this;
         }
 
@@ -806,10 +806,10 @@
         }
 
         /**
-         * White box test info: Asserts the latest suggestion for the phone ID is as expected.
+         * White box test info: Asserts the latest suggestion for the slotIndex is as expected.
          */
-        Script assertLatestPhoneSuggestion(int phoneId, PhoneTimeSuggestion expected) {
-            assertEquals(expected, mTimeDetectorStrategy.getLatestPhoneSuggestion(phoneId));
+        Script assertLatestTelephonySuggestion(int slotIndex, TelephonyTimeSuggestion expected) {
+            assertEquals(expected, mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex));
             return this;
         }
 
@@ -822,11 +822,11 @@
         }
 
         /**
-         * White box test info: Returns the phone suggestion that would be used, if any, given the
-         * current elapsed real time clock and regardless of origin prioritization.
+         * White box test info: Returns the telephony suggestion that would be used, if any, given
+         * the current elapsed real time clock and regardless of origin prioritization.
          */
-        PhoneTimeSuggestion peekBestPhoneSuggestion() {
-            return mTimeDetectorStrategy.findBestPhoneSuggestionForTests();
+        TelephonyTimeSuggestion peekBestTelephonySuggestion() {
+            return mTimeDetectorStrategy.findBestTelephonySuggestionForTests();
         }
 
         /**
@@ -848,15 +848,15 @@
         }
 
         /**
-         * Generates a PhoneTimeSuggestion using the current elapsed realtime clock for the
-         * reference time.
+         * Generates a {@link TelephonyTimeSuggestion} using the current elapsed realtime clock for
+         * the reference time.
          */
-        PhoneTimeSuggestion generatePhoneTimeSuggestion(int phoneId, Long timeMillis) {
+        TelephonyTimeSuggestion generateTelephonyTimeSuggestion(int slotIndex, Long timeMillis) {
             TimestampedValue<Long> time = null;
             if (timeMillis != null) {
                 time = new TimestampedValue<>(peekElapsedRealtimeMillis(), timeMillis);
             }
-            return createPhoneTimeSuggestion(phoneId, time);
+            return createTelephonyTimeSuggestion(slotIndex, time);
         }
 
         /**
@@ -878,9 +878,9 @@
         }
     }
 
-    private static PhoneTimeSuggestion createPhoneTimeSuggestion(int phoneId,
+    private static TelephonyTimeSuggestion createTelephonyTimeSuggestion(int slotIndex,
             TimestampedValue<Long> utcTime) {
-        return new PhoneTimeSuggestion.Builder(phoneId)
+        return new TelephonyTimeSuggestion.Builder(slotIndex)
                 .setUtcTime(utcTime)
                 .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 3e7d40a..039c2b4 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
@@ -29,7 +29,7 @@
 import static org.mockito.Mockito.when;
 
 import android.app.timezonedetector.ManualTimeZoneSuggestion;
-import android.app.timezonedetector.PhoneTimeZoneSuggestion;
+import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.HandlerThread;
@@ -76,35 +76,35 @@
     }
 
     @Test(expected = SecurityException.class)
-    public void testSuggestPhoneTime_withoutPermission() {
+    public void testSuggestTelephonyTime_withoutPermission() {
         doThrow(new SecurityException("Mock"))
                 .when(mMockContext).enforceCallingPermission(anyString(), any());
-        PhoneTimeZoneSuggestion timeZoneSuggestion = createPhoneTimeZoneSuggestion();
+        TelephonyTimeZoneSuggestion timeZoneSuggestion = createTelephonyTimeZoneSuggestion();
 
         try {
-            mTimeZoneDetectorService.suggestPhoneTimeZone(timeZoneSuggestion);
+            mTimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion);
             fail();
         } finally {
             verify(mMockContext).enforceCallingPermission(
-                    eq(android.Manifest.permission.SUGGEST_PHONE_TIME_AND_ZONE),
+                    eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE),
                     anyString());
         }
     }
 
     @Test
-    public void testSuggestPhoneTimeZone() throws Exception {
+    public void testSuggestTelephonyTimeZone() throws Exception {
         doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
 
-        PhoneTimeZoneSuggestion timeZoneSuggestion = createPhoneTimeZoneSuggestion();
-        mTimeZoneDetectorService.suggestPhoneTimeZone(timeZoneSuggestion);
+        TelephonyTimeZoneSuggestion timeZoneSuggestion = createTelephonyTimeZoneSuggestion();
+        mTimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion);
         mTestHandler.assertTotalMessagesEnqueued(1);
 
         verify(mMockContext).enforceCallingPermission(
-                eq(android.Manifest.permission.SUGGEST_PHONE_TIME_AND_ZONE),
+                eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE),
                 anyString());
 
         mTestHandler.waitForMessagesToBeProcessed();
-        mStubbedTimeZoneDetectorStrategy.verifySuggestPhoneTimeZoneCalled(timeZoneSuggestion);
+        mStubbedTimeZoneDetectorStrategy.verifySuggestTelephonyTimeZoneCalled(timeZoneSuggestion);
     }
 
     @Test(expected = SecurityException.class)
@@ -165,12 +165,12 @@
         mStubbedTimeZoneDetectorStrategy.verifyHandleAutoTimeZoneDetectionChangedCalled();
     }
 
-    private static PhoneTimeZoneSuggestion createPhoneTimeZoneSuggestion() {
+    private static TelephonyTimeZoneSuggestion createTelephonyTimeZoneSuggestion() {
         int slotIndex = 1234;
-        return new PhoneTimeZoneSuggestion.Builder(slotIndex)
+        return new TelephonyTimeZoneSuggestion.Builder(slotIndex)
                 .setZoneId("TestZoneId")
-                .setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET)
-                .setQuality(PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE)
+                .setMatchType(TelephonyTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET)
+                .setQuality(TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE)
                 .build();
     }
 
@@ -181,14 +181,14 @@
     private static class StubbedTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
 
         // Call tracking.
-        private PhoneTimeZoneSuggestion mLastPhoneSuggestion;
+        private TelephonyTimeZoneSuggestion mLastTelephonySuggestion;
         private ManualTimeZoneSuggestion mLastManualSuggestion;
         private boolean mHandleAutoTimeZoneDetectionChangedCalled;
         private boolean mDumpCalled;
 
         @Override
-        public void suggestPhoneTimeZone(PhoneTimeZoneSuggestion timeZoneSuggestion) {
-            mLastPhoneSuggestion = timeZoneSuggestion;
+        public void suggestTelephonyTimeZone(TelephonyTimeZoneSuggestion timeZoneSuggestion) {
+            mLastTelephonySuggestion = timeZoneSuggestion;
         }
 
         @Override
@@ -207,14 +207,14 @@
         }
 
         void resetCallTracking() {
-            mLastPhoneSuggestion = null;
+            mLastTelephonySuggestion = null;
             mLastManualSuggestion = null;
             mHandleAutoTimeZoneDetectionChangedCalled = false;
             mDumpCalled = false;
         }
 
-        void verifySuggestPhoneTimeZoneCalled(PhoneTimeZoneSuggestion expectedSuggestion) {
-            assertEquals(expectedSuggestion, mLastPhoneSuggestion);
+        void verifySuggestTelephonyTimeZoneCalled(TelephonyTimeZoneSuggestion expectedSuggestion) {
+            assertEquals(expectedSuggestion, mLastTelephonySuggestion);
         }
 
         public void verifySuggestManualTimeZoneCalled(ManualTimeZoneSuggestion expectedSuggestion) {
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 1e38711..ba30967 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
@@ -16,20 +16,20 @@
 
 package com.android.server.timezonedetector;
 
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID;
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET;
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY;
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY;
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS;
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
-import static android.app.timezonedetector.PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
+import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE;
 
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.PHONE_SCORE_HIGH;
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.PHONE_SCORE_HIGHEST;
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.PHONE_SCORE_LOW;
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.PHONE_SCORE_MEDIUM;
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.PHONE_SCORE_NONE;
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.PHONE_SCORE_USAGE_THRESHOLD;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.TELEPHONY_SCORE_HIGH;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.TELEPHONY_SCORE_HIGHEST;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.TELEPHONY_SCORE_LOW;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.TELEPHONY_SCORE_MEDIUM;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.TELEPHONY_SCORE_NONE;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.TELEPHONY_SCORE_USAGE_THRESHOLD;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -37,11 +37,11 @@
 import static org.junit.Assert.assertTrue;
 
 import android.app.timezonedetector.ManualTimeZoneSuggestion;
-import android.app.timezonedetector.PhoneTimeZoneSuggestion;
-import android.app.timezonedetector.PhoneTimeZoneSuggestion.MatchType;
-import android.app.timezonedetector.PhoneTimeZoneSuggestion.Quality;
+import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
+import android.app.timezonedetector.TelephonyTimeZoneSuggestion.MatchType;
+import android.app.timezonedetector.TelephonyTimeZoneSuggestion.Quality;
 
-import com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.QualifiedPhoneTimeZoneSuggestion;
+import com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.QualifiedTelephonyTimeZoneSuggestion;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,24 +58,24 @@
 
     /** A time zone used for initialization that does not occur elsewhere in tests. */
     private static final String ARBITRARY_TIME_ZONE_ID = "Etc/UTC";
-    private static final int PHONE1_ID = 10000;
-    private static final int PHONE2_ID = 20000;
+    private static final int SLOT_INDEX1 = 10000;
+    private static final int SLOT_INDEX2 = 20000;
 
     // Suggestion test cases are ordered so that each successive one is of the same or higher score
     // than the previous.
     private static final SuggestionTestCase[] TEST_CASES = new SuggestionTestCase[] {
             newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY,
-                    QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS, PHONE_SCORE_LOW),
+                    QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS, TELEPHONY_SCORE_LOW),
             newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY, QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET,
-                    PHONE_SCORE_MEDIUM),
+                    TELEPHONY_SCORE_MEDIUM),
             newTestCase(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET,
-                    QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, PHONE_SCORE_MEDIUM),
-            newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY, QUALITY_SINGLE_ZONE, PHONE_SCORE_HIGH),
+                    QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, TELEPHONY_SCORE_MEDIUM),
+            newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY, QUALITY_SINGLE_ZONE, TELEPHONY_SCORE_HIGH),
             newTestCase(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, QUALITY_SINGLE_ZONE,
-                    PHONE_SCORE_HIGH),
+                    TELEPHONY_SCORE_HIGH),
             newTestCase(MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY,
-                    QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, PHONE_SCORE_HIGHEST),
-            newTestCase(MATCH_TYPE_EMULATOR_ZONE_ID, QUALITY_SINGLE_ZONE, PHONE_SCORE_HIGHEST),
+                    QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, TELEPHONY_SCORE_HIGHEST),
+            newTestCase(MATCH_TYPE_EMULATOR_ZONE_ID, QUALITY_SINGLE_ZONE, TELEPHONY_SCORE_HIGHEST),
     };
 
     private TimeZoneDetectorStrategyImpl mTimeZoneDetectorStrategy;
@@ -89,76 +89,82 @@
     }
 
     @Test
-    public void testEmptyPhoneSuggestions() {
-        PhoneTimeZoneSuggestion phone1TimeZoneSuggestion = createEmptyPhone1Suggestion();
-        PhoneTimeZoneSuggestion phone2TimeZoneSuggestion = createEmptyPhone2Suggestion();
+    public void testEmptyTelephonySuggestions() {
+        TelephonyTimeZoneSuggestion slotIndex1TimeZoneSuggestion =
+                createEmptySlotIndex1Suggestion();
+        TelephonyTimeZoneSuggestion slotIndex2TimeZoneSuggestion =
+                createEmptySlotIndex2Suggestion();
         Script script = new Script()
                 .initializeAutoTimeZoneDetection(true)
                 .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
 
-        script.suggestPhoneTimeZone(phone1TimeZoneSuggestion)
+        script.suggestTelephonyTimeZone(slotIndex1TimeZoneSuggestion)
                 .verifyTimeZoneNotSet();
 
         // Assert internal service state.
-        QualifiedPhoneTimeZoneSuggestion expectedPhone1ScoredSuggestion =
-                new QualifiedPhoneTimeZoneSuggestion(phone1TimeZoneSuggestion, PHONE_SCORE_NONE);
-        assertEquals(expectedPhone1ScoredSuggestion,
-                mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
-        assertNull(mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE2_ID));
-        assertEquals(expectedPhone1ScoredSuggestion,
-                mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
+        QualifiedTelephonyTimeZoneSuggestion expectedSlotIndex1ScoredSuggestion =
+                new QualifiedTelephonyTimeZoneSuggestion(slotIndex1TimeZoneSuggestion,
+                        TELEPHONY_SCORE_NONE);
+        assertEquals(expectedSlotIndex1ScoredSuggestion,
+                mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
+        assertNull(mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX2));
+        assertEquals(expectedSlotIndex1ScoredSuggestion,
+                mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
 
-        script.suggestPhoneTimeZone(phone2TimeZoneSuggestion)
+        script.suggestTelephonyTimeZone(slotIndex2TimeZoneSuggestion)
                 .verifyTimeZoneNotSet();
 
         // Assert internal service state.
-        QualifiedPhoneTimeZoneSuggestion expectedPhone2ScoredSuggestion =
-                new QualifiedPhoneTimeZoneSuggestion(phone2TimeZoneSuggestion, PHONE_SCORE_NONE);
-        assertEquals(expectedPhone1ScoredSuggestion,
-                mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
-        assertEquals(expectedPhone2ScoredSuggestion,
-                mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE2_ID));
-        // Phone 1 should always beat phone 2, all other things being equal.
-        assertEquals(expectedPhone1ScoredSuggestion,
-                mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
+        QualifiedTelephonyTimeZoneSuggestion expectedSlotIndex2ScoredSuggestion =
+                new QualifiedTelephonyTimeZoneSuggestion(slotIndex2TimeZoneSuggestion,
+                        TELEPHONY_SCORE_NONE);
+        assertEquals(expectedSlotIndex1ScoredSuggestion,
+                mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
+        assertEquals(expectedSlotIndex2ScoredSuggestion,
+                mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX2));
+        // SlotIndex1 should always beat slotIndex2, all other things being equal.
+        assertEquals(expectedSlotIndex1ScoredSuggestion,
+                mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
     }
 
     @Test
-    public void testFirstPlausiblePhoneSuggestionAcceptedWhenTimeZoneUninitialized() {
+    public void testFirstPlausibleTelephonySuggestionAcceptedWhenTimeZoneUninitialized() {
         SuggestionTestCase testCase = newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY,
-                QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS, PHONE_SCORE_LOW);
-        PhoneTimeZoneSuggestion lowQualitySuggestion =
-                testCase.createSuggestion(PHONE1_ID, "America/New_York");
+                QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS, TELEPHONY_SCORE_LOW);
+        TelephonyTimeZoneSuggestion lowQualitySuggestion =
+                testCase.createSuggestion(SLOT_INDEX1, "America/New_York");
 
         // The device time zone setting is left uninitialized.
         Script script = new Script()
                 .initializeAutoTimeZoneDetection(true);
 
         // The very first suggestion will be taken.
-        script.suggestPhoneTimeZone(lowQualitySuggestion)
+        script.suggestTelephonyTimeZone(lowQualitySuggestion)
                 .verifyTimeZoneSetAndReset(lowQualitySuggestion);
 
         // Assert internal service state.
-        QualifiedPhoneTimeZoneSuggestion expectedScoredSuggestion =
-                new QualifiedPhoneTimeZoneSuggestion(lowQualitySuggestion, testCase.expectedScore);
+        QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion =
+                new QualifiedTelephonyTimeZoneSuggestion(
+                        lowQualitySuggestion, testCase.expectedScore);
         assertEquals(expectedScoredSuggestion,
-                mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
+                mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
         assertEquals(expectedScoredSuggestion,
-                mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
+                mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
 
         // Another low quality suggestion will be ignored now that the setting is initialized.
-        PhoneTimeZoneSuggestion lowQualitySuggestion2 =
-                testCase.createSuggestion(PHONE1_ID, "America/Los_Angeles");
-        script.suggestPhoneTimeZone(lowQualitySuggestion2)
+        TelephonyTimeZoneSuggestion lowQualitySuggestion2 =
+                testCase.createSuggestion(SLOT_INDEX1, "America/Los_Angeles");
+        script.suggestTelephonyTimeZone(lowQualitySuggestion2)
                 .verifyTimeZoneNotSet();
 
         // Assert internal service state.
-        QualifiedPhoneTimeZoneSuggestion expectedScoredSuggestion2 =
-                new QualifiedPhoneTimeZoneSuggestion(lowQualitySuggestion2, testCase.expectedScore);
+        QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion2 =
+                new QualifiedTelephonyTimeZoneSuggestion(
+                        lowQualitySuggestion2, testCase.expectedScore);
         assertEquals(expectedScoredSuggestion2,
-                mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
+                mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
         assertEquals(expectedScoredSuggestion2,
-                mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
+                mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
     }
 
     /**
@@ -174,28 +180,28 @@
             script.initializeAutoTimeZoneDetection(false)
                     .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
 
-            PhoneTimeZoneSuggestion suggestion =
-                    testCase.createSuggestion(PHONE1_ID, "Europe/London");
-            script.suggestPhoneTimeZone(suggestion);
+            TelephonyTimeZoneSuggestion suggestion =
+                    testCase.createSuggestion(SLOT_INDEX1, "Europe/London");
+            script.suggestTelephonyTimeZone(suggestion);
 
             // When time zone detection is not enabled, the time zone suggestion will not be set
             // regardless of the score.
             script.verifyTimeZoneNotSet();
 
             // Assert internal service state.
-            QualifiedPhoneTimeZoneSuggestion expectedScoredSuggestion =
-                    new QualifiedPhoneTimeZoneSuggestion(suggestion, testCase.expectedScore);
+            QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion =
+                    new QualifiedTelephonyTimeZoneSuggestion(suggestion, testCase.expectedScore);
             assertEquals(expectedScoredSuggestion,
-                    mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
             assertEquals(expectedScoredSuggestion,
-                    mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
+                    mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
 
             // Toggling the time zone setting on should cause the device setting to be set.
             script.autoTimeZoneDetectionEnabled(true);
 
             // When time zone detection is already enabled the suggestion (if it scores highly
             // enough) should be set immediately.
-            if (testCase.expectedScore >= PHONE_SCORE_USAGE_THRESHOLD) {
+            if (testCase.expectedScore >= TELEPHONY_SCORE_USAGE_THRESHOLD) {
                 script.verifyTimeZoneSetAndReset(suggestion);
             } else {
                 script.verifyTimeZoneNotSet();
@@ -203,9 +209,9 @@
 
             // Assert internal service state.
             assertEquals(expectedScoredSuggestion,
-                    mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
             assertEquals(expectedScoredSuggestion,
-                    mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
+                    mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
 
             // Toggling the time zone setting should off should do nothing.
             script.autoTimeZoneDetectionEnabled(false)
@@ -213,20 +219,20 @@
 
             // Assert internal service state.
             assertEquals(expectedScoredSuggestion,
-                    mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
             assertEquals(expectedScoredSuggestion,
-                    mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
+                    mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
         }
     }
 
     @Test
-    public void testPhoneSuggestionsSinglePhone() {
+    public void testTelephonySuggestionsSingleSlotId() {
         Script script = new Script()
                 .initializeAutoTimeZoneDetection(true)
                 .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
 
         for (SuggestionTestCase testCase : TEST_CASES) {
-            makePhone1SuggestionAndCheckState(script, testCase);
+            makeSlotIndex1SuggestionAndCheckState(script, testCase);
         }
 
         /*
@@ -241,125 +247,128 @@
         Collections.reverse(descendingCasesByScore);
 
         for (SuggestionTestCase testCase : descendingCasesByScore) {
-            makePhone1SuggestionAndCheckState(script, testCase);
+            makeSlotIndex1SuggestionAndCheckState(script, testCase);
         }
     }
 
-    private void makePhone1SuggestionAndCheckState(Script script, SuggestionTestCase testCase) {
+    private void makeSlotIndex1SuggestionAndCheckState(Script script, SuggestionTestCase testCase) {
         // Give the next suggestion a different zone from the currently set device time zone;
         String currentZoneId = mFakeTimeZoneDetectorStrategyCallback.getDeviceTimeZone();
         String suggestionZoneId =
                 "Europe/London".equals(currentZoneId) ? "Europe/Paris" : "Europe/London";
-        PhoneTimeZoneSuggestion zonePhone1Suggestion =
-                testCase.createSuggestion(PHONE1_ID, suggestionZoneId);
-        QualifiedPhoneTimeZoneSuggestion expectedZonePhone1ScoredSuggestion =
-                new QualifiedPhoneTimeZoneSuggestion(zonePhone1Suggestion, testCase.expectedScore);
+        TelephonyTimeZoneSuggestion zoneSlotIndex1Suggestion =
+                testCase.createSuggestion(SLOT_INDEX1, suggestionZoneId);
+        QualifiedTelephonyTimeZoneSuggestion expectedZoneSlotIndex1ScoredSuggestion =
+                new QualifiedTelephonyTimeZoneSuggestion(
+                        zoneSlotIndex1Suggestion, testCase.expectedScore);
 
-        script.suggestPhoneTimeZone(zonePhone1Suggestion);
-        if (testCase.expectedScore >= PHONE_SCORE_USAGE_THRESHOLD) {
-            script.verifyTimeZoneSetAndReset(zonePhone1Suggestion);
+        script.suggestTelephonyTimeZone(zoneSlotIndex1Suggestion);
+        if (testCase.expectedScore >= TELEPHONY_SCORE_USAGE_THRESHOLD) {
+            script.verifyTimeZoneSetAndReset(zoneSlotIndex1Suggestion);
         } else {
             script.verifyTimeZoneNotSet();
         }
 
         // Assert internal service state.
-        assertEquals(expectedZonePhone1ScoredSuggestion,
-                mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
-        assertEquals(expectedZonePhone1ScoredSuggestion,
-                mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
+        assertEquals(expectedZoneSlotIndex1ScoredSuggestion,
+                mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
+        assertEquals(expectedZoneSlotIndex1ScoredSuggestion,
+                mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
     }
 
     /**
-     * Tries a set of test cases to see if the phone with the lowest ID is given preference. This
-     * test also confirms that the time zone setting would only be set if a suggestion is of
-     * sufficient quality.
+     * Tries a set of test cases to see if the slotIndex with the lowest numeric value is given
+     * preference. This test also confirms that the time zone setting would only be set if a
+     * suggestion is of sufficient quality.
      */
     @Test
-    public void testMultiplePhoneSuggestionScoringAndPhoneIdBias() {
+    public void testMultipleSlotIndexSuggestionScoringAndSlotIndexBias() {
         String[] zoneIds = { "Europe/London", "Europe/Paris" };
-        PhoneTimeZoneSuggestion emptyPhone1Suggestion = createEmptyPhone1Suggestion();
-        PhoneTimeZoneSuggestion emptyPhone2Suggestion = createEmptyPhone2Suggestion();
-        QualifiedPhoneTimeZoneSuggestion expectedEmptyPhone1ScoredSuggestion =
-                new QualifiedPhoneTimeZoneSuggestion(emptyPhone1Suggestion, PHONE_SCORE_NONE);
-        QualifiedPhoneTimeZoneSuggestion expectedEmptyPhone2ScoredSuggestion =
-                new QualifiedPhoneTimeZoneSuggestion(emptyPhone2Suggestion, PHONE_SCORE_NONE);
+        TelephonyTimeZoneSuggestion emptySlotIndex1Suggestion = createEmptySlotIndex1Suggestion();
+        TelephonyTimeZoneSuggestion emptySlotIndex2Suggestion = createEmptySlotIndex2Suggestion();
+        QualifiedTelephonyTimeZoneSuggestion expectedEmptySlotIndex1ScoredSuggestion =
+                new QualifiedTelephonyTimeZoneSuggestion(emptySlotIndex1Suggestion,
+                        TELEPHONY_SCORE_NONE);
+        QualifiedTelephonyTimeZoneSuggestion expectedEmptySlotIndex2ScoredSuggestion =
+                new QualifiedTelephonyTimeZoneSuggestion(emptySlotIndex2Suggestion,
+                        TELEPHONY_SCORE_NONE);
 
         Script script = new Script()
                 .initializeAutoTimeZoneDetection(true)
                 .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID)
                 // Initialize the latest suggestions as empty so we don't need to worry about nulls
                 // below for the first loop.
-                .suggestPhoneTimeZone(emptyPhone1Suggestion)
-                .suggestPhoneTimeZone(emptyPhone2Suggestion)
+                .suggestTelephonyTimeZone(emptySlotIndex1Suggestion)
+                .suggestTelephonyTimeZone(emptySlotIndex2Suggestion)
                 .resetState();
 
         for (SuggestionTestCase testCase : TEST_CASES) {
-            PhoneTimeZoneSuggestion zonePhone1Suggestion =
-                    testCase.createSuggestion(PHONE1_ID, zoneIds[0]);
-            PhoneTimeZoneSuggestion zonePhone2Suggestion =
-                    testCase.createSuggestion(PHONE2_ID, zoneIds[1]);
-            QualifiedPhoneTimeZoneSuggestion expectedZonePhone1ScoredSuggestion =
-                    new QualifiedPhoneTimeZoneSuggestion(zonePhone1Suggestion,
+            TelephonyTimeZoneSuggestion zoneSlotIndex1Suggestion =
+                    testCase.createSuggestion(SLOT_INDEX1, zoneIds[0]);
+            TelephonyTimeZoneSuggestion zoneSlotIndex2Suggestion =
+                    testCase.createSuggestion(SLOT_INDEX2, zoneIds[1]);
+            QualifiedTelephonyTimeZoneSuggestion expectedZoneSlotIndex1ScoredSuggestion =
+                    new QualifiedTelephonyTimeZoneSuggestion(zoneSlotIndex1Suggestion,
                             testCase.expectedScore);
-            QualifiedPhoneTimeZoneSuggestion expectedZonePhone2ScoredSuggestion =
-                    new QualifiedPhoneTimeZoneSuggestion(zonePhone2Suggestion,
+            QualifiedTelephonyTimeZoneSuggestion expectedZoneSlotIndex2ScoredSuggestion =
+                    new QualifiedTelephonyTimeZoneSuggestion(zoneSlotIndex2Suggestion,
                             testCase.expectedScore);
 
-            // Start the test by making a suggestion for phone 1.
-            script.suggestPhoneTimeZone(zonePhone1Suggestion);
-            if (testCase.expectedScore >= PHONE_SCORE_USAGE_THRESHOLD) {
-                script.verifyTimeZoneSetAndReset(zonePhone1Suggestion);
+            // Start the test by making a suggestion for slotIndex1.
+            script.suggestTelephonyTimeZone(zoneSlotIndex1Suggestion);
+            if (testCase.expectedScore >= TELEPHONY_SCORE_USAGE_THRESHOLD) {
+                script.verifyTimeZoneSetAndReset(zoneSlotIndex1Suggestion);
             } else {
                 script.verifyTimeZoneNotSet();
             }
 
             // Assert internal service state.
-            assertEquals(expectedZonePhone1ScoredSuggestion,
-                    mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
-            assertEquals(expectedEmptyPhone2ScoredSuggestion,
-                    mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE2_ID));
-            assertEquals(expectedZonePhone1ScoredSuggestion,
-                    mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
+            assertEquals(expectedZoneSlotIndex1ScoredSuggestion,
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
+            assertEquals(expectedEmptySlotIndex2ScoredSuggestion,
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX2));
+            assertEquals(expectedZoneSlotIndex1ScoredSuggestion,
+                    mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
 
-            // Phone 2 then makes an alternative suggestion with an identical score. Phone 1's
+            // SlotIndex2 then makes an alternative suggestion with an identical score. SlotIndex1's
             // suggestion should still "win" if it is above the required threshold.
-            script.suggestPhoneTimeZone(zonePhone2Suggestion);
+            script.suggestTelephonyTimeZone(zoneSlotIndex2Suggestion);
             script.verifyTimeZoneNotSet();
 
             // Assert internal service state.
-            assertEquals(expectedZonePhone1ScoredSuggestion,
-                    mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
-            assertEquals(expectedZonePhone2ScoredSuggestion,
-                    mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE2_ID));
-            // Phone 1 should always beat phone 2, all other things being equal.
-            assertEquals(expectedZonePhone1ScoredSuggestion,
-                    mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
+            assertEquals(expectedZoneSlotIndex1ScoredSuggestion,
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
+            assertEquals(expectedZoneSlotIndex2ScoredSuggestion,
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX2));
+            // SlotIndex1 should always beat slotIndex2, all other things being equal.
+            assertEquals(expectedZoneSlotIndex1ScoredSuggestion,
+                    mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
 
-            // Withdrawing phone 1's suggestion should leave phone 2 as the new winner. Since the
-            // zoneId is different, the time zone setting should be updated if the score is high
+            // Withdrawing slotIndex1's suggestion should leave slotIndex2 as the new winner. Since
+            // the zoneId is different, the time zone setting should be updated if the score is high
             // enough.
-            script.suggestPhoneTimeZone(emptyPhone1Suggestion);
-            if (testCase.expectedScore >= PHONE_SCORE_USAGE_THRESHOLD) {
-                script.verifyTimeZoneSetAndReset(zonePhone2Suggestion);
+            script.suggestTelephonyTimeZone(emptySlotIndex1Suggestion);
+            if (testCase.expectedScore >= TELEPHONY_SCORE_USAGE_THRESHOLD) {
+                script.verifyTimeZoneSetAndReset(zoneSlotIndex2Suggestion);
             } else {
                 script.verifyTimeZoneNotSet();
             }
 
             // Assert internal service state.
-            assertEquals(expectedEmptyPhone1ScoredSuggestion,
-                    mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
-            assertEquals(expectedZonePhone2ScoredSuggestion,
-                    mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE2_ID));
-            assertEquals(expectedZonePhone2ScoredSuggestion,
-                    mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
+            assertEquals(expectedEmptySlotIndex1ScoredSuggestion,
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
+            assertEquals(expectedZoneSlotIndex2ScoredSuggestion,
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX2));
+            assertEquals(expectedZoneSlotIndex2ScoredSuggestion,
+                    mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
 
             // Reset the state for the next loop.
-            script.suggestPhoneTimeZone(emptyPhone2Suggestion)
+            script.suggestTelephonyTimeZone(emptySlotIndex2Suggestion)
                     .verifyTimeZoneNotSet();
-            assertEquals(expectedEmptyPhone1ScoredSuggestion,
-                    mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
-            assertEquals(expectedEmptyPhone2ScoredSuggestion,
-                    mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE2_ID));
+            assertEquals(expectedEmptySlotIndex1ScoredSuggestion,
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
+            assertEquals(expectedEmptySlotIndex2ScoredSuggestion,
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX2));
         }
     }
 
@@ -375,21 +384,21 @@
 
         SuggestionTestCase testCase =
                 newTestCase(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, QUALITY_SINGLE_ZONE,
-                        PHONE_SCORE_HIGH);
-        PhoneTimeZoneSuggestion losAngelesSuggestion =
-                testCase.createSuggestion(PHONE1_ID, "America/Los_Angeles");
-        PhoneTimeZoneSuggestion newYorkSuggestion =
-                testCase.createSuggestion(PHONE1_ID, "America/New_York");
+                        TELEPHONY_SCORE_HIGH);
+        TelephonyTimeZoneSuggestion losAngelesSuggestion =
+                testCase.createSuggestion(SLOT_INDEX1, "America/Los_Angeles");
+        TelephonyTimeZoneSuggestion newYorkSuggestion =
+                testCase.createSuggestion(SLOT_INDEX1, "America/New_York");
 
         // Initialization.
-        script.suggestPhoneTimeZone(losAngelesSuggestion)
+        script.suggestTelephonyTimeZone(losAngelesSuggestion)
                 .verifyTimeZoneSetAndReset(losAngelesSuggestion);
         // Suggest it again - it should not be set because it is already set.
-        script.suggestPhoneTimeZone(losAngelesSuggestion)
+        script.suggestTelephonyTimeZone(losAngelesSuggestion)
                 .verifyTimeZoneNotSet();
 
         // Toggling time zone detection should set the device time zone only if the current setting
-        // value is different from the most recent phone suggestion.
+        // value is different from the most recent telephony suggestion.
         script.autoTimeZoneDetectionEnabled(false)
                 .verifyTimeZoneNotSet()
                 .autoTimeZoneDetectionEnabled(true)
@@ -398,7 +407,7 @@
         // Simulate a user turning auto detection off, a new suggestion being made while auto
         // detection is off, and the user turning it on again.
         script.autoTimeZoneDetectionEnabled(false)
-                .suggestPhoneTimeZone(newYorkSuggestion)
+                .suggestTelephonyTimeZone(newYorkSuggestion)
                 .verifyTimeZoneNotSet();
         // Latest suggestion should be used.
         script.autoTimeZoneDetectionEnabled(true)
@@ -433,12 +442,12 @@
         return new ManualTimeZoneSuggestion(zoneId);
     }
 
-    private static PhoneTimeZoneSuggestion createEmptyPhone1Suggestion() {
-        return new PhoneTimeZoneSuggestion.Builder(PHONE1_ID).build();
+    private static TelephonyTimeZoneSuggestion createEmptySlotIndex1Suggestion() {
+        return new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX1).build();
     }
 
-    private static PhoneTimeZoneSuggestion createEmptyPhone2Suggestion() {
-        return new PhoneTimeZoneSuggestion.Builder(PHONE2_ID).build();
+    private static TelephonyTimeZoneSuggestion createEmptySlotIndex2Suggestion() {
+        return new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX2).build();
     }
 
     static class FakeTimeZoneDetectorStrategyCallback
@@ -565,9 +574,11 @@
             return this;
         }
 
-        /** Simulates the time zone detection strategy receiving a phone-originated suggestion. */
-        Script suggestPhoneTimeZone(PhoneTimeZoneSuggestion phoneTimeZoneSuggestion) {
-            mTimeZoneDetectorStrategy.suggestPhoneTimeZone(phoneTimeZoneSuggestion);
+        /**
+         * Simulates the time zone detection strategy receiving a telephony-originated suggestion.
+         */
+        Script suggestTelephonyTimeZone(TelephonyTimeZoneSuggestion timeZoneSuggestion) {
+            mTimeZoneDetectorStrategy.suggestTelephonyTimeZone(timeZoneSuggestion);
             return this;
         }
 
@@ -582,7 +593,7 @@
             return this;
         }
 
-        Script verifyTimeZoneSetAndReset(PhoneTimeZoneSuggestion suggestion) {
+        Script verifyTimeZoneSetAndReset(TelephonyTimeZoneSuggestion suggestion) {
             mFakeTimeZoneDetectorStrategyCallback.assertTimeZoneSet(suggestion.getZoneId());
             mFakeTimeZoneDetectorStrategyCallback.commitAllChanges();
             return this;
@@ -611,8 +622,8 @@
             this.expectedScore = expectedScore;
         }
 
-        private PhoneTimeZoneSuggestion createSuggestion(int phoneId, String zoneId) {
-            return new PhoneTimeZoneSuggestion.Builder(phoneId)
+        private TelephonyTimeZoneSuggestion createSuggestion(int slotIndex, String zoneId) {
+            return new TelephonyTimeZoneSuggestion.Builder(slotIndex)
                     .setZoneId(zoneId)
                     .setMatchType(matchType)
                     .setQuality(quality)
diff --git a/services/tests/uiservicestests/AndroidManifest.xml b/services/tests/uiservicestests/AndroidManifest.xml
index 7453c48..6c63dae 100644
--- a/services/tests/uiservicestests/AndroidManifest.xml
+++ b/services/tests/uiservicestests/AndroidManifest.xml
@@ -28,6 +28,8 @@
     <uses-permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE" />
     <uses-permission android:name="android.permission.DEVICE_POWER" />
     <uses-permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY" />
+    <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
+    <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" />
     <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT"/>
diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java
index c0dfec9..752707e 100644
--- a/telephony/java/android/telephony/SmsCbMessage.java
+++ b/telephony/java/android/telephony/SmsCbMessage.java
@@ -586,6 +586,7 @@
         cv.put(CellBroadcasts.SERIAL_NUMBER, getSerialNumber());
         cv.put(CellBroadcasts.SERVICE_CATEGORY, getServiceCategory());
         cv.put(CellBroadcasts.LANGUAGE_CODE, getLanguageCode());
+        cv.put(CellBroadcasts.DATA_CODING_SCHEME, getDataCodingScheme());
         cv.put(CellBroadcasts.MESSAGE_BODY, getMessageBody());
         cv.put(CellBroadcasts.MESSAGE_FORMAT, getMessageFormat());
         cv.put(CellBroadcasts.MESSAGE_PRIORITY, getMessagePriority());
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index ae034b5..1cf8f1e 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -44,6 +44,7 @@
 import android.database.ContentObserver;
 import android.net.INetworkPolicyManager;
 import android.net.NetworkCapabilities;
+import android.net.NetworkPolicyManager;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -963,6 +964,11 @@
         mContext = context;
     }
 
+    private NetworkPolicyManager getNetworkPolicyManager() {
+        return (NetworkPolicyManager) mContext
+                .getSystemService(Context.NETWORK_POLICY_SERVICE);
+    }
+
     /**
      * @deprecated developers should always obtain references directly from
      *             {@link Context#getSystemService(Class)}.
@@ -973,7 +979,7 @@
                 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
     }
 
-    private final INetworkPolicyManager getNetworkPolicy() {
+    private INetworkPolicyManager getINetworkPolicyManager() {
         if (mNetworkPolicy == null) {
             mNetworkPolicy = INetworkPolicyManager.Stub
                     .asInterface(ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
@@ -2448,14 +2454,10 @@
      *             outlined above.
      */
     public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
-        try {
-            SubscriptionPlan[] subscriptionPlans =
-                    getNetworkPolicy().getSubscriptionPlans(subId, mContext.getOpPackageName());
-            return subscriptionPlans == null
-                    ? Collections.emptyList() : Arrays.asList(subscriptionPlans);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        SubscriptionPlan[] subscriptionPlans =
+                getNetworkPolicyManager().getSubscriptionPlans(subId, mContext.getOpPackageName());
+        return subscriptionPlans == null
+                ? Collections.emptyList() : Arrays.asList(subscriptionPlans);
     }
 
     /**
@@ -2481,18 +2483,14 @@
      *             defined in {@link SubscriptionPlan}.
      */
     public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
-        try {
-            getNetworkPolicy().setSubscriptionPlans(subId,
-                    plans.toArray(new SubscriptionPlan[plans.size()]), mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        getNetworkPolicyManager().setSubscriptionPlans(subId,
+                plans.toArray(new SubscriptionPlan[plans.size()]), mContext.getOpPackageName());
     }
 
     /** @hide */
     private String getSubscriptionPlansOwner(int subId) {
         try {
-            return getNetworkPolicy().getSubscriptionPlansOwner(subId);
+            return getINetworkPolicyManager().getSubscriptionPlansOwner(subId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2523,13 +2521,10 @@
      */
     public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
             @DurationMillisLong long timeoutMillis) {
-        try {
-            final int overrideValue = overrideUnmetered ? SUBSCRIPTION_OVERRIDE_UNMETERED : 0;
-            getNetworkPolicy().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_UNMETERED,
-                    overrideValue, timeoutMillis, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+
+        final int overrideValue = overrideUnmetered ? SUBSCRIPTION_OVERRIDE_UNMETERED : 0;
+        getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_UNMETERED,
+                overrideValue, timeoutMillis, mContext.getOpPackageName());
     }
 
     /**
@@ -2558,13 +2553,9 @@
      */
     public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
             @DurationMillisLong long timeoutMillis) {
-        try {
-            final int overrideValue = overrideCongested ? SUBSCRIPTION_OVERRIDE_CONGESTED : 0;
-            getNetworkPolicy().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_CONGESTED,
-                    overrideValue, timeoutMillis, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        final int overrideValue = overrideCongested ? SUBSCRIPTION_OVERRIDE_CONGESTED : 0;
+        getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_CONGESTED,
+                overrideValue, timeoutMillis, mContext.getOpPackageName());
     }
 
     /**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 1cc3f19..ffa0810 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -45,6 +45,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.net.ConnectivityManager;
 import android.net.NetworkStats;
@@ -444,12 +445,8 @@
             case UNKNOWN:
                 modemCount = MODEM_COUNT_SINGLE_MODEM;
                 // check for voice and data support, 0 if not supported
-                if (!isVoiceCapable() && !isSmsCapable() && mContext != null) {
-                    ConnectivityManager cm = (ConnectivityManager) mContext
-                            .getSystemService(Context.CONNECTIVITY_SERVICE);
-                    if (cm != null && !cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)) {
-                        modemCount = MODEM_COUNT_NO_MODEM;
-                    }
+                if (!isVoiceCapable() && !isSmsCapable() && !isDataCapable()) {
+                    modemCount = MODEM_COUNT_NO_MODEM;
                 }
                 break;
             case DSDS:
@@ -10950,12 +10947,21 @@
     }
 
     /**
+     * Checks whether cellular data connection is enabled in the device.
+     *
+     * Whether cellular data connection is enabled, meaning upon request whether will try to setup
+     * metered data connection considering all factors below:
+     * 1) User turned on data setting {@link #isDataEnabled}.
+     * 2) Carrier allows data to be on.
+     * 3) Network policy.
+     * And possibly others.
+     *
+     * @return {@code true} if the overall data connection is capable; {@code false} if not.
      * @hide
-     * It's similar to isDataEnabled, but unlike isDataEnabled, this API also evaluates
-     * carrierDataEnabled, policyDataEnabled etc to give a final decision of whether mobile data is
-     * capable of using.
      */
-    public boolean isDataCapable() {
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isDataConnectionEnabled() {
         boolean retVal = false;
         try {
             int subId = getSubId(SubscriptionManager.getDefaultDataSubscriptionId());
@@ -10963,13 +10969,24 @@
             if (telephony != null)
                 retVal = telephony.isDataEnabled(subId);
         } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#isDataEnabled", e);
+            Log.e(TAG, "Error isDataConnectionEnabled", e);
         } catch (NullPointerException e) {
         }
         return retVal;
     }
 
     /**
+     * Checks if FEATURE_TELEPHONY_DATA is enabled.
+     *
+     * @hide
+     */
+    public boolean isDataCapable() {
+        if (mContext == null) return true;
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_mobile_data_capable);
+    }
+
+    /**
      * In this mode, modem will not send specified indications when screen is off.
      * @hide
      */
diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp
index 5e9ef8e..74dfde8 100644
--- a/tests/PlatformCompatGating/Android.bp
+++ b/tests/PlatformCompatGating/Android.bp
@@ -18,14 +18,11 @@
     name: "PlatformCompatGating",
     // Only compile source java files in this apk.
     srcs: ["src/**/*.java"],
-    certificate: "platform",
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
     static_libs: [
         "junit",
-        "android-support-test",
+        "androidx.test.runner",
+        "androidx.test.core",
+        "androidx.test.ext.junit",
         "mockito-target-minus-junit4",
         "truth-prebuilt",
         "platform-compat-test-rules"
diff --git a/tests/PlatformCompatGating/AndroidManifest.xml b/tests/PlatformCompatGating/AndroidManifest.xml
index 7f14b83..c24dc31 100644
--- a/tests/PlatformCompatGating/AndroidManifest.xml
+++ b/tests/PlatformCompatGating/AndroidManifest.xml
@@ -6,6 +6,6 @@
         <uses-library android:name="android.test.runner" />
     </application>
 
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                      android:targetPackage="com.android.tests.gating"/>
 </manifest>
diff --git a/tests/PlatformCompatGating/AndroidTest.xml b/tests/PlatformCompatGating/AndroidTest.xml
index c626848..0c7485b 100644
--- a/tests/PlatformCompatGating/AndroidTest.xml
+++ b/tests/PlatformCompatGating/AndroidTest.xml
@@ -24,7 +24,6 @@
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest">
         <option name="package" value="com.android.tests.gating"/>
-        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
         <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java
index dc317f19..c1ce0e9 100644
--- a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java
+++ b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java
@@ -18,8 +18,9 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.compat.testing.PlatformCompatChangeRule;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.compat.testing.DummyApi;
 
@@ -81,14 +82,14 @@
     @Test
     @EnableCompatChanges({DummyApi.CHANGE_SYSTEM_SERVER})
     public void testDummyGatingPositiveSystemServer() {
-        assertThat(
-                DummyApi.dummySystemServer(InstrumentationRegistry.getTargetContext())).isTrue();
+        assertThat(DummyApi.dummySystemServer(
+                InstrumentationRegistry.getInstrumentation().getTargetContext())).isTrue();
     }
 
     @Test
     @DisableCompatChanges({DummyApi.CHANGE_SYSTEM_SERVER})
     public void testDummyGatingNegativeSystemServer() {
-        assertThat(
-                DummyApi.dummySystemServer(InstrumentationRegistry.getTargetContext())).isFalse();
+        assertThat(DummyApi.dummySystemServer(
+                InstrumentationRegistry.getInstrumentation().getTargetContext())).isFalse();
     }
 }
diff --git a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatPermissionsTest.java b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatPermissionsTest.java
new file mode 100644
index 0000000..9b9e581
--- /dev/null
+++ b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatPermissionsTest.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2020 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.tests.gating;
+
+import static android.Manifest.permission.LOG_COMPAT_CHANGE;
+import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
+import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.compat.Compatibility.ChangeConfig;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Process;
+import android.os.ServiceManager;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.internal.compat.CompatibilityChangeConfig;
+import com.android.internal.compat.IPlatformCompat;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@RunWith(JUnit4.class)
+public final class PlatformCompatPermissionsTest {
+
+    // private Context mContext;
+    private IPlatformCompat mPlatformCompat;
+
+    @Rule
+    public final ExpectedException thrown = ExpectedException.none();
+    private Context mContext;
+    private UiAutomation mUiAutomation;
+    private PackageManager mPackageManager;
+
+    @Before
+    public void setUp() {
+        // mContext;
+        mPlatformCompat = IPlatformCompat.Stub
+            .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        mUiAutomation = instrumentation.getUiAutomation();
+        mContext = instrumentation.getTargetContext();
+
+        mPackageManager = mContext.getPackageManager();
+    }
+
+    @After
+    public void tearDown() {
+
+        mUiAutomation.dropShellPermissionIdentity();
+    }
+
+    @Test
+    public void reportChange_noLogCompatChangePermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+        final String packageName = mContext.getPackageName();
+
+        mPlatformCompat.reportChange(1, mPackageManager.getApplicationInfo(packageName, 0));
+    }
+
+    @Test
+    public void reportChange_logCompatChangePermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(LOG_COMPAT_CHANGE);
+        final String packageName = mContext.getPackageName();
+
+        mPlatformCompat.reportChange(1, mPackageManager.getApplicationInfo(packageName, 0));
+    }
+
+    @Test
+    public void reportChangeByPackageName_noLogCompatChangePermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+        final String packageName = mContext.getPackageName();
+
+        mPlatformCompat.reportChangeByPackageName(1, packageName, 0);
+    }
+
+    @Test
+    public void reportChangeByPackageName_logCompatChangePermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(LOG_COMPAT_CHANGE);
+        final String packageName = mContext.getPackageName();
+
+        mPlatformCompat.reportChangeByPackageName(1, packageName, 0);
+    }
+
+    @Test
+    public void reportChangeByUid_noLogCompatChangePermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+
+        mPlatformCompat.reportChangeByUid(1, Process.myUid());
+    }
+
+    @Test
+    public void reportChangeByUid_logCompatChangePermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(LOG_COMPAT_CHANGE);
+
+        mPlatformCompat.reportChangeByUid(1, Process.myUid());
+    }
+
+    @Test
+    public void isChangeEnabled_noReadCompatConfigPermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+        final String packageName = mContext.getPackageName();
+
+        mPlatformCompat.isChangeEnabled(1, mPackageManager.getApplicationInfo(packageName, 0));
+    }
+
+    @Test
+    public void isChangeEnabled_noLogCompatChangeConfigPermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+        mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG);
+        final String packageName = mContext.getPackageName();
+
+        mPlatformCompat.isChangeEnabled(1, mPackageManager.getApplicationInfo(packageName, 0));
+    }
+
+    @Test
+    public void isChangeEnabled_readAndLogCompatChangeConfigPermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG, LOG_COMPAT_CHANGE);
+        final String packageName = mContext.getPackageName();
+
+        mPlatformCompat.isChangeEnabled(1, mPackageManager.getApplicationInfo(packageName, 0));
+    }
+
+    @Test
+    public void isChangeEnabledByPackageName_noReadCompatConfigPermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+        final String packageName = mContext.getPackageName();
+
+        mPlatformCompat.isChangeEnabledByPackageName(1, packageName, 0);
+    }
+
+    @Test
+    public void isChangeEnabledByPackageName_noLogompatConfigPermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+        mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG);
+        final String packageName = mContext.getPackageName();
+
+        mPlatformCompat.isChangeEnabledByPackageName(1, packageName, 0);
+    }
+
+    @Test
+    public void isChangeEnabledByPackageName_readAndLogCompatChangeConfigPermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG, LOG_COMPAT_CHANGE);
+        final String packageName = mContext.getPackageName();
+
+        mPlatformCompat.isChangeEnabledByPackageName(1, packageName, 0);
+    }
+
+    @Test
+    public void isChangeEnabledByUid_noReadCompatConfigPermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+
+        mPlatformCompat.isChangeEnabledByUid(1, Process.myUid());
+    }
+
+    @Test
+    public void isChangeEnabledByUid_noLogCompatChangePermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+        mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG);
+
+        mPlatformCompat.isChangeEnabledByUid(1, Process.myUid());
+    }
+
+    @Test
+    public void isChangeEnabledByUid_readAndLogCompatChangeConfigPermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG, LOG_COMPAT_CHANGE);
+
+        mPlatformCompat.isChangeEnabledByUid(1, Process.myUid());
+    }
+
+    @Test
+    public void setOverrides_noOverridesPermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+        Set<Long> enabled = new HashSet<>();
+        Set<Long> disabled = new HashSet<>();
+        ChangeConfig changeConfig = new ChangeConfig(enabled, disabled);
+        CompatibilityChangeConfig compatibilityChangeConfig =
+                new CompatibilityChangeConfig(changeConfig);
+
+        mPlatformCompat.setOverrides(compatibilityChangeConfig, "foo.bar");
+    }
+    @Test
+    public void setOverrides_overridesPermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(OVERRIDE_COMPAT_CHANGE_CONFIG);
+        Set<Long> enabled = new HashSet<>();
+        Set<Long> disabled = new HashSet<>();
+        ChangeConfig changeConfig = new ChangeConfig(enabled, disabled);
+        CompatibilityChangeConfig compatibilityChangeConfig =
+                new CompatibilityChangeConfig(changeConfig);
+
+        mPlatformCompat.setOverrides(compatibilityChangeConfig, "foo.bar");
+    }
+
+    @Test
+    public void setOverridesForTest_noOverridesPermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+        Set<Long> enabled = new HashSet<>();
+        Set<Long> disabled = new HashSet<>();
+        ChangeConfig changeConfig = new ChangeConfig(enabled, disabled);
+        CompatibilityChangeConfig compatibilityChangeConfig =
+                new CompatibilityChangeConfig(changeConfig);
+
+        mPlatformCompat.setOverridesForTest(compatibilityChangeConfig, "foo.bar");
+    }
+    @Test
+    public void setOverridesForTest_overridesPermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(OVERRIDE_COMPAT_CHANGE_CONFIG);
+        Set<Long> enabled = new HashSet<>();
+        Set<Long> disabled = new HashSet<>();
+        ChangeConfig changeConfig = new ChangeConfig(enabled, disabled);
+        CompatibilityChangeConfig compatibilityChangeConfig =
+                new CompatibilityChangeConfig(changeConfig);
+
+        mPlatformCompat.setOverridesForTest(compatibilityChangeConfig, "foo.bar");
+    }
+
+    @Test
+    public void clearOverrides_noOverridesPermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+
+        mPlatformCompat.clearOverrides("foo.bar");
+    }
+    @Test
+    public void clearOverrides_overridesPermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(OVERRIDE_COMPAT_CHANGE_CONFIG);
+
+        mPlatformCompat.clearOverrides("foo.bar");
+    }
+
+    @Test
+    public void clearOverridesForTest_noOverridesPermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+
+        mPlatformCompat.clearOverridesForTest("foo.bar");
+    }
+    @Test
+    public void clearOverridesForTest_overridesPermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(OVERRIDE_COMPAT_CHANGE_CONFIG);
+
+        mPlatformCompat.clearOverridesForTest("foo.bar");
+    }
+
+    @Test
+    public void clearOverride_noOverridesPermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+
+        mPlatformCompat.clearOverride(1, "foo.bar");
+    }
+    @Test
+    public void clearOverride_overridesPermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(OVERRIDE_COMPAT_CHANGE_CONFIG);
+
+        mPlatformCompat.clearOverride(1, "foo.bar");
+    }
+
+    @Test
+    public void listAllChanges_noReadCompatConfigPermission_throwsSecurityException()
+            throws Throwable {
+        thrown.expect(SecurityException.class);
+
+        mPlatformCompat.listAllChanges();
+    }
+    @Test
+    public void listAllChanges_readCompatConfigPermission_noThrow()
+            throws Throwable {
+        mUiAutomation.adoptShellPermissionIdentity(READ_COMPAT_CHANGE_CONFIG);
+
+        mPlatformCompat.listAllChanges();
+    }
+}
diff --git a/tests/PlatformCompatGating/test-rules/Android.bp b/tests/PlatformCompatGating/test-rules/Android.bp
index 8211ef5..10fa2dc 100644
--- a/tests/PlatformCompatGating/test-rules/Android.bp
+++ b/tests/PlatformCompatGating/test-rules/Android.bp
@@ -19,7 +19,7 @@
     srcs: ["src/**/*.java"],
     static_libs: [
         "junit",
-        "android-support-test",
+        "androidx.test.core",
         "truth-prebuilt",
         "core-compat-test-rules"
     ],
diff --git a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
index 932ec64..d6846fa 100644
--- a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
+++ b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
@@ -16,13 +16,17 @@
 
 package android.compat.testing;
 
+import android.Manifest;
 import android.app.Instrumentation;
+import android.app.UiAutomation;
 import android.compat.Compatibility;
 import android.compat.Compatibility.ChangeConfig;
 import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.support.test.InstrumentationRegistry;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
 
 import com.android.internal.compat.CompatibilityChangeConfig;
 import com.android.internal.compat.IPlatformCompat;
@@ -83,12 +87,17 @@
         @Override
         public void evaluate() throws Throwable {
             Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+            UiAutomation uiAutomation = instrumentation.getUiAutomation();
             String packageName = instrumentation.getTargetContext().getPackageName();
             IPlatformCompat platformCompat = IPlatformCompat.Stub
                     .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
             if (platformCompat == null) {
                 throw new IllegalStateException("Could not get IPlatformCompat service!");
             }
+            uiAutomation.adoptShellPermissionIdentity(
+                    Manifest.permission.LOG_COMPAT_CHANGE,
+                    Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG,
+                    Manifest.permission.READ_COMPAT_CHANGE_CONFIG);
             Compatibility.setOverrides(mConfig);
             try {
                 platformCompat.setOverridesForTest(new CompatibilityChangeConfig(mConfig),
@@ -101,6 +110,7 @@
             } catch (RemoteException e) {
                 throw new RuntimeException("Could not call IPlatformCompat binder method!", e);
             } finally {
+                uiAutomation.dropShellPermissionIdentity();
                 Compatibility.clearOverrides();
             }
         }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 8162843..8da1a5b 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -24,6 +24,7 @@
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
+import static android.net.ConnectivityDiagnosticsManager.DataStallReport;
 import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL;
@@ -570,6 +571,9 @@
                 | NETWORK_VALIDATION_RESULT_PARTIAL;
         private static final int VALIDATION_RESULT_INVALID = 0;
 
+        private static final long DATA_STALL_TIMESTAMP = 10L;
+        private static final int DATA_STALL_DETECTION_METHOD = 1;
+
         private INetworkMonitor mNetworkMonitor;
         private INetworkMonitorCallbacks mNmCallbacks;
         private int mNmValidationResult = VALIDATION_RESULT_BASE;
@@ -577,6 +581,7 @@
         private int mProbesSucceeded;
         private String mNmValidationRedirectUrl = null;
         private PersistableBundle mValidationExtras = PersistableBundle.EMPTY;
+        private PersistableBundle mDataStallExtras = PersistableBundle.EMPTY;
         private boolean mNmProvNotificationRequested = false;
 
         private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
@@ -804,6 +809,11 @@
         public void expectPreventReconnectReceived() {
             expectPreventReconnectReceived(TIMEOUT_MS);
         }
+
+        void notifyDataStallSuspected() throws Exception {
+            mNmCallbacks.notifyDataStallSuspected(
+                    DATA_STALL_TIMESTAMP, DATA_STALL_DETECTION_METHOD, mDataStallExtras);
+        }
     }
 
     /**
@@ -6436,14 +6446,16 @@
     public void testRegisterUnregisterConnectivityDiagnosticsCallback() throws Exception {
         final NetworkRequest wifiRequest =
                 new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build();
-
         when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder);
 
         mService.registerConnectivityDiagnosticsCallback(
                 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName());
 
-        verify(mIBinder, timeout(TIMEOUT_MS))
-                .linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt());
+        // Block until all other events are done processing.
+        HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+
+        verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt());
+        verify(mConnectivityDiagnosticsCallback).asBinder();
         assertTrue(
                 mService.mConnectivityDiagnosticsCallbacks.containsKey(
                         mConnectivityDiagnosticsCallback));
@@ -6466,8 +6478,10 @@
         mService.registerConnectivityDiagnosticsCallback(
                 mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName());
 
-        verify(mIBinder, timeout(TIMEOUT_MS))
-                .linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt());
+        // Block until all other events are done processing.
+        HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+
+        verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt());
         verify(mConnectivityDiagnosticsCallback).asBinder();
         assertTrue(
                 mService.mConnectivityDiagnosticsCallbacks.containsKey(
@@ -6599,8 +6613,7 @@
         mServiceContext.setPermission(perm, PERMISSION_GRANTED);
     }
 
-    @Test
-    public void testConnectivityDiagnosticsCallbackOnConnectivityReport() throws Exception {
+    private void setUpConnectivityDiagnosticsCallback() throws Exception {
         final NetworkRequest request = new NetworkRequest.Builder().build();
         when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder);
 
@@ -6620,9 +6633,58 @@
         mCellNetworkAgent.connect(true);
         callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
         callback.assertNoCallback();
+    }
 
-        // Wait for onConnectivityReport to fire
-        verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS))
+    @Test
+    public void testConnectivityDiagnosticsCallbackOnConnectivityReport() throws Exception {
+        setUpConnectivityDiagnosticsCallback();
+
+        // Block until all other events are done processing.
+        HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+
+        // Verify onConnectivityReport fired
+        verify(mConnectivityDiagnosticsCallback)
                 .onConnectivityReport(any(ConnectivityReport.class));
     }
+
+    @Test
+    public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() throws Exception {
+        setUpConnectivityDiagnosticsCallback();
+
+        // Trigger notifyDataStallSuspected() on the INetworkMonitorCallbacks instance in the
+        // cellular network agent
+        mCellNetworkAgent.notifyDataStallSuspected();
+
+        // Block until all other events are done processing.
+        HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+
+        // Verify onDataStallSuspected fired
+        verify(mConnectivityDiagnosticsCallback).onDataStallSuspected(any(DataStallReport.class));
+    }
+
+    @Test
+    public void testConnectivityDiagnosticsCallbackOnConnectivityReported() throws Exception {
+        setUpConnectivityDiagnosticsCallback();
+
+        final Network n = mCellNetworkAgent.getNetwork();
+        final boolean hasConnectivity = true;
+        mService.reportNetworkConnectivity(n, hasConnectivity);
+
+        // Block until all other events are done processing.
+        HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+
+        // Verify onNetworkConnectivityReported fired
+        verify(mConnectivityDiagnosticsCallback)
+                .onNetworkConnectivityReported(eq(n), eq(hasConnectivity));
+
+        final boolean noConnectivity = false;
+        mService.reportNetworkConnectivity(n, noConnectivity);
+
+        // Block until all other events are done processing.
+        HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+
+        // Wait for onNetworkConnectivityReported to fire
+        verify(mConnectivityDiagnosticsCallback)
+                .onNetworkConnectivityReported(eq(n), eq(noConnectivity));
+    }
 }