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

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

Merge "Fix flakes related to concurrent access of PluginManager."

parents 73057fd3 48279602
Loading
Loading
Loading
Loading
+44 −26
Original line number Diff line number Diff line
@@ -171,17 +171,23 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
        PluginInstanceManager p = mFactory.createPluginInstanceManager(mContext, action, listener,
                allowMultiple, mLooper, cls, this);
        p.loadAll();
        synchronized (this) {
            mPluginMap.put(listener, p);
        }
        startListening();
    }

    public void removePluginListener(PluginListener<?> listener) {
        if (!mPluginMap.containsKey(listener)) return;
        synchronized (this) {
            if (!mPluginMap.containsKey(listener)) {
                return;
            }
            mPluginMap.remove(listener).destroy();
            if (mPluginMap.size() == 0) {
                stopListening();
            }
        }
    }

    private void startListening() {
        if (mListening) return;
@@ -208,9 +214,11 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
            synchronized (this) {
                for (PluginInstanceManager manager : mPluginMap.values()) {
                    manager.loadAll();
                }
            }
        } else if (DISABLE_PLUGIN.equals(intent.getAction())) {
            Uri uri = intent.getData();
            ComponentName component = ComponentName.unflattenFromString(
@@ -274,6 +282,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
                    getPluginEnabler().setEnabled(componentName);
                }
            }
            synchronized (this) {
                if (!Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
                    for (PluginInstanceManager manager : mPluginMap.values()) {
                        manager.onPackageChange(pkg);
@@ -285,6 +294,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
                }
            }
        }
    }

    /** Returns class loader specific for the given plugin. */
    public ClassLoader getClassLoader(ApplicationInfo appInfo) {
@@ -322,11 +332,13 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
    }

    public <T> boolean dependsOn(Plugin p, Class<T> cls) {
        synchronized (this) {
            for (int i = 0; i < mPluginMap.size(); i++) {
                if (mPluginMap.valueAt(i).dependsOn(p, cls)) {
                    return true;
                }
            }
        }
        return false;
    }

@@ -335,12 +347,14 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
    }

    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()) {
                pw.println(String.format("    %s -> %s",
                        listener, mPluginMap.get(listener)));
            }
        }
    }

    @VisibleForTesting
    public static class PluginInstanceManagerFactory {
@@ -418,10 +432,12 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
                // We couldn't find any plugins involved in this crash, just to be safe
                // disable all the plugins, so we can be sure that SysUI is running as
                // best as possible.
                synchronized (this) {
                    for (PluginInstanceManager manager : mPluginMap.values()) {
                        disabledAny |= manager.disableAll();
                    }
                }
            }
            if (disabledAny) {
                throwable = new CrashWhilePluginActiveException(throwable);
            }
@@ -433,11 +449,13 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
        private boolean checkStack(Throwable throwable) {
            if (throwable == null) return false;
            boolean disabledAny = false;
            synchronized (this) {
                for (StackTraceElement element : throwable.getStackTrace()) {
                    for (PluginInstanceManager manager : mPluginMap.values()) {
                        disabledAny |= manager.checkAndDisable(element.getClassName());
                    }
                }
            }
            return disabledAny | checkStack(throwable.getCause());
        }
    }