Merge "Make TimeDetectorService more aware of origin" am: 4ef2551dfa am: 3150e58082 am: 84c6981a8f
am: a4783a8a28

Change-Id: I5fbb8544613475f750f59adafc784a0ad625ea1a
diff --git a/core/java/android/app/timedetector/ITimeDetectorService.aidl b/core/java/android/app/timedetector/ITimeDetectorService.aidl
index f624446..ddc4932 100644
--- a/core/java/android/app/timedetector/ITimeDetectorService.aidl
+++ b/core/java/android/app/timedetector/ITimeDetectorService.aidl
@@ -16,10 +16,10 @@
 
 package android.app.timedetector;
 
-import android.app.timedetector.TimeSignal;
+import android.app.timedetector.PhoneTimeSuggestion;
 
 /**
- * System private API to comunicate with time detector service.
+ * System private API to communicate with time detector service.
  *
  * <p>Used by parts of the Android system with signals associated with the device's time to provide
  * information to the Time Detector Service.
@@ -32,5 +32,5 @@
  * {@hide}
  */
 interface ITimeDetectorService {
-  void suggestTime(in TimeSignal timeSignal);
+  void suggestPhoneTime(in PhoneTimeSuggestion timeSuggestion);
 }
diff --git a/core/java/android/app/timedetector/TimeSignal.aidl b/core/java/android/app/timedetector/PhoneTimeSuggestion.aidl
similarity index 94%
rename from core/java/android/app/timedetector/TimeSignal.aidl
rename to core/java/android/app/timedetector/PhoneTimeSuggestion.aidl
index d2ec357..f5e2405 100644
--- a/core/java/android/app/timedetector/TimeSignal.aidl
+++ b/core/java/android/app/timedetector/PhoneTimeSuggestion.aidl
@@ -16,4 +16,4 @@
 
 package android.app.timedetector;
 
-parcelable TimeSignal;
\ No newline at end of file
+parcelable PhoneTimeSuggestion;
diff --git a/core/java/android/app/timedetector/PhoneTimeSuggestion.java b/core/java/android/app/timedetector/PhoneTimeSuggestion.java
new file mode 100644
index 0000000..475a4aa
--- /dev/null
+++ b/core/java/android/app/timedetector/PhoneTimeSuggestion.java
@@ -0,0 +1,137 @@
+/*
+ * 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.timedetector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.TimestampedValue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A time signal from a telephony source. The value consists of the number of milliseconds elapsed
+ * since 1/1/1970 00:00:00 UTC and the time according to the elapsed realtime clock when that number
+ * was established. The elapsed realtime clock is considered accurate but volatile, so time signals
+ * must not be persisted across device resets.
+ *
+ * @hide
+ */
+public final class PhoneTimeSuggestion implements Parcelable {
+
+    public static final @NonNull Parcelable.Creator<PhoneTimeSuggestion> CREATOR =
+            new Parcelable.Creator<PhoneTimeSuggestion>() {
+                public PhoneTimeSuggestion createFromParcel(Parcel in) {
+                    return PhoneTimeSuggestion.createFromParcel(in);
+                }
+
+                public PhoneTimeSuggestion[] newArray(int size) {
+                    return new PhoneTimeSuggestion[size];
+                }
+            };
+
+    private final int mPhoneId;
+    @NonNull
+    private final TimestampedValue<Long> mUtcTime;
+    @Nullable
+    private ArrayList<String> mDebugInfo;
+
+    public PhoneTimeSuggestion(int phoneId, @NonNull TimestampedValue<Long> utcTime) {
+        mPhoneId = phoneId;
+        mUtcTime = Objects.requireNonNull(utcTime);
+    }
+
+    private static PhoneTimeSuggestion createFromParcel(Parcel in) {
+        int phoneId = in.readInt();
+        TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */);
+        PhoneTimeSuggestion suggestion = new PhoneTimeSuggestion(phoneId, utcTime);
+        @SuppressWarnings("unchecked")
+        ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
+        suggestion.mDebugInfo = debugInfo;
+        return suggestion;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mPhoneId);
+        dest.writeParcelable(mUtcTime, 0);
+        dest.writeList(mDebugInfo);
+    }
+
+    public int getPhoneId() {
+        return mPhoneId;
+    }
+
+    @NonNull
+    public TimestampedValue<Long> getUtcTime() {
+        return mUtcTime;
+    }
+
+    @NonNull
+    public List<String> getDebugInfo() {
+        return Collections.unmodifiableList(mDebugInfo);
+    }
+
+    /**
+     * Associates information with the instance that can be useful for debugging / logging. The
+     * information is present in {@link #toString()} but is not considered for
+     * {@link #equals(Object)} and {@link #hashCode()}.
+     */
+    public void addDebugInfo(String... debugInfos) {
+        if (mDebugInfo == null) {
+            mDebugInfo = new ArrayList<>();
+        }
+        mDebugInfo.addAll(Arrays.asList(debugInfos));
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        PhoneTimeSuggestion that = (PhoneTimeSuggestion) o;
+        return mPhoneId == that.mPhoneId
+                && Objects.equals(mUtcTime, that.mUtcTime);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPhoneId, mUtcTime);
+    }
+
+    @Override
+    public String toString() {
+        return "PhoneTimeSuggestion{"
+                + "mPhoneId='" + mPhoneId + '\''
+                + ", mUtcTime=" + mUtcTime
+                + ", mDebugInfo=" + mDebugInfo
+                + '}';
+    }
+}
diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java
index 052050d..334e958 100644
--- a/core/java/android/app/timedetector/TimeDetector.java
+++ b/core/java/android/app/timedetector/TimeDetector.java
@@ -45,12 +45,12 @@
      * signals are available such as those that come from more reliable sources or were
      * determined more recently.
      */
-    public void suggestTime(@NonNull TimeSignal timeSignal) {
+    public void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSuggestion) {
         if (DEBUG) {
-            Log.d(TAG, "suggestTime called: " + timeSignal);
+            Log.d(TAG, "suggestPhoneTime called: " + timeSuggestion);
         }
         try {
-            mITimeDetectorService.suggestTime(timeSignal);
+            mITimeDetectorService.suggestPhoneTime(timeSuggestion);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/timedetector/TimeSignal.java b/core/java/android/app/timedetector/TimeSignal.java
deleted file mode 100644
index b494260..0000000
--- a/core/java/android/app/timedetector/TimeSignal.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2018 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.timedetector;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.TimestampedValue;
-
-import java.util.Objects;
-
-/**
- * A time signal from a named source. The value consists of the number of milliseconds elapsed since
- * 1/1/1970 00:00:00 UTC and the time according to the elapsed realtime clock when that number was
- * established. The elapsed realtime clock is considered accurate but volatile, so time signals
- * must not be persisted across device resets.
- *
- * @hide
- */
-public final class TimeSignal implements Parcelable {
-
-    public static final @android.annotation.NonNull Parcelable.Creator<TimeSignal> CREATOR =
-            new Parcelable.Creator<TimeSignal>() {
-                public TimeSignal createFromParcel(Parcel in) {
-                    return TimeSignal.createFromParcel(in);
-                }
-
-                public TimeSignal[] newArray(int size) {
-                    return new TimeSignal[size];
-                }
-            };
-
-    public static final String SOURCE_ID_NITZ = "nitz";
-
-    private final String mSourceId;
-    private final TimestampedValue<Long> mUtcTime;
-
-    public TimeSignal(String sourceId, TimestampedValue<Long> utcTime) {
-        mSourceId = Objects.requireNonNull(sourceId);
-        mUtcTime = Objects.requireNonNull(utcTime);
-    }
-
-    private static TimeSignal createFromParcel(Parcel in) {
-        String sourceId = in.readString();
-        TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */);
-        return new TimeSignal(sourceId, utcTime);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeString(mSourceId);
-        dest.writeParcelable(mUtcTime, 0);
-    }
-
-    @NonNull
-    public String getSourceId() {
-        return mSourceId;
-    }
-
-    @NonNull
-    public TimestampedValue<Long> getUtcTime() {
-        return mUtcTime;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        TimeSignal that = (TimeSignal) o;
-        return Objects.equals(mSourceId, that.mSourceId)
-                && Objects.equals(mUtcTime, that.mUtcTime);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mSourceId, mUtcTime);
-    }
-
-    @Override
-    public String toString() {
-        return "TimeSignal{"
-                + "mSourceId='" + mSourceId + '\''
-                + ", mUtcTime=" + mUtcTime
-                + '}';
-    }
-}
diff --git a/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java
new file mode 100644
index 0000000..1b5ad88
--- /dev/null
+++ b/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.timedetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.TimestampedValue;
+
+import org.junit.Test;
+
+public class PhoneTimeSuggestionTest {
+    private static final int PHONE_ID = 99999;
+
+    @Test
+    public void testEquals() {
+        PhoneTimeSuggestion one =
+                new PhoneTimeSuggestion(PHONE_ID, new TimestampedValue<>(1111L, 2222L));
+        assertEquals(one, one);
+
+        PhoneTimeSuggestion two =
+                new PhoneTimeSuggestion(PHONE_ID, new TimestampedValue<>(1111L, 2222L));
+        assertEquals(one, two);
+        assertEquals(two, one);
+
+        PhoneTimeSuggestion three =
+                new PhoneTimeSuggestion(PHONE_ID + 1, new TimestampedValue<>(1111L, 2222L));
+        assertNotEquals(one, three);
+        assertNotEquals(three, one);
+
+        // DebugInfo must not be considered in equals().
+        one.addDebugInfo("Debug info 1");
+        two.addDebugInfo("Debug info 2");
+        assertEquals(one, two);
+    }
+
+    @Test
+    public void testParcelable() {
+        PhoneTimeSuggestion one =
+                new PhoneTimeSuggestion(PHONE_ID, new TimestampedValue<>(1111L, 2222L));
+        assertEquals(one, roundTripParcelable(one));
+
+        // DebugInfo should also be stored (but is not checked by equals()
+        one.addDebugInfo("This is debug info");
+        PhoneTimeSuggestion two = roundTripParcelable(one);
+        assertEquals(one.getDebugInfo(), two.getDebugInfo());
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T extends Parcelable> T roundTripParcelable(T one) {
+        Parcel parcel = Parcel.obtain();
+        parcel.writeTypedObject(one, 0);
+        parcel.setDataPosition(0);
+
+        T toReturn = (T) parcel.readTypedObject(PhoneTimeSuggestion.CREATOR);
+        parcel.recycle();
+        return toReturn;
+    }
+}
diff --git a/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java
index 7bdc8a3..9dbbf16 100644
--- a/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java
@@ -19,7 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AlarmManager;
-import android.app.timedetector.TimeSignal;
+import android.app.timedetector.PhoneTimeSuggestion;
 import android.content.Intent;
 import android.util.Slog;
 import android.util.TimestampedValue;
@@ -48,9 +48,8 @@
     // @NonNull after initialize()
     private Callback mCallback;
 
-    // NITZ state.
-    @Nullable private TimestampedValue<Long> mLastNitzTime;
-
+    // Last phone suggestion.
+    @Nullable private PhoneTimeSuggestion mLastPhoneSuggestion;
 
     // Information about the last time signal received: Used when toggling auto-time.
     @Nullable private TimestampedValue<Long> mLastSystemClockTime;
@@ -65,46 +64,40 @@
     }
 
     @Override
-    public void suggestTime(@NonNull TimeSignal timeSignal) {
-        if (!TimeSignal.SOURCE_ID_NITZ.equals(timeSignal.getSourceId())) {
-            Slog.w(TAG, "Ignoring signal from unsupported source: " + timeSignal);
-            return;
-        }
-
+    public void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSuggestion) {
         // NITZ logic
 
-        TimestampedValue<Long> newNitzUtcTime = timeSignal.getUtcTime();
-        boolean nitzTimeIsValid = validateNewNitzTime(newNitzUtcTime, mLastNitzTime);
-        if (!nitzTimeIsValid) {
+        boolean timeSuggestionIsValid =
+                validateNewPhoneSuggestion(timeSuggestion, mLastPhoneSuggestion);
+        if (!timeSuggestionIsValid) {
             return;
         }
         // Always store the last NITZ value received, regardless of whether we go on to use it to
         // update the system clock. This is so that we can validate future NITZ signals.
-        mLastNitzTime = newNitzUtcTime;
+        mLastPhoneSuggestion = timeSuggestion;
 
         // System clock update logic.
 
         // Historically, Android has sent a telephony broadcast only when setting the time using
         // NITZ.
-        final boolean sendNetworkBroadcast =
-                TimeSignal.SOURCE_ID_NITZ.equals(timeSignal.getSourceId());
+        final boolean sendNetworkBroadcast = true;
 
-        final TimestampedValue<Long> newUtcTime = newNitzUtcTime;
+        final TimestampedValue<Long> newUtcTime = timeSuggestion.getUtcTime();
         setSystemClockIfRequired(newUtcTime, sendNetworkBroadcast);
     }
 
-    private static boolean validateNewNitzTime(TimestampedValue<Long> newNitzUtcTime,
-            TimestampedValue<Long> lastNitzTime) {
+    private static boolean validateNewPhoneSuggestion(@NonNull PhoneTimeSuggestion newSuggestion,
+            @Nullable PhoneTimeSuggestion lastSuggestion) {
 
-        if (lastNitzTime != null) {
-            long referenceTimeDifference =
-                    TimestampedValue.referenceTimeDifference(newNitzUtcTime, lastNitzTime);
+        if (lastSuggestion != null) {
+            long referenceTimeDifference = TimestampedValue.referenceTimeDifference(
+                    newSuggestion.getUtcTime(), lastSuggestion.getUtcTime());
             if (referenceTimeDifference < 0 || referenceTimeDifference > Integer.MAX_VALUE) {
                 // Out of order or bogus.
                 Slog.w(TAG, "validateNewNitzTime: Bad NITZ signal received."
                         + " referenceTimeDifference=" + referenceTimeDifference
-                        + " lastNitzTime=" + lastNitzTime
-                        + " newNitzUtcTime=" + newNitzUtcTime);
+                        + " lastSuggestion=" + lastSuggestion
+                        + " newSuggestion=" + newSuggestion);
                 return false;
             }
         }
@@ -182,7 +175,7 @@
 
     @Override
     public void dump(@NonNull PrintWriter pw, @Nullable String[] args) {
-        pw.println("mLastNitzTime=" + mLastNitzTime);
+        pw.println("mLastPhoneSuggestion=" + mLastPhoneSuggestion);
         pw.println("mLastSystemClockTimeSet=" + mLastSystemClockTimeSet);
         pw.println("mLastSystemClockTime=" + mLastSystemClockTime);
         pw.println("mLastSystemClockTimeSendNetworkBroadcast="
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 9c83000..ee42279 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -19,7 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.timedetector.ITimeDetectorService;
-import android.app.timedetector.TimeSignal;
+import android.app.timedetector.PhoneTimeSuggestion;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
@@ -96,14 +96,14 @@
     }
 
     @Override
-    public void suggestTime(@NonNull TimeSignal timeSignal) {
+    public void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSignal) {
         enforceSetTimePermission();
         Objects.requireNonNull(timeSignal);
 
         long idToken = Binder.clearCallingIdentity();
         try {
             synchronized (mStrategyLock) {
-                mTimeDetectorStrategy.suggestTime(timeSignal);
+                mTimeDetectorStrategy.suggestPhoneTime(timeSignal);
             }
         } finally {
             Binder.restoreCallingIdentity(idToken);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index e050865..7c2a945 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -18,7 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.timedetector.TimeSignal;
+import android.app.timedetector.PhoneTimeSuggestion;
 import android.content.Intent;
 import android.util.TimestampedValue;
 
@@ -72,7 +72,7 @@
     void initialize(@NonNull Callback callback);
 
     /** Process the suggested time. */
-    void suggestTime(@NonNull TimeSignal timeSignal);
+    void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSuggestion);
 
     /** Handle the auto-time setting being toggled on or off. */
     void handleAutoTimeDetectionToggle(boolean enabled);
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java b/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java
index 9e00077..d797955 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java
@@ -23,7 +23,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.app.timedetector.TimeSignal;
+import android.app.timedetector.PhoneTimeSuggestion;
 import android.content.Intent;
 import android.icu.util.Calendar;
 import android.icu.util.GregorianCalendar;
@@ -45,6 +45,8 @@
             .setActualTimeUtc(2018, 1, 1, 12, 0, 0)
             .build();
 
+    private static final int ARBITRARY_PHONE_ID = 123456;
+
     private Script mScript;
 
     @Before
@@ -53,30 +55,32 @@
     }
 
     @Test
-    public void testSuggestTime_nitz_timeDetectionEnabled() {
+    public void testSuggestPhoneTime_nitz_timeDetectionEnabled() {
         Scenario scenario = SCENARIO_1;
         mScript.pokeFakeClocks(scenario)
                 .pokeTimeDetectionEnabled(true);
 
-        TimeSignal timeSignal = scenario.createTimeSignalForActual(TimeSignal.SOURCE_ID_NITZ);
+        PhoneTimeSuggestion timeSuggestion =
+                scenario.createPhoneTimeSuggestionForActual(ARBITRARY_PHONE_ID);
         final int clockIncrement = 1000;
         long expectSystemClockMillis = scenario.getActualTimeMillis() + clockIncrement;
 
         mScript.simulateTimePassing(clockIncrement)
-                .simulateTimeSignalReceived(timeSignal)
+                .simulatePhoneTimeSuggestion(timeSuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(expectSystemClockMillis);
     }
 
     @Test
-    public void testSuggestTime_systemClockThreshold() {
+    public void testSuggestPhoneTime_systemClockThreshold() {
         Scenario scenario = SCENARIO_1;
         final int systemClockUpdateThresholdMillis = 1000;
         mScript.pokeFakeClocks(scenario)
                 .pokeThresholds(systemClockUpdateThresholdMillis)
                 .pokeTimeDetectionEnabled(true);
 
-        TimeSignal timeSignal1 = scenario.createTimeSignalForActual(TimeSignal.SOURCE_ID_NITZ);
-        TimestampedValue<Long> utcTime1 = timeSignal1.getUtcTime();
+        PhoneTimeSuggestion timeSuggestion1 =
+                scenario.createPhoneTimeSuggestionForActual(ARBITRARY_PHONE_ID);
+        TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime();
 
         final int clockIncrement = 100;
         // Increment the the device clocks to simulate the passage of time.
@@ -86,7 +90,7 @@
                 TimeDetectorStrategy.getTimeAt(utcTime1, mScript.peekElapsedRealtimeMillis());
 
         // Send the first time signal. It should be used.
-        mScript.simulateTimeSignalReceived(timeSignal1)
+        mScript.simulatePhoneTimeSuggestion(timeSuggestion1)
                 .verifySystemClockWasSetAndResetCallTracking(expectSystemClockMillis1);
 
         // Now send another time signal, but one that is too similar to the last one and should be
@@ -95,9 +99,9 @@
         TimestampedValue<Long> utcTime2 = new TimestampedValue<>(
                 mScript.peekElapsedRealtimeMillis(),
                 mScript.peekSystemClockMillis() + underThresholdMillis);
-        TimeSignal timeSignal2 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime2);
+        PhoneTimeSuggestion timeSuggestion2 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime2);
         mScript.simulateTimePassing(clockIncrement)
-                .simulateTimeSignalReceived(timeSignal2)
+                .simulatePhoneTimeSuggestion(timeSuggestion2)
                 .verifySystemClockWasNotSetAndResetCallTracking();
 
         // Now send another time signal, but one that is on the threshold and so should be used.
@@ -105,42 +109,44 @@
                 mScript.peekElapsedRealtimeMillis(),
                 mScript.peekSystemClockMillis() + systemClockUpdateThresholdMillis);
 
-        TimeSignal timeSignal3 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime3);
+        PhoneTimeSuggestion timeSuggestion3 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime3);
         mScript.simulateTimePassing(clockIncrement);
 
         long expectSystemClockMillis3 =
                 TimeDetectorStrategy.getTimeAt(utcTime3, mScript.peekElapsedRealtimeMillis());
 
-        mScript.simulateTimeSignalReceived(timeSignal3)
+        mScript.simulatePhoneTimeSuggestion(timeSuggestion3)
                 .verifySystemClockWasSetAndResetCallTracking(expectSystemClockMillis3);
     }
 
     @Test
-    public void testSuggestTime_nitz_timeDetectionDisabled() {
+    public void testSuggestPhoneTime_nitz_timeDetectionDisabled() {
         Scenario scenario = SCENARIO_1;
         mScript.pokeFakeClocks(scenario)
                 .pokeTimeDetectionEnabled(false);
 
-        TimeSignal timeSignal = scenario.createTimeSignalForActual(TimeSignal.SOURCE_ID_NITZ);
-        mScript.simulateTimeSignalReceived(timeSignal)
+        PhoneTimeSuggestion timeSuggestion =
+                scenario.createPhoneTimeSuggestionForActual(ARBITRARY_PHONE_ID);
+        mScript.simulatePhoneTimeSuggestion(timeSuggestion)
                 .verifySystemClockWasNotSetAndResetCallTracking();
     }
 
     @Test
-    public void testSuggestTime_nitz_invalidNitzReferenceTimesIgnored() {
+    public void testSuggestPhoneTime_nitz_invalidNitzReferenceTimesIgnored() {
         Scenario scenario = SCENARIO_1;
         final int systemClockUpdateThreshold = 2000;
         mScript.pokeFakeClocks(scenario)
                 .pokeThresholds(systemClockUpdateThreshold)
                 .pokeTimeDetectionEnabled(true);
-        TimeSignal timeSignal1 = scenario.createTimeSignalForActual(TimeSignal.SOURCE_ID_NITZ);
-        TimestampedValue<Long> utcTime1 = timeSignal1.getUtcTime();
+        PhoneTimeSuggestion timeSuggestion1 =
+                scenario.createPhoneTimeSuggestionForActual(ARBITRARY_PHONE_ID);
+        TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime();
 
         // Initialize the strategy / device with a time set from NITZ.
         mScript.simulateTimePassing(100);
         long expectedSystemClockMillis1 =
                 TimeDetectorStrategy.getTimeAt(utcTime1, mScript.peekElapsedRealtimeMillis());
-        mScript.simulateTimeSignalReceived(timeSignal1)
+        mScript.simulatePhoneTimeSuggestion(timeSuggestion1)
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1);
 
         // The UTC time increment should be larger than the system clock update threshold so we
@@ -152,8 +158,8 @@
         long referenceTimeBeforeLastSignalMillis = utcTime1.getReferenceTimeMillis() - 1;
         TimestampedValue<Long> utcTime2 = new TimestampedValue<>(
                 referenceTimeBeforeLastSignalMillis, validUtcTimeMillis);
-        TimeSignal timeSignal2 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime2);
-        mScript.simulateTimeSignalReceived(timeSignal2)
+        PhoneTimeSuggestion timeSuggestion2 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime2);
+        mScript.simulatePhoneTimeSuggestion(timeSuggestion2)
                 .verifySystemClockWasNotSetAndResetCallTracking();
 
         // Now supply a new signal that has an obviously bogus reference time : substantially in the
@@ -162,8 +168,8 @@
                 utcTime1.getReferenceTimeMillis() + Integer.MAX_VALUE + 1;
         TimestampedValue<Long> utcTime3 = new TimestampedValue<>(
                 referenceTimeInFutureMillis, validUtcTimeMillis);
-        TimeSignal timeSignal3 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime3);
-        mScript.simulateTimeSignalReceived(timeSignal3)
+        PhoneTimeSuggestion timeSuggestion3 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime3);
+        mScript.simulatePhoneTimeSuggestion(timeSuggestion3)
                 .verifySystemClockWasNotSetAndResetCallTracking();
 
         // Just to prove validUtcTimeMillis is valid.
@@ -172,13 +178,13 @@
                 validReferenceTimeMillis, validUtcTimeMillis);
         long expectedSystemClockMillis4 =
                 TimeDetectorStrategy.getTimeAt(utcTime4, mScript.peekElapsedRealtimeMillis());
-        TimeSignal timeSignal4 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime4);
-        mScript.simulateTimeSignalReceived(timeSignal4)
+        PhoneTimeSuggestion timeSuggestion4 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime4);
+        mScript.simulatePhoneTimeSuggestion(timeSuggestion4)
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis4);
     }
 
     @Test
-    public void testSuggestTime_timeDetectionToggled() {
+    public void testSuggestPhoneTime_timeDetectionToggled() {
         Scenario scenario = SCENARIO_1;
         final int clockIncrementMillis = 100;
         final int systemClockUpdateThreshold = 2000;
@@ -186,15 +192,16 @@
                 .pokeThresholds(systemClockUpdateThreshold)
                 .pokeTimeDetectionEnabled(false);
 
-        TimeSignal timeSignal1 = scenario.createTimeSignalForActual(TimeSignal.SOURCE_ID_NITZ);
-        TimestampedValue<Long> utcTime1 = timeSignal1.getUtcTime();
+        PhoneTimeSuggestion timeSuggestion1 =
+                scenario.createPhoneTimeSuggestionForActual(ARBITRARY_PHONE_ID);
+        TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime();
 
         // Simulate time passing.
         mScript.simulateTimePassing(clockIncrementMillis);
 
         // Simulate the time signal being received. It should not be used because auto time
         // detection is off but it should be recorded.
-        mScript.simulateTimeSignalReceived(timeSignal1)
+        mScript.simulatePhoneTimeSuggestion(timeSuggestion1)
                 .verifySystemClockWasNotSetAndResetCallTracking();
 
         // Simulate more time passing.
@@ -216,7 +223,7 @@
         TimestampedValue<Long> utcTime2 = new TimestampedValue<>(
                 mScript.peekElapsedRealtimeMillis(),
                 mScript.peekSystemClockMillis() + systemClockUpdateThreshold);
-        TimeSignal timeSignal2 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime2);
+        PhoneTimeSuggestion timeSuggestion2 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime2);
 
         // Simulate more time passing.
         mScript.simulateTimePassing(clockIncrementMillis);
@@ -226,7 +233,7 @@
 
         // The new time, though valid, should not be set in the system clock because auto time is
         // disabled.
-        mScript.simulateTimeSignalReceived(timeSignal2)
+        mScript.simulatePhoneTimeSuggestion(timeSuggestion2)
                 .verifySystemClockWasNotSetAndResetCallTracking();
 
         // Turn on auto time detection.
@@ -234,17 +241,6 @@
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis2);
     }
 
-    @Test
-    public void testSuggestTime_unknownSource() {
-        Scenario scenario = SCENARIO_1;
-        mScript.pokeFakeClocks(scenario)
-                .pokeTimeDetectionEnabled(true);
-
-        TimeSignal timeSignal = scenario.createTimeSignalForActual("unknown");
-        mScript.simulateTimeSignalReceived(timeSignal)
-                .verifySystemClockWasNotSetAndResetCallTracking();
-    }
-
     /**
      * A fake implementation of TimeDetectorStrategy.Callback. Besides tracking changes and behaving
      * like the real thing should, it also asserts preconditions.
@@ -407,8 +403,8 @@
             return mFakeCallback.peekSystemClockMillis();
         }
 
-        Script simulateTimeSignalReceived(TimeSignal timeSignal) {
-            mSimpleTimeDetectorStrategy.suggestTime(timeSignal);
+        Script simulatePhoneTimeSuggestion(PhoneTimeSuggestion timeSuggestion) {
+            mSimpleTimeDetectorStrategy.suggestPhoneTime(timeSuggestion);
             return this;
         }
 
@@ -466,10 +462,10 @@
             return mActualTimeMillis;
         }
 
-        TimeSignal createTimeSignalForActual(String sourceId) {
+        PhoneTimeSuggestion createPhoneTimeSuggestionForActual(int phoneId) {
             TimestampedValue<Long> time = new TimestampedValue<>(
                     mInitialDeviceRealtimeMillis, mActualTimeMillis);
-            return new TimeSignal(sourceId, time);
+            return new PhoneTimeSuggestion(phoneId, time);
         }
 
         static class Builder {
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 45fef76..37da018 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -28,7 +28,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.app.timedetector.TimeSignal;
+import android.app.timedetector.PhoneTimeSuggestion;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.util.TimestampedValue;
@@ -67,10 +67,10 @@
     public void testStubbedCall_withoutPermission() {
         doThrow(new SecurityException("Mock"))
                 .when(mMockContext).enforceCallingPermission(anyString(), any());
-        TimeSignal timeSignal = createNitzTimeSignal();
+        PhoneTimeSuggestion phoneTimeSuggestion = createPhoneTimeSuggestion();
 
         try {
-            mTimeDetectorService.suggestTime(timeSignal);
+            mTimeDetectorService.suggestPhoneTime(phoneTimeSuggestion);
         } finally {
             verify(mMockContext).enforceCallingPermission(
                     eq(android.Manifest.permission.SET_TIME), anyString());
@@ -78,15 +78,15 @@
     }
 
     @Test
-    public void testSuggestTime() {
+    public void testSuggestPhoneTime() {
         doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
 
-        TimeSignal timeSignal = createNitzTimeSignal();
-        mTimeDetectorService.suggestTime(timeSignal);
+        PhoneTimeSuggestion phoneTimeSuggestion = createPhoneTimeSuggestion();
+        mTimeDetectorService.suggestPhoneTime(phoneTimeSuggestion);
 
         verify(mMockContext)
                 .enforceCallingPermission(eq(android.Manifest.permission.SET_TIME), anyString());
-        mStubbedTimeDetectorStrategy.verifySuggestTimeCalled(timeSignal);
+        mStubbedTimeDetectorStrategy.verifySuggestPhoneTimeCalled(phoneTimeSuggestion);
     }
 
     @Test
@@ -115,15 +115,16 @@
         mStubbedTimeDetectorStrategy.verifyHandleAutoTimeDetectionToggleCalled(false);
     }
 
-    private static TimeSignal createNitzTimeSignal() {
+    private static PhoneTimeSuggestion createPhoneTimeSuggestion() {
+        int phoneId = 1234;
         TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
-        return new TimeSignal(TimeSignal.SOURCE_ID_NITZ, timeValue);
+        return new PhoneTimeSuggestion(phoneId, timeValue);
     }
 
     private static class StubbedTimeDetectorStrategy implements TimeDetectorStrategy {
 
         // Call tracking.
-        private TimeSignal mLastSuggestedTime;
+        private PhoneTimeSuggestion mLastPhoneSuggestion;
         private Boolean mLastAutoTimeDetectionToggle;
         private boolean mDumpCalled;
 
@@ -132,9 +133,9 @@
         }
 
         @Override
-        public void suggestTime(TimeSignal timeSignal) {
+        public void suggestPhoneTime(PhoneTimeSuggestion timeSuggestion) {
             resetCallTracking();
-            mLastSuggestedTime = timeSignal;
+            mLastPhoneSuggestion = timeSuggestion;
         }
 
         @Override
@@ -150,13 +151,13 @@
         }
 
         void resetCallTracking() {
-            mLastSuggestedTime = null;
+            mLastPhoneSuggestion = null;
             mLastAutoTimeDetectionToggle = null;
             mDumpCalled = false;
         }
 
-        void verifySuggestTimeCalled(TimeSignal expectedSignal) {
-            assertEquals(expectedSignal, mLastSuggestedTime);
+        void verifySuggestPhoneTimeCalled(PhoneTimeSuggestion expectedSignal) {
+            assertEquals(expectedSignal, mLastPhoneSuggestion);
         }
 
         void verifyHandleAutoTimeDetectionToggleCalled(boolean expectedEnable) {