Loading cmds/idmap/scan.cpp +2 −1 Original line number Original line Diff line number Diff line Loading @@ -119,7 +119,8 @@ namespace { int parse_manifest(const void *data, size_t size, const char *target_package_name) int parse_manifest(const void *data, size_t size, const char *target_package_name) { { ResXMLTree parser(data, size); ResXMLTree parser; parser.setTo(data, size); if (parser.getError() != NO_ERROR) { if (parser.getError() != NO_ERROR) { ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError()); ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError()); return -1; return -1; Loading core/java/android/app/ActivityThread.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -1592,10 +1592,10 @@ public final class ActivityThread { /** /** * Creates the top level resources for the given package. * Creates the top level resources for the given package. */ */ Resources getTopLevelResources(String resDir, String[] overlayDirs, Resources getTopLevelResources(String resDir, String[] overlayDirs, String[] libDirs, int displayId, Configuration overrideConfiguration, int displayId, Configuration overrideConfiguration, LoadedApk pkgInfo) { LoadedApk pkgInfo) { return mResourcesManager.getTopLevelResources(resDir, overlayDirs, displayId, return mResourcesManager.getTopLevelResources(resDir, overlayDirs, libDirs, displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo(), null); overrideConfiguration, pkgInfo.getCompatibilityInfo(), null); } } Loading core/java/android/app/ApplicationPackageManager.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -805,7 +805,7 @@ final class ApplicationPackageManager extends PackageManager { } } Resources r = mContext.mMainThread.getTopLevelResources( Resources r = mContext.mMainThread.getTopLevelResources( app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir, app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir, app.resourceDirs, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo); app.resourceDirs, null, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo); if (r != null) { if (r != null) { return r; return r; } } Loading core/java/android/app/ContextImpl.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -2044,8 +2044,9 @@ class ContextImpl extends Context { || (compatInfo != null && compatInfo.applicationScale || (compatInfo != null && compatInfo.applicationScale != resources.getCompatibilityInfo().applicationScale)) { != resources.getCompatibilityInfo().applicationScale)) { resources = mResourcesManager.getTopLevelResources( resources = mResourcesManager.getTopLevelResources( packageInfo.getResDir(), packageInfo.getOverlayDirs(), displayId, packageInfo.getResDir(), packageInfo.getOverlayDirs(), overrideConfiguration, compatInfo, activityToken); packageInfo.getApplicationInfo().sharedLibraryFiles, displayId, overrideConfiguration, compatInfo, activityToken); } } } } mResources = resources; mResources = resources; Loading core/java/android/app/LoadedApk.java +96 −2 Original line number Original line Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.os.Trace; import android.os.UserHandle; import android.os.UserHandle; import android.util.AndroidRuntimeException; import android.util.AndroidRuntimeException; import android.util.Slog; import android.util.Slog; import android.util.SparseArray; import android.view.DisplayAdjustments; import android.view.DisplayAdjustments; import android.view.Display; import android.view.Display; Loading @@ -48,6 +49,8 @@ import java.io.File; import java.io.IOException; import java.io.IOException; import java.io.InputStream; import java.io.InputStream; import java.lang.ref.WeakReference; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.net.URL; import java.net.URL; import java.util.Enumeration; import java.util.Enumeration; Loading Loading @@ -485,7 +488,7 @@ public final class LoadedApk { public Resources getResources(ActivityThread mainThread) { public Resources getResources(ActivityThread mainThread) { if (mResources == null) { if (mResources == null) { mResources = mainThread.getTopLevelResources(mResDir, mOverlayDirs, mResources = mainThread.getTopLevelResources(mResDir, mOverlayDirs, Display.DEFAULT_DISPLAY, null, this); mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, null, this); } } return mResources; return mResources; } } Loading Loading @@ -531,9 +534,100 @@ public final class LoadedApk { } } } } // Rewrite the R 'constants' for all library apks. SparseArray<String> packageIdentifiers = getAssets(mActivityThread) .getAssignedPackageIdentifiers(); final int N = packageIdentifiers.size(); for (int i = 0; i < N; i++) { final int id = packageIdentifiers.keyAt(i); if (id == 0x01 || id == 0x7f) { continue; } rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id); } return app; return app; } } private void rewriteIntField(Field field, int packageId) throws IllegalAccessException { int requiredModifiers = Modifier.STATIC | Modifier.PUBLIC; int bannedModifiers = Modifier.FINAL; int mod = field.getModifiers(); if ((mod & requiredModifiers) != requiredModifiers || (mod & bannedModifiers) != 0) { throw new IllegalArgumentException("Field " + field.getName() + " is not rewritable"); } if (field.getType() != int.class && field.getType() != Integer.class) { throw new IllegalArgumentException("Field " + field.getName() + " is not an integer"); } try { int resId = field.getInt(null); field.setInt(null, (resId & 0x00ffffff) | (packageId << 24)); } catch (IllegalAccessException e) { // This should not occur (we check above if we can write to it) throw new IllegalArgumentException(e); } } private void rewriteIntArrayField(Field field, int packageId) { int requiredModifiers = Modifier.STATIC | Modifier.PUBLIC; if ((field.getModifiers() & requiredModifiers) != requiredModifiers) { throw new IllegalArgumentException("Field " + field.getName() + " is not rewritable"); } if (field.getType() != int[].class) { throw new IllegalArgumentException("Field " + field.getName() + " is not an integer array"); } try { int[] array = (int[]) field.get(null); for (int i = 0; i < array.length; i++) { array[i] = (array[i] & 0x00ffffff) | (packageId << 24); } } catch (IllegalAccessException e) { // This should not occur (we check above if we can write to it) throw new IllegalArgumentException(e); } } private void rewriteRValues(ClassLoader cl, String packageName, int id) { try { final Class<?> rClazz = cl.loadClass(packageName + ".R"); Class<?>[] declaredClasses = rClazz.getDeclaredClasses(); for (Class<?> clazz : declaredClasses) { try { if (clazz.getSimpleName().equals("styleable")) { for (Field field : clazz.getDeclaredFields()) { if (field.getType() == int[].class) { rewriteIntArrayField(field, id); } } } else { for (Field field : clazz.getDeclaredFields()) { rewriteIntField(field, id); } } } catch (Exception e) { throw new IllegalArgumentException("Failed to rewrite R values for " + clazz.getName(), e); } } } catch (Exception e) { throw new IllegalArgumentException("Failed to rewrite R values", e); } } public void removeContextRegistrations(Context context, public void removeContextRegistrations(Context context, String who, String what) { String who, String what) { final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled(); final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled(); Loading Loading
cmds/idmap/scan.cpp +2 −1 Original line number Original line Diff line number Diff line Loading @@ -119,7 +119,8 @@ namespace { int parse_manifest(const void *data, size_t size, const char *target_package_name) int parse_manifest(const void *data, size_t size, const char *target_package_name) { { ResXMLTree parser(data, size); ResXMLTree parser; parser.setTo(data, size); if (parser.getError() != NO_ERROR) { if (parser.getError() != NO_ERROR) { ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError()); ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError()); return -1; return -1; Loading
core/java/android/app/ActivityThread.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -1592,10 +1592,10 @@ public final class ActivityThread { /** /** * Creates the top level resources for the given package. * Creates the top level resources for the given package. */ */ Resources getTopLevelResources(String resDir, String[] overlayDirs, Resources getTopLevelResources(String resDir, String[] overlayDirs, String[] libDirs, int displayId, Configuration overrideConfiguration, int displayId, Configuration overrideConfiguration, LoadedApk pkgInfo) { LoadedApk pkgInfo) { return mResourcesManager.getTopLevelResources(resDir, overlayDirs, displayId, return mResourcesManager.getTopLevelResources(resDir, overlayDirs, libDirs, displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo(), null); overrideConfiguration, pkgInfo.getCompatibilityInfo(), null); } } Loading
core/java/android/app/ApplicationPackageManager.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -805,7 +805,7 @@ final class ApplicationPackageManager extends PackageManager { } } Resources r = mContext.mMainThread.getTopLevelResources( Resources r = mContext.mMainThread.getTopLevelResources( app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir, app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir, app.resourceDirs, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo); app.resourceDirs, null, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo); if (r != null) { if (r != null) { return r; return r; } } Loading
core/java/android/app/ContextImpl.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -2044,8 +2044,9 @@ class ContextImpl extends Context { || (compatInfo != null && compatInfo.applicationScale || (compatInfo != null && compatInfo.applicationScale != resources.getCompatibilityInfo().applicationScale)) { != resources.getCompatibilityInfo().applicationScale)) { resources = mResourcesManager.getTopLevelResources( resources = mResourcesManager.getTopLevelResources( packageInfo.getResDir(), packageInfo.getOverlayDirs(), displayId, packageInfo.getResDir(), packageInfo.getOverlayDirs(), overrideConfiguration, compatInfo, activityToken); packageInfo.getApplicationInfo().sharedLibraryFiles, displayId, overrideConfiguration, compatInfo, activityToken); } } } } mResources = resources; mResources = resources; Loading
core/java/android/app/LoadedApk.java +96 −2 Original line number Original line Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.os.Trace; import android.os.UserHandle; import android.os.UserHandle; import android.util.AndroidRuntimeException; import android.util.AndroidRuntimeException; import android.util.Slog; import android.util.Slog; import android.util.SparseArray; import android.view.DisplayAdjustments; import android.view.DisplayAdjustments; import android.view.Display; import android.view.Display; Loading @@ -48,6 +49,8 @@ import java.io.File; import java.io.IOException; import java.io.IOException; import java.io.InputStream; import java.io.InputStream; import java.lang.ref.WeakReference; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.net.URL; import java.net.URL; import java.util.Enumeration; import java.util.Enumeration; Loading Loading @@ -485,7 +488,7 @@ public final class LoadedApk { public Resources getResources(ActivityThread mainThread) { public Resources getResources(ActivityThread mainThread) { if (mResources == null) { if (mResources == null) { mResources = mainThread.getTopLevelResources(mResDir, mOverlayDirs, mResources = mainThread.getTopLevelResources(mResDir, mOverlayDirs, Display.DEFAULT_DISPLAY, null, this); mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, null, this); } } return mResources; return mResources; } } Loading Loading @@ -531,9 +534,100 @@ public final class LoadedApk { } } } } // Rewrite the R 'constants' for all library apks. SparseArray<String> packageIdentifiers = getAssets(mActivityThread) .getAssignedPackageIdentifiers(); final int N = packageIdentifiers.size(); for (int i = 0; i < N; i++) { final int id = packageIdentifiers.keyAt(i); if (id == 0x01 || id == 0x7f) { continue; } rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id); } return app; return app; } } private void rewriteIntField(Field field, int packageId) throws IllegalAccessException { int requiredModifiers = Modifier.STATIC | Modifier.PUBLIC; int bannedModifiers = Modifier.FINAL; int mod = field.getModifiers(); if ((mod & requiredModifiers) != requiredModifiers || (mod & bannedModifiers) != 0) { throw new IllegalArgumentException("Field " + field.getName() + " is not rewritable"); } if (field.getType() != int.class && field.getType() != Integer.class) { throw new IllegalArgumentException("Field " + field.getName() + " is not an integer"); } try { int resId = field.getInt(null); field.setInt(null, (resId & 0x00ffffff) | (packageId << 24)); } catch (IllegalAccessException e) { // This should not occur (we check above if we can write to it) throw new IllegalArgumentException(e); } } private void rewriteIntArrayField(Field field, int packageId) { int requiredModifiers = Modifier.STATIC | Modifier.PUBLIC; if ((field.getModifiers() & requiredModifiers) != requiredModifiers) { throw new IllegalArgumentException("Field " + field.getName() + " is not rewritable"); } if (field.getType() != int[].class) { throw new IllegalArgumentException("Field " + field.getName() + " is not an integer array"); } try { int[] array = (int[]) field.get(null); for (int i = 0; i < array.length; i++) { array[i] = (array[i] & 0x00ffffff) | (packageId << 24); } } catch (IllegalAccessException e) { // This should not occur (we check above if we can write to it) throw new IllegalArgumentException(e); } } private void rewriteRValues(ClassLoader cl, String packageName, int id) { try { final Class<?> rClazz = cl.loadClass(packageName + ".R"); Class<?>[] declaredClasses = rClazz.getDeclaredClasses(); for (Class<?> clazz : declaredClasses) { try { if (clazz.getSimpleName().equals("styleable")) { for (Field field : clazz.getDeclaredFields()) { if (field.getType() == int[].class) { rewriteIntArrayField(field, id); } } } else { for (Field field : clazz.getDeclaredFields()) { rewriteIntField(field, id); } } } catch (Exception e) { throw new IllegalArgumentException("Failed to rewrite R values for " + clazz.getName(), e); } } } catch (Exception e) { throw new IllegalArgumentException("Failed to rewrite R values", e); } } public void removeContextRegistrations(Context context, public void removeContextRegistrations(Context context, String who, String what) { String who, String what) { final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled(); final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled(); Loading