Loading packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInitializer.java +3 −14 Original line number Diff line number Diff line Loading @@ -15,31 +15,20 @@ package com.android.systemui.shared.plugins; import android.content.Context; import android.os.Looper; /** * Provides necessary components for initializing {@link PluginManagerImpl}. */ public interface PluginInitializer { Looper getBgLooper(); /** * Called from the bg looper during initialization of {@link PluginManagerImpl}. * Return a list of plugins that don't get disabled when an exception occurs. */ void onPluginManagerInit(); String[] getWhitelistedPlugins(Context context); String[] getPrivilegedPlugins(Context context); PluginEnabler getPluginEnabler(Context context); /** * Called from {@link PluginManagerImpl#handleWtfs()}. * Called from {@link PluginInstanceManager}. */ void handleWtfs(); /** * Returns if pluging manager should run in debug mode. */ boolean isDebuggable(); } packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java +32 −9 Original line number Diff line number Diff line Loading @@ -67,17 +67,13 @@ public class PluginInstanceManager<T extends Plugin> { private final PackageManager mPm; private final PluginManagerImpl mManager; private final ArraySet<String> mWhitelistedPlugins = new ArraySet<>(); private final PluginInitializer mInitializer; PluginInstanceManager(Context context, String action, PluginListener<T> listener, boolean allowMultiple, Looper looper, VersionInfo version, PluginManagerImpl manager) { this(context, context.getPackageManager(), action, listener, allowMultiple, looper, version, manager, manager.isDebuggable(), manager.getWhitelistedPlugins()); } @VisibleForTesting PluginInstanceManager(Context context, PackageManager pm, String action, PluginListener<T> listener, boolean allowMultiple, Looper looper, VersionInfo version, PluginManagerImpl manager, boolean debuggable, String[] pluginWhitelist) { PluginManagerImpl manager, boolean debuggable, String[] pluginWhitelist, PluginInitializer initializer) { mInitializer = initializer; mMainHandler = new MainHandler(Looper.getMainLooper()); mPluginHandler = new PluginHandler(looper); mManager = manager; Loading Loading @@ -214,7 +210,7 @@ public class PluginInstanceManager<T extends Plugin> { if (DEBUG) Log.d(TAG, "onPluginConnected"); PluginPrefs.setHasPlugins(mContext); PluginInfo<T> info = (PluginInfo<T>) msg.obj; mManager.handleWtfs(); 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. Loading Loading @@ -417,6 +413,33 @@ public class PluginInstanceManager<T extends Plugin> { } } /** * Construct a {@link PluginInstanceManager} */ public static class Factory { private final Context mContext; private final PackageManager mPackageManager; private final Looper mLooper; private final PluginInitializer mInitializer; public Factory(Context context, PackageManager packageManager, Looper looper, PluginInitializer initializer) { mContext = context; mPackageManager = packageManager; mLooper = looper; mInitializer = initializer; } <T extends Plugin> PluginInstanceManager<T> create( String action, 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); } } public static class PluginContextWrapper extends ContextWrapper { private final ClassLoader mClassLoader; private LayoutInflater mInflater; Loading packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManager.java +3 −2 Original line number Diff line number Diff line Loading @@ -27,7 +27,8 @@ public interface PluginManager { // must be one of the channels created in NotificationChannels.java String NOTIFICATION_CHANNEL_ID = "ALR"; String[] getWhitelistedPlugins(); /** 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); Loading @@ -38,7 +39,7 @@ public interface PluginManager { <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener, Class<?> cls); <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener, Class cls, boolean allowMultiple); Class<?> cls, boolean allowMultiple); void removePluginListener(PluginListener<?> listener); Loading packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java +52 −70 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.Handler; import android.os.Looper; import android.os.SystemProperties; import android.text.TextUtils; Loading @@ -39,7 +38,6 @@ import android.util.ArraySet; import android.util.Log; import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginListener; Loading @@ -56,6 +54,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Optional; /** * @see Plugin */ Loading @@ -64,57 +64,45 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage private static final String TAG = PluginManagerImpl.class.getSimpleName(); static final String DISABLE_PLUGIN = "com.android.systemui.action.DISABLE_PLUGIN"; private final ArrayMap<PluginListener<?>, PluginInstanceManager> mPluginMap private final ArrayMap<PluginListener<?>, PluginInstanceManager<?>> mPluginMap = new ArrayMap<>(); private final Map<String, ClassLoader> mClassLoaders = new ArrayMap<>(); private final ArraySet<String> mOneShotPackages = new ArraySet<>(); private final ArraySet<String> mWhitelistedPlugins = new ArraySet<>(); private final ArraySet<String> mPrivilegedPlugins = new ArraySet<>(); private final Context mContext; private final PluginInstanceManagerFactory mFactory; private final PluginInstanceManager.Factory mInstanceManagerFactory; private final boolean mIsDebuggable; private final PluginPrefs mPluginPrefs; private final PluginEnabler mPluginEnabler; private final PluginInitializer mPluginInitializer; private ClassLoaderFilter mParentClassLoader; private boolean mListening; private boolean mHasOneShot; private Looper mLooper; public PluginManagerImpl(Context context, PluginInitializer initializer) { this(context, new PluginInstanceManagerFactory(), initializer.isDebuggable(), Thread.getUncaughtExceptionPreHandler(), initializer); } @VisibleForTesting PluginManagerImpl(Context context, PluginInstanceManagerFactory factory, boolean debuggable, UncaughtExceptionHandler defaultHandler, final PluginInitializer initializer) { public PluginManagerImpl(Context context, PluginInstanceManager.Factory instanceManagerFactory, boolean debuggable, Optional<UncaughtExceptionHandler> defaultHandlerOptional, PluginEnabler pluginEnabler, PluginPrefs pluginPrefs, String[] privilegedPlugins) { mContext = context; mFactory = factory; mLooper = initializer.getBgLooper(); mInstanceManagerFactory = instanceManagerFactory; mIsDebuggable = debuggable; mWhitelistedPlugins.addAll(Arrays.asList(initializer.getWhitelistedPlugins(mContext))); mPluginPrefs = new PluginPrefs(mContext); mPluginEnabler = initializer.getPluginEnabler(mContext); mPluginInitializer = initializer; mPrivilegedPlugins.addAll(Arrays.asList(privilegedPlugins)); mPluginPrefs = pluginPrefs; mPluginEnabler = pluginEnabler; PluginExceptionHandler uncaughtExceptionHandler = new PluginExceptionHandler( defaultHandler); defaultHandlerOptional); Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler); new Handler(mLooper).post(new Runnable() { @Override public void run() { initializer.onPluginManagerInit(); } }); } public boolean isDebuggable() { return mIsDebuggable; } public String[] getWhitelistedPlugins() { return mWhitelistedPlugins.toArray(new String[0]); public String[] getPrivilegedPlugins() { return mPrivilegedPlugins.toArray(new String[0]); } public PluginEnabler getPluginEnabler() { Loading @@ -138,9 +126,10 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage throw new RuntimeException("Must be called from UI thread"); } // Passing null causes compiler to complain about incompatible (generic) types. PluginListener<Plugin> dummy = null; PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, dummy, false, mLooper, cls, this); 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) { Loading @@ -167,10 +156,11 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener, Class cls, boolean allowMultiple) { Class<?> cls, boolean allowMultiple) { mPluginPrefs.addAction(action); PluginInstanceManager p = mFactory.createPluginInstanceManager(mContext, action, listener, allowMultiple, mLooper, cls, this); PluginInstanceManager<T> p = mInstanceManagerFactory.create(action, listener, allowMultiple, new VersionInfo().addClass(cls), this, isDebuggable(), getPrivilegedPlugins()); p.loadAll(); synchronized (this) { mPluginMap.put(listener, p); Loading Loading @@ -218,7 +208,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage public void onReceive(Context context, Intent intent) { if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) { synchronized (this) { for (PluginInstanceManager manager : mPluginMap.values()) { for (PluginInstanceManager<?> manager : mPluginMap.values()) { manager.loadAll(); } } Loading @@ -226,8 +216,8 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage Uri uri = intent.getData(); ComponentName component = ComponentName.unflattenFromString( uri.toString().substring(10)); if (isPluginWhitelisted(component)) { // Don't disable whitelisted plugins as they are a part of the OS. if (isPluginPrivileged(component)) { // Don't disable privileged plugins as they are a part of the OS. return; } getPluginEnabler().setDisabled(component, PluginEnabler.DISABLED_INVALID_VERSION); Loading Loading @@ -287,11 +277,11 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } synchronized (this) { if (!Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { for (PluginInstanceManager manager : mPluginMap.values()) { for (PluginInstanceManager<?> manager : mPluginMap.values()) { manager.onPackageChange(pkg); } } else { for (PluginInstanceManager manager : mPluginMap.values()) { for (PluginInstanceManager<?> manager : mPluginMap.values()) { manager.onPackageRemoved(pkg); } } Loading @@ -301,8 +291,8 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage /** Returns class loader specific for the given plugin. */ public ClassLoader getClassLoader(ApplicationInfo appInfo) { if (!mIsDebuggable && !isPluginPackageWhitelisted(appInfo.packageName)) { Log.w(TAG, "Cannot get class loader for non-whitelisted plugin. Src:" if (!mIsDebuggable && !isPluginPackagePrivileged(appInfo.packageName)) { Log.w(TAG, "Cannot get class loader for non-privileged plugin. Src:" + appInfo.sourceDir + ", pkg: " + appInfo.packageName); return null; } Loading Loading @@ -345,32 +335,18 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage return false; } public void handleWtfs() { mPluginInitializer.handleWtfs(); } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { synchronized (this) { pw.println(String.format(" plugin map (%d):", mPluginMap.size())); for (PluginListener listener : mPluginMap.keySet()) { for (PluginListener<?> listener : mPluginMap.keySet()) { pw.println(String.format(" %s -> %s", listener, mPluginMap.get(listener))); } } } @VisibleForTesting public static class PluginInstanceManagerFactory { public <T extends Plugin> PluginInstanceManager createPluginInstanceManager(Context context, String action, PluginListener<T> listener, boolean allowMultiple, Looper looper, Class<?> cls, PluginManagerImpl manager) { return new PluginInstanceManager(context, action, listener, allowMultiple, looper, new VersionInfo().addClass(cls), manager); } } private boolean isPluginPackageWhitelisted(String packageName) { for (String componentNameOrPackage : mWhitelistedPlugins) { private boolean isPluginPackagePrivileged(String packageName) { for (String componentNameOrPackage : mPrivilegedPlugins) { ComponentName componentName = ComponentName.unflattenFromString(componentNameOrPackage); if (componentName != null) { if (componentName.getPackageName().equals(packageName)) { Loading @@ -383,8 +359,8 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage return false; } private boolean isPluginWhitelisted(ComponentName pluginName) { for (String componentNameOrPackage : mWhitelistedPlugins) { private boolean isPluginPrivileged(ComponentName pluginName) { for (String componentNameOrPackage : mPrivilegedPlugins) { ComponentName componentName = ComponentName.unflattenFromString(componentNameOrPackage); if (componentName != null) { if (componentName.equals(pluginName)) { Loading Loading @@ -417,16 +393,20 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } private class PluginExceptionHandler implements UncaughtExceptionHandler { private final UncaughtExceptionHandler mHandler; private final Optional<UncaughtExceptionHandler> mExceptionHandlerOptional; private PluginExceptionHandler(UncaughtExceptionHandler handler) { mHandler = handler; private PluginExceptionHandler( Optional<UncaughtExceptionHandler> exceptionHandlerOptional) { mExceptionHandlerOptional = exceptionHandlerOptional; } @Override public void uncaughtException(Thread thread, Throwable throwable) { if (SystemProperties.getBoolean("plugin.debugging", false)) { mHandler.uncaughtException(thread, throwable); Throwable finalThrowable = throwable; mExceptionHandlerOptional.ifPresent( handler -> handler.uncaughtException(thread, finalThrowable)); return; } // Search for and disable plugins that may have been involved in this crash. Loading @@ -436,7 +416,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage // disable all the plugins, so we can be sure that SysUI is running as // best as possible. synchronized (this) { for (PluginInstanceManager manager : mPluginMap.values()) { for (PluginInstanceManager<?> manager : mPluginMap.values()) { disabledAny |= manager.disableAll(); } } Loading @@ -446,7 +426,9 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } // Run the normal exception handler so we can crash and cleanup our state. mHandler.uncaughtException(thread, throwable); Throwable finalThrowable = throwable; mExceptionHandlerOptional.ifPresent( handler -> handler.uncaughtException(thread, finalThrowable)); } private boolean checkStack(Throwable throwable) { Loading @@ -454,7 +436,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage boolean disabledAny = false; synchronized (this) { for (StackTraceElement element : throwable.getStackTrace()) { for (PluginInstanceManager manager : mPluginMap.values()) { for (PluginInstanceManager<?> manager : mPluginMap.values()) { disabledAny |= manager.checkAndDisable(element.getClassName()); } } Loading packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +3 −13 Original line number Diff line number Diff line Loading @@ -68,21 +68,15 @@ import com.android.systemui.navigationbar.NavigationBarController; import com.android.systemui.navigationbar.NavigationBarOverlayController; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.TaskbarDelegate; import com.android.systemui.plugins.PluginInitializerImpl; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.ReduceBrightColorsController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; import com.android.systemui.settings.UserTracker; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.plugins.PluginManagerImpl; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.DevicePolicyManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.unfold.UnfoldTransitionFactory; import com.android.unfold.UnfoldTransitionProgressProvider; import com.android.unfold.config.UnfoldTransitionConfig; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShadeDepthController; Loading @@ -98,6 +92,9 @@ import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.theme.ThemeOverlayApplier; import com.android.systemui.util.leak.LeakDetector; import com.android.systemui.util.settings.SecureSettings; import com.android.unfold.UnfoldTransitionFactory; import com.android.unfold.UnfoldTransitionProgressProvider; import com.android.unfold.config.UnfoldTransitionConfig; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; import com.android.wm.shell.pip.Pip; Loading Loading @@ -195,13 +192,6 @@ public class DependencyProvider { return new MetricsLogger(); } /** */ @Provides @SysUISingleton public PluginManager providePluginManager(Context context) { return new PluginManagerImpl(context, new PluginInitializerImpl()); } /** */ @SysUISingleton @Provides Loading Loading
packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInitializer.java +3 −14 Original line number Diff line number Diff line Loading @@ -15,31 +15,20 @@ package com.android.systemui.shared.plugins; import android.content.Context; import android.os.Looper; /** * Provides necessary components for initializing {@link PluginManagerImpl}. */ public interface PluginInitializer { Looper getBgLooper(); /** * Called from the bg looper during initialization of {@link PluginManagerImpl}. * Return a list of plugins that don't get disabled when an exception occurs. */ void onPluginManagerInit(); String[] getWhitelistedPlugins(Context context); String[] getPrivilegedPlugins(Context context); PluginEnabler getPluginEnabler(Context context); /** * Called from {@link PluginManagerImpl#handleWtfs()}. * Called from {@link PluginInstanceManager}. */ void handleWtfs(); /** * Returns if pluging manager should run in debug mode. */ boolean isDebuggable(); }
packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java +32 −9 Original line number Diff line number Diff line Loading @@ -67,17 +67,13 @@ public class PluginInstanceManager<T extends Plugin> { private final PackageManager mPm; private final PluginManagerImpl mManager; private final ArraySet<String> mWhitelistedPlugins = new ArraySet<>(); private final PluginInitializer mInitializer; PluginInstanceManager(Context context, String action, PluginListener<T> listener, boolean allowMultiple, Looper looper, VersionInfo version, PluginManagerImpl manager) { this(context, context.getPackageManager(), action, listener, allowMultiple, looper, version, manager, manager.isDebuggable(), manager.getWhitelistedPlugins()); } @VisibleForTesting PluginInstanceManager(Context context, PackageManager pm, String action, PluginListener<T> listener, boolean allowMultiple, Looper looper, VersionInfo version, PluginManagerImpl manager, boolean debuggable, String[] pluginWhitelist) { PluginManagerImpl manager, boolean debuggable, String[] pluginWhitelist, PluginInitializer initializer) { mInitializer = initializer; mMainHandler = new MainHandler(Looper.getMainLooper()); mPluginHandler = new PluginHandler(looper); mManager = manager; Loading Loading @@ -214,7 +210,7 @@ public class PluginInstanceManager<T extends Plugin> { if (DEBUG) Log.d(TAG, "onPluginConnected"); PluginPrefs.setHasPlugins(mContext); PluginInfo<T> info = (PluginInfo<T>) msg.obj; mManager.handleWtfs(); 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. Loading Loading @@ -417,6 +413,33 @@ public class PluginInstanceManager<T extends Plugin> { } } /** * Construct a {@link PluginInstanceManager} */ public static class Factory { private final Context mContext; private final PackageManager mPackageManager; private final Looper mLooper; private final PluginInitializer mInitializer; public Factory(Context context, PackageManager packageManager, Looper looper, PluginInitializer initializer) { mContext = context; mPackageManager = packageManager; mLooper = looper; mInitializer = initializer; } <T extends Plugin> PluginInstanceManager<T> create( String action, 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); } } public static class PluginContextWrapper extends ContextWrapper { private final ClassLoader mClassLoader; private LayoutInflater mInflater; Loading
packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManager.java +3 −2 Original line number Diff line number Diff line Loading @@ -27,7 +27,8 @@ public interface PluginManager { // must be one of the channels created in NotificationChannels.java String NOTIFICATION_CHANNEL_ID = "ALR"; String[] getWhitelistedPlugins(); /** 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); Loading @@ -38,7 +39,7 @@ public interface PluginManager { <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener, Class<?> cls); <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener, Class cls, boolean allowMultiple); Class<?> cls, boolean allowMultiple); void removePluginListener(PluginListener<?> listener); Loading
packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java +52 −70 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.Handler; import android.os.Looper; import android.os.SystemProperties; import android.text.TextUtils; Loading @@ -39,7 +38,6 @@ import android.util.ArraySet; import android.util.Log; import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginListener; Loading @@ -56,6 +54,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Optional; /** * @see Plugin */ Loading @@ -64,57 +64,45 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage private static final String TAG = PluginManagerImpl.class.getSimpleName(); static final String DISABLE_PLUGIN = "com.android.systemui.action.DISABLE_PLUGIN"; private final ArrayMap<PluginListener<?>, PluginInstanceManager> mPluginMap private final ArrayMap<PluginListener<?>, PluginInstanceManager<?>> mPluginMap = new ArrayMap<>(); private final Map<String, ClassLoader> mClassLoaders = new ArrayMap<>(); private final ArraySet<String> mOneShotPackages = new ArraySet<>(); private final ArraySet<String> mWhitelistedPlugins = new ArraySet<>(); private final ArraySet<String> mPrivilegedPlugins = new ArraySet<>(); private final Context mContext; private final PluginInstanceManagerFactory mFactory; private final PluginInstanceManager.Factory mInstanceManagerFactory; private final boolean mIsDebuggable; private final PluginPrefs mPluginPrefs; private final PluginEnabler mPluginEnabler; private final PluginInitializer mPluginInitializer; private ClassLoaderFilter mParentClassLoader; private boolean mListening; private boolean mHasOneShot; private Looper mLooper; public PluginManagerImpl(Context context, PluginInitializer initializer) { this(context, new PluginInstanceManagerFactory(), initializer.isDebuggable(), Thread.getUncaughtExceptionPreHandler(), initializer); } @VisibleForTesting PluginManagerImpl(Context context, PluginInstanceManagerFactory factory, boolean debuggable, UncaughtExceptionHandler defaultHandler, final PluginInitializer initializer) { public PluginManagerImpl(Context context, PluginInstanceManager.Factory instanceManagerFactory, boolean debuggable, Optional<UncaughtExceptionHandler> defaultHandlerOptional, PluginEnabler pluginEnabler, PluginPrefs pluginPrefs, String[] privilegedPlugins) { mContext = context; mFactory = factory; mLooper = initializer.getBgLooper(); mInstanceManagerFactory = instanceManagerFactory; mIsDebuggable = debuggable; mWhitelistedPlugins.addAll(Arrays.asList(initializer.getWhitelistedPlugins(mContext))); mPluginPrefs = new PluginPrefs(mContext); mPluginEnabler = initializer.getPluginEnabler(mContext); mPluginInitializer = initializer; mPrivilegedPlugins.addAll(Arrays.asList(privilegedPlugins)); mPluginPrefs = pluginPrefs; mPluginEnabler = pluginEnabler; PluginExceptionHandler uncaughtExceptionHandler = new PluginExceptionHandler( defaultHandler); defaultHandlerOptional); Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler); new Handler(mLooper).post(new Runnable() { @Override public void run() { initializer.onPluginManagerInit(); } }); } public boolean isDebuggable() { return mIsDebuggable; } public String[] getWhitelistedPlugins() { return mWhitelistedPlugins.toArray(new String[0]); public String[] getPrivilegedPlugins() { return mPrivilegedPlugins.toArray(new String[0]); } public PluginEnabler getPluginEnabler() { Loading @@ -138,9 +126,10 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage throw new RuntimeException("Must be called from UI thread"); } // Passing null causes compiler to complain about incompatible (generic) types. PluginListener<Plugin> dummy = null; PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, dummy, false, mLooper, cls, this); 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) { Loading @@ -167,10 +156,11 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener, Class cls, boolean allowMultiple) { Class<?> cls, boolean allowMultiple) { mPluginPrefs.addAction(action); PluginInstanceManager p = mFactory.createPluginInstanceManager(mContext, action, listener, allowMultiple, mLooper, cls, this); PluginInstanceManager<T> p = mInstanceManagerFactory.create(action, listener, allowMultiple, new VersionInfo().addClass(cls), this, isDebuggable(), getPrivilegedPlugins()); p.loadAll(); synchronized (this) { mPluginMap.put(listener, p); Loading Loading @@ -218,7 +208,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage public void onReceive(Context context, Intent intent) { if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) { synchronized (this) { for (PluginInstanceManager manager : mPluginMap.values()) { for (PluginInstanceManager<?> manager : mPluginMap.values()) { manager.loadAll(); } } Loading @@ -226,8 +216,8 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage Uri uri = intent.getData(); ComponentName component = ComponentName.unflattenFromString( uri.toString().substring(10)); if (isPluginWhitelisted(component)) { // Don't disable whitelisted plugins as they are a part of the OS. if (isPluginPrivileged(component)) { // Don't disable privileged plugins as they are a part of the OS. return; } getPluginEnabler().setDisabled(component, PluginEnabler.DISABLED_INVALID_VERSION); Loading Loading @@ -287,11 +277,11 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } synchronized (this) { if (!Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { for (PluginInstanceManager manager : mPluginMap.values()) { for (PluginInstanceManager<?> manager : mPluginMap.values()) { manager.onPackageChange(pkg); } } else { for (PluginInstanceManager manager : mPluginMap.values()) { for (PluginInstanceManager<?> manager : mPluginMap.values()) { manager.onPackageRemoved(pkg); } } Loading @@ -301,8 +291,8 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage /** Returns class loader specific for the given plugin. */ public ClassLoader getClassLoader(ApplicationInfo appInfo) { if (!mIsDebuggable && !isPluginPackageWhitelisted(appInfo.packageName)) { Log.w(TAG, "Cannot get class loader for non-whitelisted plugin. Src:" if (!mIsDebuggable && !isPluginPackagePrivileged(appInfo.packageName)) { Log.w(TAG, "Cannot get class loader for non-privileged plugin. Src:" + appInfo.sourceDir + ", pkg: " + appInfo.packageName); return null; } Loading Loading @@ -345,32 +335,18 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage return false; } public void handleWtfs() { mPluginInitializer.handleWtfs(); } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { synchronized (this) { pw.println(String.format(" plugin map (%d):", mPluginMap.size())); for (PluginListener listener : mPluginMap.keySet()) { for (PluginListener<?> listener : mPluginMap.keySet()) { pw.println(String.format(" %s -> %s", listener, mPluginMap.get(listener))); } } } @VisibleForTesting public static class PluginInstanceManagerFactory { public <T extends Plugin> PluginInstanceManager createPluginInstanceManager(Context context, String action, PluginListener<T> listener, boolean allowMultiple, Looper looper, Class<?> cls, PluginManagerImpl manager) { return new PluginInstanceManager(context, action, listener, allowMultiple, looper, new VersionInfo().addClass(cls), manager); } } private boolean isPluginPackageWhitelisted(String packageName) { for (String componentNameOrPackage : mWhitelistedPlugins) { private boolean isPluginPackagePrivileged(String packageName) { for (String componentNameOrPackage : mPrivilegedPlugins) { ComponentName componentName = ComponentName.unflattenFromString(componentNameOrPackage); if (componentName != null) { if (componentName.getPackageName().equals(packageName)) { Loading @@ -383,8 +359,8 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage return false; } private boolean isPluginWhitelisted(ComponentName pluginName) { for (String componentNameOrPackage : mWhitelistedPlugins) { private boolean isPluginPrivileged(ComponentName pluginName) { for (String componentNameOrPackage : mPrivilegedPlugins) { ComponentName componentName = ComponentName.unflattenFromString(componentNameOrPackage); if (componentName != null) { if (componentName.equals(pluginName)) { Loading Loading @@ -417,16 +393,20 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } private class PluginExceptionHandler implements UncaughtExceptionHandler { private final UncaughtExceptionHandler mHandler; private final Optional<UncaughtExceptionHandler> mExceptionHandlerOptional; private PluginExceptionHandler(UncaughtExceptionHandler handler) { mHandler = handler; private PluginExceptionHandler( Optional<UncaughtExceptionHandler> exceptionHandlerOptional) { mExceptionHandlerOptional = exceptionHandlerOptional; } @Override public void uncaughtException(Thread thread, Throwable throwable) { if (SystemProperties.getBoolean("plugin.debugging", false)) { mHandler.uncaughtException(thread, throwable); Throwable finalThrowable = throwable; mExceptionHandlerOptional.ifPresent( handler -> handler.uncaughtException(thread, finalThrowable)); return; } // Search for and disable plugins that may have been involved in this crash. Loading @@ -436,7 +416,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage // disable all the plugins, so we can be sure that SysUI is running as // best as possible. synchronized (this) { for (PluginInstanceManager manager : mPluginMap.values()) { for (PluginInstanceManager<?> manager : mPluginMap.values()) { disabledAny |= manager.disableAll(); } } Loading @@ -446,7 +426,9 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } // Run the normal exception handler so we can crash and cleanup our state. mHandler.uncaughtException(thread, throwable); Throwable finalThrowable = throwable; mExceptionHandlerOptional.ifPresent( handler -> handler.uncaughtException(thread, finalThrowable)); } private boolean checkStack(Throwable throwable) { Loading @@ -454,7 +436,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage boolean disabledAny = false; synchronized (this) { for (StackTraceElement element : throwable.getStackTrace()) { for (PluginInstanceManager manager : mPluginMap.values()) { for (PluginInstanceManager<?> manager : mPluginMap.values()) { disabledAny |= manager.checkAndDisable(element.getClassName()); } } Loading
packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +3 −13 Original line number Diff line number Diff line Loading @@ -68,21 +68,15 @@ import com.android.systemui.navigationbar.NavigationBarController; import com.android.systemui.navigationbar.NavigationBarOverlayController; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.TaskbarDelegate; import com.android.systemui.plugins.PluginInitializerImpl; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.ReduceBrightColorsController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; import com.android.systemui.settings.UserTracker; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.plugins.PluginManagerImpl; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.DevicePolicyManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.unfold.UnfoldTransitionFactory; import com.android.unfold.UnfoldTransitionProgressProvider; import com.android.unfold.config.UnfoldTransitionConfig; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShadeDepthController; Loading @@ -98,6 +92,9 @@ import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.theme.ThemeOverlayApplier; import com.android.systemui.util.leak.LeakDetector; import com.android.systemui.util.settings.SecureSettings; import com.android.unfold.UnfoldTransitionFactory; import com.android.unfold.UnfoldTransitionProgressProvider; import com.android.unfold.config.UnfoldTransitionConfig; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; import com.android.wm.shell.pip.Pip; Loading Loading @@ -195,13 +192,6 @@ public class DependencyProvider { return new MetricsLogger(); } /** */ @Provides @SysUISingleton public PluginManager providePluginManager(Context context) { return new PluginManagerImpl(context, new PluginInitializerImpl()); } /** */ @SysUISingleton @Provides Loading