Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7362abd0 authored by Tony Wickham's avatar Tony Wickham Committed by Android (Google) Code Review
Browse files

Merge "Move plugin support to shared lib"

parents d3b47a68 023cb195
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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",
+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);
}
+10 −9
Original line number Diff line number Diff line
@@ -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;
@@ -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> {

@@ -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
@@ -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();
@@ -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);
@@ -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));
        }
@@ -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);
+14 −9
Original line number Diff line number Diff line
@@ -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 {
@@ -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");
@@ -51,3 +54,5 @@ public interface PluginManager {
            return info.action();
        }
    }

}
+30 −21
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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) {
@@ -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();
@@ -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,
@@ -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