summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Christophe Koessler <ckoessler@google.com> 2019-12-17 16:40:47 -0800
committer Christophe Koessler <ckoessler@google.com> 2020-01-10 00:12:11 +0000
commit611bad95564695d6b5fa87efa89c9a4e1979dc80 (patch)
tree61d438ba30cfa6d22ff8544be1f2d8385a97fde7
parentb43b52a2e138b7648005ba8187947da2bd749d73 (diff)
Refactor CountryDetectorService
Clean-up the test to use Mockito instead of the deprecated AndroidTestCase, also getting rid of 1.5s of Thread.sleep. No logic change. Bug: 141626568 Test: atest CountryDetectorServiceTest Merged-in: Ic0782b1ffcd1dcb30b9f1d91b37521d1f9887f03 Change-Id: Ic0782b1ffcd1dcb30b9f1d91b37521d1f9887f03 (cherry picked from commit 50361687ba6bc20877af43eb5367a5ba3a2911df)
-rw-r--r--services/core/java/com/android/server/CountryDetectorService.java76
-rw-r--r--services/tests/servicestests/Android.bp1
-rw-r--r--services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java143
3 files changed, 129 insertions, 91 deletions
diff --git a/services/core/java/com/android/server/CountryDetectorService.java b/services/core/java/com/android/server/CountryDetectorService.java
index d8a2fe35c7e8..861c731c69e0 100644
--- a/services/core/java/com/android/server/CountryDetectorService.java
+++ b/services/core/java/com/android/server/CountryDetectorService.java
@@ -16,14 +16,6 @@
package com.android.server;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.HashMap;
-
-import com.android.internal.os.BackgroundThread;
-import com.android.internal.util.DumpUtils;
-import com.android.server.location.ComprehensiveCountryDetector;
-
import android.content.Context;
import android.location.Country;
import android.location.CountryListener;
@@ -36,17 +28,25 @@ import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
+import com.android.server.location.ComprehensiveCountryDetector;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.HashMap;
+
/**
- * This class detects the country that the user is in through
- * {@link ComprehensiveCountryDetector}.
+ * This class detects the country that the user is in through {@link ComprehensiveCountryDetector}.
*
* @hide
*/
-public class CountryDetectorService extends ICountryDetector.Stub implements Runnable {
+public class CountryDetectorService extends ICountryDetector.Stub {
/**
- * The class represents the remote listener, it will also removes itself
- * from listener list when the remote process was died.
+ * The class represents the remote listener, it will also removes itself from listener list when
+ * the remote process was died.
*/
private final class Receiver implements IBinder.DeathRecipient {
private final ICountryListener mListener;
@@ -79,9 +79,11 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run
}
}
- private final static String TAG = "CountryDetector";
+ private static final String TAG = "CountryDetector";
- /** Whether to dump the state of the country detector service to bugreports */
+ /**
+ * Whether to dump the state of the country detector service to bugreports
+ */
private static final boolean DEBUG = false;
private final HashMap<IBinder, Receiver> mReceivers;
@@ -92,15 +94,21 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run
private CountryListener mLocationBasedDetectorListener;
public CountryDetectorService(Context context) {
+ this(context, BackgroundThread.getHandler());
+ }
+
+ @VisibleForTesting
+ CountryDetectorService(Context context, Handler handler) {
super();
- mReceivers = new HashMap<IBinder, Receiver>();
+ mReceivers = new HashMap<>();
mContext = context;
+ mHandler = handler;
}
@Override
public Country detectCountry() {
if (!mSystemReady) {
- return null; // server not yet active
+ return null; // server not yet active
} else {
return mCountryDetector.detectCountry();
}
@@ -154,9 +162,8 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run
}
}
-
protected void notifyReceivers(Country country) {
- synchronized(mReceivers) {
+ synchronized (mReceivers) {
for (Receiver receiver : mReceivers.values()) {
try {
receiver.getListener().onCountryDetected(country);
@@ -170,38 +177,23 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run
void systemRunning() {
// Shall we wait for the initialization finish.
- BackgroundThread.getHandler().post(this);
+ mHandler.post(
+ () -> {
+ initialize();
+ mSystemReady = true;
+ });
}
private void initialize() {
mCountryDetector = new ComprehensiveCountryDetector(mContext);
- mLocationBasedDetectorListener = new CountryListener() {
- public void onCountryDetected(final Country country) {
- mHandler.post(new Runnable() {
- public void run() {
- notifyReceivers(country);
- }
- });
- }
- };
- }
-
- public void run() {
- mHandler = new Handler();
- initialize();
- mSystemReady = true;
+ mLocationBasedDetectorListener = country -> mHandler.post(() -> notifyReceivers(country));
}
protected void setCountryListener(final CountryListener listener) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mCountryDetector.setCountryListener(listener);
- }
- });
+ mHandler.post(() -> mCountryDetector.setCountryListener(listener));
}
- // For testing
+ @VisibleForTesting
boolean isSystemReady() {
return mSystemReady;
}
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 3edbd7ee6eed..d42042d3641d 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -28,6 +28,7 @@ android_test {
"services.net",
"services.usage",
"guava",
+ "androidx.test.core",
"androidx.test.runner",
"androidx.test.rules",
"mockito-target-minus-junit4",
diff --git a/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java
index 192c50c7dc19..e9c5ce7127de 100644
--- a/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * 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.
@@ -11,28 +11,48 @@
* 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
+ * limitations under the License.
*/
package com.android.server;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+
import android.content.Context;
import android.location.Country;
import android.location.CountryListener;
import android.location.ICountryListener;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.os.RemoteException;
-import android.test.AndroidTestCase;
-public class CountryDetectorServiceTest extends AndroidTestCase {
- private class CountryListenerTester extends ICountryListener.Stub {
+import androidx.test.core.app.ApplicationProvider;
+
+import com.google.common.truth.Expect;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class CountryDetectorServiceTest {
+
+ private static class CountryListenerTester extends ICountryListener.Stub {
private Country mCountry;
@Override
- public void onCountryDetected(Country country) throws RemoteException {
+ public void onCountryDetected(Country country) {
mCountry = country;
}
- public Country getCountry() {
+ Country getCountry() {
return mCountry;
}
@@ -41,12 +61,11 @@ public class CountryDetectorServiceTest extends AndroidTestCase {
}
}
- private class CountryDetectorServiceTester extends CountryDetectorService {
-
+ private static class CountryDetectorServiceTester extends CountryDetectorService {
private CountryListener mListener;
- public CountryDetectorServiceTester(Context context) {
- super(context);
+ CountryDetectorServiceTester(Context context, Handler handler) {
+ super(context, handler);
}
@Override
@@ -59,51 +78,77 @@ public class CountryDetectorServiceTest extends AndroidTestCase {
mListener = listener;
}
- public boolean isListenerSet() {
+ boolean isListenerSet() {
return mListener != null;
}
}
- public void testAddRemoveListener() throws RemoteException {
- CountryDetectorServiceTester serviceTester = new CountryDetectorServiceTester(getContext());
- serviceTester.systemRunning();
- waitForSystemReady(serviceTester);
- CountryListenerTester listenerTester = new CountryListenerTester();
- serviceTester.addCountryListener(listenerTester);
- assertTrue(serviceTester.isListenerSet());
- serviceTester.removeCountryListener(listenerTester);
- assertFalse(serviceTester.isListenerSet());
+ @Rule
+ public final Expect expect = Expect.create();
+ @Spy
+ private Context mContext = ApplicationProvider.getApplicationContext();
+ @Spy
+ private Handler mHandler = new Handler(Looper.myLooper());
+ private CountryDetectorServiceTester mCountryDetectorService;
+
+ @BeforeClass
+ public static void oneTimeInitialization() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
}
- public void testNotifyListeners() throws RemoteException {
- CountryDetectorServiceTester serviceTester = new CountryDetectorServiceTester(getContext());
- CountryListenerTester listenerTesterA = new CountryListenerTester();
- CountryListenerTester listenerTesterB = new CountryListenerTester();
- Country country = new Country("US", Country.COUNTRY_SOURCE_NETWORK);
- serviceTester.systemRunning();
- waitForSystemReady(serviceTester);
- serviceTester.addCountryListener(listenerTesterA);
- serviceTester.addCountryListener(listenerTesterB);
- serviceTester.notifyReceivers(country);
- assertTrue(serviceTester.isListenerSet());
- assertTrue(listenerTesterA.isNotified());
- assertTrue(listenerTesterB.isNotified());
- serviceTester.removeCountryListener(listenerTesterA);
- serviceTester.removeCountryListener(listenerTesterB);
- assertFalse(serviceTester.isListenerSet());
+ @Before
+ public void setUp() {
+ mCountryDetectorService = new CountryDetectorServiceTester(mContext, mHandler);
+
+ // Immediately invoke run on the Runnable posted to the handler
+ doAnswer(invocation -> {
+ Message message = invocation.getArgument(0);
+ message.getCallback().run();
+ return true;
+ }).when(mHandler).sendMessageAtTime(any(Message.class), anyLong());
}
- private void waitForSystemReady(CountryDetectorService service) {
- int count = 5;
- while (count-- > 0) {
- try {
- Thread.sleep(500);
- } catch (Exception e) {
- }
- if (service.isSystemReady()) {
- return;
- }
- }
- throw new RuntimeException("Wait System Ready timeout");
+ @Test
+ public void countryListener_add_successful() throws RemoteException {
+ CountryListenerTester countryListener = new CountryListenerTester();
+
+ mCountryDetectorService.systemRunning();
+ expect.that(mCountryDetectorService.isListenerSet()).isFalse();
+ mCountryDetectorService.addCountryListener(countryListener);
+
+ expect.that(mCountryDetectorService.isListenerSet()).isTrue();
+ }
+
+ @Test
+ public void countryListener_remove_successful() throws RemoteException {
+ CountryListenerTester countryListener = new CountryListenerTester();
+
+ mCountryDetectorService.systemRunning();
+ mCountryDetectorService.addCountryListener(countryListener);
+ expect.that(mCountryDetectorService.isListenerSet()).isTrue();
+ mCountryDetectorService.removeCountryListener(countryListener);
+
+ expect.that(mCountryDetectorService.isListenerSet()).isFalse();
+ }
+
+ @Test
+ public void countryListener_notify_successful() throws RemoteException {
+ CountryListenerTester countryListenerA = new CountryListenerTester();
+ CountryListenerTester countryListenerB = new CountryListenerTester();
+ Country country = new Country("US", Country.COUNTRY_SOURCE_NETWORK);
+
+ mCountryDetectorService.systemRunning();
+ mCountryDetectorService.addCountryListener(countryListenerA);
+ mCountryDetectorService.addCountryListener(countryListenerB);
+ expect.that(countryListenerA.isNotified()).isFalse();
+ expect.that(countryListenerB.isNotified()).isFalse();
+ mCountryDetectorService.notifyReceivers(country);
+
+ expect.that(countryListenerA.isNotified()).isTrue();
+ expect.that(countryListenerB.isNotified()).isTrue();
+ expect.that(countryListenerA.getCountry().equalsIgnoreSource(country)).isTrue();
+ expect.that(countryListenerB.getCountry().equalsIgnoreSource(country)).isTrue();
}
}