From ebe0e5f71672d1b01c5bac20b5e078dc8fa3ee0e Mon Sep 17 00:00:00 2001 From: Tetsutoki Shiozawa Date: Wed, 17 Jan 2018 11:07:09 +0900 Subject: [PATCH] Keep the legacy ssaid for apps on SD card Symptom: After O OS upgrade, LINE application on SD card got crash loop. The encrypted data depended on the ssaid and it was changed by OS upgrade. Root cause: At the 1st boot-time of OS upgrade, StorageProvider migrates the legacy ssaids. At that moment, SD card is not mounted yet. The target of migration depends on the list of PMS#getInstalledPackages() and the list doesn't contain the apps on unmounted SD card. As a result, the ssaids for the apps on SD card are not migrated. Solution: The target of ssaid migration respects the all known packages of PMS. To achieve it, getInstalledPackages() with MATCH_UNINSTALLED_PACKAGES is improved. Now, it can provide the information of package which has an inaccessible package file. Even though SD card is not mounted, the package list contains the apps on SD card. Bug: 72343790 Change-Id: If5d31e44cf7ec44da6010434515a157b00a5a09a --- .../providers/settings/SettingsProvider.java | 11 +++- .../server/pm/PackageManagerService.java | 66 ++++++++++++------- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index d1459bba90c13..06dff53995fb3 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -2328,7 +2328,9 @@ public class SettingsProvider extends ContentProvider { // Get all uids for the user's packages. final List packages; try { - packages = mPackageManager.getInstalledPackages(0, user.id).getList(); + packages = mPackageManager.getInstalledPackages( + PackageManager.MATCH_UNINSTALLED_PACKAGES, + user.id).getList(); } catch (RemoteException e) { throw new IllegalStateException("Package manager not available"); } @@ -3401,7 +3403,9 @@ public class SettingsProvider extends ContentProvider { // Fill each uid with the legacy ssaid to be backwards compatible. final List packages; try { - packages = mPackageManager.getInstalledPackages(0, userId).getList(); + packages = mPackageManager.getInstalledPackages( + PackageManager.MATCH_UNINSTALLED_PACKAGES, + userId).getList(); } catch (RemoteException e) { throw new IllegalStateException("Package manager not available"); } @@ -3416,6 +3420,9 @@ public class SettingsProvider extends ContentProvider { // Android Id doesn't exist for this package so create it. ssaidSettings.insertSettingLocked(uid, legacySsaid, null, true, info.packageName); + if (DEBUG) { + Slog.d(LOG_TAG, "Keep the legacy ssaid for uid=" + uid); + } } } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index c6b55cc1d555a..f8e89f51a6949 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3849,10 +3849,6 @@ Slog.e("TODD", if (ps == null) { return null; } - PackageParser.Package p = ps.pkg; - if (p == null) { - return null; - } final int callingUid = Binder.getCallingUid(); // Filter out ephemeral app metadata: // * The system/shell/root can see metadata for any app @@ -3864,32 +3860,58 @@ Slog.e("TODD", return null; } - final PermissionsState permissionsState = ps.getPermissionsState(); - - // Compute GIDs only if requested - final int[] gids = (flags & PackageManager.GET_GIDS) == 0 - ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); - // Compute granted permissions only if package has requested permissions - final Set permissions = ArrayUtils.isEmpty(p.requestedPermissions) - ? Collections.emptySet() : permissionsState.getPermissions(userId); - final PackageUserState state = ps.readUserState(userId); - if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && ps.isSystem()) { flags |= MATCH_ANY_USER; } - PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags, - ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); + final PackageUserState state = ps.readUserState(userId); + PackageParser.Package p = ps.pkg; + if (p != null) { + final PermissionsState permissionsState = ps.getPermissionsState(); - if (packageInfo == null) { + // Compute GIDs only if requested + final int[] gids = (flags & PackageManager.GET_GIDS) == 0 + ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); + // Compute granted permissions only if package has requested permissions + final Set permissions = ArrayUtils.isEmpty(p.requestedPermissions) + ? Collections.emptySet() : permissionsState.getPermissions(userId); + + PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags, + ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); + + if (packageInfo == null) { + return null; + } + + packageInfo.packageName = packageInfo.applicationInfo.packageName = + resolveExternalPackageNameLPr(p); + + return packageInfo; + } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) { + PackageInfo pi = new PackageInfo(); + pi.packageName = ps.name; + pi.setLongVersionCode(ps.versionCode); + pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null; + pi.firstInstallTime = ps.firstInstallTime; + pi.lastUpdateTime = ps.lastUpdateTime; + + ApplicationInfo ai = new ApplicationInfo(); + ai.packageName = ps.name; + ai.uid = UserHandle.getUid(userId, ps.appId); + ai.primaryCpuAbi = ps.primaryCpuAbiString; + ai.secondaryCpuAbi = ps.secondaryCpuAbiString; + ai.versionCode = ps.versionCode; + ai.flags = ps.pkgFlags; + ai.privateFlags = ps.pkgPrivateFlags; + pi.applicationInfo = PackageParser.generateApplicationInfo(ai, flags, state, userId); + + if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for [" + + ps.name + "]. Provides a minimum info."); + return pi; + } else { return null; } - - packageInfo.packageName = packageInfo.applicationInfo.packageName = - resolveExternalPackageNameLPr(p); - - return packageInfo; } @Override