Loading core/java/android/app/ActivityThread.java +16 −3 Original line number Diff line number Diff line Loading @@ -220,6 +220,7 @@ public final class ActivityThread { // which means this lock gets held while the activity and window managers // holds their own lock. Thus you MUST NEVER call back into the activity manager // or window manager or anything that depends on them while holding this lock. // These LoadedApk are only valid for the userId that we're running as. final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<String, WeakReference<LoadedApk>>(); final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages Loading Loading @@ -1705,13 +1706,18 @@ public final class ActivityThread { public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, int flags, int userId) { final boolean differentUser = (UserHandle.myUserId() != userId); synchronized (mResourcesManager) { WeakReference<LoadedApk> ref; if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) { if (differentUser) { // Caching not supported across users ref = null; } else if ((flags & Context.CONTEXT_INCLUDE_CODE) != 0) { ref = mPackages.get(packageName); } else { ref = mResourcePackages.get(packageName); } LoadedApk packageInfo = ref != null ? ref.get() : null; //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo); //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir Loading Loading @@ -1791,13 +1797,18 @@ public final class ActivityThread { private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo, ClassLoader baseLoader, boolean securityViolation, boolean includeCode, boolean registerPackage) { final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid)); synchronized (mResourcesManager) { WeakReference<LoadedApk> ref; if (includeCode) { if (differentUser) { // Caching not supported across users ref = null; } else if (includeCode) { ref = mPackages.get(aInfo.packageName); } else { ref = mResourcePackages.get(aInfo.packageName); } LoadedApk packageInfo = ref != null ? ref.get() : null; if (packageInfo == null || (packageInfo.mResources != null && !packageInfo.mResources.getAssets().isUpToDate())) { Loading @@ -1816,7 +1827,9 @@ public final class ActivityThread { getSystemContext().mPackageInfo.getClassLoader()); } if (includeCode) { if (differentUser) { // Caching not supported across users } else if (includeCode) { mPackages.put(aInfo.packageName, new WeakReference<LoadedApk>(packageInfo)); } else { Loading core/java/android/app/LoadedApk.java +1 −5 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package android.app; import android.text.TextUtils; import android.util.ArrayMap; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -46,6 +45,7 @@ import android.util.SparseArray; import android.view.DisplayAdjustments; import android.view.Display; import android.os.SystemProperties; import dalvik.system.VMRuntime; import java.io.File; Loading Loading @@ -136,10 +136,6 @@ public final class LoadedApk { mSplitAppDirs = aInfo.splitSourceDirs; mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs; mOverlayDirs = aInfo.resourceDirs; if (!UserHandle.isSameUser(aInfo.uid, myUid) && !Process.isIsolated()) { aInfo.dataDir = PackageManager.getDataDirForUser(UserHandle.getUserId(myUid), mPackageName); } mSharedLibraries = aInfo.sharedLibraryFiles; mDataDir = aInfo.dataDir; mDataDirFile = mDataDir != null ? new File(mDataDir) : null; Loading core/java/android/content/pm/PackageManager.java +11 −7 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.os.Environment; import android.os.RemoteException; import android.os.UserHandle; import android.os.storage.VolumeInfo; import android.text.TextUtils; import android.util.AndroidException; import com.android.internal.util.ArrayUtils; Loading Loading @@ -4184,16 +4185,19 @@ public abstract class PackageManager { public abstract @NonNull PackageInstaller getPackageInstaller(); /** * Returns the data directory for a particular user and package, given the uid of the package. * @param uid uid of the package, including the userId and appId * @param packageName name of the package * @return the user-specific data directory for the package * Returns the data directory for a particular package and user. * * @hide */ public static String getDataDirForUser(int userId, String packageName) { public static File getDataDirForUser(String volumeUuid, String packageName, int userId) { // TODO: This should be shared with Installer's knowledge of user directory return Environment.getDataDirectory().toString() + "/user/" + userId + "/" + packageName; final File base; if (TextUtils.isEmpty(volumeUuid)) { base = Environment.getDataDirectory(); } else { base = new File("/mnt/expand/" + volumeUuid); } return new File(base, "user/" + userId + "/" + packageName); } /** Loading core/java/android/content/pm/PackageParser.java +16 −2 Original line number Diff line number Diff line Loading @@ -111,6 +111,9 @@ public class PackageParser { /** File name in an APK for the Android manifest. */ private static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml"; /** Path prefix for apps on expanded storage */ private static final String MNT_EXPAND = "/mnt/expand/"; /** @hide */ public static class NewPermissionInfo { public final String name; Loading Loading @@ -860,6 +863,12 @@ public class PackageParser { throws PackageParserException { final String apkPath = apkFile.getAbsolutePath(); String volumeUuid = null; if (apkPath.startsWith(MNT_EXPAND)) { final int end = apkPath.indexOf('/', MNT_EXPAND.length()); volumeUuid = apkPath.substring(MNT_EXPAND.length(), end); } mParseError = PackageManager.INSTALL_SUCCEEDED; mArchiveSourcePath = apkFile.getAbsolutePath(); Loading @@ -882,6 +891,7 @@ public class PackageParser { apkPath + " (at " + parser.getPositionDescription() + "): " + outError[0]); } pkg.volumeUuid = volumeUuid; pkg.baseCodePath = apkPath; pkg.mSignatures = null; Loading Loading @@ -4206,6 +4216,8 @@ public class PackageParser { // TODO: work towards making these paths invariant public String volumeUuid; /** * Path where this package was found on disk. For monolithic packages * this is path to single base APK file; for cluster packages this is Loading Loading @@ -4727,7 +4739,8 @@ public class PackageParser { ApplicationInfo ai = new ApplicationInfo(p.applicationInfo); if (userId != 0) { ai.uid = UserHandle.getUid(userId, ai.uid); ai.dataDir = PackageManager.getDataDirForUser(userId, ai.packageName); ai.dataDir = PackageManager.getDataDirForUser(ai.volumeUuid, ai.packageName, userId) .getAbsolutePath(); } if ((flags & PackageManager.GET_META_DATA) != 0) { ai.metaData = p.mAppMetaData; Loading Loading @@ -4755,7 +4768,8 @@ public class PackageParser { ai = new ApplicationInfo(ai); if (userId != 0) { ai.uid = UserHandle.getUid(userId, ai.uid); ai.dataDir = PackageManager.getDataDirForUser(userId, ai.packageName); ai.dataDir = PackageManager.getDataDirForUser(ai.volumeUuid, ai.packageName, userId) .getAbsolutePath(); } if (state.stopped) { ai.flags |= ApplicationInfo.FLAG_STOPPED; Loading core/tests/coretests/src/android/content/pm/PackageManagerTests.java +0 −8 Original line number Diff line number Diff line Loading @@ -576,14 +576,6 @@ public class PackageManagerTests extends AndroidTestCase { fail(pkgName + " shouldnt be installed"); } catch (NameNotFoundException e) { } UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); List<UserInfo> users = um.getUsers(); for (UserInfo user : users) { String dataDir = PackageManager.getDataDirForUser(user.id, pkgName); assertFalse("Application data directory should not exist: " + dataDir, new File(dataDir).exists()); } } class InstallParams { Loading Loading
core/java/android/app/ActivityThread.java +16 −3 Original line number Diff line number Diff line Loading @@ -220,6 +220,7 @@ public final class ActivityThread { // which means this lock gets held while the activity and window managers // holds their own lock. Thus you MUST NEVER call back into the activity manager // or window manager or anything that depends on them while holding this lock. // These LoadedApk are only valid for the userId that we're running as. final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<String, WeakReference<LoadedApk>>(); final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages Loading Loading @@ -1705,13 +1706,18 @@ public final class ActivityThread { public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, int flags, int userId) { final boolean differentUser = (UserHandle.myUserId() != userId); synchronized (mResourcesManager) { WeakReference<LoadedApk> ref; if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) { if (differentUser) { // Caching not supported across users ref = null; } else if ((flags & Context.CONTEXT_INCLUDE_CODE) != 0) { ref = mPackages.get(packageName); } else { ref = mResourcePackages.get(packageName); } LoadedApk packageInfo = ref != null ? ref.get() : null; //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo); //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir Loading Loading @@ -1791,13 +1797,18 @@ public final class ActivityThread { private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo, ClassLoader baseLoader, boolean securityViolation, boolean includeCode, boolean registerPackage) { final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid)); synchronized (mResourcesManager) { WeakReference<LoadedApk> ref; if (includeCode) { if (differentUser) { // Caching not supported across users ref = null; } else if (includeCode) { ref = mPackages.get(aInfo.packageName); } else { ref = mResourcePackages.get(aInfo.packageName); } LoadedApk packageInfo = ref != null ? ref.get() : null; if (packageInfo == null || (packageInfo.mResources != null && !packageInfo.mResources.getAssets().isUpToDate())) { Loading @@ -1816,7 +1827,9 @@ public final class ActivityThread { getSystemContext().mPackageInfo.getClassLoader()); } if (includeCode) { if (differentUser) { // Caching not supported across users } else if (includeCode) { mPackages.put(aInfo.packageName, new WeakReference<LoadedApk>(packageInfo)); } else { Loading
core/java/android/app/LoadedApk.java +1 −5 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package android.app; import android.text.TextUtils; import android.util.ArrayMap; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -46,6 +45,7 @@ import android.util.SparseArray; import android.view.DisplayAdjustments; import android.view.Display; import android.os.SystemProperties; import dalvik.system.VMRuntime; import java.io.File; Loading Loading @@ -136,10 +136,6 @@ public final class LoadedApk { mSplitAppDirs = aInfo.splitSourceDirs; mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs; mOverlayDirs = aInfo.resourceDirs; if (!UserHandle.isSameUser(aInfo.uid, myUid) && !Process.isIsolated()) { aInfo.dataDir = PackageManager.getDataDirForUser(UserHandle.getUserId(myUid), mPackageName); } mSharedLibraries = aInfo.sharedLibraryFiles; mDataDir = aInfo.dataDir; mDataDirFile = mDataDir != null ? new File(mDataDir) : null; Loading
core/java/android/content/pm/PackageManager.java +11 −7 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.os.Environment; import android.os.RemoteException; import android.os.UserHandle; import android.os.storage.VolumeInfo; import android.text.TextUtils; import android.util.AndroidException; import com.android.internal.util.ArrayUtils; Loading Loading @@ -4184,16 +4185,19 @@ public abstract class PackageManager { public abstract @NonNull PackageInstaller getPackageInstaller(); /** * Returns the data directory for a particular user and package, given the uid of the package. * @param uid uid of the package, including the userId and appId * @param packageName name of the package * @return the user-specific data directory for the package * Returns the data directory for a particular package and user. * * @hide */ public static String getDataDirForUser(int userId, String packageName) { public static File getDataDirForUser(String volumeUuid, String packageName, int userId) { // TODO: This should be shared with Installer's knowledge of user directory return Environment.getDataDirectory().toString() + "/user/" + userId + "/" + packageName; final File base; if (TextUtils.isEmpty(volumeUuid)) { base = Environment.getDataDirectory(); } else { base = new File("/mnt/expand/" + volumeUuid); } return new File(base, "user/" + userId + "/" + packageName); } /** Loading
core/java/android/content/pm/PackageParser.java +16 −2 Original line number Diff line number Diff line Loading @@ -111,6 +111,9 @@ public class PackageParser { /** File name in an APK for the Android manifest. */ private static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml"; /** Path prefix for apps on expanded storage */ private static final String MNT_EXPAND = "/mnt/expand/"; /** @hide */ public static class NewPermissionInfo { public final String name; Loading Loading @@ -860,6 +863,12 @@ public class PackageParser { throws PackageParserException { final String apkPath = apkFile.getAbsolutePath(); String volumeUuid = null; if (apkPath.startsWith(MNT_EXPAND)) { final int end = apkPath.indexOf('/', MNT_EXPAND.length()); volumeUuid = apkPath.substring(MNT_EXPAND.length(), end); } mParseError = PackageManager.INSTALL_SUCCEEDED; mArchiveSourcePath = apkFile.getAbsolutePath(); Loading @@ -882,6 +891,7 @@ public class PackageParser { apkPath + " (at " + parser.getPositionDescription() + "): " + outError[0]); } pkg.volumeUuid = volumeUuid; pkg.baseCodePath = apkPath; pkg.mSignatures = null; Loading Loading @@ -4206,6 +4216,8 @@ public class PackageParser { // TODO: work towards making these paths invariant public String volumeUuid; /** * Path where this package was found on disk. For monolithic packages * this is path to single base APK file; for cluster packages this is Loading Loading @@ -4727,7 +4739,8 @@ public class PackageParser { ApplicationInfo ai = new ApplicationInfo(p.applicationInfo); if (userId != 0) { ai.uid = UserHandle.getUid(userId, ai.uid); ai.dataDir = PackageManager.getDataDirForUser(userId, ai.packageName); ai.dataDir = PackageManager.getDataDirForUser(ai.volumeUuid, ai.packageName, userId) .getAbsolutePath(); } if ((flags & PackageManager.GET_META_DATA) != 0) { ai.metaData = p.mAppMetaData; Loading Loading @@ -4755,7 +4768,8 @@ public class PackageParser { ai = new ApplicationInfo(ai); if (userId != 0) { ai.uid = UserHandle.getUid(userId, ai.uid); ai.dataDir = PackageManager.getDataDirForUser(userId, ai.packageName); ai.dataDir = PackageManager.getDataDirForUser(ai.volumeUuid, ai.packageName, userId) .getAbsolutePath(); } if (state.stopped) { ai.flags |= ApplicationInfo.FLAG_STOPPED; Loading
core/tests/coretests/src/android/content/pm/PackageManagerTests.java +0 −8 Original line number Diff line number Diff line Loading @@ -576,14 +576,6 @@ public class PackageManagerTests extends AndroidTestCase { fail(pkgName + " shouldnt be installed"); } catch (NameNotFoundException e) { } UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); List<UserInfo> users = um.getUsers(); for (UserInfo user : users) { String dataDir = PackageManager.getDataDirForUser(user.id, pkgName); assertFalse("Application data directory should not exist: " + dataDir, new File(dataDir).exists()); } } class InstallParams { Loading