OSDN Git Service

Less cereal, more stable
authorJason Monk <jmonk@google.com>
Thu, 23 Mar 2017 18:52:17 +0000 (14:52 -0400)
committerJason Monk <jmonk@google.com>
Thu, 23 Mar 2017 18:52:17 +0000 (14:52 -0400)
Sometimes when the PluginManagerImpl got around to executing the
message it posts in the constructor, the next test would be initializing
the Dependencies and it would cause a crash. Clean up this whole
thing by making the looper injectable and the message runs at
a deterministic time.

Test: runtest systemui
Change-Id: I485d72aea22aa8f6c759012d54701af8a503681b

packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java

index 1fb6c87..ec5f9e7 100644 (file)
@@ -59,7 +59,6 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
 
     private static PluginManager sInstance;
 
-    private final HandlerThread mBackgroundThread;
     private final ArrayMap<PluginListener<?>, PluginInstanceManager> mPluginMap
             = new ArrayMap<>();
     private final Map<String, ClassLoader> mClassLoaders = new ArrayMap<>();
@@ -71,6 +70,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
     private ClassLoaderFilter mParentClassLoader;
     private boolean mListening;
     private boolean mHasOneShot;
+    private Looper mLooper;
 
     public PluginManagerImpl(Context context) {
         this(context, new PluginInstanceManagerFactory(),
@@ -82,8 +82,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
             UncaughtExceptionHandler defaultHandler) {
         mContext = context;
         mFactory = factory;
-        mBackgroundThread = new HandlerThread("Plugins");
-        mBackgroundThread.start();
+        mLooper = Dependency.get(Dependency.BG_LOOPER);
         isDebuggable = debuggable;
         mPluginPrefs = new PluginPrefs(mContext);
 
@@ -91,7 +90,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
                 defaultHandler);
         Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
         if (isDebuggable) {
-            new Handler(mBackgroundThread.getLooper()).post(() -> {
+            new Handler(mLooper).post(() -> {
                 // Plugin dependencies that don't have another good home can go here, but
                 // dependencies that have better places to init can happen elsewhere.
                 Dependency.get(PluginDependencyProvider.class)
@@ -120,7 +119,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
             throw new RuntimeException("Must be called from UI thread");
         }
         PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, null,
-                false, mBackgroundThread.getLooper(), cls, this);
+                false, mLooper, cls, this);
         mPluginPrefs.addAction(action);
         PluginInfo<T> info = p.getPlugin();
         if (info != null) {
@@ -154,7 +153,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
         }
         mPluginPrefs.addAction(action);
         PluginInstanceManager p = mFactory.createPluginInstanceManager(mContext, action, listener,
-                allowMultiple, mBackgroundThread.getLooper(), cls, this);
+                allowMultiple, mLooper, cls, this);
         p.loadAll();
         mPluginMap.put(listener, p);
         startListening();
index a3d5d5f..b8e9fcd 100644 (file)
@@ -29,13 +29,18 @@ import android.net.Uri;
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
 
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.annotations.ProvidesInterface;
 import com.android.systemui.plugins.PluginInstanceManager.PluginInfo;
 import com.android.systemui.plugins.PluginManagerImpl.PluginInstanceManagerFactory;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -45,7 +50,8 @@ import org.mockito.Mockito;
 import java.lang.Thread.UncaughtExceptionHandler;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
 public class PluginManagerTest extends SysuiTestCase {
 
     private PluginInstanceManagerFactory mMockFactory;
@@ -59,6 +65,8 @@ public class PluginManagerTest extends SysuiTestCase {
 
     @Before
     public void setup() throws Exception {
+        mDependency.injectTestDependency(Dependency.BG_LOOPER,
+                TestableLooper.get(this).getLooper());
         mRealExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
         mMockExceptionHandler = mock(UncaughtExceptionHandler.class);
         mMockFactory = mock(PluginInstanceManagerFactory.class);
@@ -72,7 +80,7 @@ public class PluginManagerTest extends SysuiTestCase {
         mMockListener = mock(PluginListener.class);
     }
 
-    @UiThreadTest
+    @RunWithLooper(setAsMainLooper = true)
     @Test
     public void testOneShot() {
         Plugin mockPlugin = mock(Plugin.class);