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

Commit 0dc6a89f authored by Dave Mankoff's avatar Dave Mankoff Committed by Android (Google) Code Review
Browse files

Merge "Track when plugins are disabled due to crashes."

parents ac040fdd fd2c695e
Loading
Loading
Loading
Loading
+29 −1
Original line number Diff line number Diff line
@@ -14,12 +14,40 @@

package com.android.systemui.shared.plugins;

import android.annotation.IntDef;
import android.content.ComponentName;

/**
 * Enables and disables plugins.
 */
public interface PluginEnabler {
    void setEnabled(ComponentName component, boolean enabled);

    int ENABLED = 0;
    int DISABLED_MANUALLY = 1;
    int DISABLED_INVALID_VERSION = 1;
    int DISABLED_FROM_EXPLICIT_CRASH = 2;
    int DISABLED_FROM_SYSTEM_CRASH = 3;

    @IntDef({ENABLED, DISABLED_MANUALLY, DISABLED_INVALID_VERSION, DISABLED_FROM_EXPLICIT_CRASH,
            DISABLED_FROM_SYSTEM_CRASH})
    @interface DisableReason {
    }

    /** Enables plugin via the PackageManager. */
    void setEnabled(ComponentName component);

    /** Disables a plugin via the PackageManager and records the reason for disabling. */
    void setDisabled(ComponentName component, @DisableReason int reason);

    /** Returns true if the plugin is enabled in the PackageManager. */
    boolean isEnabled(ComponentName component);

    /**
     * Returns the reason that a plugin is disabled, (if it is).
     *
     * It should return {@link #ENABLED} if the plugin is turned on.
     * It should return {@link #DISABLED_MANUALLY} if the plugin is off but the reason is unknown.
     */
    @DisableReason
    int getDisableReason(ComponentName componentName);
}
+7 −6
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ public class PluginInstanceManager<T extends Plugin> {
        ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins);
        for (PluginInfo info : plugins) {
            if (className.startsWith(info.mPackage)) {
                disable(info);
                disable(info, PluginEnabler.DISABLED_FROM_EXPLICIT_CRASH);
                disableAny = true;
            }
        }
@@ -146,12 +146,13 @@ public class PluginInstanceManager<T extends Plugin> {
    public boolean disableAll() {
        ArrayList<PluginInfo> plugins = new ArrayList<PluginInfo>(mPluginHandler.mPlugins);
        for (int i = 0; i < plugins.size(); i++) {
            disable(plugins.get(i));
            disable(plugins.get(i), PluginEnabler.DISABLED_FROM_SYSTEM_CRASH);
        }
        return plugins.size() != 0;
    }

    private void disable(PluginInfo info) {
    private void disable(PluginInfo 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.

@@ -162,9 +163,9 @@ public class PluginInstanceManager<T extends Plugin> {
            // Don't disable whitelisted plugins as they are a part of the OS.
            return;
        }
        Log.w(TAG, "Disabling plugin " + info.mPackage + "/" + info.mClass);
        mManager.getPluginEnabler().setEnabled(new ComponentName(info.mPackage, info.mClass),
                false);
        ComponentName pluginComponent = new ComponentName(info.mPackage, info.mClass);
        Log.w(TAG, "Disabling plugin " + pluginComponent.flattenToShortString());
        mManager.getPluginEnabler().setDisabled(pluginComponent, reason);
    }

    public <T> boolean dependsOn(Plugin p, Class<T> cls) {
+14 −1
Original line number Diff line number Diff line
@@ -184,6 +184,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
        mListening = true;
        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        filter.addAction(PLUGIN_CHANGED);
        filter.addAction(DISABLE_PLUGIN);
@@ -214,12 +215,13 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
                // Don't disable whitelisted plugins as they are a part of the OS.
                return;
            }
            getPluginEnabler().setEnabled(component, false);
            getPluginEnabler().setDisabled(component, PluginEnabler.DISABLED_INVALID_VERSION);
            mContext.getSystemService(NotificationManager.class).cancel(component.getClassName(),
                    SystemMessage.NOTE_PLUGIN);
        } else {
            Uri data = intent.getData();
            String pkg = data.getEncodedSchemeSpecificPart();
            ComponentName componentName = ComponentName.unflattenFromString(pkg);
            if (mOneShotPackages.contains(pkg)) {
                int icon = mContext.getResources().getIdentifier("tuner", "drawable",
                        mContext.getPackageName());
@@ -256,6 +258,17 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
                    Log.v(TAG, "Reloading " + pkg);
                }
            }
            if (Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())) {
                @PluginEnabler.DisableReason int disableReason =
                        getPluginEnabler().getDisableReason(componentName);
                if (disableReason == PluginEnabler.DISABLED_FROM_EXPLICIT_CRASH
                        || disableReason == PluginEnabler.DISABLED_FROM_SYSTEM_CRASH
                        || disableReason == PluginEnabler.DISABLED_INVALID_VERSION) {
                    Log.i(TAG, "Re-enabling previously disabled plugin that has been "
                            + "updated: " + componentName.flattenToShortString());
                    getPluginEnabler().setEnabled(componentName);
                }
            }
            if (!Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
                for (PluginInstanceManager manager : mPluginMap.values()) {
                    manager.onPackageChange(pkg);
+28 −4
Original line number Diff line number Diff line
@@ -16,28 +16,44 @@ package com.android.systemui.plugins;

import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.shared.plugins.PluginEnabler;

public class PluginEnablerImpl implements PluginEnabler {
    private static final String CRASH_DISABLED_PLUGINS_PREF_FILE = "auto_disabled_plugins_prefs";

    final private PackageManager mPm;
    private PackageManager mPm;
    private final SharedPreferences mAutoDisabledPrefs;

    public PluginEnablerImpl(Context context) {
        this(context.getPackageManager());
        this(context, context.getPackageManager());
    }

    @VisibleForTesting public PluginEnablerImpl(PackageManager pm) {
    @VisibleForTesting public PluginEnablerImpl(Context context, PackageManager pm) {
        mAutoDisabledPrefs = context.getSharedPreferences(
                CRASH_DISABLED_PLUGINS_PREF_FILE, Context.MODE_PRIVATE);
        mPm = pm;
    }

    @Override
    public void setEnabled(ComponentName component, boolean enabled) {
    public void setEnabled(ComponentName component) {
        setDisabled(component, ENABLED);
    }

    @Override
    public void setDisabled(ComponentName component, @DisableReason int reason) {
        boolean enabled = reason == ENABLED;
        final int desiredState = enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
                : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
        mPm.setComponentEnabledSetting(component, desiredState, PackageManager.DONT_KILL_APP);
        if (enabled) {
            mAutoDisabledPrefs.edit().remove(component.flattenToString()).apply();
        } else {
            mAutoDisabledPrefs.edit().putInt(component.flattenToString(), reason).apply();
        }
    }

    @Override
@@ -45,4 +61,12 @@ public class PluginEnablerImpl implements PluginEnabler {
        return mPm.getComponentEnabledSetting(component)
                != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
    }

    @Override
    public @DisableReason int getDisableReason(ComponentName componentName) {
        if (isEnabled(componentName)) {
            return ENABLED;
        }
        return mAutoDisabledPrefs.getInt(componentName.flattenToString(), DISABLED_MANUALLY);
    }
}
+5 −1
Original line number Diff line number Diff line
@@ -184,7 +184,11 @@ public class PluginFragment extends PreferenceFragment {
                        mInfo.services[i].name);

                if (mPluginEnabler.isEnabled(componentName) != isEnabled) {
                    mPluginEnabler.setEnabled(componentName, isEnabled);
                    if (isEnabled) {
                        mPluginEnabler.setEnabled(componentName);
                    } else {
                        mPluginEnabler.setDisabled(componentName, PluginEnabler.DISABLED_MANUALLY);
                    }
                    shouldSendBroadcast = true;
                }
            }
Loading