Loading core/java/android/content/pm/PackageManagerInternal.java +12 −0 Original line number Diff line number Diff line Loading @@ -702,6 +702,18 @@ public abstract class PackageManagerInternal { */ public abstract SparseArray<String> getAppsWithSharedUserIds(); /** * Get the value of attribute android:sharedUserId for the given packageName if specified, * otherwise {@code null}. */ public abstract String getSharedUserIdForPackage(@NonNull String packageName); /** * Get all packages which specified the given sharedUserId as android:sharedUserId attribute * or an empty array if no package specified it. */ public abstract String[] getPackagesForSharedUserId(@NonNull String sharedUserId, int userId); /** * Return if device is currently in a "core" boot environment, typically * used to support full-disk encryption. Only apps marked with Loading core/java/android/os/storage/StorageManagerInternal.java +3 −1 Original line number Diff line number Diff line Loading @@ -101,9 +101,11 @@ public abstract class StorageManagerInternal { * Delete storage sandbox for the given package. * * @param packageName The package for which the sandbox needs to be destroyed. * @param sharedUserId The sharedUserId if specified by the package. * @param userId The userId in which the sandbox needs to be destroyed. */ public abstract void destroySandboxForApp(@NonNull String packageName, int userId); public abstract void destroySandboxForApp(@NonNull String packageName, @Nullable String sharedUserId, int userId); /** * @return Labels of storage volumes that are visible to the given userId. Loading services/core/java/com/android/server/StorageManagerService.java +58 −144 Original line number Diff line number Diff line Loading @@ -112,7 +112,6 @@ import android.util.TimeUtils; import android.util.Xml; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.AppFuseMount; import com.android.internal.os.BackgroundThread; import com.android.internal.os.FuseUnavailableMountException; Loading Loading @@ -323,12 +322,6 @@ class StorageManagerService extends IStorageManager.Stub @GuardedBy("mPackagesLock") private final SparseArray<ArraySet<String>> mPackages = new SparseArray<>(); @GuardedBy("mPackagesLock") private final ArrayMap<String, Integer> mAppIds = new ArrayMap<>(); @GuardedBy("mPackagesLock") private final SparseArray<String> mSandboxIds = new SparseArray<>(); /** * List of volumes visible to any user. * TODO: may be have a map of userId -> volumes? Loading Loading @@ -876,13 +869,12 @@ class StorageManagerService extends IStorageManager.Stub try { mVold.reset(); pushPackagesInfo(); // Tell vold about all existing and started users for (UserInfo user : users) { mVold.onUserAdded(user.id, user.serialNumber); } for (int userId : systemUnlockedUsers) { mVold.onUserStarted(userId, getPackagesArrayForUser(userId)); sendUserStartedCallback(userId); mStoraged.onUserStarted(userId); } mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing); Loading @@ -899,7 +891,7 @@ class StorageManagerService extends IStorageManager.Stub // staging area is ready so it's ready for zygote-forked apps to // bind mount against. try { mVold.onUserStarted(userId, getPackagesArrayForUser(userId)); sendUserStartedCallback(userId); mStoraged.onUserStarted(userId); } catch (Exception e) { Slog.wtf(TAG, e); Loading Loading @@ -932,11 +924,52 @@ class StorageManagerService extends IStorageManager.Stub Slog.wtf(TAG, e); } synchronized (mPackagesLock) { mPackages.delete(userId); } synchronized (mLock) { mSystemUnlockedUsers = ArrayUtils.removeInt(mSystemUnlockedUsers, userId); } } private void sendUserStartedCallback(int userId) throws Exception { if (!ENABLE_ISOLATED_STORAGE) { mVold.onUserStarted(userId, EmptyArray.STRING, EmptyArray.INT, EmptyArray.STRING); } final String[] packages; final int[] appIds; final String[] sandboxIds; final SparseArray<String> sharedUserIds = mPmInternal.getAppsWithSharedUserIds(); final List<ApplicationInfo> appInfos = mContext.getPackageManager().getInstalledApplicationsAsUser( PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); synchronized (mPackagesLock) { final ArraySet<String> userPackages = new ArraySet<>(); final ArrayMap<String, Integer> packageToAppId = new ArrayMap<>(); for (int i = appInfos.size() - 1; i >= 0; --i) { final ApplicationInfo appInfo = appInfos.get(i); if (appInfo.isInstantApp()) { continue; } userPackages.add(appInfo.packageName); packageToAppId.put(appInfo.packageName, UserHandle.getAppId(appInfo.uid)); } mPackages.put(userId, userPackages); packages = new String[userPackages.size()]; appIds = new int[userPackages.size()]; sandboxIds = new String[userPackages.size()]; for (int i = userPackages.size() - 1; i >= 0; --i) { packages[i] = userPackages.valueAt(i); appIds[i] = packageToAppId.get(packages[i]); sandboxIds[i] = getSandboxId(packages[i], sharedUserIds.get(appIds[i])); } } mVold.onUserStarted(userId, packages, appIds, sandboxIds); } @Override public void onAwakeStateChanged(boolean isAwake) { // Ignored Loading Loading @@ -1454,111 +1487,12 @@ class StorageManagerService extends IStorageManager.Stub } private void start() { collectPackagesInfo(); connect(); } @VisibleForTesting void collectPackagesInfo() { if (!ENABLE_ISOLATED_STORAGE) return; resetPackageData(); final SparseArray<String> sharedUserIds = mPmInternal.getAppsWithSharedUserIds(); final int[] userIds = mUmInternal.getUserIds(); for (int userId : userIds) { final List<ApplicationInfo> appInfos = mContext.getPackageManager().getInstalledApplicationsAsUser( PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); synchronized (mPackagesLock) { final ArraySet<String> userPackages = getAvailablePackagesForUserPL(userId); for (int i = appInfos.size() - 1; i >= 0; --i) { if (appInfos.get(i).isInstantApp()) { continue; } final String packageName = appInfos.get(i).packageName; userPackages.add(packageName); final int appId = UserHandle.getAppId(appInfos.get(i).uid); mAppIds.put(packageName, appId); mSandboxIds.put(appId, getSandboxId(packageName, sharedUserIds.get(appId))); } } } } private void resetPackageData() { synchronized (mPackagesLock) { mPackages.clear(); mAppIds.clear(); mSandboxIds.clear(); } } private static String getSandboxId(String packageName, String sharedUserId) { return sharedUserId == null ? packageName : SHARED_SANDBOX_ID_PREFIX + sharedUserId; } private void pushPackagesInfo() throws RemoteException { if (!ENABLE_ISOLATED_STORAGE) return; // Arrays to fill up from {@link #mAppIds} final String[] allPackageNames; final int[] appIdsForPackages; // Arrays to fill up from {@link #mSandboxIds} final int[] allAppIds; final String[] sandboxIdsForApps; synchronized (mPackagesLock) { allPackageNames = new String[mAppIds.size()]; appIdsForPackages = new int[mAppIds.size()]; for (int i = mAppIds.size() - 1; i >= 0; --i) { allPackageNames[i] = mAppIds.keyAt(i); appIdsForPackages[i] = mAppIds.valueAt(i); } allAppIds = new int[mSandboxIds.size()]; sandboxIdsForApps = new String[mSandboxIds.size()]; for (int i = mSandboxIds.size() - 1; i >= 0; --i) { allAppIds[i] = mSandboxIds.keyAt(i); sandboxIdsForApps[i] = mSandboxIds.valueAt(i); } } mVold.addAppIds(allPackageNames, appIdsForPackages); mVold.addSandboxIds(allAppIds, sandboxIdsForApps); } @GuardedBy("mPackagesLock") private ArraySet<String> getAvailablePackagesForUserPL(int userId) { ArraySet<String> userPackages = mPackages.get(userId); if (userPackages == null) { userPackages = new ArraySet<>(); mPackages.put(userId, userPackages); } return userPackages; } private String[] getPackagesArrayForUser(int userId) { if (!ENABLE_ISOLATED_STORAGE) return EmptyArray.STRING; final ArraySet<String> userPackages; synchronized (mPackagesLock) { userPackages = getAvailablePackagesForUserPL(userId); if (!userPackages.isEmpty()) { return userPackages.toArray(new String[0]); } } final List<ApplicationInfo> appInfos = mContext.getPackageManager().getInstalledApplicationsAsUser( PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); synchronized (mPackagesLock) { for (int i = appInfos.size() - 1; i >= 0; --i) { if (appInfos.get(i).isInstantApp()) { continue; } userPackages.add(appInfos.get(i).packageName); } return userPackages.toArray(new String[0]); } } private void connect() { IBinder binder = ServiceManager.getService("storaged"); Loading Loading @@ -3122,15 +3056,8 @@ class StorageManagerService extends IStorageManager.Stub throw new SecurityException("Shady looking path " + path); } final int uid = mPmInternal.getPackageUid(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); final String sandboxId; synchronized (mPackagesLock) { sandboxId = mSandboxIds.get(UserHandle.getAppId(uid)); } if (uid < 0 || sandboxId == null) { throw new IllegalArgumentException("Unknown package " + packageName); } final String sharedUserId = mPmInternal.getSharedUserIdForPackage(packageName); final String sandboxId = getSandboxId(packageName, sharedUserId); final Matcher m = PATTERN_TRANSLATE.matcher(path); if (m.matches()) { Loading @@ -3139,7 +3066,9 @@ class StorageManagerService extends IStorageManager.Stub // Does path belong to any packages belonging to this UID? If so, // they get to go straight through to legacy paths. final String[] pkgs = mContext.getPackageManager().getPackagesForUid(uid); final String[] pkgs = (sharedUserId == null) ? new String[] {packageName} : mPmInternal.getPackagesForSharedUserId(sharedUserId, userId); for (String pkg : pkgs) { if (devicePath.startsWith("Android/data/" + pkg + "/") || devicePath.startsWith("Android/media/" + pkg + "/") || Loading Loading @@ -3758,16 +3687,14 @@ class StorageManagerService extends IStorageManager.Stub int userId) { final String sandboxId; synchronized (mPackagesLock) { final ArraySet<String> userPackages = getAvailablePackagesForUserPL(userId); final ArraySet<String> userPackages = mPackages.get(userId); // If userPackages is empty, it means the user is not started yet, so no need to // do anything now. if (userPackages.isEmpty() || userPackages.contains(packageName)) { if (userPackages == null || userPackages.contains(packageName)) { return; } userPackages.add(packageName); mAppIds.put(packageName, appId); sandboxId = getSandboxId(packageName, sharedUserId); mSandboxIds.put(appId, sandboxId); } try { Loading @@ -3778,34 +3705,21 @@ class StorageManagerService extends IStorageManager.Stub } @Override public void destroySandboxForApp(String packageName, int userId) { public void destroySandboxForApp(String packageName, String sharedUserId, int userId) { if (!ENABLE_ISOLATED_STORAGE) { return; } final int appId; final String sandboxId; final String sandboxId = getSandboxId(packageName, sharedUserId); synchronized (mPackagesLock) { final ArraySet<String> userPackages = getAvailablePackagesForUserPL(userId); final ArraySet<String> userPackages = mPackages.get(userId); // If the userPackages is null, it means the user is not started but we still // need to delete the sandbox data though. if (userPackages != null) { userPackages.remove(packageName); appId = mAppIds.get(packageName); sandboxId = mSandboxIds.get(appId); // If the package is not uninstalled in any other users, remove appId and sandboxId // corresponding to it from the internal state. boolean installedInAnyUser = false; for (int i = mPackages.size() - 1; i >= 0; --i) { if (mPackages.valueAt(i).contains(packageName)) { installedInAnyUser = true; break; } } if (!installedInAnyUser) { mAppIds.remove(packageName); mSandboxIds.remove(appId); } } try { mVold.destroySandboxForApp(packageName, appId, sandboxId, userId); mVold.destroySandboxForApp(packageName, sandboxId, userId); } catch (Exception e) { Slog.wtf(TAG, e); } Loading services/core/java/com/android/server/pm/PackageManagerService.java +50 −1 Original line number Diff line number Diff line Loading @@ -322,6 +322,7 @@ import dalvik.system.CloseGuard; import dalvik.system.VMRuntime; import libcore.io.IoUtils; import libcore.util.EmptyArray; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; Loading Loading @@ -9530,7 +9531,8 @@ public class PackageManagerService extends IPackageManager.Stub } } if (deleteSandboxData && getStorageManagerInternal() != null) { getStorageManagerInternal().destroySandboxForApp(pkg.packageName, realUserId); getStorageManagerInternal().destroySandboxForApp(pkg.packageName, pkg.mSharedUserId, realUserId); } } catch (PackageManagerException e) { // Should not happen Loading Loading @@ -22941,6 +22943,20 @@ public class PackageManagerService extends IPackageManager.Stub } } @Override public String getSharedUserIdForPackage(String packageName) { synchronized (mPackages) { return getSharedUserIdForPackageLocked(packageName); } } @Override public String[] getPackagesForSharedUserId(String sharedUserId, int userId) { synchronized (mPackages) { return getPackagesForSharedUserIdLocked(sharedUserId, userId); } } @Override public boolean isOnlyCoreApps() { return PackageManagerService.this.isOnlyCoreApps(); Loading @@ -22953,6 +22969,7 @@ public class PackageManagerService extends IPackageManager.Stub } } @GuardedBy("mPackages") private SparseArray<String> getAppsWithSharedUserIdsLocked() { final SparseArray<String> sharedUserIds = new SparseArray<>(); synchronized (mPackages) { Loading @@ -22963,6 +22980,38 @@ public class PackageManagerService extends IPackageManager.Stub return sharedUserIds; } @GuardedBy("mPackages") private String getSharedUserIdForPackageLocked(String packageName) { final PackageSetting ps = mSettings.mPackages.get(packageName); return (ps != null && ps.isSharedUser()) ? ps.sharedUser.name : null; } @GuardedBy("mPackages") private String[] getPackagesForSharedUserIdLocked(String sharedUserId, int userId) { try { final SharedUserSetting sus = mSettings.getSharedUserLPw( sharedUserId, 0, 0, false); if (sus == null) { return EmptyArray.STRING; } String[] res = new String[sus.packages.size()]; final Iterator<PackageSetting> it = sus.packages.iterator(); int i = 0; while (it.hasNext()) { PackageSetting ps = it.next(); if (ps.getInstalled(userId)) { res[i++] = ps.name; } else { res = ArrayUtils.removeElement(String.class, res, res[i]); } } return res; } catch (PackageManagerException e) { // Should not happen } return EmptyArray.STRING; } @Override public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java +5 −24 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.os.UserManagerInternal; import android.os.storage.StorageManagerInternal; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.util.SparseArray; import org.junit.Before; import org.junit.Test; Loading @@ -38,9 +37,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; @SmallTest @RunWith(AndroidJUnit4.class) public class StorageManagerServiceTest { Loading Loading @@ -83,29 +79,14 @@ public class StorageManagerServiceTest { when(mUmi.getUserIds()).thenReturn(new int[] { 0 }); { final SparseArray<String> res = new SparseArray<>(); res.put(UID_COLORS, NAME_COLORS); when(mPmi.getAppsWithSharedUserIds()).thenReturn(res); } { final List<ApplicationInfo> res = new ArrayList<>(); res.add(buildApplicationInfo(PKG_GREY, UID_GREY)); res.add(buildApplicationInfo(PKG_RED, UID_COLORS)); res.add(buildApplicationInfo(PKG_BLUE, UID_COLORS)); when(mPm.getInstalledApplicationsAsUser(anyInt(), anyInt())).thenReturn(res); } when(mPmi.getPackageUid(eq(PKG_GREY), anyInt(), anyInt())).thenReturn(UID_GREY); when(mPmi.getPackageUid(eq(PKG_RED), anyInt(), anyInt())).thenReturn(UID_COLORS); when(mPmi.getPackageUid(eq(PKG_BLUE), anyInt(), anyInt())).thenReturn(UID_COLORS); when(mPmi.getSharedUserIdForPackage(eq(PKG_GREY))).thenReturn(null); when(mPmi.getSharedUserIdForPackage(eq(PKG_RED))).thenReturn(NAME_COLORS); when(mPmi.getSharedUserIdForPackage(eq(PKG_BLUE))).thenReturn(NAME_COLORS); when(mPm.getPackagesForUid(eq(UID_GREY))).thenReturn(new String[] { PKG_GREY }); when(mPm.getPackagesForUid(eq(UID_COLORS))).thenReturn(new String[] { PKG_RED, PKG_BLUE }); when(mPmi.getPackagesForSharedUserId(eq(NAME_COLORS), anyInt())) .thenReturn(new String[] { PKG_RED, PKG_BLUE }); mService = new StorageManagerService(mContext); mService.collectPackagesInfo(); } @Test Loading Loading
core/java/android/content/pm/PackageManagerInternal.java +12 −0 Original line number Diff line number Diff line Loading @@ -702,6 +702,18 @@ public abstract class PackageManagerInternal { */ public abstract SparseArray<String> getAppsWithSharedUserIds(); /** * Get the value of attribute android:sharedUserId for the given packageName if specified, * otherwise {@code null}. */ public abstract String getSharedUserIdForPackage(@NonNull String packageName); /** * Get all packages which specified the given sharedUserId as android:sharedUserId attribute * or an empty array if no package specified it. */ public abstract String[] getPackagesForSharedUserId(@NonNull String sharedUserId, int userId); /** * Return if device is currently in a "core" boot environment, typically * used to support full-disk encryption. Only apps marked with Loading
core/java/android/os/storage/StorageManagerInternal.java +3 −1 Original line number Diff line number Diff line Loading @@ -101,9 +101,11 @@ public abstract class StorageManagerInternal { * Delete storage sandbox for the given package. * * @param packageName The package for which the sandbox needs to be destroyed. * @param sharedUserId The sharedUserId if specified by the package. * @param userId The userId in which the sandbox needs to be destroyed. */ public abstract void destroySandboxForApp(@NonNull String packageName, int userId); public abstract void destroySandboxForApp(@NonNull String packageName, @Nullable String sharedUserId, int userId); /** * @return Labels of storage volumes that are visible to the given userId. Loading
services/core/java/com/android/server/StorageManagerService.java +58 −144 Original line number Diff line number Diff line Loading @@ -112,7 +112,6 @@ import android.util.TimeUtils; import android.util.Xml; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.AppFuseMount; import com.android.internal.os.BackgroundThread; import com.android.internal.os.FuseUnavailableMountException; Loading Loading @@ -323,12 +322,6 @@ class StorageManagerService extends IStorageManager.Stub @GuardedBy("mPackagesLock") private final SparseArray<ArraySet<String>> mPackages = new SparseArray<>(); @GuardedBy("mPackagesLock") private final ArrayMap<String, Integer> mAppIds = new ArrayMap<>(); @GuardedBy("mPackagesLock") private final SparseArray<String> mSandboxIds = new SparseArray<>(); /** * List of volumes visible to any user. * TODO: may be have a map of userId -> volumes? Loading Loading @@ -876,13 +869,12 @@ class StorageManagerService extends IStorageManager.Stub try { mVold.reset(); pushPackagesInfo(); // Tell vold about all existing and started users for (UserInfo user : users) { mVold.onUserAdded(user.id, user.serialNumber); } for (int userId : systemUnlockedUsers) { mVold.onUserStarted(userId, getPackagesArrayForUser(userId)); sendUserStartedCallback(userId); mStoraged.onUserStarted(userId); } mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing); Loading @@ -899,7 +891,7 @@ class StorageManagerService extends IStorageManager.Stub // staging area is ready so it's ready for zygote-forked apps to // bind mount against. try { mVold.onUserStarted(userId, getPackagesArrayForUser(userId)); sendUserStartedCallback(userId); mStoraged.onUserStarted(userId); } catch (Exception e) { Slog.wtf(TAG, e); Loading Loading @@ -932,11 +924,52 @@ class StorageManagerService extends IStorageManager.Stub Slog.wtf(TAG, e); } synchronized (mPackagesLock) { mPackages.delete(userId); } synchronized (mLock) { mSystemUnlockedUsers = ArrayUtils.removeInt(mSystemUnlockedUsers, userId); } } private void sendUserStartedCallback(int userId) throws Exception { if (!ENABLE_ISOLATED_STORAGE) { mVold.onUserStarted(userId, EmptyArray.STRING, EmptyArray.INT, EmptyArray.STRING); } final String[] packages; final int[] appIds; final String[] sandboxIds; final SparseArray<String> sharedUserIds = mPmInternal.getAppsWithSharedUserIds(); final List<ApplicationInfo> appInfos = mContext.getPackageManager().getInstalledApplicationsAsUser( PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); synchronized (mPackagesLock) { final ArraySet<String> userPackages = new ArraySet<>(); final ArrayMap<String, Integer> packageToAppId = new ArrayMap<>(); for (int i = appInfos.size() - 1; i >= 0; --i) { final ApplicationInfo appInfo = appInfos.get(i); if (appInfo.isInstantApp()) { continue; } userPackages.add(appInfo.packageName); packageToAppId.put(appInfo.packageName, UserHandle.getAppId(appInfo.uid)); } mPackages.put(userId, userPackages); packages = new String[userPackages.size()]; appIds = new int[userPackages.size()]; sandboxIds = new String[userPackages.size()]; for (int i = userPackages.size() - 1; i >= 0; --i) { packages[i] = userPackages.valueAt(i); appIds[i] = packageToAppId.get(packages[i]); sandboxIds[i] = getSandboxId(packages[i], sharedUserIds.get(appIds[i])); } } mVold.onUserStarted(userId, packages, appIds, sandboxIds); } @Override public void onAwakeStateChanged(boolean isAwake) { // Ignored Loading Loading @@ -1454,111 +1487,12 @@ class StorageManagerService extends IStorageManager.Stub } private void start() { collectPackagesInfo(); connect(); } @VisibleForTesting void collectPackagesInfo() { if (!ENABLE_ISOLATED_STORAGE) return; resetPackageData(); final SparseArray<String> sharedUserIds = mPmInternal.getAppsWithSharedUserIds(); final int[] userIds = mUmInternal.getUserIds(); for (int userId : userIds) { final List<ApplicationInfo> appInfos = mContext.getPackageManager().getInstalledApplicationsAsUser( PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); synchronized (mPackagesLock) { final ArraySet<String> userPackages = getAvailablePackagesForUserPL(userId); for (int i = appInfos.size() - 1; i >= 0; --i) { if (appInfos.get(i).isInstantApp()) { continue; } final String packageName = appInfos.get(i).packageName; userPackages.add(packageName); final int appId = UserHandle.getAppId(appInfos.get(i).uid); mAppIds.put(packageName, appId); mSandboxIds.put(appId, getSandboxId(packageName, sharedUserIds.get(appId))); } } } } private void resetPackageData() { synchronized (mPackagesLock) { mPackages.clear(); mAppIds.clear(); mSandboxIds.clear(); } } private static String getSandboxId(String packageName, String sharedUserId) { return sharedUserId == null ? packageName : SHARED_SANDBOX_ID_PREFIX + sharedUserId; } private void pushPackagesInfo() throws RemoteException { if (!ENABLE_ISOLATED_STORAGE) return; // Arrays to fill up from {@link #mAppIds} final String[] allPackageNames; final int[] appIdsForPackages; // Arrays to fill up from {@link #mSandboxIds} final int[] allAppIds; final String[] sandboxIdsForApps; synchronized (mPackagesLock) { allPackageNames = new String[mAppIds.size()]; appIdsForPackages = new int[mAppIds.size()]; for (int i = mAppIds.size() - 1; i >= 0; --i) { allPackageNames[i] = mAppIds.keyAt(i); appIdsForPackages[i] = mAppIds.valueAt(i); } allAppIds = new int[mSandboxIds.size()]; sandboxIdsForApps = new String[mSandboxIds.size()]; for (int i = mSandboxIds.size() - 1; i >= 0; --i) { allAppIds[i] = mSandboxIds.keyAt(i); sandboxIdsForApps[i] = mSandboxIds.valueAt(i); } } mVold.addAppIds(allPackageNames, appIdsForPackages); mVold.addSandboxIds(allAppIds, sandboxIdsForApps); } @GuardedBy("mPackagesLock") private ArraySet<String> getAvailablePackagesForUserPL(int userId) { ArraySet<String> userPackages = mPackages.get(userId); if (userPackages == null) { userPackages = new ArraySet<>(); mPackages.put(userId, userPackages); } return userPackages; } private String[] getPackagesArrayForUser(int userId) { if (!ENABLE_ISOLATED_STORAGE) return EmptyArray.STRING; final ArraySet<String> userPackages; synchronized (mPackagesLock) { userPackages = getAvailablePackagesForUserPL(userId); if (!userPackages.isEmpty()) { return userPackages.toArray(new String[0]); } } final List<ApplicationInfo> appInfos = mContext.getPackageManager().getInstalledApplicationsAsUser( PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); synchronized (mPackagesLock) { for (int i = appInfos.size() - 1; i >= 0; --i) { if (appInfos.get(i).isInstantApp()) { continue; } userPackages.add(appInfos.get(i).packageName); } return userPackages.toArray(new String[0]); } } private void connect() { IBinder binder = ServiceManager.getService("storaged"); Loading Loading @@ -3122,15 +3056,8 @@ class StorageManagerService extends IStorageManager.Stub throw new SecurityException("Shady looking path " + path); } final int uid = mPmInternal.getPackageUid(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); final String sandboxId; synchronized (mPackagesLock) { sandboxId = mSandboxIds.get(UserHandle.getAppId(uid)); } if (uid < 0 || sandboxId == null) { throw new IllegalArgumentException("Unknown package " + packageName); } final String sharedUserId = mPmInternal.getSharedUserIdForPackage(packageName); final String sandboxId = getSandboxId(packageName, sharedUserId); final Matcher m = PATTERN_TRANSLATE.matcher(path); if (m.matches()) { Loading @@ -3139,7 +3066,9 @@ class StorageManagerService extends IStorageManager.Stub // Does path belong to any packages belonging to this UID? If so, // they get to go straight through to legacy paths. final String[] pkgs = mContext.getPackageManager().getPackagesForUid(uid); final String[] pkgs = (sharedUserId == null) ? new String[] {packageName} : mPmInternal.getPackagesForSharedUserId(sharedUserId, userId); for (String pkg : pkgs) { if (devicePath.startsWith("Android/data/" + pkg + "/") || devicePath.startsWith("Android/media/" + pkg + "/") || Loading Loading @@ -3758,16 +3687,14 @@ class StorageManagerService extends IStorageManager.Stub int userId) { final String sandboxId; synchronized (mPackagesLock) { final ArraySet<String> userPackages = getAvailablePackagesForUserPL(userId); final ArraySet<String> userPackages = mPackages.get(userId); // If userPackages is empty, it means the user is not started yet, so no need to // do anything now. if (userPackages.isEmpty() || userPackages.contains(packageName)) { if (userPackages == null || userPackages.contains(packageName)) { return; } userPackages.add(packageName); mAppIds.put(packageName, appId); sandboxId = getSandboxId(packageName, sharedUserId); mSandboxIds.put(appId, sandboxId); } try { Loading @@ -3778,34 +3705,21 @@ class StorageManagerService extends IStorageManager.Stub } @Override public void destroySandboxForApp(String packageName, int userId) { public void destroySandboxForApp(String packageName, String sharedUserId, int userId) { if (!ENABLE_ISOLATED_STORAGE) { return; } final int appId; final String sandboxId; final String sandboxId = getSandboxId(packageName, sharedUserId); synchronized (mPackagesLock) { final ArraySet<String> userPackages = getAvailablePackagesForUserPL(userId); final ArraySet<String> userPackages = mPackages.get(userId); // If the userPackages is null, it means the user is not started but we still // need to delete the sandbox data though. if (userPackages != null) { userPackages.remove(packageName); appId = mAppIds.get(packageName); sandboxId = mSandboxIds.get(appId); // If the package is not uninstalled in any other users, remove appId and sandboxId // corresponding to it from the internal state. boolean installedInAnyUser = false; for (int i = mPackages.size() - 1; i >= 0; --i) { if (mPackages.valueAt(i).contains(packageName)) { installedInAnyUser = true; break; } } if (!installedInAnyUser) { mAppIds.remove(packageName); mSandboxIds.remove(appId); } } try { mVold.destroySandboxForApp(packageName, appId, sandboxId, userId); mVold.destroySandboxForApp(packageName, sandboxId, userId); } catch (Exception e) { Slog.wtf(TAG, e); } Loading
services/core/java/com/android/server/pm/PackageManagerService.java +50 −1 Original line number Diff line number Diff line Loading @@ -322,6 +322,7 @@ import dalvik.system.CloseGuard; import dalvik.system.VMRuntime; import libcore.io.IoUtils; import libcore.util.EmptyArray; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; Loading Loading @@ -9530,7 +9531,8 @@ public class PackageManagerService extends IPackageManager.Stub } } if (deleteSandboxData && getStorageManagerInternal() != null) { getStorageManagerInternal().destroySandboxForApp(pkg.packageName, realUserId); getStorageManagerInternal().destroySandboxForApp(pkg.packageName, pkg.mSharedUserId, realUserId); } } catch (PackageManagerException e) { // Should not happen Loading Loading @@ -22941,6 +22943,20 @@ public class PackageManagerService extends IPackageManager.Stub } } @Override public String getSharedUserIdForPackage(String packageName) { synchronized (mPackages) { return getSharedUserIdForPackageLocked(packageName); } } @Override public String[] getPackagesForSharedUserId(String sharedUserId, int userId) { synchronized (mPackages) { return getPackagesForSharedUserIdLocked(sharedUserId, userId); } } @Override public boolean isOnlyCoreApps() { return PackageManagerService.this.isOnlyCoreApps(); Loading @@ -22953,6 +22969,7 @@ public class PackageManagerService extends IPackageManager.Stub } } @GuardedBy("mPackages") private SparseArray<String> getAppsWithSharedUserIdsLocked() { final SparseArray<String> sharedUserIds = new SparseArray<>(); synchronized (mPackages) { Loading @@ -22963,6 +22980,38 @@ public class PackageManagerService extends IPackageManager.Stub return sharedUserIds; } @GuardedBy("mPackages") private String getSharedUserIdForPackageLocked(String packageName) { final PackageSetting ps = mSettings.mPackages.get(packageName); return (ps != null && ps.isSharedUser()) ? ps.sharedUser.name : null; } @GuardedBy("mPackages") private String[] getPackagesForSharedUserIdLocked(String sharedUserId, int userId) { try { final SharedUserSetting sus = mSettings.getSharedUserLPw( sharedUserId, 0, 0, false); if (sus == null) { return EmptyArray.STRING; } String[] res = new String[sus.packages.size()]; final Iterator<PackageSetting> it = sus.packages.iterator(); int i = 0; while (it.hasNext()) { PackageSetting ps = it.next(); if (ps.getInstalled(userId)) { res[i++] = ps.name; } else { res = ArrayUtils.removeElement(String.class, res, res[i]); } } return res; } catch (PackageManagerException e) { // Should not happen } return EmptyArray.STRING; } @Override public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java +5 −24 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.os.UserManagerInternal; import android.os.storage.StorageManagerInternal; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.util.SparseArray; import org.junit.Before; import org.junit.Test; Loading @@ -38,9 +37,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; @SmallTest @RunWith(AndroidJUnit4.class) public class StorageManagerServiceTest { Loading Loading @@ -83,29 +79,14 @@ public class StorageManagerServiceTest { when(mUmi.getUserIds()).thenReturn(new int[] { 0 }); { final SparseArray<String> res = new SparseArray<>(); res.put(UID_COLORS, NAME_COLORS); when(mPmi.getAppsWithSharedUserIds()).thenReturn(res); } { final List<ApplicationInfo> res = new ArrayList<>(); res.add(buildApplicationInfo(PKG_GREY, UID_GREY)); res.add(buildApplicationInfo(PKG_RED, UID_COLORS)); res.add(buildApplicationInfo(PKG_BLUE, UID_COLORS)); when(mPm.getInstalledApplicationsAsUser(anyInt(), anyInt())).thenReturn(res); } when(mPmi.getPackageUid(eq(PKG_GREY), anyInt(), anyInt())).thenReturn(UID_GREY); when(mPmi.getPackageUid(eq(PKG_RED), anyInt(), anyInt())).thenReturn(UID_COLORS); when(mPmi.getPackageUid(eq(PKG_BLUE), anyInt(), anyInt())).thenReturn(UID_COLORS); when(mPmi.getSharedUserIdForPackage(eq(PKG_GREY))).thenReturn(null); when(mPmi.getSharedUserIdForPackage(eq(PKG_RED))).thenReturn(NAME_COLORS); when(mPmi.getSharedUserIdForPackage(eq(PKG_BLUE))).thenReturn(NAME_COLORS); when(mPm.getPackagesForUid(eq(UID_GREY))).thenReturn(new String[] { PKG_GREY }); when(mPm.getPackagesForUid(eq(UID_COLORS))).thenReturn(new String[] { PKG_RED, PKG_BLUE }); when(mPmi.getPackagesForSharedUserId(eq(NAME_COLORS), anyInt())) .thenReturn(new String[] { PKG_RED, PKG_BLUE }); mService = new StorageManagerService(mContext); mService.collectPackagesInfo(); } @Test Loading