summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageManager.java10
-rw-r--r--core/java/android/content/pm/PackageParser.java5
-rw-r--r--services/java/com/android/server/PackageManagerService.java21
3 files changed, 35 insertions, 1 deletions
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 15a446b8eea5..b14555a8bda3 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -610,6 +610,16 @@ public abstract class PackageManager {
public static final int MOVE_FAILED_INTERNAL_ERROR = -6;
/**
+ * Error code that is passed to the {@link IPackageMoveObserver} by
+ * {@link #movePackage(android.net.Uri, IPackageMoveObserver)} if the
+ * specified package already has an operation pending in the
+ * {@link PackageHandler} queue.
+ *
+ * @hide
+ */
+ public static final int MOVE_FAILED_OPERATION_PENDING = -7;
+
+ /**
* Flag parameter for {@link #movePackage} to indicate that
* the package should be moved to internal storage if its
* been installed on external media.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 8c9cc4e41eef..155c86cf9f0e 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2799,7 +2799,10 @@ public class PackageParser {
// Additional data supplied by callers.
public Object mExtras;
-
+
+ // Whether an operation is currently pending on this package
+ public boolean mOperationPending;
+
/*
* Applications hardware preferences
*/
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 7cc254b9f1c8..e63b355a4851 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -7202,6 +7202,9 @@ class PackageManagerService extends IPackageManager.Stub {
pw.print(" pkgFlags=0x"); pw.print(Integer.toHexString(ps.pkgFlags));
pw.print(" installStatus="); pw.print(ps.installStatus);
pw.print(" enabled="); pw.println(ps.enabled);
+ if (ps.pkg.mOperationPending) {
+ pw.println(" mOperationPending=true");
+ }
if (ps.disabledComponents.size() > 0) {
pw.println(" disabledComponents:");
for (String s : ps.disabledComponents) {
@@ -9890,6 +9893,9 @@ class PackageManagerService extends IPackageManager.Stub {
(pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0) {
Slog.w(TAG, "Cannot move forward locked app.");
returnCode = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
+ } else if (pkg.mOperationPending) {
+ Slog.w(TAG, "Attempt to move package which has pending operations");
+ returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
} else {
// Find install location first
if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 &&
@@ -9906,6 +9912,9 @@ class PackageManagerService extends IPackageManager.Stub {
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
}
}
+ if (returnCode == PackageManager.MOVE_SUCCEEDED) {
+ pkg.mOperationPending = true;
+ }
}
}
if (returnCode != PackageManager.MOVE_SUCCEEDED) {
@@ -10018,6 +10027,18 @@ class PackageManagerService extends IPackageManager.Stub {
mp.srcArgs.doPostDeleteLI(true);
}
}
+
+ // Allow more operations on this file if we didn't fail because
+ // an operation was already pending for this package.
+ if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) {
+ synchronized (mPackages) {
+ PackageParser.Package pkg = mPackages.get(mp.packageName);
+ if (pkg != null) {
+ pkg.mOperationPending = false;
+ }
+ }
+ }
+
IPackageMoveObserver observer = mp.observer;
if (observer != null) {
try {