diff options
6 files changed, 265 insertions, 85 deletions
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java b/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java new file mode 100644 index 000000000000..181f5adee55f --- /dev/null +++ b/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.timedetector; + +/** + * The internal (in-process) system server API for the {@link + * com.android.server.timedetector.TimeDetectorService}. + * + * <p>The methods on this class can be called from any thread. + * @hide + */ +public interface TimeDetectorInternal { + +} diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java new file mode 100644 index 000000000000..1b47ebb3caaa --- /dev/null +++ b/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.timedetector; + +import android.annotation.NonNull; +import android.content.Context; +import android.os.Handler; + +import java.util.Objects; + +/** + * The real {@link TimeDetectorInternal} local service implementation. + * + * @hide + */ +public class TimeDetectorInternalImpl implements TimeDetectorInternal { + + @NonNull private final Context mContext; + @NonNull private final Handler mHandler; + @NonNull private final TimeDetectorStrategy mTimeDetectorStrategy; + + public TimeDetectorInternalImpl(@NonNull Context context, @NonNull Handler handler, + @NonNull TimeDetectorStrategy timeDetectorStrategy) { + mContext = Objects.requireNonNull(context); + mHandler = Objects.requireNonNull(handler); + mTimeDetectorStrategy = Objects.requireNonNull(timeDetectorStrategy); + } +} diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java index b3ec27b4f0f2..02d3487ac431 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java @@ -83,6 +83,11 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub TimeDetectorStrategy timeDetectorStrategy = TimeDetectorStrategyImpl.create(context, handler, serviceConfigAccessor); + // Create and publish the local service for use by internal callers. + TimeDetectorInternal internal = + new TimeDetectorInternalImpl(context, handler, timeDetectorStrategy); + publishLocalService(TimeDetectorInternal.class, internal); + TimeDetectorService service = new TimeDetectorService( context, handler, serviceConfigAccessor, timeDetectorStrategy); diff --git a/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java b/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java new file mode 100644 index 000000000000..d016d7e3e748 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.timedetector; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.annotation.UserIdInt; +import android.app.time.ExternalTimeSuggestion; +import android.app.timedetector.GnssTimeSuggestion; +import android.app.timedetector.ManualTimeSuggestion; +import android.app.timedetector.NetworkTimeSuggestion; +import android.app.timedetector.TelephonyTimeSuggestion; +import android.util.IndentingPrintWriter; + +/** + * A fake implementation of {@link com.android.server.timedetector.TimeDetectorStrategy} for use + * in tests. + */ +class FakeTimeDetectorStrategy implements TimeDetectorStrategy { + + // Call tracking. + private TelephonyTimeSuggestion mLastTelephonySuggestion; + private @UserIdInt Integer mLastManualSuggestionUserId; + private ManualTimeSuggestion mLastManualSuggestion; + private NetworkTimeSuggestion mLastNetworkSuggestion; + private GnssTimeSuggestion mLastGnssSuggestion; + private ExternalTimeSuggestion mLastExternalSuggestion; + private boolean mDumpCalled; + + @Override + public void suggestTelephonyTime(TelephonyTimeSuggestion timeSuggestion) { + mLastTelephonySuggestion = timeSuggestion; + } + + @Override + public boolean suggestManualTime(@UserIdInt int userId, ManualTimeSuggestion timeSuggestion) { + mLastManualSuggestionUserId = userId; + mLastManualSuggestion = timeSuggestion; + return true; + } + + @Override + public void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion) { + mLastNetworkSuggestion = timeSuggestion; + } + + @Override + public void suggestGnssTime(GnssTimeSuggestion timeSuggestion) { + mLastGnssSuggestion = timeSuggestion; + } + + @Override + public void suggestExternalTime(ExternalTimeSuggestion timeSuggestion) { + mLastExternalSuggestion = timeSuggestion; + } + + @Override + public void dump(IndentingPrintWriter pw, String[] args) { + mDumpCalled = true; + } + + void resetCallTracking() { + mLastTelephonySuggestion = null; + mLastManualSuggestionUserId = null; + mLastManualSuggestion = null; + mLastNetworkSuggestion = null; + mLastGnssSuggestion = null; + mLastExternalSuggestion = null; + mDumpCalled = false; + } + + void verifySuggestTelephonyTimeCalled(TelephonyTimeSuggestion expectedSuggestion) { + assertEquals(expectedSuggestion, mLastTelephonySuggestion); + } + + void verifySuggestManualTimeCalled( + @UserIdInt int expectedUserId, ManualTimeSuggestion expectedSuggestion) { + assertEquals((Integer) expectedUserId, mLastManualSuggestionUserId); + assertEquals(expectedSuggestion, mLastManualSuggestion); + } + + void verifySuggestNetworkTimeCalled(NetworkTimeSuggestion expectedSuggestion) { + assertEquals(expectedSuggestion, mLastNetworkSuggestion); + } + + void verifySuggestGnssTimeCalled(GnssTimeSuggestion expectedSuggestion) { + assertEquals(expectedSuggestion, mLastGnssSuggestion); + } + + void verifySuggestExternalTimeCalled(ExternalTimeSuggestion expectedSuggestion) { + assertEquals(expectedSuggestion, mLastExternalSuggestion); + } + + void verifyDumpCalled() { + assertTrue(mDumpCalled); + } +} diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java new file mode 100644 index 000000000000..06512fbfed06 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.timedetector; + +import static org.mockito.Mockito.mock; + +import android.content.Context; +import android.os.HandlerThread; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.server.timezonedetector.TestHandler; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class TimeDetectorInternalImplTest { + + private Context mMockContext; + private FakeTimeDetectorStrategy mFakeTimeDetectorStrategy; + + private TimeDetectorInternalImpl mTimeDetectorInternal; + private HandlerThread mHandlerThread; + private TestHandler mTestHandler; + + @Before + public void setUp() { + mMockContext = mock(Context.class); + + // Create a thread + handler for processing the work that the service posts. + mHandlerThread = new HandlerThread("TimeDetectorInternalTest"); + mHandlerThread.start(); + mTestHandler = new TestHandler(mHandlerThread.getLooper()); + + mFakeTimeDetectorStrategy = new FakeTimeDetectorStrategy(); + + mTimeDetectorInternal = new TimeDetectorInternalImpl( + mMockContext, mTestHandler, mFakeTimeDetectorStrategy); + } + + @Test + public void placeholder() { + // A placeholder test until there are real methods to test. + } + + @After + public void tearDown() throws Exception { + mHandlerThread.quit(); + mHandlerThread.join(); + } +} 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 2570158f50b2..702ebeb3a4f9 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java @@ -49,7 +49,6 @@ import android.os.HandlerThread; import android.os.IBinder; import android.os.ParcelableException; import android.os.TimestampedValue; -import android.util.IndentingPrintWriter; import android.util.NtpTrustedTime; import androidx.test.runner.AndroidJUnit4; @@ -82,7 +81,7 @@ public class TimeDetectorServiceTest { private TestCallerIdentityInjector mTestCallerIdentityInjector; private FakeServiceConfigAccessor mFakeServiceConfigAccessor; private NtpTrustedTime mMockNtpTrustedTime; - private StubbedTimeDetectorStrategy mStubbedTimeDetectorStrategy; + private FakeTimeDetectorStrategy mFakeTimeDetectorStrategy; @Before @@ -97,13 +96,13 @@ public class TimeDetectorServiceTest { mTestCallerIdentityInjector = new TestCallerIdentityInjector(); mTestCallerIdentityInjector.initializeCallingUserId(ARBITRARY_USER_ID); - mStubbedTimeDetectorStrategy = new StubbedTimeDetectorStrategy(); + mFakeTimeDetectorStrategy = new FakeTimeDetectorStrategy(); mFakeServiceConfigAccessor = new FakeServiceConfigAccessor(); mMockNtpTrustedTime = mock(NtpTrustedTime.class); mTimeDetectorService = new TimeDetectorService( mMockContext, mTestHandler, mFakeServiceConfigAccessor, - mStubbedTimeDetectorStrategy, mTestCallerIdentityInjector, mMockNtpTrustedTime); + mFakeTimeDetectorStrategy, mTestCallerIdentityInjector, mMockNtpTrustedTime); } @After @@ -281,7 +280,7 @@ public class TimeDetectorServiceTest { anyString()); mTestHandler.waitForMessagesToBeProcessed(); - mStubbedTimeDetectorStrategy.verifySuggestTelephonyTimeCalled(timeSuggestion); + mFakeTimeDetectorStrategy.verifySuggestTelephonyTimeCalled(timeSuggestion); } @Test(expected = SecurityException.class) @@ -307,7 +306,8 @@ public class TimeDetectorServiceTest { ManualTimeSuggestion manualTimeSuggestion = createManualTimeSuggestion(); assertTrue(mTimeDetectorService.suggestManualTime(manualTimeSuggestion)); - mStubbedTimeDetectorStrategy.verifySuggestManualTimeCalled(manualTimeSuggestion); + mFakeTimeDetectorStrategy.verifySuggestManualTimeCalled( + mTestCallerIdentityInjector.getCallingUserId(), manualTimeSuggestion); verify(mMockContext).enforceCallingOrSelfPermission( eq(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE), @@ -342,7 +342,7 @@ public class TimeDetectorServiceTest { eq(android.Manifest.permission.SET_TIME), anyString()); mTestHandler.waitForMessagesToBeProcessed(); - mStubbedTimeDetectorStrategy.verifySuggestNetworkTimeCalled(NetworkTimeSuggestion); + mFakeTimeDetectorStrategy.verifySuggestNetworkTimeCalled(NetworkTimeSuggestion); } @Test(expected = SecurityException.class) @@ -372,7 +372,7 @@ public class TimeDetectorServiceTest { eq(android.Manifest.permission.SET_TIME), anyString()); mTestHandler.waitForMessagesToBeProcessed(); - mStubbedTimeDetectorStrategy.verifySuggestGnssTimeCalled(gnssTimeSuggestion); + mFakeTimeDetectorStrategy.verifySuggestGnssTimeCalled(gnssTimeSuggestion); } @Test(expected = SecurityException.class) @@ -402,7 +402,7 @@ public class TimeDetectorServiceTest { eq(android.Manifest.permission.SUGGEST_EXTERNAL_TIME), anyString()); mTestHandler.waitForMessagesToBeProcessed(); - mStubbedTimeDetectorStrategy.verifySuggestExternalTimeCalled(externalTimeSuggestion); + mFakeTimeDetectorStrategy.verifySuggestExternalTimeCalled(externalTimeSuggestion); } @Test @@ -431,7 +431,7 @@ public class TimeDetectorServiceTest { mTimeDetectorService.dump(null, pw, null); verify(mMockContext).checkCallingOrSelfPermission(eq(android.Manifest.permission.DUMP)); - mStubbedTimeDetectorStrategy.verifyDumpCalled(); + mFakeTimeDetectorStrategy.verifyDumpCalled(); } private static TimeConfiguration createTimeConfiguration(boolean autoDetectionEnabled) { @@ -478,79 +478,4 @@ public class TimeDetectorServiceTest { private static ExternalTimeSuggestion createExternalTimeSuggestion() { return new ExternalTimeSuggestion(100L, 1_000_000L); } - - private static class StubbedTimeDetectorStrategy implements TimeDetectorStrategy { - - // Call tracking. - private TelephonyTimeSuggestion mLastTelephonySuggestion; - private ManualTimeSuggestion mLastManualSuggestion; - private NetworkTimeSuggestion mLastNetworkSuggestion; - private GnssTimeSuggestion mLastGnssSuggestion; - private ExternalTimeSuggestion mLastExternalSuggestion; - private boolean mDumpCalled; - - @Override - public void suggestTelephonyTime(TelephonyTimeSuggestion timeSuggestion) { - mLastTelephonySuggestion = timeSuggestion; - } - - @Override - public boolean suggestManualTime(int userId, ManualTimeSuggestion timeSuggestion) { - mLastManualSuggestion = timeSuggestion; - return true; - } - - @Override - public void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion) { - mLastNetworkSuggestion = timeSuggestion; - } - - @Override - public void suggestGnssTime(GnssTimeSuggestion timeSuggestion) { - mLastGnssSuggestion = timeSuggestion; - } - - @Override - public void suggestExternalTime(ExternalTimeSuggestion timeSuggestion) { - mLastExternalSuggestion = timeSuggestion; - } - - @Override - public void dump(IndentingPrintWriter pw, String[] args) { - mDumpCalled = true; - } - - void resetCallTracking() { - mLastTelephonySuggestion = null; - mLastManualSuggestion = null; - mLastNetworkSuggestion = null; - mLastGnssSuggestion = null; - mLastExternalSuggestion = null; - mDumpCalled = false; - } - - void verifySuggestTelephonyTimeCalled(TelephonyTimeSuggestion expectedSuggestion) { - assertEquals(expectedSuggestion, mLastTelephonySuggestion); - } - - void verifySuggestManualTimeCalled(ManualTimeSuggestion expectedSuggestion) { - assertEquals(expectedSuggestion, mLastManualSuggestion); - } - - void verifySuggestNetworkTimeCalled(NetworkTimeSuggestion expectedSuggestion) { - assertEquals(expectedSuggestion, mLastNetworkSuggestion); - } - - void verifySuggestGnssTimeCalled(GnssTimeSuggestion expectedSuggestion) { - assertEquals(expectedSuggestion, mLastGnssSuggestion); - } - - void verifySuggestExternalTimeCalled(ExternalTimeSuggestion expectedSuggestion) { - assertEquals(expectedSuggestion, mLastExternalSuggestion); - } - - void verifyDumpCalled() { - assertTrue(mDumpCalled); - } - } } |