Make CTS tests ambivalent to server impl
Implement shell command test support that will work regardless of which of the two location NetworkTimeHelper implementations is in use at the time. This is to prevent CTS breaking if OEMs or form factors switch the implementation to the new one during the next Android release cycle. New shell commands have been added temporarily to support the new SystemClockNetworkTimeTest and do the right thing depending on the implementation in use. This avoids the need for the tests to know which impl is in use. In a future release cycle, when the old impl is deleted these shell commands can be removed and the test changed as the new impl uses the time_detector and suitable commands (mostly) exist for other reasons. Bug: 222295093 Test: atest services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java Test: See associated CTS change Change-Id: Icca02ec263bb20bc02a0dd6dd6cc13342d9e4e7b
This commit is contained in:
@@ -114,6 +114,20 @@ public interface TimeDetector {
|
||||
*/
|
||||
String SHELL_COMMAND_CONFIRM_TIME = "confirm_time";
|
||||
|
||||
/**
|
||||
* A shell command that clears the network time signal used by {@link
|
||||
* SystemClock#currentNetworkTimeClock()}.
|
||||
* @hide
|
||||
*/
|
||||
String SHELL_COMMAND_CLEAR_SYSTEM_CLOCK_NETWORK_TIME = "clear_system_clock_network_time";
|
||||
|
||||
/**
|
||||
* A shell command that sets the network time signal used by {@link
|
||||
* SystemClock#currentNetworkTimeClock()}.
|
||||
* @hide
|
||||
*/
|
||||
String SHELL_COMMAND_SET_SYSTEM_CLOCK_NETWORK_TIME = "set_system_clock_network_time";
|
||||
|
||||
/**
|
||||
* A shared utility method to create a {@link ManualTimeSuggestion}.
|
||||
*
|
||||
|
||||
@@ -477,7 +477,14 @@ public abstract class NtpTrustedTime implements TrustedTime {
|
||||
return mTimeResult;
|
||||
}
|
||||
|
||||
/** Clears the last received NTP. Intended for use during tests. */
|
||||
/** Sets the last received NTP time. Intended for use during tests. */
|
||||
public void setCachedTimeResult(TimeResult timeResult) {
|
||||
synchronized (this) {
|
||||
mTimeResult = timeResult;
|
||||
}
|
||||
}
|
||||
|
||||
/** Clears the last received NTP time. Intended for use during tests. */
|
||||
public void clearCachedTimeResult() {
|
||||
synchronized (this) {
|
||||
mTimeResult = null;
|
||||
|
||||
@@ -180,24 +180,6 @@ public class NetworkTimeUpdateService extends Binder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cached NTP time. For use during tests to simulate when no NTP time is available.
|
||||
*
|
||||
* <p>This operation takes place in the calling thread rather than the service's handler thread.
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.SET_TIME)
|
||||
void clearTimeForTests() {
|
||||
mContext.enforceCallingPermission(
|
||||
android.Manifest.permission.SET_TIME, "clear latest network time");
|
||||
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mNtpTrustedTime.clearCachedTimeResult();
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the service to refresh the NTP time.
|
||||
*
|
||||
|
||||
@@ -36,11 +36,6 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
|
||||
*/
|
||||
private static final String SHELL_COMMAND_SERVICE_NAME = "network_time_update_service";
|
||||
|
||||
/**
|
||||
* A shell command that clears the time signal received from the network.
|
||||
*/
|
||||
private static final String SHELL_COMMAND_CLEAR_TIME = "clear_time";
|
||||
|
||||
/**
|
||||
* A shell command that forces the time signal to be refreshed from the network.
|
||||
*/
|
||||
@@ -73,8 +68,6 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case SHELL_COMMAND_CLEAR_TIME:
|
||||
return runClearTime();
|
||||
case SHELL_COMMAND_FORCE_REFRESH:
|
||||
return runForceRefresh();
|
||||
case SHELL_COMMAND_SET_SERVER_CONFIG:
|
||||
@@ -87,11 +80,6 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private int runClearTime() {
|
||||
mNetworkTimeUpdateService.clearTimeForTests();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runForceRefresh() {
|
||||
boolean success = mNetworkTimeUpdateService.forceRefreshForTests();
|
||||
getOutPrintWriter().println(success);
|
||||
@@ -147,8 +135,6 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
|
||||
pw.printf("Network Time Update Service (%s) commands:\n", SHELL_COMMAND_SERVICE_NAME);
|
||||
pw.printf(" help\n");
|
||||
pw.printf(" Print this help text.\n");
|
||||
pw.printf(" %s\n", SHELL_COMMAND_CLEAR_TIME);
|
||||
pw.printf(" Clears the latest time.\n");
|
||||
pw.printf(" %s\n", SHELL_COMMAND_FORCE_REFRESH);
|
||||
pw.printf(" Refreshes the latest time. Prints whether it was successful.\n");
|
||||
pw.printf(" %s\n", SHELL_COMMAND_SET_SERVER_CONFIG);
|
||||
|
||||
@@ -37,6 +37,7 @@ import android.os.ParcelableException;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ResultReceiver;
|
||||
import android.os.ShellCallback;
|
||||
import android.os.SystemClock;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.NtpTrustedTime;
|
||||
@@ -53,6 +54,7 @@ import com.android.server.timezonedetector.CurrentUserIdentityInjector;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.time.DateTimeException;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -377,7 +379,7 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
|
||||
*
|
||||
* <p>This operation takes place in the calling thread.
|
||||
*/
|
||||
void clearNetworkTime() {
|
||||
void clearLatestNetworkTime() {
|
||||
enforceSuggestNetworkTimePermission();
|
||||
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
@@ -390,12 +392,29 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
|
||||
|
||||
@Override
|
||||
public UnixEpochTime latestNetworkTime() {
|
||||
NetworkTimeSuggestion suggestion = getLatestNetworkSuggestion();
|
||||
if (suggestion != null) {
|
||||
return suggestion.getUnixEpochTime();
|
||||
NetworkTimeSuggestion latestNetworkTime;
|
||||
// TODO(b/222295093): Remove this condition once we can be sure that all uses of
|
||||
// NtpTrustedTime result in a suggestion being made to the time detector.
|
||||
// mNtpTrustedTime can be removed once this happens.
|
||||
if (TimeDetectorNetworkTimeHelper.isInUse()) {
|
||||
// The new implementation.
|
||||
latestNetworkTime = mTimeDetectorStrategy.getLatestNetworkSuggestion();
|
||||
} else {
|
||||
// The old implementation.
|
||||
NtpTrustedTime.TimeResult ntpResult = mNtpTrustedTime.getCachedTimeResult();
|
||||
if (ntpResult != null) {
|
||||
latestNetworkTime = new NetworkTimeSuggestion(
|
||||
new UnixEpochTime(
|
||||
ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis()),
|
||||
ntpResult.getUncertaintyMillis());
|
||||
} else {
|
||||
latestNetworkTime = null;
|
||||
}
|
||||
}
|
||||
if (latestNetworkTime == null) {
|
||||
throw new ParcelableException(new DateTimeException("Missing network time fix"));
|
||||
}
|
||||
return latestNetworkTime.getUnixEpochTime();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -403,23 +422,7 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
|
||||
*/
|
||||
@Nullable
|
||||
NetworkTimeSuggestion getLatestNetworkSuggestion() {
|
||||
// TODO(b/222295093): Return the latest network time from mTimeDetectorStrategy once we can
|
||||
// be sure that all uses of NtpTrustedTime results in a suggestion being made to the time
|
||||
// detector. mNtpTrustedTime can be removed once this happens.
|
||||
if (TimeDetectorNetworkTimeHelper.isInUse()) {
|
||||
// The new implementation.
|
||||
return mTimeDetectorStrategy.getLatestNetworkSuggestion();
|
||||
} else {
|
||||
// The old implementation.
|
||||
NtpTrustedTime.TimeResult ntpResult = mNtpTrustedTime.getCachedTimeResult();
|
||||
if (ntpResult != null) {
|
||||
UnixEpochTime unixEpochTime = new UnixEpochTime(
|
||||
ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis());
|
||||
return new NetworkTimeSuggestion(unixEpochTime, ntpResult.getUncertaintyMillis());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return mTimeDetectorStrategy.getLatestNetworkSuggestion();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -440,6 +443,57 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
|
||||
mHandler.post(() -> mTimeDetectorStrategy.suggestExternalTime(timeSignal));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the network time for testing {@link SystemClock#currentNetworkTimeClock()}.
|
||||
*
|
||||
* <p>This operation takes place in the calling thread.
|
||||
*/
|
||||
void setNetworkTimeForSystemClockForTests(
|
||||
@NonNull UnixEpochTime unixEpochTime, int uncertaintyMillis) {
|
||||
enforceSuggestNetworkTimePermission();
|
||||
|
||||
// TODO(b/222295093): Remove this condition once we can be sure that all uses of
|
||||
// NtpTrustedTime result in a suggestion being made to the time detector.
|
||||
// mNtpTrustedTime can be removed once this happens.
|
||||
if (TimeDetectorNetworkTimeHelper.isInUse()) {
|
||||
NetworkTimeSuggestion suggestion =
|
||||
new NetworkTimeSuggestion(unixEpochTime, uncertaintyMillis);
|
||||
suggestion.addDebugInfo("Injected for tests");
|
||||
mTimeDetectorStrategy.suggestNetworkTime(suggestion);
|
||||
} else {
|
||||
NtpTrustedTime.TimeResult timeResult = new NtpTrustedTime.TimeResult(
|
||||
unixEpochTime.getUnixEpochTimeMillis(),
|
||||
unixEpochTime.getElapsedRealtimeMillis(),
|
||||
uncertaintyMillis,
|
||||
InetSocketAddress.createUnresolved("time.set.for.tests", 123));
|
||||
mNtpTrustedTime.setCachedTimeResult(timeResult);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the network time for testing {@link SystemClock#currentNetworkTimeClock()}.
|
||||
*
|
||||
* <p>This operation takes place in the calling thread.
|
||||
*/
|
||||
void clearNetworkTimeForSystemClockForTests() {
|
||||
enforceSuggestNetworkTimePermission();
|
||||
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
// TODO(b/222295093): Remove this condition once we can be sure that all uses of
|
||||
// NtpTrustedTime result in a suggestion being made to the time detector.
|
||||
// mNtpTrustedTime can be removed once this happens.
|
||||
if (TimeDetectorNetworkTimeHelper.isInUse()) {
|
||||
// Clear the latest network suggestion. Done in all c
|
||||
mTimeDetectorStrategy.clearLatestNetworkSuggestion();
|
||||
} else {
|
||||
mNtpTrustedTime.clearCachedTimeResult();
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
|
||||
@Nullable String[] args) {
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
package com.android.server.timedetector;
|
||||
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_CLEAR_NETWORK_TIME;
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_CLEAR_SYSTEM_CLOCK_NETWORK_TIME;
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_CONFIRM_TIME;
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_GET_NETWORK_TIME;
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_GET_TIME_STATE;
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED;
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SERVICE_NAME;
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SET_AUTO_DETECTION_ENABLED;
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SET_SYSTEM_CLOCK_NETWORK_TIME;
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SET_TIME_STATE;
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SUGGEST_EXTERNAL_TIME;
|
||||
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SUGGEST_GNSS_TIME;
|
||||
@@ -73,9 +75,9 @@ class TimeDetectorShellCommand extends ShellCommand {
|
||||
case SHELL_COMMAND_SUGGEST_NETWORK_TIME:
|
||||
return runSuggestNetworkTime();
|
||||
case SHELL_COMMAND_GET_NETWORK_TIME:
|
||||
return runGetNetworkTime();
|
||||
return runGetLatestNetworkTime();
|
||||
case SHELL_COMMAND_CLEAR_NETWORK_TIME:
|
||||
return runClearNetworkTime();
|
||||
return runClearLatestNetworkTime();
|
||||
case SHELL_COMMAND_SUGGEST_GNSS_TIME:
|
||||
return runSuggestGnssTime();
|
||||
case SHELL_COMMAND_SUGGEST_EXTERNAL_TIME:
|
||||
@@ -86,6 +88,10 @@ class TimeDetectorShellCommand extends ShellCommand {
|
||||
return runSetTimeState();
|
||||
case SHELL_COMMAND_CONFIRM_TIME:
|
||||
return runConfirmTime();
|
||||
case SHELL_COMMAND_CLEAR_SYSTEM_CLOCK_NETWORK_TIME:
|
||||
return runClearSystemClockNetworkTime();
|
||||
case SHELL_COMMAND_SET_SYSTEM_CLOCK_NETWORK_TIME:
|
||||
return runSetSystemClockNetworkTime();
|
||||
default: {
|
||||
return handleDefaultCommands(cmd);
|
||||
}
|
||||
@@ -128,15 +134,15 @@ class TimeDetectorShellCommand extends ShellCommand {
|
||||
mInterface::suggestNetworkTime);
|
||||
}
|
||||
|
||||
private int runGetNetworkTime() {
|
||||
private int runGetLatestNetworkTime() {
|
||||
NetworkTimeSuggestion networkTimeSuggestion = mInterface.getLatestNetworkSuggestion();
|
||||
final PrintWriter pw = getOutPrintWriter();
|
||||
pw.println(networkTimeSuggestion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runClearNetworkTime() {
|
||||
mInterface.clearNetworkTime();
|
||||
private int runClearLatestNetworkTime() {
|
||||
mInterface.clearLatestNetworkTime();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -187,6 +193,20 @@ class TimeDetectorShellCommand extends ShellCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runClearSystemClockNetworkTime() {
|
||||
mInterface.clearNetworkTimeForSystemClockForTests();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runSetSystemClockNetworkTime() {
|
||||
NetworkTimeSuggestion networkTimeSuggestion =
|
||||
NetworkTimeSuggestion.parseCommandLineArg(this);
|
||||
mInterface.setNetworkTimeForSystemClockForTests(
|
||||
networkTimeSuggestion.getUnixEpochTime(),
|
||||
networkTimeSuggestion.getUncertaintyMillis());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHelp() {
|
||||
final PrintWriter pw = getOutPrintWriter();
|
||||
@@ -218,6 +238,16 @@ class TimeDetectorShellCommand extends ShellCommand {
|
||||
pw.printf(" Prints the network time information held by the detector.\n");
|
||||
pw.printf(" %s\n", SHELL_COMMAND_CLEAR_NETWORK_TIME);
|
||||
pw.printf(" Clears the network time information held by the detector.\n");
|
||||
// TODO(b/222295093) Remove these "system_clock" commands when
|
||||
// SystemClock.currentNetworkTimeClock() is guaranteed to use the latest network
|
||||
// suggestion. Then, commands above can be used instead.
|
||||
pw.printf(" %s <network suggestion opts>\n",
|
||||
SHELL_COMMAND_SET_SYSTEM_CLOCK_NETWORK_TIME);
|
||||
pw.printf(" Sets the network time information used for"
|
||||
+ " SystemClock.currentNetworkTimeClock().\n");
|
||||
pw.printf(" %s\n", SHELL_COMMAND_CLEAR_SYSTEM_CLOCK_NETWORK_TIME);
|
||||
pw.printf(" Clears the network time information used for"
|
||||
+ " SystemClock.currentNetworkTimeClock().\n");
|
||||
pw.println();
|
||||
ManualTimeSuggestion.printCommandLineOpts(pw);
|
||||
pw.println();
|
||||
|
||||
@@ -386,70 +386,65 @@ public class TimeDetectorServiceTest {
|
||||
.when(mMockContext).enforceCallingPermission(anyString(), any());
|
||||
|
||||
assertThrows(SecurityException.class,
|
||||
() -> mTimeDetectorService.clearNetworkTime());
|
||||
() -> mTimeDetectorService.clearLatestNetworkTime());
|
||||
verify(mMockContext).enforceCallingPermission(
|
||||
eq(android.Manifest.permission.SET_TIME), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearNetworkTime() throws Exception {
|
||||
public void testClearLatestNetworkSuggestion() throws Exception {
|
||||
doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
|
||||
|
||||
mTimeDetectorService.clearNetworkTime();
|
||||
mTimeDetectorService.clearLatestNetworkTime();
|
||||
|
||||
verify(mMockContext).enforceCallingPermission(
|
||||
eq(android.Manifest.permission.SET_TIME), anyString());
|
||||
verify(mFakeTimeDetectorStrategySpy).clearLatestNetworkSuggestion();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLatestNetworkTime() {
|
||||
NtpTrustedTime.TimeResult latestNetworkTime = new NtpTrustedTime.TimeResult(
|
||||
1234L, 54321L, 999, InetSocketAddress.createUnresolved("test.timeserver", 123));
|
||||
when(mMockNtpTrustedTime.getCachedTimeResult())
|
||||
.thenReturn(latestNetworkTime);
|
||||
UnixEpochTime expected = new UnixEpochTime(
|
||||
latestNetworkTime.getElapsedRealtimeMillis(), latestNetworkTime.getTimeMillis());
|
||||
assertEquals(expected, mTimeDetectorService.latestNetworkTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLatestNetworkTime_noTimeAvailable() {
|
||||
when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(null);
|
||||
assertThrows(ParcelableException.class, () -> mTimeDetectorService.latestNetworkTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLatestNetworkSuggestion() {
|
||||
if (TimeDetectorNetworkTimeHelper.isInUse()) {
|
||||
NetworkTimeSuggestion latestNetworkTime = createNetworkTimeSuggestion();
|
||||
mFakeTimeDetectorStrategySpy.setLatestNetworkTime(latestNetworkTime);
|
||||
NetworkTimeSuggestion latestNetworkSuggestion = createNetworkTimeSuggestion();
|
||||
mFakeTimeDetectorStrategySpy.setLatestNetworkTime(latestNetworkSuggestion);
|
||||
|
||||
assertEquals(latestNetworkTime, mTimeDetectorService.getLatestNetworkSuggestion());
|
||||
assertEquals(latestNetworkSuggestion, mTimeDetectorService.getLatestNetworkSuggestion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLatestNetworkSuggestion_noTimeAvailable() {
|
||||
mFakeTimeDetectorStrategySpy.setLatestNetworkTime(null);
|
||||
|
||||
assertNull(mTimeDetectorService.getLatestNetworkSuggestion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLatestNetworkTime() {
|
||||
if (TimeDetectorNetworkTimeHelper.isInUse()) {
|
||||
NetworkTimeSuggestion latestNetworkSuggestion = createNetworkTimeSuggestion();
|
||||
mFakeTimeDetectorStrategySpy.setLatestNetworkTime(latestNetworkSuggestion);
|
||||
|
||||
assertEquals(latestNetworkSuggestion.getUnixEpochTime(),
|
||||
mTimeDetectorService.latestNetworkTime());
|
||||
} else {
|
||||
NtpTrustedTime.TimeResult latestNetworkTime = new NtpTrustedTime.TimeResult(
|
||||
1234L, 54321L, 999, InetSocketAddress.createUnresolved("test.timeserver", 123));
|
||||
when(mMockNtpTrustedTime.getCachedTimeResult())
|
||||
.thenReturn(latestNetworkTime);
|
||||
UnixEpochTime expectedUnixEpochTime = new UnixEpochTime(
|
||||
UnixEpochTime expected = new UnixEpochTime(
|
||||
latestNetworkTime.getElapsedRealtimeMillis(),
|
||||
latestNetworkTime.getTimeMillis());
|
||||
NetworkTimeSuggestion expected = new NetworkTimeSuggestion(
|
||||
expectedUnixEpochTime, latestNetworkTime.getUncertaintyMillis());
|
||||
assertEquals(expected, mTimeDetectorService.getLatestNetworkSuggestion());
|
||||
assertEquals(expected, mTimeDetectorService.latestNetworkTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLatestNetworkSuggestion_noTimeAvailable() {
|
||||
public void testLatestNetworkTime_noTimeAvailable() {
|
||||
if (TimeDetectorNetworkTimeHelper.isInUse()) {
|
||||
mFakeTimeDetectorStrategySpy.setLatestNetworkTime(null);
|
||||
|
||||
assertNull(mTimeDetectorService.getLatestNetworkSuggestion());
|
||||
} else {
|
||||
when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(null);
|
||||
assertNull(mTimeDetectorService.getLatestNetworkSuggestion());
|
||||
}
|
||||
assertThrows(ParcelableException.class, () -> mTimeDetectorService.latestNetworkTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user