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

Commit b938def5 authored by Dave Mankoff's avatar Dave Mankoff
Browse files

Fix the library paths of plugins to allow loading native libraries.

Test: atest
Bug: 111394067
Change-Id: I05db6db5e735f7532f772a59ff57b8ad0595c1a2
parent b867295c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -323,7 +323,7 @@ public class PluginInstanceManager<T extends Plugin> {
                    return null;
                }
                // Create our own ClassLoader so we can use our own code as the parent.
                ClassLoader classLoader = mManager.getClassLoader(info.sourceDir, info.packageName);
                ClassLoader classLoader = mManager.getClassLoader(info);
                Context pluginContext = new PluginContextWrapper(
                        mContext.createApplicationContext(info, 0), classLoader);
                Class<?> pluginClass = Class.forName(cls, true, classLoader);
+21 −14
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@

package com.android.systemui.shared.plugins;

import android.app.LoadedApk;
import android.app.Notification;
import android.app.Notification.Action;
import android.app.NotificationManager;
@@ -44,15 +45,17 @@ import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.annotations.ProvidesInterface;
import com.android.systemui.shared.plugins.PluginInstanceManager.PluginContextWrapper;
import com.android.systemui.shared.plugins.PluginInstanceManager.PluginInfo;

import dalvik.system.PathClassLoader;

import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
 * @see Plugin
@@ -117,6 +120,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
        return mPluginEnabler;
    }

    // TODO(mankoff): This appears to be only called from tests. Remove?
    public <T extends Plugin> T getOneShotPlugin(Class<T> cls) {
        ProvidesInterface info = cls.getDeclaredAnnotation(ProvidesInterface.class);
        if (info == null) {
@@ -282,17 +286,25 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
        }
    }

    public ClassLoader getClassLoader(String sourceDir, String pkg) {
        if (!isDebuggable && !mWhitelistedPlugins.contains(pkg)) {
            Log.w(TAG, "Cannot get class loader for non-whitelisted plugin. Src:" + sourceDir +
                    ", pkg: " + pkg);
    /** Returns class loader specific for the given plugin. */
    public ClassLoader getClassLoader(ApplicationInfo appInfo) {
        if (!isDebuggable && !mWhitelistedPlugins.contains(appInfo.packageName)) {
            Log.w(TAG, "Cannot get class loader for non-whitelisted plugin. Src:"
                    + appInfo.sourceDir + ", pkg: " + appInfo.packageName);
            return null;
        }
        if (mClassLoaders.containsKey(pkg)) {
            return mClassLoaders.get(pkg);
        if (mClassLoaders.containsKey(appInfo.packageName)) {
            return mClassLoaders.get(appInfo.packageName);
        }
        ClassLoader classLoader = new PathClassLoader(sourceDir, getParentClassLoader());
        mClassLoaders.put(pkg, classLoader);

        List<String> zipPaths = new ArrayList<>();
        List<String> libPaths = new ArrayList<>();
        LoadedApk.makePaths(null, true, appInfo, zipPaths, libPaths);
        ClassLoader classLoader = new PathClassLoader(
                TextUtils.join(File.pathSeparator, zipPaths),
                TextUtils.join(File.pathSeparator, libPaths),
                getParentClassLoader());
        mClassLoaders.put(appInfo.packageName, classLoader);
        return classLoader;
    }

@@ -309,11 +321,6 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
        return mParentClassLoader;
    }

    public Context getContext(ApplicationInfo info, String pkg) throws NameNotFoundException {
        ClassLoader classLoader = getClassLoader(info.sourceDir, pkg);
        return new PluginContextWrapper(mContext.createApplicationContext(info, 0), classLoader);
    }

    public <T> boolean dependsOn(Plugin p, Class<T> cls) {
        for (int i = 0; i < mPluginMap.size(); i++) {
            if (mPluginMap.valueAt(i).dependsOn(p, cls)) {
+1 −1
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ public class PluginInstanceManagerTest extends SysuiTestCase {
        mMockPm = mock(PackageManager.class);
        mMockListener = mock(PluginListener.class);
        mMockManager = mock(PluginManagerImpl.class);
        when(mMockManager.getClassLoader(any(), any())).thenReturn(getClass().getClassLoader());
        when(mMockManager.getClassLoader(any())).thenReturn(getClass().getClassLoader());
        mMockEnabler = mock(PluginEnabler.class);
        when(mMockManager.getPluginEnabler()).thenReturn(mMockEnabler);
        mMockVersionInfo = mock(VersionInfo.class);
+16 −4
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.test.suitebuilder.annotation.SmallTest;
@@ -135,9 +136,13 @@ public class PluginManagerTest extends SysuiTestCase {
        });
        resetExceptionHandler();

        String sourceDir = "myPlugin";
        ApplicationInfo applicationInfo = new ApplicationInfo();
        applicationInfo.sourceDir = sourceDir;
        applicationInfo.packageName = WHITELISTED_PACKAGE;
        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
        assertNull(mPluginManager.getOneShotPlugin("myPlugin", TestPlugin.class));
        assertNull(mPluginManager.getClassLoader("myPlugin", WHITELISTED_PACKAGE));
        assertNull(mPluginManager.getOneShotPlugin(sourceDir, TestPlugin.class));
        assertNull(mPluginManager.getClassLoader(applicationInfo));
    }

    @Test
@@ -152,9 +157,16 @@ public class PluginManagerTest extends SysuiTestCase {
        });
        resetExceptionHandler();

        String sourceDir = "myPlugin";
        ApplicationInfo whiteListedApplicationInfo = new ApplicationInfo();
        whiteListedApplicationInfo.sourceDir = sourceDir;
        whiteListedApplicationInfo.packageName = WHITELISTED_PACKAGE;
        ApplicationInfo invalidApplicationInfo = new ApplicationInfo();
        invalidApplicationInfo.sourceDir = sourceDir;
        invalidApplicationInfo.packageName = "com.android.invalidpackage";
        mPluginManager.addPluginListener("myAction", mMockListener, TestPlugin.class);
        assertNotNull(mPluginManager.getClassLoader("myPlugin", WHITELISTED_PACKAGE));
        assertNull(mPluginManager.getClassLoader("myPlugin", "com.android.invalidpackage"));
        assertNotNull(mPluginManager.getClassLoader(whiteListedApplicationInfo));
        assertNull(mPluginManager.getClassLoader(invalidApplicationInfo));
    }

    @Test