diff options
7 files changed, 79 insertions, 58 deletions
diff --git a/core/java/android/app/time/ExternalTimeSuggestion.java b/core/java/android/app/time/ExternalTimeSuggestion.java index b566eab9867d..61defb588170 100644 --- a/core/java/android/app/time/ExternalTimeSuggestion.java +++ b/core/java/android/app/time/ExternalTimeSuggestion.java @@ -16,6 +16,8 @@ package android.app.time; +import android.annotation.CurrentTimeMillisLong; +import android.annotation.ElapsedRealtimeLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; @@ -31,9 +33,9 @@ import java.util.Objects; /** * A time signal from an External source. * - * External time suggestions are for use in situations where the Android device is part of a wider - * network of devices that are required to use a single time source, and where authority for the - * time is external to the Android device. For example, for the Android Auto use case where the + * <p>External time suggestions are for use in situations where the Android device is part of a + * wider network of devices that are required to use a single time source, and where authority for + * the time is external to the Android device. For example, for the Android Auto use case where the * Android device is part of a wider in-car network of devices that should display the same time. * * <p>Android allows for a single external source for time. If there are several external sources @@ -49,19 +51,19 @@ import java.util.Objects; * capture the elapsed realtime reference clock, e.g. via {@link SystemClock#elapsedRealtime()}, * when the UTC time is first obtained (usually under a wakelock). This enables Android to adjust * for latency introduced between suggestion creation and eventual use. Adjustments for other - * sources of latency, i.e. those before the external time suggestion is created, must be handled - * by the creator. + * sources of latency, i.e. those before the external time suggestion is created, must be handled by + * the creator. * - * <p>{@code utcTime} is the suggested time. The {@code utcTime.value} is the number of milliseconds - * elapsed since 1/1/1970 00:00:00 UTC. The {@code utcTime.referenceTimeMillis} is the value of the - * elapsed realtime clock when the {@code utcTime.value} was established. - * Note that the elapsed realtime clock is considered accurate but it is volatile, so time - * suggestions cannot be persisted across device resets. + * <p>{@code elapsedRealtimeMillis} and {@code suggestionMillis} represent the suggested time. + * {@code suggestionMillis} is the number of milliseconds elapsed since 1/1/1970 00:00:00 UTC. + * {@code elapsedRealtimeMillis} is the value of the elapsed realtime clock when {@code + * suggestionMillis} was established. Note that the elapsed realtime clock is considered accurate + * but it is volatile, so time suggestions cannot be persisted across device resets. * * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to * record why the suggestion exists and how it was entered. This information exists only to aid in - * debugging and therefore is used by {@link #toString()}, but it is not for use in detection - * logic and is not considered in {@link #hashCode()} or {@link #equals(Object)}. + * debugging and therefore is used by {@link #toString()}, but it is not for use in detection logic + * and is not considered in {@link #hashCode()} or {@link #equals(Object)}. * * @hide */ @@ -78,17 +80,28 @@ public final class ExternalTimeSuggestion implements Parcelable { } }; - @NonNull private final TimestampedValue<Long> mUtcTime; - @Nullable private ArrayList<String> mDebugInfo; + @NonNull + private final TimestampedValue<Long> mUtcTime; + @Nullable + private ArrayList<String> mDebugInfo; - public ExternalTimeSuggestion(@NonNull TimestampedValue<Long> utcTime) { - mUtcTime = Objects.requireNonNull(utcTime); - Objects.requireNonNull(utcTime.getValue()); + /** + * Creates a time suggestion cross-referenced to the elapsed realtime clock. See {@link + * ExternalTimeSuggestion} for more details. + * + * @param elapsedRealtimeMillis the elapsed realtime clock reference for the suggestion + * @param suggestionMillis the suggested UTC time in milliseconds since the start of the + * Unix epoch + */ + public ExternalTimeSuggestion(@ElapsedRealtimeLong long elapsedRealtimeMillis, + @CurrentTimeMillisLong long suggestionMillis) { + mUtcTime = new TimestampedValue(elapsedRealtimeMillis, suggestionMillis); } private static ExternalTimeSuggestion createFromParcel(Parcel in) { TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */); - ExternalTimeSuggestion suggestion = new ExternalTimeSuggestion(utcTime); + ExternalTimeSuggestion suggestion = + new ExternalTimeSuggestion(utcTime.getReferenceTimeMillis(), utcTime.getValue()); @SuppressWarnings("unchecked") ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */); suggestion.mDebugInfo = debugInfo; @@ -106,23 +119,31 @@ public final class ExternalTimeSuggestion implements Parcelable { dest.writeList(mDebugInfo); } + /** + * {@hide} + */ @NonNull public TimestampedValue<Long> getUtcTime() { return mUtcTime; } + /** + * Returns information that can be useful for debugging / logging. See {@link #addDebugInfo}. + * {@hide} + */ @NonNull public List<String> getDebugInfo() { return mDebugInfo == null - ? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo); + ? Collections.emptyList() + : 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()}. + * information is present in {@link #toString()} but is not considered for {@link + * #equals(Object)} and {@link #hashCode()}. */ - public void addDebugInfo(String... debugInfos) { + public void addDebugInfo(@NonNull String... debugInfos) { if (mDebugInfo == null) { mDebugInfo = new ArrayList<>(); } @@ -148,9 +169,7 @@ public final class ExternalTimeSuggestion implements Parcelable { @Override public String toString() { - return "ExternalTimeSuggestion{" - + "mUtcTime=" + mUtcTime - + ", mDebugInfo=" + mDebugInfo + return "ExternalTimeSuggestion{" + "mUtcTime=" + mUtcTime + ", mDebugInfo=" + mDebugInfo + '}'; } } diff --git a/core/java/android/app/time/TimeManager.java b/core/java/android/app/time/TimeManager.java index 262d244c5b1c..430960fb11a8 100644 --- a/core/java/android/app/time/TimeManager.java +++ b/core/java/android/app/time/TimeManager.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; +import android.app.timedetector.ITimeDetectorService; import android.app.timezonedetector.ITimeZoneDetectorService; import android.content.Context; import android.os.RemoteException; @@ -45,6 +46,7 @@ public final class TimeManager { private final Object mLock = new Object(); private final ITimeZoneDetectorService mITimeZoneDetectorService; + private final ITimeDetectorService mITimeDetectorService; @GuardedBy("mLock") private ITimeZoneDetectorListener mTimeZoneDetectorReceiver; @@ -62,6 +64,8 @@ public final class TimeManager { // internal refactoring. mITimeZoneDetectorService = ITimeZoneDetectorService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.TIME_ZONE_DETECTOR_SERVICE)); + mITimeDetectorService = ITimeDetectorService.Stub.asInterface( + ServiceManager.getServiceOrThrow(Context.TIME_DETECTOR_SERVICE)); } /** @@ -214,4 +218,23 @@ public final class TimeManager { } } } + + /** + * Suggests the current time from an external time source. For example, a form factor-specific + * HAL. This time <em>may</em> be used to set the device system clock, depending on the device + * configuration and user settings. This method call is processed asynchronously. + * See {@link ExternalTimeSuggestion} for more details. + * {@hide} + */ + @RequiresPermission(android.Manifest.permission.SET_TIME) + public void suggestExternalTime(@NonNull ExternalTimeSuggestion timeSuggestion) { + if (DEBUG) { + Log.d(TAG, "suggestExternalTime called: " + timeSuggestion); + } + try { + mITimeDetectorService.suggestExternalTime(timeSuggestion); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java index 76f378590ae2..52016b65688b 100644 --- a/core/java/android/app/timedetector/TimeDetector.java +++ b/core/java/android/app/timedetector/TimeDetector.java @@ -19,7 +19,6 @@ package android.app.timedetector; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemService; -import android.app.time.ExternalTimeSuggestion; import android.content.Context; import android.os.SystemClock; import android.os.TimestampedValue; @@ -80,12 +79,4 @@ public interface TimeDetector { */ @RequiresPermission(android.Manifest.permission.SET_TIME) void suggestGnssTime(GnssTimeSuggestion timeSuggestion); - - /** - * Suggests the time according to an external time source (form factor specific HAL, etc). - * - * @hide - */ - @RequiresPermission(android.Manifest.permission.SET_TIME) - void suggestExternalTime(ExternalTimeSuggestion timeSuggestion); } diff --git a/core/java/android/app/timedetector/TimeDetectorImpl.java b/core/java/android/app/timedetector/TimeDetectorImpl.java index ef818ef647d6..b0aa3c8d4575 100644 --- a/core/java/android/app/timedetector/TimeDetectorImpl.java +++ b/core/java/android/app/timedetector/TimeDetectorImpl.java @@ -17,7 +17,6 @@ package android.app.timedetector; import android.annotation.NonNull; -import android.app.time.ExternalTimeSuggestion; import android.content.Context; import android.os.RemoteException; import android.os.ServiceManager; @@ -87,16 +86,4 @@ public final class TimeDetectorImpl implements TimeDetector { throw e.rethrowFromSystemServer(); } } - - @Override - public void suggestExternalTime(ExternalTimeSuggestion timeSuggestion) { - if (DEBUG) { - Log.d(TAG, "suggestExternalTime called: " + timeSuggestion); - } - try { - mITimeDetectorService.suggestExternalTime(timeSuggestion); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } } diff --git a/core/tests/coretests/src/android/app/time/ExternalTimeSuggestionTest.java b/core/tests/coretests/src/android/app/time/ExternalTimeSuggestionTest.java index 266ff3dd09f6..1c6b3cc47a45 100644 --- a/core/tests/coretests/src/android/app/time/ExternalTimeSuggestionTest.java +++ b/core/tests/coretests/src/android/app/time/ExternalTimeSuggestionTest.java @@ -33,17 +33,20 @@ public class ExternalTimeSuggestionTest { @Test public void testEquals() { - ExternalTimeSuggestion one = new ExternalTimeSuggestion(ARBITRARY_TIME); + ExternalTimeSuggestion one = new ExternalTimeSuggestion( + ARBITRARY_TIME.getReferenceTimeMillis(), + ARBITRARY_TIME.getValue()); assertEquals(one, one); - ExternalTimeSuggestion two = new ExternalTimeSuggestion(ARBITRARY_TIME); + ExternalTimeSuggestion two = new ExternalTimeSuggestion( + ARBITRARY_TIME.getReferenceTimeMillis(), + ARBITRARY_TIME.getValue()); assertEquals(one, two); assertEquals(two, one); - TimestampedValue<Long> differentTime = new TimestampedValue<>( + ExternalTimeSuggestion three = new ExternalTimeSuggestion( ARBITRARY_TIME.getReferenceTimeMillis() + 1, ARBITRARY_TIME.getValue()); - ExternalTimeSuggestion three = new ExternalTimeSuggestion(differentTime); assertNotEquals(one, three); assertNotEquals(three, one); @@ -55,7 +58,9 @@ public class ExternalTimeSuggestionTest { @Test public void testParcelable() { - ExternalTimeSuggestion suggestion = new ExternalTimeSuggestion(ARBITRARY_TIME); + ExternalTimeSuggestion suggestion = new ExternalTimeSuggestion( + ARBITRARY_TIME.getReferenceTimeMillis(), + ARBITRARY_TIME.getValue()); assertRoundTripParcelable(suggestion); // DebugInfo should also be stored (but is not checked by equals()) 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 55748366c1ba..5f86d282406a 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java @@ -287,8 +287,7 @@ public class TimeDetectorServiceTest { } private static ExternalTimeSuggestion createExternalTimeSuggestion() { - TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L); - return new ExternalTimeSuggestion(timeValue); + return new ExternalTimeSuggestion(100L, 1_000_000L); } private static class StubbedTimeDetectorStrategy implements TimeDetectorStrategy { 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 daa1b25de22f..f7a498bc9d73 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java @@ -1483,11 +1483,8 @@ public class TimeDetectorStrategyImplTest { * reference time. */ ExternalTimeSuggestion generateExternalTimeSuggestion(Instant suggestedTime) { - TimestampedValue<Long> utcTime = - new TimestampedValue<>( - mFakeEnvironment.peekElapsedRealtimeMillis(), + return new ExternalTimeSuggestion(mFakeEnvironment.peekElapsedRealtimeMillis(), suggestedTime.toEpochMilli()); - return new ExternalTimeSuggestion(utcTime); } /** |