Merge "Remove custom MainHandler from PluginInstanceManager" into sc-v2-dev am: b325b69f12 am: ab598526fd
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15478379 Change-Id: Id7167af966e2e93f71b5542a728763f2ebf31461
This commit is contained in:
@@ -45,6 +45,7 @@ import com.android.systemui.shared.plugins.VersionInfo.InvalidVersionException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public class PluginInstanceManager<T extends Plugin> {
|
||||
|
||||
@@ -59,8 +60,6 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
private final boolean mAllowMultiple;
|
||||
private final VersionInfo mVersion;
|
||||
|
||||
@VisibleForTesting
|
||||
final MainHandler mMainHandler;
|
||||
@VisibleForTesting
|
||||
final PluginHandler mPluginHandler;
|
||||
private final boolean isDebuggable;
|
||||
@@ -68,13 +67,14 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
private final PluginManagerImpl mManager;
|
||||
private final ArraySet<String> mWhitelistedPlugins = new ArraySet<>();
|
||||
private final PluginInitializer mInitializer;
|
||||
private final Executor mMainExecutor;
|
||||
|
||||
PluginInstanceManager(Context context, PackageManager pm, String action,
|
||||
PluginListener<T> listener, boolean allowMultiple, Looper looper, VersionInfo version,
|
||||
PluginManagerImpl manager, boolean debuggable, String[] pluginWhitelist,
|
||||
PluginInitializer initializer) {
|
||||
PluginListener<T> listener, boolean allowMultiple, Executor mainExecutor,
|
||||
Looper looper, VersionInfo version, PluginManagerImpl manager, boolean debuggable,
|
||||
String[] pluginWhitelist, PluginInitializer initializer) {
|
||||
mInitializer = initializer;
|
||||
mMainHandler = new MainHandler(Looper.getMainLooper());
|
||||
mMainExecutor = mainExecutor;
|
||||
mPluginHandler = new PluginHandler(looper);
|
||||
mManager = manager;
|
||||
mContext = context;
|
||||
@@ -87,21 +87,6 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
isDebuggable = debuggable;
|
||||
}
|
||||
|
||||
public PluginInfo<T> getPlugin() {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
throw new RuntimeException("Must be called from UI thread");
|
||||
}
|
||||
mPluginHandler.handleQueryPlugins(null /* All packages */);
|
||||
if (mPluginHandler.mPlugins.size() > 0) {
|
||||
mMainHandler.removeMessages(MainHandler.PLUGIN_CONNECTED);
|
||||
PluginInfo<T> info = mPluginHandler.mPlugins.get(0);
|
||||
PluginPrefs.setHasPlugins(mContext);
|
||||
info.mPlugin.onCreate(mContext, info.mPluginContext);
|
||||
return info;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void loadAll() {
|
||||
if (DEBUG) Log.d(TAG, "startListening");
|
||||
mPluginHandler.sendEmptyMessage(PluginHandler.QUERY_ALL);
|
||||
@@ -109,10 +94,9 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
|
||||
public void destroy() {
|
||||
if (DEBUG) Log.d(TAG, "stopListening");
|
||||
ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins);
|
||||
for (PluginInfo plugin : plugins) {
|
||||
mMainHandler.obtainMessage(MainHandler.PLUGIN_DISCONNECTED,
|
||||
plugin.mPlugin).sendToTarget();
|
||||
ArrayList<PluginInfo<T>> plugins = new ArrayList<>(mPluginHandler.mPlugins);
|
||||
for (PluginInfo<T> pluginInfo : plugins) {
|
||||
mMainExecutor.execute(() -> onPluginDisconnected(pluginInfo.mPlugin));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,8 +111,8 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
|
||||
public boolean checkAndDisable(String className) {
|
||||
boolean disableAny = false;
|
||||
ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins);
|
||||
for (PluginInfo info : plugins) {
|
||||
ArrayList<PluginInfo<T>> plugins = new ArrayList<>(mPluginHandler.mPlugins);
|
||||
for (PluginInfo<T> info : plugins) {
|
||||
if (className.startsWith(info.mPackage)) {
|
||||
disableAny |= disable(info, PluginEnabler.DISABLED_FROM_EXPLICIT_CRASH);
|
||||
}
|
||||
@@ -137,7 +121,7 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
}
|
||||
|
||||
public boolean disableAll() {
|
||||
ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins);
|
||||
ArrayList<PluginInfo<T>> plugins = new ArrayList<>(mPluginHandler.mPlugins);
|
||||
boolean disabledAny = false;
|
||||
for (int i = 0; i < plugins.size(); i++) {
|
||||
disabledAny |= disable(plugins.get(i), PluginEnabler.DISABLED_FROM_SYSTEM_CRASH);
|
||||
@@ -161,7 +145,7 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean disable(PluginInfo info, @PluginEnabler.DisableReason int reason) {
|
||||
private boolean disable(PluginInfo<T> info, @PluginEnabler.DisableReason int reason) {
|
||||
// Live by the sword, die by the sword.
|
||||
// Misbehaving plugins get disabled and won't come back until uninstall/reinstall.
|
||||
|
||||
@@ -179,9 +163,9 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
return true;
|
||||
}
|
||||
|
||||
public <T> boolean dependsOn(Plugin p, Class<T> cls) {
|
||||
ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins);
|
||||
for (PluginInfo info : plugins) {
|
||||
<C> boolean dependsOn(Plugin p, Class<C> cls) {
|
||||
ArrayList<PluginInfo<T>> plugins = new ArrayList<>(mPluginHandler.mPlugins);
|
||||
for (PluginInfo<T> info : plugins) {
|
||||
if (info.mPlugin.getClass().getName().equals(p.getClass().getName())) {
|
||||
return info.mVersion != null && info.mVersion.hasClass(cls);
|
||||
}
|
||||
@@ -195,42 +179,25 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
getClass().getSimpleName(), hashCode(), mAction);
|
||||
}
|
||||
|
||||
private class MainHandler extends Handler {
|
||||
private static final int PLUGIN_CONNECTED = 1;
|
||||
private static final int PLUGIN_DISCONNECTED = 2;
|
||||
|
||||
public MainHandler(Looper looper) {
|
||||
super(looper);
|
||||
private void onPluginConnected(PluginInfo<T> pluginInfo) {
|
||||
if (DEBUG) Log.d(TAG, "onPluginConnected");
|
||||
PluginPrefs.setHasPlugins(mContext);
|
||||
mInitializer.handleWtfs();
|
||||
if (!(pluginInfo.mPlugin instanceof PluginFragment)) {
|
||||
// Only call onCreate for plugins that aren't fragments, as fragments
|
||||
// will get the onCreate as part of the fragment lifecycle.
|
||||
pluginInfo.mPlugin.onCreate(mContext, pluginInfo.mPluginContext);
|
||||
}
|
||||
mListener.onPluginConnected(pluginInfo.mPlugin, pluginInfo.mPluginContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case PLUGIN_CONNECTED:
|
||||
if (DEBUG) Log.d(TAG, "onPluginConnected");
|
||||
PluginPrefs.setHasPlugins(mContext);
|
||||
PluginInfo<T> info = (PluginInfo<T>) msg.obj;
|
||||
mInitializer.handleWtfs();
|
||||
if (!(msg.obj instanceof PluginFragment)) {
|
||||
// Only call onDestroy for plugins that aren't fragments, as fragments
|
||||
// will get the onCreate as part of the fragment lifecycle.
|
||||
info.mPlugin.onCreate(mContext, info.mPluginContext);
|
||||
}
|
||||
mListener.onPluginConnected(info.mPlugin, info.mPluginContext);
|
||||
break;
|
||||
case PLUGIN_DISCONNECTED:
|
||||
if (DEBUG) Log.d(TAG, "onPluginDisconnected");
|
||||
mListener.onPluginDisconnected((T) msg.obj);
|
||||
if (!(msg.obj instanceof PluginFragment)) {
|
||||
// Only call onDestroy for plugins that aren't fragments, as fragments
|
||||
// will get the onDestroy as part of the fragment lifecycle.
|
||||
((T) msg.obj).onDestroy();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
super.handleMessage(msg);
|
||||
break;
|
||||
}
|
||||
private void onPluginDisconnected(T plugin) {
|
||||
if (DEBUG) Log.d(TAG, "onPluginDisconnected");
|
||||
mListener.onPluginDisconnected(plugin);
|
||||
if (!(plugin instanceof PluginFragment)) {
|
||||
// Only call onDestroy for plugins that aren't fragments, as fragments
|
||||
// will get the onDestroy as part of the fragment lifecycle.
|
||||
plugin.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,8 +219,7 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
if (DEBUG) Log.d(TAG, "queryAll " + mAction);
|
||||
for (int i = mPlugins.size() - 1; i >= 0; i--) {
|
||||
PluginInfo<T> pluginInfo = mPlugins.get(i);
|
||||
mMainHandler.obtainMessage(
|
||||
MainHandler.PLUGIN_DISCONNECTED, pluginInfo.mPlugin).sendToTarget();
|
||||
mMainExecutor.execute(() -> onPluginDisconnected(pluginInfo.mPlugin));
|
||||
}
|
||||
mPlugins.clear();
|
||||
handleQueryPlugins(null);
|
||||
@@ -261,10 +227,9 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
case REMOVE_PKG:
|
||||
String pkg = (String) msg.obj;
|
||||
for (int i = mPlugins.size() - 1; i >= 0; i--) {
|
||||
final PluginInfo<T> plugin = mPlugins.get(i);
|
||||
if (plugin.mPackage.equals(pkg)) {
|
||||
mMainHandler.obtainMessage(MainHandler.PLUGIN_DISCONNECTED,
|
||||
plugin.mPlugin).sendToTarget();
|
||||
final PluginInfo<T> pluginInfo = mPlugins.get(i);
|
||||
if (pluginInfo.mPackage.equals(pkg)) {
|
||||
mMainExecutor.execute(() -> onPluginDisconnected(pluginInfo.mPlugin));
|
||||
mPlugins.remove(i);
|
||||
}
|
||||
}
|
||||
@@ -307,12 +272,12 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
for (ResolveInfo info : result) {
|
||||
ComponentName name = new ComponentName(info.serviceInfo.packageName,
|
||||
info.serviceInfo.name);
|
||||
PluginInfo<T> t = handleLoadPlugin(name);
|
||||
if (t == null) continue;
|
||||
PluginInfo<T> pluginInfo = handleLoadPlugin(name);
|
||||
if (pluginInfo == null) continue;
|
||||
|
||||
// add plugin before sending PLUGIN_CONNECTED message
|
||||
mPlugins.add(t);
|
||||
mMainHandler.obtainMessage(mMainHandler.PLUGIN_CONNECTED, t).sendToTarget();
|
||||
mPlugins.add(pluginInfo);
|
||||
mMainExecutor.execute(() -> onPluginConnected(pluginInfo));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +314,7 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
try {
|
||||
VersionInfo version = checkVersion(pluginClass, plugin, mVersion);
|
||||
if (DEBUG) Log.d(TAG, "createPlugin");
|
||||
return new PluginInfo(pkg, cls, plugin, pluginContext, version);
|
||||
return new PluginInfo<>(pkg, cls, plugin, pluginContext, version);
|
||||
} catch (InvalidVersionException e) {
|
||||
final int icon = Resources.getSystem().getIdentifier(
|
||||
"stat_sys_warning", "drawable", "android");
|
||||
@@ -419,13 +384,15 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
public static class Factory {
|
||||
private final Context mContext;
|
||||
private final PackageManager mPackageManager;
|
||||
private final Executor mMainExecutor;
|
||||
private final Looper mLooper;
|
||||
private final PluginInitializer mInitializer;
|
||||
|
||||
public Factory(Context context, PackageManager packageManager, Looper looper,
|
||||
PluginInitializer initializer) {
|
||||
public Factory(Context context, PackageManager packageManager,
|
||||
Executor mainExecutor, Looper looper, PluginInitializer initializer) {
|
||||
mContext = context;
|
||||
mPackageManager = packageManager;
|
||||
mMainExecutor = mainExecutor;
|
||||
mLooper = looper;
|
||||
mInitializer = initializer;
|
||||
}
|
||||
@@ -435,8 +402,8 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
PluginListener<T> listener, boolean allowMultiple, VersionInfo version,
|
||||
PluginManagerImpl manager, boolean debuggable, String[] pluginWhitelist) {
|
||||
return new PluginInstanceManager<>(mContext, mPackageManager, action, listener,
|
||||
allowMultiple, mLooper, version, manager, debuggable, pluginWhitelist,
|
||||
mInitializer);
|
||||
allowMultiple, mMainExecutor, mLooper, version, manager, debuggable,
|
||||
pluginWhitelist, mInitializer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,10 +433,10 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
}
|
||||
}
|
||||
|
||||
static class PluginInfo<T> {
|
||||
static class PluginInfo<T extends Plugin> {
|
||||
private final Context mPluginContext;
|
||||
private final VersionInfo mVersion;
|
||||
private String mClass;
|
||||
private final String mClass;
|
||||
T mPlugin;
|
||||
String mPackage;
|
||||
|
||||
|
||||
@@ -30,9 +30,6 @@ public interface PluginManager {
|
||||
/** Returns plugins that don't get disabled when an exceptoin occurs. */
|
||||
String[] getPrivilegedPlugins();
|
||||
|
||||
<T extends Plugin> T getOneShotPlugin(Class<T> cls);
|
||||
<T extends Plugin> T getOneShotPlugin(String action, Class<?> cls);
|
||||
|
||||
<T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls);
|
||||
<T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls,
|
||||
boolean allowMultiple);
|
||||
|
||||
@@ -30,7 +30,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemProperties;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
@@ -41,8 +40,6 @@ import android.widget.Toast;
|
||||
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
||||
import com.android.systemui.plugins.Plugin;
|
||||
import com.android.systemui.plugins.PluginListener;
|
||||
import com.android.systemui.plugins.annotations.ProvidesInterface;
|
||||
import com.android.systemui.shared.plugins.PluginInstanceManager.PluginInfo;
|
||||
|
||||
import dalvik.system.PathClassLoader;
|
||||
|
||||
@@ -109,38 +106,6 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
|
||||
return mPluginEnabler;
|
||||
}
|
||||
|
||||
// TODO(mankoff): This appears to be only called from tests. Remove?
|
||||
public <T extends Plugin> T getOneShotPlugin(Class<T> cls) {
|
||||
ProvidesInterface info = cls.getDeclaredAnnotation(ProvidesInterface.class);
|
||||
if (info == null) {
|
||||
throw new RuntimeException(cls + " doesn't provide an interface");
|
||||
}
|
||||
if (TextUtils.isEmpty(info.action())) {
|
||||
throw new RuntimeException(cls + " doesn't provide an action");
|
||||
}
|
||||
return getOneShotPlugin(info.action(), cls);
|
||||
}
|
||||
|
||||
public <T extends Plugin> T getOneShotPlugin(String action, Class<?> cls) {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
throw new RuntimeException("Must be called from UI thread");
|
||||
}
|
||||
// Passing null causes compiler to complain about incompatible (generic) types.
|
||||
PluginListener<T> dummy = null;
|
||||
PluginInstanceManager<T> p = mInstanceManagerFactory.create(
|
||||
action, dummy, false, new VersionInfo().addClass(cls), this,
|
||||
isDebuggable(), getPrivilegedPlugins());
|
||||
mPluginPrefs.addAction(action);
|
||||
PluginInfo<T> info = p.getPlugin();
|
||||
if (info != null) {
|
||||
mOneShotPackages.add(info.mPackage);
|
||||
mHasOneShot = true;
|
||||
startListening();
|
||||
return info.mPlugin;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls) {
|
||||
addPluginListener(listener, cls, false);
|
||||
}
|
||||
|
||||
@@ -23,15 +23,18 @@ import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.shared.plugins.PluginEnabler;
|
||||
import com.android.systemui.shared.plugins.PluginInitializer;
|
||||
import com.android.systemui.shared.plugins.PluginInstanceManager;
|
||||
import com.android.systemui.shared.plugins.PluginManager;
|
||||
import com.android.systemui.shared.plugins.PluginManagerImpl;
|
||||
import com.android.systemui.shared.plugins.PluginPrefs;
|
||||
import com.android.systemui.util.concurrency.GlobalConcurrencyModule;
|
||||
import com.android.systemui.util.concurrency.ThreadFactory;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
@@ -46,7 +49,7 @@ import dagger.Provides;
|
||||
* Covers code both in com.android.systemui.plugins and code in
|
||||
* com.android.systemui.shared.plugins.
|
||||
*/
|
||||
@Module
|
||||
@Module(includes = {GlobalConcurrencyModule.class})
|
||||
public abstract class PluginsModule {
|
||||
public static final String PLUGIN_THREAD = "plugin_thread";
|
||||
public static final String PLUGIN_DEBUG = "plugin_debug";
|
||||
@@ -67,10 +70,10 @@ public abstract class PluginsModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
static PluginInstanceManager.Factory providePluginInstanceManagerFactory(Context context,
|
||||
PackageManager packageManager, @Named(PLUGIN_THREAD) Looper pluginLooper,
|
||||
PluginInitializer initializer) {
|
||||
PackageManager packageManager, @Main Executor mainExecutor,
|
||||
@Named(PLUGIN_THREAD) Looper pluginLooper, PluginInitializer initializer) {
|
||||
return new PluginInstanceManager.Factory(
|
||||
context, packageManager, pluginLooper, initializer);
|
||||
context, packageManager, mainExecutor, pluginLooper, initializer);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -67,11 +67,23 @@ public abstract class GlobalConcurrencyModule {
|
||||
* Provide a Main-Thread Executor.
|
||||
*/
|
||||
@Provides
|
||||
@Singleton
|
||||
@Main
|
||||
public static Executor provideMainExecutor(Context context) {
|
||||
return context.getMainExecutor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a Main-Thread DelayableExecutor.
|
||||
*/
|
||||
@Provides
|
||||
@Singleton
|
||||
@Main
|
||||
public static DelayableExecutor provideMainDelayableExecutor(@Main Looper looper) {
|
||||
return new ExecutorImpl(looper);
|
||||
}
|
||||
|
||||
|
||||
/** */
|
||||
@Binds
|
||||
@Singleton
|
||||
|
||||
@@ -119,16 +119,6 @@ public abstract class SysUIConcurrencyModule {
|
||||
return new ExecutorImpl(looper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a Main-Thread Executor.
|
||||
*/
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@Main
|
||||
public static DelayableExecutor provideMainDelayableExecutor(@Main Looper looper) {
|
||||
return new ExecutorImpl(looper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a Background-Thread Executor by default.
|
||||
*/
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package com.android.systemui.shared.plugins;
|
||||
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
@@ -42,7 +41,6 @@ import android.content.pm.ServiceInfo;
|
||||
import android.os.HandlerThread;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
||||
@@ -50,8 +48,9 @@ import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.Plugin;
|
||||
import com.android.systemui.plugins.PluginListener;
|
||||
import com.android.systemui.plugins.annotations.Requires;
|
||||
import com.android.systemui.shared.plugins.PluginInstanceManager.PluginInfo;
|
||||
import com.android.systemui.shared.plugins.VersionInfo.InvalidVersionException;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -83,6 +82,7 @@ public class PluginInstanceManagerTest extends SysuiTestCase {
|
||||
ComponentName mTestPluginComponentName =
|
||||
new ComponentName(WHITELISTED_PACKAGE, TestPlugin.class.getName());
|
||||
private PluginInitializer mInitializer;
|
||||
private final FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
@@ -98,8 +98,8 @@ public class PluginInstanceManagerTest extends SysuiTestCase {
|
||||
mMockVersionInfo = mock(VersionInfo.class);
|
||||
mInitializer = mock(PluginInitializer.class);
|
||||
mPluginInstanceManager = new PluginInstanceManager(mContextWrapper, mMockPm, "myAction",
|
||||
mMockListener, true, mHandlerThread.getLooper(), mMockVersionInfo,
|
||||
mMockManager, true, new String[0], mInitializer);
|
||||
mMockListener, true, mFakeExecutor, mHandlerThread.getLooper(),
|
||||
mMockVersionInfo, mMockManager, true, new String[0], mInitializer);
|
||||
sMockPlugin = mock(Plugin.class);
|
||||
when(sMockPlugin.getVersion()).thenReturn(1);
|
||||
}
|
||||
@@ -110,23 +110,14 @@ public class PluginInstanceManagerTest extends SysuiTestCase {
|
||||
sMockPlugin = null;
|
||||
}
|
||||
|
||||
@UiThreadTest
|
||||
@Test
|
||||
public void testGetPlugin() throws Exception {
|
||||
setupFakePmQuery();
|
||||
PluginInfo p = mPluginInstanceManager.getPlugin();
|
||||
assertNotNull(p.mPlugin);
|
||||
verify(sMockPlugin).onCreate(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoPlugins() throws Exception {
|
||||
public void testNoPlugins() {
|
||||
when(mMockPm.queryIntentServices(any(), anyInt())).thenReturn(
|
||||
Collections.emptyList());
|
||||
mPluginInstanceManager.loadAll();
|
||||
|
||||
waitForIdleSync(mPluginInstanceManager.mPluginHandler);
|
||||
waitForIdleSync(mPluginInstanceManager.mMainHandler);
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
verify(mMockListener, never()).onPluginConnected(any(), any());
|
||||
}
|
||||
@@ -148,7 +139,8 @@ public class PluginInstanceManagerTest extends SysuiTestCase {
|
||||
mPluginInstanceManager.destroy();
|
||||
|
||||
waitForIdleSync(mPluginInstanceManager.mPluginHandler);
|
||||
waitForIdleSync(mPluginInstanceManager.mMainHandler);
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
|
||||
// Verify shutdown lifecycle
|
||||
verify(mMockListener).onPluginDisconnected(ArgumentCaptor.forClass(Plugin.class).capture());
|
||||
@@ -165,7 +157,8 @@ public class PluginInstanceManagerTest extends SysuiTestCase {
|
||||
mPluginInstanceManager.loadAll();
|
||||
|
||||
waitForIdleSync(mPluginInstanceManager.mPluginHandler);
|
||||
waitForIdleSync(mPluginInstanceManager.mMainHandler);
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
|
||||
// Plugin shouldn't be connected because it is the wrong version.
|
||||
verify(mMockListener, never()).onPluginConnected(any(), any());
|
||||
@@ -179,7 +172,7 @@ public class PluginInstanceManagerTest extends SysuiTestCase {
|
||||
mPluginInstanceManager.onPackageChange("com.android.systemui");
|
||||
|
||||
waitForIdleSync(mPluginInstanceManager.mPluginHandler);
|
||||
waitForIdleSync(mPluginInstanceManager.mMainHandler);
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
// Verify the old one was destroyed.
|
||||
verify(mMockListener).onPluginDisconnected(ArgumentCaptor.forClass(Plugin.class).capture());
|
||||
@@ -195,14 +188,14 @@ public class PluginInstanceManagerTest extends SysuiTestCase {
|
||||
public void testNonDebuggable() throws Exception {
|
||||
// Create a version that thinks the build is not debuggable.
|
||||
mPluginInstanceManager = new PluginInstanceManager(mContextWrapper, mMockPm, "myAction",
|
||||
mMockListener, true, mHandlerThread.getLooper(), mMockVersionInfo,
|
||||
mMockManager, false, new String[0], mInitializer);
|
||||
mMockListener, true, mFakeExecutor, mHandlerThread.getLooper(),
|
||||
mMockVersionInfo, mMockManager, false, new String[0], mInitializer);
|
||||
setupFakePmQuery();
|
||||
|
||||
mPluginInstanceManager.loadAll();
|
||||
|
||||
waitForIdleSync(mPluginInstanceManager.mPluginHandler);
|
||||
waitForIdleSync(mPluginInstanceManager.mMainHandler);;
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
// Non-debuggable build should receive no plugins.
|
||||
verify(mMockListener, never()).onPluginConnected(any(), any());
|
||||
@@ -212,14 +205,15 @@ public class PluginInstanceManagerTest extends SysuiTestCase {
|
||||
public void testNonDebuggable_whitelist() throws Exception {
|
||||
// Create a version that thinks the build is not debuggable.
|
||||
mPluginInstanceManager = new PluginInstanceManager(mContextWrapper, mMockPm, "myAction",
|
||||
mMockListener, true, mHandlerThread.getLooper(), mMockVersionInfo,
|
||||
mMockManager, false, new String[] {WHITELISTED_PACKAGE}, mInitializer);
|
||||
mMockListener, true, mFakeExecutor, mHandlerThread.getLooper(),
|
||||
mMockVersionInfo, mMockManager, false,
|
||||
new String[] {WHITELISTED_PACKAGE}, mInitializer);
|
||||
setupFakePmQuery();
|
||||
|
||||
mPluginInstanceManager.loadAll();
|
||||
|
||||
waitForIdleSync(mPluginInstanceManager.mPluginHandler);
|
||||
waitForIdleSync(mPluginInstanceManager.mMainHandler);
|
||||
mFakeExecutor.runAllReady();
|
||||
|
||||
// Verify startup lifecycle
|
||||
verify(sMockPlugin).onCreate(ArgumentCaptor.forClass(Context.class).capture(),
|
||||
@@ -256,8 +250,9 @@ public class PluginInstanceManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testDisableWhitelisted() throws Exception {
|
||||
mPluginInstanceManager = new PluginInstanceManager(mContextWrapper, mMockPm, "myAction",
|
||||
mMockListener, true, mHandlerThread.getLooper(), mMockVersionInfo,
|
||||
mMockManager, false, new String[] {WHITELISTED_PACKAGE}, mInitializer);
|
||||
mMockListener, true, mFakeExecutor, mHandlerThread.getLooper(),
|
||||
mMockVersionInfo, mMockManager, false, new String[] {WHITELISTED_PACKAGE},
|
||||
mInitializer);
|
||||
createPlugin(); // Get into valid created state.
|
||||
|
||||
mPluginInstanceManager.disableAll();
|
||||
@@ -294,7 +289,7 @@ public class PluginInstanceManagerTest extends SysuiTestCase {
|
||||
mPluginInstanceManager.loadAll();
|
||||
|
||||
waitForIdleSync(mPluginInstanceManager.mPluginHandler);
|
||||
waitForIdleSync(mPluginInstanceManager.mMainHandler);
|
||||
mFakeExecutor.runAllReady();
|
||||
}
|
||||
|
||||
// Real context with no registering/unregistering of receivers.
|
||||
|
||||
@@ -15,7 +15,6 @@ package com.android.systemui.shared.plugins;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -37,7 +36,6 @@ import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.Plugin;
|
||||
import com.android.systemui.plugins.PluginListener;
|
||||
import com.android.systemui.plugins.annotations.ProvidesInterface;
|
||||
import com.android.systemui.shared.plugins.PluginInstanceManager.PluginInfo;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -90,16 +88,6 @@ public class PluginManagerTest extends SysuiTestCase {
|
||||
mMockListener = mock(PluginListener.class);
|
||||
}
|
||||
|
||||
@RunWithLooper(setAsMainLooper = true)
|
||||
@Test
|
||||
public void testOneShot() {
|
||||
Plugin mockPlugin = mock(Plugin.class);
|
||||
when(mMockPluginInstance.getPlugin()).thenReturn(new PluginInfo(null, null, mockPlugin,
|
||||
null, null));
|
||||
Plugin result = mPluginManager.getOneShotPlugin("myAction", TestPlugin.class);
|
||||
assertSame(mockPlugin, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddListener() {
|
||||
mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
|
||||
@@ -129,7 +117,6 @@ public class PluginManagerTest extends SysuiTestCase {
|
||||
applicationInfo.sourceDir = sourceDir;
|
||||
applicationInfo.packageName = WHITELISTED_PACKAGE;
|
||||
mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
|
||||
assertNull(mPluginManager.getOneShotPlugin(sourceDir, TestPlugin.class));
|
||||
assertNull(mPluginManager.getClassLoader(applicationInfo));
|
||||
}
|
||||
|
||||
@@ -206,8 +193,8 @@ public class PluginManagerTest extends SysuiTestCase {
|
||||
}
|
||||
|
||||
@ProvidesInterface(action = TestPlugin.ACTION, version = TestPlugin.VERSION)
|
||||
public static interface TestPlugin extends Plugin {
|
||||
public static final String ACTION = "testAction";
|
||||
public static final int VERSION = 1;
|
||||
public interface TestPlugin extends Plugin {
|
||||
String ACTION = "testAction";
|
||||
int VERSION = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,14 +65,4 @@ public class FakePluginManager implements PluginManager {
|
||||
public String[] getPrivilegedPlugins() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Plugin> T getOneShotPlugin(Class<T> cls) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Plugin> T getOneShotPlugin(String action, Class<?> cls) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user