Loading packages/SystemUI/shared/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,10 @@ android_library { "src/**/I*.aidl", ], static_libs: [ "SystemUIPluginLib" ], // Enforce that the library is build agains java 7 so that there are // no compatibility issues with launcher java_version: "1.7", Loading packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInitializer.java 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language governing * permissions and limitations under the License. */ 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(); /** * This Runnable is run on the bg looper during initialization of {@link PluginManagerImpl}. * It can be null. */ Runnable getBgInitCallback(); String[] getWhitelistedPlugins(Context context); } packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java→packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java +10 −9 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ * permissions and limitations under the License. */ package com.android.systemui.plugins; package com.android.systemui.shared.plugins; import android.app.Notification; import android.app.Notification.Action; Loading @@ -39,12 +39,14 @@ import android.view.LayoutInflater; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.plugins.VersionInfo.InvalidVersionException; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginFragment; import com.android.systemui.plugins.PluginListener; import com.android.systemui.shared.plugins.VersionInfo.InvalidVersionException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.android.systemui.R; public class PluginInstanceManager<T extends Plugin> { Loading @@ -71,8 +73,7 @@ public class PluginInstanceManager<T extends Plugin> { 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, Build.IS_DEBUGGABLE, context.getResources().getStringArray(R.array.config_pluginWhitelist)); manager, Build.IS_DEBUGGABLE, manager.getWhitelistedPlugins()); } @VisibleForTesting Loading Loading @@ -114,7 +115,7 @@ public class PluginInstanceManager<T extends Plugin> { public void destroy() { if (DEBUG) Log.d(TAG, "stopListening"); ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins); ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins); for (PluginInfo plugin : plugins) { mMainHandler.obtainMessage(MainHandler.PLUGIN_DISCONNECTED, plugin.mPlugin).sendToTarget(); Loading @@ -132,7 +133,7 @@ public class PluginInstanceManager<T extends Plugin> { public boolean checkAndDisable(String className) { boolean disableAny = false; ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins); ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins); for (PluginInfo info : plugins) { if (className.startsWith(info.mPackage)) { disable(info); Loading @@ -143,7 +144,7 @@ public class PluginInstanceManager<T extends Plugin> { } public boolean disableAll() { ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins); ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins); for (int i = 0; i < plugins.size(); i++) { disable(plugins.get(i)); } Loading @@ -165,7 +166,7 @@ public class PluginInstanceManager<T extends Plugin> { } public <T> boolean dependsOn(Plugin p, Class<T> cls) { ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins); ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins); for (PluginInfo info : plugins) { if (info.mPlugin.getClass().getName().equals(p.getClass().getName())) { return info.mVersion != null && info.mVersion.hasClass(cls); Loading packages/SystemUI/src/com/android/systemui/plugins/PluginManager.java→packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManager.java +14 −9 Original line number Diff line number Diff line Loading @@ -12,10 +12,12 @@ * permissions and limitations under the License. */ package com.android.systemui.plugins; package com.android.systemui.shared.plugins; import android.text.TextUtils; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.annotations.ProvidesInterface; public interface PluginManager { Loading @@ -40,7 +42,8 @@ public interface PluginManager { <T> boolean dependsOn(Plugin p, Class<T> cls); static <P> String getAction(Class<P> cls) { class Helper { public static <P> String getAction(Class<P> cls) { ProvidesInterface info = cls.getDeclaredAnnotation(ProvidesInterface.class); if (info == null) { throw new RuntimeException(cls + " doesn't provide an interface"); Loading @@ -51,3 +54,5 @@ public interface PluginManager { return info.action(); } } } packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java→packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java +30 −21 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ * permissions and limitations under the License. */ package com.android.systemui.plugins; package com.android.systemui.shared.plugins; import android.app.Notification; import android.app.Notification.Action; Loading Loading @@ -41,10 +41,11 @@ import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.PluginInstanceManager.PluginContextWrapper; import com.android.systemui.plugins.PluginInstanceManager.PluginInfo; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.shared.plugins.PluginInstanceManager.PluginContextWrapper; import com.android.systemui.shared.plugins.PluginInstanceManager.PluginInfo; import com.android.systemui.plugins.annotations.ProvidesInterface; import dalvik.system.PathClassLoader; Loading Loading @@ -79,31 +80,33 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage private Looper mLooper; private boolean mWtfsSet; public PluginManagerImpl(Context context) { public PluginManagerImpl(Context context, PluginInitializer initializer) { this(context, new PluginInstanceManagerFactory(), Build.IS_DEBUGGABLE, context.getResources().getStringArray(R.array.config_pluginWhitelist), Thread.getUncaughtExceptionPreHandler()); Thread.getUncaughtExceptionPreHandler(), initializer); } @VisibleForTesting PluginManagerImpl(Context context, PluginInstanceManagerFactory factory, boolean debuggable, String[] whitelistedPlugins, UncaughtExceptionHandler defaultHandler) { UncaughtExceptionHandler defaultHandler, PluginInitializer initializer) { mContext = context; mFactory = factory; mLooper = Dependency.get(Dependency.BG_LOOPER); mLooper = initializer.getBgLooper(); isDebuggable = debuggable; mWhitelistedPlugins.addAll(Arrays.asList(whitelistedPlugins)); mWhitelistedPlugins.addAll(Arrays.asList(initializer.getWhitelistedPlugins(mContext))); mPluginPrefs = new PluginPrefs(mContext); PluginExceptionHandler uncaughtExceptionHandler = new PluginExceptionHandler( defaultHandler); Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler); new Handler(mLooper).post(() -> { // Plugin dependencies that don't have another good home can go here, but // dependencies that have better places to init can happen elsewhere. Dependency.get(PluginDependencyProvider.class) .allowPluginDependency(ActivityStarter.class); }); Runnable bgRunnable = initializer.getBgInitCallback(); if (bgRunnable != null) { new Handler(mLooper).post(bgRunnable); } } public String[] getWhitelistedPlugins() { return mWhitelistedPlugins.toArray(new String[0]); } public <T extends Plugin> T getOneShotPlugin(Class<T> cls) { Loading @@ -121,7 +124,9 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage if (Looper.myLooper() != Looper.getMainLooper()) { throw new RuntimeException("Must be called from UI thread"); } PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, null, // 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); mPluginPrefs.addAction(action); PluginInfo<T> info = p.getPlugin(); Loading @@ -140,7 +145,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage public <T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls, boolean allowMultiple) { addPluginListener(PluginManager.getAction(cls), listener, cls, allowMultiple); addPluginListener(PluginManager.Helper.getAction(cls), listener, cls, allowMultiple); } public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener, Loading Loading @@ -293,8 +298,12 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage public void handleWtfs() { if (!mWtfsSet) { mWtfsSet = true; Log.setWtfHandler((tag, what, system) -> { Log.setWtfHandler(new Log.TerribleFailureHandler() { @Override public void onTerribleFailure(String tag, Log.TerribleFailure what, boolean system) { throw new CrashWhilePluginActiveException(what); } }); } } Loading Loading
packages/SystemUI/shared/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,10 @@ android_library { "src/**/I*.aidl", ], static_libs: [ "SystemUIPluginLib" ], // Enforce that the library is build agains java 7 so that there are // no compatibility issues with launcher java_version: "1.7", Loading
packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInitializer.java 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language governing * permissions and limitations under the License. */ 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(); /** * This Runnable is run on the bg looper during initialization of {@link PluginManagerImpl}. * It can be null. */ Runnable getBgInitCallback(); String[] getWhitelistedPlugins(Context context); }
packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java→packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java +10 −9 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ * permissions and limitations under the License. */ package com.android.systemui.plugins; package com.android.systemui.shared.plugins; import android.app.Notification; import android.app.Notification.Action; Loading @@ -39,12 +39,14 @@ import android.view.LayoutInflater; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.plugins.VersionInfo.InvalidVersionException; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginFragment; import com.android.systemui.plugins.PluginListener; import com.android.systemui.shared.plugins.VersionInfo.InvalidVersionException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.android.systemui.R; public class PluginInstanceManager<T extends Plugin> { Loading @@ -71,8 +73,7 @@ public class PluginInstanceManager<T extends Plugin> { 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, Build.IS_DEBUGGABLE, context.getResources().getStringArray(R.array.config_pluginWhitelist)); manager, Build.IS_DEBUGGABLE, manager.getWhitelistedPlugins()); } @VisibleForTesting Loading Loading @@ -114,7 +115,7 @@ public class PluginInstanceManager<T extends Plugin> { public void destroy() { if (DEBUG) Log.d(TAG, "stopListening"); ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins); ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins); for (PluginInfo plugin : plugins) { mMainHandler.obtainMessage(MainHandler.PLUGIN_DISCONNECTED, plugin.mPlugin).sendToTarget(); Loading @@ -132,7 +133,7 @@ public class PluginInstanceManager<T extends Plugin> { public boolean checkAndDisable(String className) { boolean disableAny = false; ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins); ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins); for (PluginInfo info : plugins) { if (className.startsWith(info.mPackage)) { disable(info); Loading @@ -143,7 +144,7 @@ public class PluginInstanceManager<T extends Plugin> { } public boolean disableAll() { ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins); ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins); for (int i = 0; i < plugins.size(); i++) { disable(plugins.get(i)); } Loading @@ -165,7 +166,7 @@ public class PluginInstanceManager<T extends Plugin> { } public <T> boolean dependsOn(Plugin p, Class<T> cls) { ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins); ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins); for (PluginInfo info : plugins) { if (info.mPlugin.getClass().getName().equals(p.getClass().getName())) { return info.mVersion != null && info.mVersion.hasClass(cls); Loading
packages/SystemUI/src/com/android/systemui/plugins/PluginManager.java→packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManager.java +14 −9 Original line number Diff line number Diff line Loading @@ -12,10 +12,12 @@ * permissions and limitations under the License. */ package com.android.systemui.plugins; package com.android.systemui.shared.plugins; import android.text.TextUtils; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.annotations.ProvidesInterface; public interface PluginManager { Loading @@ -40,7 +42,8 @@ public interface PluginManager { <T> boolean dependsOn(Plugin p, Class<T> cls); static <P> String getAction(Class<P> cls) { class Helper { public static <P> String getAction(Class<P> cls) { ProvidesInterface info = cls.getDeclaredAnnotation(ProvidesInterface.class); if (info == null) { throw new RuntimeException(cls + " doesn't provide an interface"); Loading @@ -51,3 +54,5 @@ public interface PluginManager { return info.action(); } } }
packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java→packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java +30 −21 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ * permissions and limitations under the License. */ package com.android.systemui.plugins; package com.android.systemui.shared.plugins; import android.app.Notification; import android.app.Notification.Action; Loading Loading @@ -41,10 +41,11 @@ import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.PluginInstanceManager.PluginContextWrapper; import com.android.systemui.plugins.PluginInstanceManager.PluginInfo; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.shared.plugins.PluginInstanceManager.PluginContextWrapper; import com.android.systemui.shared.plugins.PluginInstanceManager.PluginInfo; import com.android.systemui.plugins.annotations.ProvidesInterface; import dalvik.system.PathClassLoader; Loading Loading @@ -79,31 +80,33 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage private Looper mLooper; private boolean mWtfsSet; public PluginManagerImpl(Context context) { public PluginManagerImpl(Context context, PluginInitializer initializer) { this(context, new PluginInstanceManagerFactory(), Build.IS_DEBUGGABLE, context.getResources().getStringArray(R.array.config_pluginWhitelist), Thread.getUncaughtExceptionPreHandler()); Thread.getUncaughtExceptionPreHandler(), initializer); } @VisibleForTesting PluginManagerImpl(Context context, PluginInstanceManagerFactory factory, boolean debuggable, String[] whitelistedPlugins, UncaughtExceptionHandler defaultHandler) { UncaughtExceptionHandler defaultHandler, PluginInitializer initializer) { mContext = context; mFactory = factory; mLooper = Dependency.get(Dependency.BG_LOOPER); mLooper = initializer.getBgLooper(); isDebuggable = debuggable; mWhitelistedPlugins.addAll(Arrays.asList(whitelistedPlugins)); mWhitelistedPlugins.addAll(Arrays.asList(initializer.getWhitelistedPlugins(mContext))); mPluginPrefs = new PluginPrefs(mContext); PluginExceptionHandler uncaughtExceptionHandler = new PluginExceptionHandler( defaultHandler); Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler); new Handler(mLooper).post(() -> { // Plugin dependencies that don't have another good home can go here, but // dependencies that have better places to init can happen elsewhere. Dependency.get(PluginDependencyProvider.class) .allowPluginDependency(ActivityStarter.class); }); Runnable bgRunnable = initializer.getBgInitCallback(); if (bgRunnable != null) { new Handler(mLooper).post(bgRunnable); } } public String[] getWhitelistedPlugins() { return mWhitelistedPlugins.toArray(new String[0]); } public <T extends Plugin> T getOneShotPlugin(Class<T> cls) { Loading @@ -121,7 +124,9 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage if (Looper.myLooper() != Looper.getMainLooper()) { throw new RuntimeException("Must be called from UI thread"); } PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, null, // 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); mPluginPrefs.addAction(action); PluginInfo<T> info = p.getPlugin(); Loading @@ -140,7 +145,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage public <T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls, boolean allowMultiple) { addPluginListener(PluginManager.getAction(cls), listener, cls, allowMultiple); addPluginListener(PluginManager.Helper.getAction(cls), listener, cls, allowMultiple); } public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener, Loading Loading @@ -293,8 +298,12 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage public void handleWtfs() { if (!mWtfsSet) { mWtfsSet = true; Log.setWtfHandler((tag, what, system) -> { Log.setWtfHandler(new Log.TerribleFailureHandler() { @Override public void onTerribleFailure(String tag, Log.TerribleFailure what, boolean system) { throw new CrashWhilePluginActiveException(what); } }); } } Loading