Loading core/java/android/app/DexLoadReporter.java +4 −4 Original line number Diff line number Diff line Loading @@ -87,7 +87,7 @@ import java.util.Set; } @Override public void report(List<BaseDexClassLoader> classLoadersChain, List<String> classPaths) { public void report(List<ClassLoader> classLoadersChain, List<String> classPaths) { if (classLoadersChain.size() != classPaths.size()) { Slog.wtf(TAG, "Bad call to DexLoadReporter: argument size mismatch"); return; Loading @@ -113,12 +113,12 @@ import java.util.Set; registerSecondaryDexForProfiling(dexPathsForRegistration); } private void notifyPackageManager(List<BaseDexClassLoader> classLoadersChain, private void notifyPackageManager(List<ClassLoader> classLoadersChain, List<String> classPaths) { // Get the class loader names for the binder call. List<String> classLoadersNames = new ArrayList<>(classPaths.size()); for (BaseDexClassLoader bdc : classLoadersChain) { classLoadersNames.add(bdc.getClass().getName()); for (ClassLoader classLoader : classLoadersChain) { classLoadersNames.add(classLoader.getClass().getName()); } String packageName = ActivityThread.currentPackageName(); try { Loading core/java/android/content/pm/IPackageManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -475,7 +475,7 @@ interface IPackageManager { * @param classPaths the class paths corresponding to the class loaders names from * {@param classLoadersNames}. The the first element corresponds to the first class loader * and so on. A classpath is represented as a list of dex files separated by * {@code File.pathSeparator}. * {@code File.pathSeparator}, or null if the class loader's classpath is not known. * The dex files found in the first class path will be recorded in the usage file. * @param loaderIsa the ISA of the loader process */ Loading services/core/java/com/android/server/pm/dex/DexManager.java +11 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.util.Slog; import android.util.jar.StrictJarFile; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.server.pm.Installer; import com.android.server.pm.Installer.InstallerException; Loading Loading @@ -153,7 +154,7 @@ public class DexManager { * @param classPaths the class paths corresponding to the class loaders names from * {@param classLoadersNames}. The the first element corresponds to the first class loader * and so on. A classpath is represented as a list of dex files separated by * {@code File.pathSeparator}. * {@code File.pathSeparator}, or null if the class loader's classpath is not known. * The dex files found in the first class path will be recorded in the usage file. * @param loaderIsa the ISA of the app loading the dex files * @param loaderUserId the user id which runs the code loading the dex files Loading @@ -169,7 +170,8 @@ public class DexManager { } } private void notifyDexLoadInternal(ApplicationInfo loadingAppInfo, @VisibleForTesting /*package*/ void notifyDexLoadInternal(ApplicationInfo loadingAppInfo, List<String> classLoaderNames, List<String> classPaths, String loaderIsa, int loaderUserId) { if (classLoaderNames.size() != classPaths.size()) { Loading @@ -186,8 +188,14 @@ public class DexManager { return; } // The first classpath should never be null because the first classloader // should always be an instance of BaseDexClassLoader. String firstClassPath = classPaths.get(0); if (firstClassPath == null) { return; } // The classpath is represented as a list of dex files separated by File.pathSeparator. String[] dexPathsToRegister = classPaths.get(0).split(File.pathSeparator); String[] dexPathsToRegister = firstClassPath.split(File.pathSeparator); // Encode the class loader contexts for the dexPathsToRegister. String[] classLoaderContexts = DexoptUtils.processContextForDexLoad( Loading services/core/java/com/android/server/pm/dex/DexoptUtils.java +2 −1 Original line number Diff line number Diff line Loading @@ -318,7 +318,8 @@ public final class DexoptUtils { // is fine (they come over binder). Even if something changes we expect the sizes to be // very small and it shouldn't matter much. for (int i = 1; i < classLoadersNames.size(); i++) { if (!ClassLoaderFactory.isValidClassLoaderName(classLoadersNames.get(i))) { if (!ClassLoaderFactory.isValidClassLoaderName(classLoadersNames.get(i)) || classPaths.get(i) == null) { return null; } String classpath = encodeClasspath(classPaths.get(i).split(File.pathSeparator)); Loading services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java +28 −6 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ public class DexManagerTests { private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName(); private static final String DELEGATE_LAST_CLASS_LOADER_NAME = DelegateLastClassLoader.class.getName(); private static final String UNSUPPORTED_CLASS_LOADER_NAME = "unsupported.class_loader"; @Rule public MockitoRule mockito = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); @Mock Installer mInstaller; Loading Loading @@ -106,7 +107,7 @@ public class DexManagerTests { mDoesNotExist = new TestData("DOES.NOT.EXIST", isa, mUser1); mBarUser0UnsupportedClassLoader = new TestData(bar, isa, mUser0, "unsupported.class_loader"); UNSUPPORTED_CLASS_LOADER_NAME); mBarUser0DelegateLastClassLoader = new TestData(bar, isa, mUser0, DELEGATE_LAST_CLASS_LOADER_NAME); Loading Loading @@ -405,6 +406,24 @@ public class DexManagerTests { assertNoUseInfo(mBarUser0UnsupportedClassLoader); } @Test public void testNotifySupportedAndUnsupportedClassLoader() { String classPath = String.join(File.pathSeparator, mBarUser0.getSecondaryDexPaths()); List<String> classLoaders = Arrays.asList(PATH_CLASS_LOADER_NAME, UNSUPPORTED_CLASS_LOADER_NAME); List<String> classPaths = Arrays.asList(classPath, classPath); notifyDexLoad(mBarUser0, classLoaders, classPaths, mUser0); assertNoUseInfo(mBarUser0); } @Test public void testNotifyNullClassPath() { notifyDexLoad(mBarUser0, null, mUser0); assertNoUseInfo(mBarUser0); } @Test public void testNotifyVariableClassLoader() { // Record bar secondaries with the default PathClassLoader. Loading Loading @@ -500,14 +519,17 @@ public class DexManagerTests { // By default, assume a single class loader in the chain. // This makes writing tests much easier. List<String> classLoaders = Arrays.asList(testData.mClassLoader); List<String> classPaths = Arrays.asList(String.join(File.pathSeparator, dexPaths)); List<String> classPaths = (dexPaths == null) ? Arrays.asList((String) null) : Arrays.asList(String.join(File.pathSeparator, dexPaths)); notifyDexLoad(testData, classLoaders, classPaths, loaderUserId); } private void notifyDexLoad(TestData testData, List<String> classLoader, List<String> classPaths, int loaderUserId) { mDexManager.notifyDexLoad(testData.mPackageInfo.applicationInfo, classLoader, classPaths, testData.mLoaderIsa, loaderUserId); private void notifyDexLoad(TestData testData, List<String> classLoaders, List<String> classPaths, int loaderUserId) { // We call the internal function so any exceptions thrown cause test failures. mDexManager.notifyDexLoadInternal(testData.mPackageInfo.applicationInfo, classLoaders, classPaths, testData.mLoaderIsa, loaderUserId); } private PackageUseInfo getPackageUseInfo(TestData testData) { Loading Loading
core/java/android/app/DexLoadReporter.java +4 −4 Original line number Diff line number Diff line Loading @@ -87,7 +87,7 @@ import java.util.Set; } @Override public void report(List<BaseDexClassLoader> classLoadersChain, List<String> classPaths) { public void report(List<ClassLoader> classLoadersChain, List<String> classPaths) { if (classLoadersChain.size() != classPaths.size()) { Slog.wtf(TAG, "Bad call to DexLoadReporter: argument size mismatch"); return; Loading @@ -113,12 +113,12 @@ import java.util.Set; registerSecondaryDexForProfiling(dexPathsForRegistration); } private void notifyPackageManager(List<BaseDexClassLoader> classLoadersChain, private void notifyPackageManager(List<ClassLoader> classLoadersChain, List<String> classPaths) { // Get the class loader names for the binder call. List<String> classLoadersNames = new ArrayList<>(classPaths.size()); for (BaseDexClassLoader bdc : classLoadersChain) { classLoadersNames.add(bdc.getClass().getName()); for (ClassLoader classLoader : classLoadersChain) { classLoadersNames.add(classLoader.getClass().getName()); } String packageName = ActivityThread.currentPackageName(); try { Loading
core/java/android/content/pm/IPackageManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -475,7 +475,7 @@ interface IPackageManager { * @param classPaths the class paths corresponding to the class loaders names from * {@param classLoadersNames}. The the first element corresponds to the first class loader * and so on. A classpath is represented as a list of dex files separated by * {@code File.pathSeparator}. * {@code File.pathSeparator}, or null if the class loader's classpath is not known. * The dex files found in the first class path will be recorded in the usage file. * @param loaderIsa the ISA of the loader process */ Loading
services/core/java/com/android/server/pm/dex/DexManager.java +11 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.util.Slog; import android.util.jar.StrictJarFile; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.server.pm.Installer; import com.android.server.pm.Installer.InstallerException; Loading Loading @@ -153,7 +154,7 @@ public class DexManager { * @param classPaths the class paths corresponding to the class loaders names from * {@param classLoadersNames}. The the first element corresponds to the first class loader * and so on. A classpath is represented as a list of dex files separated by * {@code File.pathSeparator}. * {@code File.pathSeparator}, or null if the class loader's classpath is not known. * The dex files found in the first class path will be recorded in the usage file. * @param loaderIsa the ISA of the app loading the dex files * @param loaderUserId the user id which runs the code loading the dex files Loading @@ -169,7 +170,8 @@ public class DexManager { } } private void notifyDexLoadInternal(ApplicationInfo loadingAppInfo, @VisibleForTesting /*package*/ void notifyDexLoadInternal(ApplicationInfo loadingAppInfo, List<String> classLoaderNames, List<String> classPaths, String loaderIsa, int loaderUserId) { if (classLoaderNames.size() != classPaths.size()) { Loading @@ -186,8 +188,14 @@ public class DexManager { return; } // The first classpath should never be null because the first classloader // should always be an instance of BaseDexClassLoader. String firstClassPath = classPaths.get(0); if (firstClassPath == null) { return; } // The classpath is represented as a list of dex files separated by File.pathSeparator. String[] dexPathsToRegister = classPaths.get(0).split(File.pathSeparator); String[] dexPathsToRegister = firstClassPath.split(File.pathSeparator); // Encode the class loader contexts for the dexPathsToRegister. String[] classLoaderContexts = DexoptUtils.processContextForDexLoad( Loading
services/core/java/com/android/server/pm/dex/DexoptUtils.java +2 −1 Original line number Diff line number Diff line Loading @@ -318,7 +318,8 @@ public final class DexoptUtils { // is fine (they come over binder). Even if something changes we expect the sizes to be // very small and it shouldn't matter much. for (int i = 1; i < classLoadersNames.size(); i++) { if (!ClassLoaderFactory.isValidClassLoaderName(classLoadersNames.get(i))) { if (!ClassLoaderFactory.isValidClassLoaderName(classLoadersNames.get(i)) || classPaths.get(i) == null) { return null; } String classpath = encodeClasspath(classPaths.get(i).split(File.pathSeparator)); Loading
services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java +28 −6 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ public class DexManagerTests { private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName(); private static final String DELEGATE_LAST_CLASS_LOADER_NAME = DelegateLastClassLoader.class.getName(); private static final String UNSUPPORTED_CLASS_LOADER_NAME = "unsupported.class_loader"; @Rule public MockitoRule mockito = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); @Mock Installer mInstaller; Loading Loading @@ -106,7 +107,7 @@ public class DexManagerTests { mDoesNotExist = new TestData("DOES.NOT.EXIST", isa, mUser1); mBarUser0UnsupportedClassLoader = new TestData(bar, isa, mUser0, "unsupported.class_loader"); UNSUPPORTED_CLASS_LOADER_NAME); mBarUser0DelegateLastClassLoader = new TestData(bar, isa, mUser0, DELEGATE_LAST_CLASS_LOADER_NAME); Loading Loading @@ -405,6 +406,24 @@ public class DexManagerTests { assertNoUseInfo(mBarUser0UnsupportedClassLoader); } @Test public void testNotifySupportedAndUnsupportedClassLoader() { String classPath = String.join(File.pathSeparator, mBarUser0.getSecondaryDexPaths()); List<String> classLoaders = Arrays.asList(PATH_CLASS_LOADER_NAME, UNSUPPORTED_CLASS_LOADER_NAME); List<String> classPaths = Arrays.asList(classPath, classPath); notifyDexLoad(mBarUser0, classLoaders, classPaths, mUser0); assertNoUseInfo(mBarUser0); } @Test public void testNotifyNullClassPath() { notifyDexLoad(mBarUser0, null, mUser0); assertNoUseInfo(mBarUser0); } @Test public void testNotifyVariableClassLoader() { // Record bar secondaries with the default PathClassLoader. Loading Loading @@ -500,14 +519,17 @@ public class DexManagerTests { // By default, assume a single class loader in the chain. // This makes writing tests much easier. List<String> classLoaders = Arrays.asList(testData.mClassLoader); List<String> classPaths = Arrays.asList(String.join(File.pathSeparator, dexPaths)); List<String> classPaths = (dexPaths == null) ? Arrays.asList((String) null) : Arrays.asList(String.join(File.pathSeparator, dexPaths)); notifyDexLoad(testData, classLoaders, classPaths, loaderUserId); } private void notifyDexLoad(TestData testData, List<String> classLoader, List<String> classPaths, int loaderUserId) { mDexManager.notifyDexLoad(testData.mPackageInfo.applicationInfo, classLoader, classPaths, testData.mLoaderIsa, loaderUserId); private void notifyDexLoad(TestData testData, List<String> classLoaders, List<String> classPaths, int loaderUserId) { // We call the internal function so any exceptions thrown cause test failures. mDexManager.notifyDexLoadInternal(testData.mPackageInfo.applicationInfo, classLoaders, classPaths, testData.mLoaderIsa, loaderUserId); } private PackageUseInfo getPackageUseInfo(TestData testData) { Loading