From deb112674e9940a46c87fa4e3bae5d8d1ee84ef3 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Mon, 2 Aug 2010 11:36:21 -0700 Subject: [PATCH] Only allow one movePackage operation in-flight When a movePackage operation is requested, don't allow multiple requests to pile up for one package. Once a move is completed, an observer will receive the message and be allowed to call movePackage again. Change-Id: Ie3842b6d96446febc0037bf9b8f1ca250735edc2 --- .../android/content/pm/PackageManager.java | 10 +++++++++ .../android/content/pm/PackageParser.java | 5 ++++- .../android/server/PackageManagerService.java | 21 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 15a446b8eea58..b14555a8bda38 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -609,6 +609,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 diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 0b35d8b1c0daa..47e668d445453 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -2791,7 +2791,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 ff4ff7422b970..7827d2698df20 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) { @@ -9889,6 +9892,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 && @@ -9905,6 +9911,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) { @@ -10017,6 +10026,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 {