Merge "Revise the checking logic of checkPackage"
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 587b5d2..4153b11 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -3307,15 +3307,23 @@
         Objects.requireNonNull(packageName);
         try {
             verifyAndGetBypass(uid, packageName, null);
-            if (filterAppAccessUnlocked(packageName)) {
-                return AppOpsManager.MODE_ERRORED;
+            // When the caller is the system, it's possible that the packageName is the special
+            // one (e.g., "root") which isn't actually existed.
+            if (resolveUid(packageName) == uid
+                    || (isPackageExisted(packageName) && !filterAppAccessUnlocked(packageName))) {
+                return AppOpsManager.MODE_ALLOWED;
             }
-            return AppOpsManager.MODE_ALLOWED;
+            return AppOpsManager.MODE_ERRORED;
         } catch (SecurityException ignored) {
             return AppOpsManager.MODE_ERRORED;
         }
     }
 
+    private boolean isPackageExisted(String packageName) {
+        return LocalServices.getService(PackageManagerInternal.class)
+                .getPackageSetting(packageName) != null;
+    }
+
     /**
      * This method will check with PackageManager to determine if the package provided should
      * be visible to the {@link Binder#getCallingUid()}.