summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ApplicationPackageManager.java9
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl2
-rw-r--r--core/java/android/content/pm/PackageManager.java12
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java19
4 files changed, 42 insertions, 0 deletions
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 21fb18a212a8..80ed0ea825f1 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2810,4 +2810,13 @@ public class ApplicationPackageManager extends PackageManager {
throw e.rethrowAsRuntimeException();
}
}
+
+ @Override
+ public boolean isPackageStateProtected(String packageName, int userId) {
+ try {
+ return mPM.isPackageStateProtected(packageName, userId);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 36a74a489890..d87c13c2ef5d 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -662,4 +662,6 @@ interface IPackageManager {
boolean hasUidSigningCertificate(int uid, in byte[] signingCertificate, int flags);
String getSystemTextClassifierPackageName();
+
+ boolean isPackageStateProtected(String packageName, int userId);
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index bd7961fffca8..53bfeb9f82e6 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -6032,4 +6032,16 @@ public abstract class PackageManager {
throw new UnsupportedOperationException(
"getSystemTextClassifierPackageName not implemented in subclass");
}
+
+ /**
+ * @return whether a given package's state is protected, e.g. package cannot be disabled,
+ * suspended, hidden or force stopped.
+ *
+ * @hide
+ */
+ public boolean isPackageStateProtected(String packageName, int userId) {
+ throw new UnsupportedOperationException(
+ "isPackageStateProtected not implemented in subclass");
+ }
+
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 052f23999f1e..bde2ec0a6a4e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.pm;
import static android.Manifest.permission.DELETE_PACKAGES;
+import static android.Manifest.permission.MANAGE_DEVICE_ADMINS;
import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
import static android.Manifest.permission.INSTALL_PACKAGES;
import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
@@ -117,6 +118,7 @@ import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
@@ -24212,6 +24214,23 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
return mSettings.getHarmfulAppWarningLPr(packageName, userId);
}
}
+
+ @Override
+ public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingAppId = UserHandle.getAppId(callingUid);
+
+ mPermissionManager.enforceCrossUserPermission(callingUid, userId,
+ false /*requireFullPermission*/, true /*checkShell*/, "isPackageStateProtected");
+
+ if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
+ && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
+ throw new SecurityException("Caller must have the "
+ + MANAGE_DEVICE_ADMINS + " permission.");
+ }
+
+ return mProtectedPackages.isPackageStateProtected(userId, packageName);
+ }
}
interface PackageSender {