OSDN Git Service

[automerger] Merge "Allow unsuspending critical packages" into pi-dev am: 5c4b2f6e08...
[android-x86/frameworks-base.git] / services / core / java / com / android / server / pm / PackageManagerService.java
index 9ed2b9c..8ffe120 100644 (file)
@@ -24,6 +24,9 @@ import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
 import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
 import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
+import static android.content.Intent.ACTION_MAIN;
+import static android.content.Intent.CATEGORY_DEFAULT;
+import static android.content.Intent.CATEGORY_HOME;
 import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
 import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
@@ -2140,7 +2143,13 @@ public class PackageManagerService extends IPackageManager.Stub
                         // app's nature doesn't depend on the user, so we can just check
                         // its browser nature in any user and generalize.
                         if (packageIsBrowser(packageName, userId)) {
-                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
+                            // If this browser is restored from user's backup, do not clear
+                            // default-browser state for this user
+                            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
+                            if (pkgSetting.getInstallReason(userId)
+                                    != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
+                                mSettings.setDefaultBrowserPackageNameLPw(null, userId);
+                            }
                         }
 
                         // We may also need to apply pending (restored) runtime
@@ -2632,6 +2641,10 @@ public class PackageManagerService extends IPackageManager.Stub
                     | SCAN_AS_SYSTEM
                     | SCAN_AS_PRIVILEGED,
                     0);
+            if (!mPackages.containsKey("android")) {
+                throw new IllegalStateException(
+                        "Failed to load frameworks package; check log for warnings");
+            }
 
             // Collect privileged system packages.
             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
@@ -4163,7 +4176,7 @@ public class PackageManagerService extends IPackageManager.Stub
      * Access may be limited based upon whether the calling or target applications
      * are instant applications.
      *
-     * @see #canAccessInstantApps(int)
+     * @see #canViewInstantApps(int, int)
      */
     private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
             @Nullable ComponentName component, @ComponentType int componentType, int userId) {
@@ -4220,7 +4233,7 @@ public class PackageManagerService extends IPackageManager.Stub
     }
 
     /**
-     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
+     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, int, int)
      */
     private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
         return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
@@ -4516,9 +4529,8 @@ public class PackageManagerService extends IPackageManager.Stub
 
     @Override
     public void deletePreloadsFileCache() {
-        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
-            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
-        }
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE,
+                "deletePreloadsFileCache");
         File dir = Environment.getDataPreloadsFileCacheDirectory();
         Slog.i(TAG, "Deleting preloaded file cache " + dir);
         FileUtils.deleteContents(dir);
@@ -6302,6 +6314,17 @@ public class PackageManagerService extends IPackageManager.Stub
         return null;
     }
 
+    private boolean isHomeIntent(Intent intent) {
+        return ACTION_MAIN.equals(intent.getAction())
+                && intent.hasCategory(CATEGORY_HOME)
+                && intent.hasCategory(CATEGORY_DEFAULT);
+    }
+
+    private boolean isDeviceProvisioned() {
+        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
+                android.provider.Settings.Global.DEVICE_PROVISIONED, 0) == 1;
+    }
+
     // TODO: handle preferred activities missing while user has amnesia
     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
             List<ResolveInfo> query, int priority, boolean always,
@@ -6386,7 +6409,15 @@ public class PackageManagerService extends IPackageManager.Stub
                                 Slog.v(TAG, "  null");
                             }
                         }
+                        final boolean excludeSetupWizardHomeActivity = isHomeIntent(intent)
+                                && !isDeviceProvisioned();
                         if (ai == null) {
+                            // Do not remove launcher's preferred activity during SetupWizard
+                            // due to it may not install yet
+                            if (excludeSetupWizardHomeActivity) {
+                                continue;
+                            }
+
                             // This previously registered preferred activity
                             // component is no longer known.  Most likely an update
                             // to the app was installed and in the new version this
@@ -6422,25 +6453,34 @@ public class PackageManagerService extends IPackageManager.Stub
                             // was created, and is not a subset of the preferred set, we need to
                             // clear it and re-ask the user their preference, if we're looking for
                             // an "always" type entry.
-                            if (always && !pa.mPref.sameSet(query)) {
-                                if (pa.mPref.isSuperset(query)) {
-                                    // some components of the set are no longer present in
-                                    // the query, but the preferred activity can still be reused
-                                    if (DEBUG_PREFERRED) {
-                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
-                                                + " still valid as only non-preferred components"
-                                                + " were removed for " + intent + " type "
-                                                + resolvedType);
+
+                            if (always && !pa.mPref.sameSet(query, excludeSetupWizardHomeActivity)) {
+                                if (pa.mPref.isSuperset(query, excludeSetupWizardHomeActivity)) {
+                                    if (!excludeSetupWizardHomeActivity) {
+                                        // some components of the set are no longer present in
+                                        // the query, but the preferred activity can still be reused
+                                        if (DEBUG_PREFERRED) {
+                                            Slog.i(TAG, "Result set changed, but PreferredActivity"
+                                                    + " is still valid as only non-preferred"
+                                                    + " components were removed for " + intent
+                                                    + " type " + resolvedType);
+                                        }
+                                        // remove obsolete components and re-add the up-to-date
+                                        // filter
+                                        PreferredActivity freshPa = new PreferredActivity(pa,
+                                                pa.mPref.mMatch,
+                                                pa.mPref.discardObsoleteComponents(query),
+                                                pa.mPref.mComponent,
+                                                pa.mPref.mAlways);
+                                        pir.removeFilter(pa);
+                                        pir.addFilter(freshPa);
+                                        changed = true;
+                                    } else {
+                                        if (DEBUG_PREFERRED) {
+                                            Slog.i(TAG, "Do not remove preferred activity for launcher"
+                                                    + " during SetupWizard");
+                                        }
                                     }
-                                    // remove obsolete components and re-add the up-to-date filter
-                                    PreferredActivity freshPa = new PreferredActivity(pa,
-                                            pa.mPref.mMatch,
-                                            pa.mPref.discardObsoleteComponents(query),
-                                            pa.mPref.mComponent,
-                                            pa.mPref.mAlways);
-                                    pir.removeFilter(pa);
-                                    pir.addFilter(freshPa);
-                                    changed = true;
                                 } else {
                                     Slog.i(TAG,
                                             "Result set changed, dropping preferred activity for "
@@ -10300,9 +10340,12 @@ public class PackageManagerService extends IPackageManager.Stub
                         compareSignatures(
                             signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures,
                             pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
-                        throw new PackageManagerException(
-                                INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
-                                "Signature mismatch for shared user: " + pkgSetting.sharedUser);
+                        // Treat mismatched signatures on system packages using a shared UID as
+                        // fatal for the system overall, rather than just failing to install
+                        // whichever package happened to be scanned later.
+                        throw new IllegalStateException(
+                                "Signature mismatch on system package " + pkg.packageName
+                                + " for shared user " + pkgSetting.sharedUser);
                     }
 
                     signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
@@ -10313,12 +10356,11 @@ public class PackageManagerService extends IPackageManager.Stub
                         + " signature changed; retaining data.";
                 reportSettingsProblem(Log.WARN, msg);
             } catch (IllegalArgumentException e) {
-
                 // should never happen: certs matched when checking, but not when comparing
                 // old to new for sharedUser
-                throw new PackageManagerException(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
+                throw new RuntimeException(
                         "Signing certificates comparison made on incomparable signing details"
-                        + " but somehow passed verifySignatures!");
+                        + " but somehow passed verifySignatures!", e);
             }
         }
 
@@ -15134,15 +15176,13 @@ public class PackageManagerService extends IPackageManager.Stub
         final File file;
 
         /**
-         * Flag indicating that {@link #file} or {@link #cid} has already been
-         * staged, meaning downstream users don't need to defensively copy the
-         * contents.
+         * Flag indicating that {@link #file} has already been staged, meaning downstream users
+         * don't need to defensively copy the contents.
          */
         final boolean staged;
 
         /**
-         * Flag indicating that {@link #file} or {@link #cid} is an already
-         * installed app that is being moved.
+         * Flag indicating that {@link #file} is an already installed app that is being moved.
          */
         final boolean existing;
 
@@ -17847,17 +17887,19 @@ public class PackageManagerService extends IPackageManager.Stub
         final int uid = Binder.getCallingUid();
         if (!isOrphaned(internalPackageName)
                 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
-            try {
-                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
-                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
-                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
-                observer.onUserActionRequired(intent);
-            } catch (RemoteException re) {
-            }
+            mHandler.post(() -> {
+                try {
+                    final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
+                    intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
+                    intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
+                    observer.onUserActionRequired(intent);
+                } catch (RemoteException re) {
+                }
+            });
             return;
         }
         final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
-        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
+        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{userId};
         if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
@@ -17865,20 +17907,24 @@ public class PackageManagerService extends IPackageManager.Stub
         }
 
         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
-            try {
-                observer.onPackageDeleted(packageName,
-                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
-            } catch (RemoteException re) {
-            }
+            mHandler.post(() -> {
+                try {
+                    observer.onPackageDeleted(packageName,
+                            PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
+                } catch (RemoteException re) {
+                }
+            });
             return;
         }
 
         if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
-            try {
-                observer.onPackageDeleted(packageName,
-                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
-            } catch (RemoteException re) {
-            }
+            mHandler.post(() -> {
+                try {
+                    observer.onPackageDeleted(packageName,
+                            PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
+                } catch (RemoteException re) {
+                }
+            });
             return;
         }
 
@@ -17889,56 +17935,53 @@ public class PackageManagerService extends IPackageManager.Stub
                     ? "VERSION_CODE_HIGHEST" : versionCode));
         }
         // Queue up an async operation since the package deletion may take a little while.
-        mHandler.post(new Runnable() {
-            public void run() {
-                mHandler.removeCallbacks(this);
-                int returnCode;
-                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
-                boolean doDeletePackage = true;
-                if (ps != null) {
-                    final boolean targetIsInstantApp =
-                            ps.getInstantApp(UserHandle.getUserId(callingUid));
-                    doDeletePackage = !targetIsInstantApp
-                            || canViewInstantApps;
-                }
-                if (doDeletePackage) {
-                    if (!deleteAllUsers) {
+        mHandler.post(() -> {
+            int returnCode;
+            final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
+            boolean doDeletePackage = true;
+            if (ps != null) {
+                final boolean targetIsInstantApp =
+                        ps.getInstantApp(UserHandle.getUserId(callingUid));
+                doDeletePackage = !targetIsInstantApp
+                        || canViewInstantApps;
+            }
+            if (doDeletePackage) {
+                if (!deleteAllUsers) {
+                    returnCode = deletePackageX(internalPackageName, versionCode,
+                            userId, deleteFlags);
+                } else {
+                    int[] blockUninstallUserIds = getBlockUninstallForUsers(
+                            internalPackageName, users);
+                    // If nobody is blocking uninstall, proceed with delete for all users
+                    if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
                         returnCode = deletePackageX(internalPackageName, versionCode,
                                 userId, deleteFlags);
                     } else {
-                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
-                                internalPackageName, users);
-                        // If nobody is blocking uninstall, proceed with delete for all users
-                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
-                            returnCode = deletePackageX(internalPackageName, versionCode,
-                                    userId, deleteFlags);
-                        } else {
-                            // Otherwise uninstall individually for users with blockUninstalls=false
-                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
-                            for (int userId : users) {
-                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
-                                    returnCode = deletePackageX(internalPackageName, versionCode,
-                                            userId, userFlags);
-                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
-                                        Slog.w(TAG, "Package delete failed for user " + userId
-                                                + ", returnCode " + returnCode);
-                                    }
+                        // Otherwise uninstall individually for users with blockUninstalls=false
+                        final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
+                        for (int userId1 : users) {
+                            if (!ArrayUtils.contains(blockUninstallUserIds, userId1)) {
+                                returnCode = deletePackageX(internalPackageName, versionCode,
+                                        userId1, userFlags);
+                                if (returnCode != PackageManager.DELETE_SUCCEEDED) {
+                                    Slog.w(TAG, "Package delete failed for user " + userId1
+                                            + ", returnCode " + returnCode);
                                 }
                             }
-                            // The app has only been marked uninstalled for certain users.
-                            // We still need to report that delete was blocked
-                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
                         }
+                        // The app has only been marked uninstalled for certain users.
+                        // We still need to report that delete was blocked
+                        returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
                     }
-                } else {
-                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
                 }
-                try {
-                    observer.onPackageDeleted(packageName, returnCode, null);
-                } catch (RemoteException e) {
-                    Log.i(TAG, "Observer no longer exists.");
-                } //end catch
-            } //end run
+            } else {
+                returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
+            }
+            try {
+                observer.onPackageDeleted(packageName, returnCode, null);
+            } catch (RemoteException e) {
+                Log.i(TAG, "Observer no longer exists.");
+            } //end catch
         });
     }
 
@@ -21024,6 +21067,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
     public boolean isOrphaned(String packageName) {
         // reader
         synchronized (mPackages) {
+            if (!mPackages.containsKey(packageName)) {
+                return false;
+            }
             return mSettings.isOrphaned(packageName);
         }
     }