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

Commit 3120b13f authored by Brad Stenning's avatar Brad Stenning Committed by Gerrit Code Review
Browse files

Merge "Allow a shared library to be positioned after the application on the classpath"

parents d3dfca9c 89dfd090
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -48,18 +48,19 @@ public class ApplicationLoaders {
                               ClassLoader parent, String classLoaderName) {
        return getClassLoaderWithSharedLibraries(zip, targetSdkVersion, isBundled,
                              librarySearchPath, libraryPermittedPath, parent, classLoaderName,
                              null, null);
                              null, null, null);
    }

    ClassLoader getClassLoaderWithSharedLibraries(
            String zip, int targetSdkVersion, boolean isBundled,
            String librarySearchPath, String libraryPermittedPath,
            ClassLoader parent, String classLoaderName,
            List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries) {
            List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries,
            List<ClassLoader> sharedLibrariesLoadedAfterApp) {
        // For normal usage the cache key used is the same as the zip path.
        return getClassLoader(zip, targetSdkVersion, isBundled, librarySearchPath,
                              libraryPermittedPath, parent, zip, classLoaderName, sharedLibraries,
                              nativeSharedLibraries);
                              nativeSharedLibraries, sharedLibrariesLoadedAfterApp);
    }

    /**
@@ -71,7 +72,8 @@ public class ApplicationLoaders {
     */
    ClassLoader getSharedLibraryClassLoaderWithSharedLibraries(String zip, int targetSdkVersion,
            boolean isBundled, String librarySearchPath, String libraryPermittedPath,
            ClassLoader parent, String classLoaderName, List<ClassLoader> sharedLibraries) {
            ClassLoader parent, String classLoaderName, List<ClassLoader> sharedLibraries,
            List<ClassLoader> sharedLibrariesAfter) {
        ClassLoader loader = getCachedNonBootclasspathSystemLib(zip, parent, classLoaderName,
                sharedLibraries);
        if (loader != null) {
@@ -86,14 +88,15 @@ public class ApplicationLoaders {
        nativeSharedLibraries.add("ALL");
        return getClassLoaderWithSharedLibraries(zip, targetSdkVersion, isBundled,
              librarySearchPath, libraryPermittedPath, parent, classLoaderName, sharedLibraries,
              nativeSharedLibraries);
              nativeSharedLibraries, sharedLibrariesAfter);
    }

    private ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
                                       String librarySearchPath, String libraryPermittedPath,
                                       ClassLoader parent, String cacheKey,
                                       String classLoaderName, List<ClassLoader> sharedLibraries,
                                       List<String> nativeSharedLibraries) {
                                       List<String> nativeSharedLibraries,
                                       List<ClassLoader> sharedLibrariesLoadedAfterApp) {
        /*
         * This is the parent we use if they pass "null" in.  In theory
         * this should be the "system" class loader; in practice we
@@ -123,7 +126,7 @@ public class ApplicationLoaders {
                ClassLoader classloader = ClassLoaderFactory.createClassLoader(
                        zip,  librarySearchPath, libraryPermittedPath, parent,
                        targetSdkVersion, isBundled, classLoaderName, sharedLibraries,
                        nativeSharedLibraries);
                        nativeSharedLibraries, sharedLibrariesLoadedAfterApp);

                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

@@ -140,7 +143,8 @@ public class ApplicationLoaders {

            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
            ClassLoader loader = ClassLoaderFactory.createClassLoader(
                    zip, null, parent, classLoaderName, sharedLibraries);
                    zip, null, parent, classLoaderName, sharedLibraries,
                    null /*sharedLibrariesLoadedAfterApp*/);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            return loader;
        }
@@ -196,7 +200,7 @@ public class ApplicationLoaders {
        ClassLoader classLoader = getClassLoader(path, Build.VERSION.SDK_INT, true /*isBundled*/,
                null /*librarySearchPath*/, null /*libraryPermittedPath*/, null /*parent*/,
                null /*cacheKey*/, null /*classLoaderName*/, sharedLibraries /*sharedLibraries*/,
                null /* nativeSharedLibraries */);
                null /* nativeSharedLibraries */, null /*sharedLibrariesLoadedAfterApp*/);

        if (classLoader == null) {
            // bad configuration or break in classloading code
@@ -267,7 +271,8 @@ public class ApplicationLoaders {
        // stub's APK path, when the actual package path is the donor APK.
        return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null,
                              cacheKey, null /* classLoaderName */, null /* sharedLibraries */,
                              null /* nativeSharedLibraries */);
                              null /* nativeSharedLibraries */,
                              null /*sharedLibrariesLoadedAfterApp*/);
    }

    /**
+41 −12
Original line number Diff line number Diff line
@@ -54,10 +54,12 @@ import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.view.DisplayAdjustments;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;

@@ -76,6 +78,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
@@ -700,7 +703,7 @@ public final class LoadedApk {
    ClassLoader createSharedLibraryLoader(SharedLibraryInfo sharedLibrary,
            boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
        List<String> paths = sharedLibrary.getAllCodePaths();
        List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
        Pair<List<ClassLoader>, List<ClassLoader>> sharedLibraries = createSharedLibrariesLoaders(
                sharedLibrary.getDependencies(), isBundledApp, librarySearchPath,
                libraryPermittedPath);
        final String jars = (paths.size() == 1) ? paths.get(0) :
@@ -711,15 +714,31 @@ public final class LoadedApk {
        return ApplicationLoaders.getDefault().getSharedLibraryClassLoaderWithSharedLibraries(jars,
                    mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
                    libraryPermittedPath, /* parent */ null,
                    /* classLoaderName */ null, sharedLibraries);
                    /* classLoaderName */ null, sharedLibraries.first, sharedLibraries.second);
    }

    private List<ClassLoader> createSharedLibrariesLoaders(List<SharedLibraryInfo> sharedLibraries,
    /**
     *
     * @return a {@link Pair} of List<ClassLoader> where the first is for standard shared libraries
     *         and the second is list for shared libraries that code should be loaded after the dex
     */
    private Pair<List<ClassLoader>, List<ClassLoader>> createSharedLibrariesLoaders(
            List<SharedLibraryInfo> sharedLibraries,
            boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
        if (sharedLibraries == null) {
            return null;
        if (sharedLibraries == null || sharedLibraries.isEmpty()) {
            return new Pair<>(null, null);
        }

        // if configured to do so, shared libs are split into 2 collections: those that are
        // on the class path before the applications code, which is standard, and those
        // specified to be loaded after the applications code.
        HashSet<String> libsToLoadAfter = new HashSet<>();
        Resources systemR = Resources.getSystem();
        Collections.addAll(libsToLoadAfter, systemR.getStringArray(
                R.array.config_sharedLibrariesLoadedAfterApp));

        List<ClassLoader> loaders = new ArrayList<>();
        List<ClassLoader> after = new ArrayList<>();
        for (SharedLibraryInfo info : sharedLibraries) {
            if (info.isNative()) {
                // Native shared lib doesn't contribute to the native lib search path. Its name is
@@ -727,10 +746,19 @@ public final class LoadedApk {
                // default linker namespace.
                continue;
            }
            if (libsToLoadAfter.contains(info.getName())) {
                if (DEBUG) {
                    Slog.v(ActivityThread.TAG,
                            info.getName() + " will be loaded after application code");
                }
                after.add(createSharedLibraryLoader(
                        info, isBundledApp, librarySearchPath, libraryPermittedPath));
            } else {
                loaders.add(createSharedLibraryLoader(
                        info, isBundledApp, librarySearchPath, libraryPermittedPath));
            }
        return loaders;
        }
        return new Pair<>(loaders, after);
    }

    private StrictMode.ThreadPolicy allowThreadDiskReads() {
@@ -955,9 +983,9 @@ public final class LoadedApk {
            // as this is early and necessary.
            StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();

            List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
                    mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath,
                    libraryPermittedPath);
            Pair<List<ClassLoader>, List<ClassLoader>> sharedLibraries =
                    createSharedLibrariesLoaders(mApplicationInfo.sharedLibraryInfos, isBundledApp,
                            librarySearchPath, libraryPermittedPath);

            List<String> nativeSharedLibraries = new ArrayList<>();
            if (mApplicationInfo.sharedLibraryInfos != null) {
@@ -971,7 +999,8 @@ public final class LoadedApk {
            mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(
                    zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
                    libraryPermittedPath, mBaseClassLoader,
                    mApplicationInfo.classLoaderName, sharedLibraries, nativeSharedLibraries);
                    mApplicationInfo.classLoaderName, sharedLibraries.first, nativeSharedLibraries,
                    sharedLibraries.second);
            mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);

            setThreadPolicy(oldPolicy);
+12 −7
Original line number Diff line number Diff line
@@ -80,15 +80,20 @@ public class ClassLoaderFactory {
     */
    public static ClassLoader createClassLoader(String dexPath,
            String librarySearchPath, ClassLoader parent, String classloaderName,
            List<ClassLoader> sharedLibraries) {
            List<ClassLoader> sharedLibraries, List<ClassLoader> sharedLibrariesLoadedAfter) {
        ClassLoader[] arrayOfSharedLibraries = (sharedLibraries == null)
                ? null
                : sharedLibraries.toArray(new ClassLoader[sharedLibraries.size()]);
        ClassLoader[] arrayOfSharedLibrariesLoadedAfterApp = (sharedLibrariesLoadedAfter == null)
                ? null
                : sharedLibrariesLoadedAfter.toArray(
                        new ClassLoader[sharedLibrariesLoadedAfter.size()]);
        if (isPathClassLoaderName(classloaderName)) {
            return new PathClassLoader(dexPath, librarySearchPath, parent, arrayOfSharedLibraries);
            return new PathClassLoader(dexPath, librarySearchPath, parent, arrayOfSharedLibraries,
                    arrayOfSharedLibrariesLoadedAfterApp);
        } else if (isDelegateLastClassLoaderName(classloaderName)) {
            return new DelegateLastClassLoader(dexPath, librarySearchPath, parent,
                    arrayOfSharedLibraries);
                    arrayOfSharedLibraries, arrayOfSharedLibrariesLoadedAfterApp);
        }

        throw new AssertionError("Invalid classLoaderName: " + classloaderName);
@@ -102,20 +107,20 @@ public class ClassLoaderFactory {
            String librarySearchPath, String libraryPermittedPath, ClassLoader parent,
            int targetSdkVersion, boolean isNamespaceShared, String classLoaderName) {
        return createClassLoader(dexPath, librarySearchPath, libraryPermittedPath,
            parent, targetSdkVersion, isNamespaceShared, classLoaderName, null, null);
            parent, targetSdkVersion, isNamespaceShared, classLoaderName, null, null, null);
    }


    /**
     * Create a ClassLoader and initialize a linker-namespace for it.
     */
    public static ClassLoader createClassLoader(String dexPath,
            String librarySearchPath, String libraryPermittedPath, ClassLoader parent,
            int targetSdkVersion, boolean isNamespaceShared, String classLoaderName,
            List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries) {
            List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries,
            List<ClassLoader> sharedLibrariesAfter) {

        final ClassLoader classLoader = createClassLoader(dexPath, librarySearchPath, parent,
                classLoaderName, sharedLibraries);
                classLoaderName, sharedLibraries, sharedLibrariesAfter);

        String sonameList = "";
        if (nativeSharedLibraries != null) {
+5 −0
Original line number Diff line number Diff line
@@ -5047,6 +5047,11 @@
         to 0, the seconds hand will be disabled. -->
    <integer name="config_defaultAnalogClockSecondsHandFps">1</integer>

    <!-- List of shared library packages that should be loaded by the classloader after the
         code and resources provided by applications. This value will be set by the manufacturer  -->
    <string-array name="config_sharedLibrariesLoadedAfterApp" translatable="false">
    </string-array>

    <!-- the number of the max cached processes in the system. -->
    <integer name="config_customizedMaxCachedProcesses">32</integer>
</resources>
+4 −0
Original line number Diff line number Diff line
@@ -4425,5 +4425,9 @@

  <java-symbol type="bool" name="config_volumeShowRemoteSessions" />

  <!-- List of shared library packages that should be loaded by the classloader after the
       code and resources provided by applications. -->
  <java-symbol type="array" name="config_sharedLibrariesLoadedAfterApp" />

  <java-symbol type="integer" name="config_customizedMaxCachedProcesses" />
</resources>
Loading