diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index dbddc22172730..ef34ea68a74d9 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1685,6 +1685,15 @@ public abstract class PackageManager { * {@hide} */ public static final int DELETE_FAILED_USED_SHARED_LIBRARY = -6; + /** + * Deletion failed return code: this is passed to the + * {@link IPackageDeleteObserver} if the system failed to delete the package + * because there is an app pinned. + * + * @hide + */ + public static final int DELETE_FAILED_APP_PINNED = -7; + /** * Return code that is passed to the {@link IPackageMoveObserver} when the * package has been successfully moved by the system. @@ -7527,6 +7536,7 @@ public abstract class PackageManager { case DELETE_FAILED_OWNER_BLOCKED: return "DELETE_FAILED_OWNER_BLOCKED"; case DELETE_FAILED_ABORTED: return "DELETE_FAILED_ABORTED"; case DELETE_FAILED_USED_SHARED_LIBRARY: return "DELETE_FAILED_USED_SHARED_LIBRARY"; + case DELETE_FAILED_APP_PINNED: return "DELETE_FAILED_APP_PINNED"; default: return Integer.toString(status); } } @@ -7541,6 +7551,7 @@ public abstract class PackageManager { case DELETE_FAILED_OWNER_BLOCKED: return PackageInstaller.STATUS_FAILURE_BLOCKED; case DELETE_FAILED_ABORTED: return PackageInstaller.STATUS_FAILURE_ABORTED; case DELETE_FAILED_USED_SHARED_LIBRARY: return PackageInstaller.STATUS_FAILURE_CONFLICT; + case DELETE_FAILED_APP_PINNED: return PackageInstaller.STATUS_FAILURE_BLOCKED; default: return PackageInstaller.STATUS_FAILURE; } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 9d306e6ab2f7c..f7d1a5926bcb1 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18187,6 +18187,19 @@ public class PackageManagerService extends IPackageManager.Stub final String packageName = versionedPackage.getPackageName(); final long versionCode = versionedPackage.getLongVersionCode(); final String internalPackageName; + + try { + if (LocalServices.getService(ActivityTaskManagerInternal.class) + .isBaseOfLockedTask(packageName)) { + observer.onPackageDeleted( + packageName, PackageManager.DELETE_FAILED_APP_PINNED, null); + EventLog.writeEvent(0x534e4554, "127605586", -1, ""); + return; + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + synchronized (mLock) { // Normalize package name to handle renamed packages and static libs internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index d4dd35f53cf08..eb749f6e06bbd 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -568,4 +568,10 @@ public abstract class ActivityTaskManagerInternal { /** Set all associated companion app that belongs to an userId. */ public abstract void setCompanionAppPackages(int userId, Set companionAppPackages); + + /** + * @param packageName The package to check + * @return Whether the package is the base of any locked task + */ + public abstract boolean isBaseOfLockedTask(String packageName); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 0542ef9b09a40..8dbd661cff91d 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -7473,5 +7473,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mCompanionAppUidsMap.put(userId, result); } } + + + @Override + public boolean isBaseOfLockedTask(String packageName) { + synchronized (mGlobalLock) { + return getLockTaskController().isBaseOfLockedTask(packageName); + } + } } } diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java index c36dede013f4d..c4a42ab7e7be2 100644 --- a/services/core/java/com/android/server/wm/LockTaskController.java +++ b/services/core/java/com/android/server/wm/LockTaskController.java @@ -870,6 +870,21 @@ public class LockTaskController { return new Pair<>(flags1, flags2); } + /** + * @param packageName The package to check + * @return Whether the package is the base of any locked task + */ + boolean isBaseOfLockedTask(String packageName) { + for (int i = 0; i < mLockTaskModeTasks.size(); i++) { + final Intent bi = mLockTaskModeTasks.get(i).getBaseIntent(); + if (bi != null && packageName.equals(bi.getComponent() + .getPackageName())) { + return true; + } + } + return false; + } + /** * Gets the cached value of LockTask feature flags for a specific user. */