Add infra for an internal API for time_detector

Add the infrastructure / plumbing for an internal API for time_detector
service. Methods will be added to TimeDetectorInternal in later commits.

Bug: 219693030
Bug: 222295093
Test: atest services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java
Test: atest services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
Change-Id: I8fd95a2c721432c9d3fa99d6257121e9246b8ab1
This commit is contained in:
Neil Fuller
2022-06-28 14:05:03 +01:00
parent 83ad73ecdc
commit 286769a086
6 changed files with 265 additions and 85 deletions

View File

@@ -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 {
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}
}