Loading packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java +50 −83 Original line number Diff line number Diff line Loading @@ -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> { Loading @@ -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; Loading @@ -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; Loading @@ -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); Loading @@ -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)); } } Loading @@ -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); } Loading @@ -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); Loading @@ -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. Loading @@ -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); } Loading @@ -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); } @Override public void handleMessage(Message msg) { switch (msg.what) { case PLUGIN_CONNECTED: private void onPluginConnected(PluginInfo<T> pluginInfo) { 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 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. info.mPlugin.onCreate(mContext, info.mPluginContext); pluginInfo.mPlugin.onCreate(mContext, pluginInfo.mPluginContext); } mListener.onPluginConnected(info.mPlugin, info.mPluginContext); break; case PLUGIN_DISCONNECTED: mListener.onPluginConnected(pluginInfo.mPlugin, pluginInfo.mPluginContext); } private void onPluginDisconnected(T plugin) { if (DEBUG) Log.d(TAG, "onPluginDisconnected"); mListener.onPluginDisconnected((T) msg.obj); if (!(msg.obj instanceof PluginFragment)) { 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. ((T) msg.obj).onDestroy(); } break; default: super.handleMessage(msg); break; } plugin.onDestroy(); } } Loading @@ -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); Loading @@ -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); } } Loading Loading @@ -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)); } } Loading Loading @@ -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"); Loading Loading @@ -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; } Loading @@ -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); } } Loading Loading @@ -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; Loading packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManager.java +0 −3 Original line number Diff line number Diff line Loading @@ -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); Loading packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java +0 −35 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } Loading packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java +7 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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"; Loading @@ -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 Loading packages/SystemUI/src/com/android/systemui/util/concurrency/GlobalConcurrencyModule.java +12 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java +50 −83 Original line number Diff line number Diff line Loading @@ -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> { Loading @@ -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; Loading @@ -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; Loading @@ -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); Loading @@ -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)); } } Loading @@ -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); } Loading @@ -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); Loading @@ -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. Loading @@ -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); } Loading @@ -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); } @Override public void handleMessage(Message msg) { switch (msg.what) { case PLUGIN_CONNECTED: private void onPluginConnected(PluginInfo<T> pluginInfo) { 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 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. info.mPlugin.onCreate(mContext, info.mPluginContext); pluginInfo.mPlugin.onCreate(mContext, pluginInfo.mPluginContext); } mListener.onPluginConnected(info.mPlugin, info.mPluginContext); break; case PLUGIN_DISCONNECTED: mListener.onPluginConnected(pluginInfo.mPlugin, pluginInfo.mPluginContext); } private void onPluginDisconnected(T plugin) { if (DEBUG) Log.d(TAG, "onPluginDisconnected"); mListener.onPluginDisconnected((T) msg.obj); if (!(msg.obj instanceof PluginFragment)) { 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. ((T) msg.obj).onDestroy(); } break; default: super.handleMessage(msg); break; } plugin.onDestroy(); } } Loading @@ -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); Loading @@ -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); } } Loading Loading @@ -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)); } } Loading Loading @@ -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"); Loading Loading @@ -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; } Loading @@ -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); } } Loading Loading @@ -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; Loading
packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManager.java +0 −3 Original line number Diff line number Diff line Loading @@ -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); Loading
packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java +0 −35 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } Loading
packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java +7 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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"; Loading @@ -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 Loading
packages/SystemUI/src/com/android/systemui/util/concurrency/GlobalConcurrencyModule.java +12 −0 Original line number Diff line number Diff line Loading @@ -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 Loading