diff options
author | Jeff Sharkey <jsharkey@android.com> | 2012-09-23 16:25:12 -0700 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2012-09-23 16:44:34 -0700 |
commit | 752cd922f7091dfd5401faf70dc248934a9dbb6d (patch) | |
tree | 687e7c87a3fa71ac84c3fc5db8327d452a7cddc3 | |
parent | 5a370882f87321629f98f6149ac946a57e25dfa8 (diff) | |
download | frameworks_base-752cd922f7091dfd5401faf70dc248934a9dbb6d.zip frameworks_base-752cd922f7091dfd5401faf70dc248934a9dbb6d.tar.gz frameworks_base-752cd922f7091dfd5401faf70dc248934a9dbb6d.tar.bz2 |
Always bind to DefaultContainerService as OWNER.
When PackageManagerService deals with external storage, always bind
to DefaultContainerService as USER_OWNER. This avoids binding to a
stopped user, which would fail.
Bug: 7203111
Change-Id: I8e303c7558e8b5cbe4fea0acc9a472b598df0caa
4 files changed, 65 insertions, 100 deletions
diff --git a/core/java/android/content/pm/PackageCleanItem.java b/core/java/android/content/pm/PackageCleanItem.java index eea3b9c..b1896aa 100644 --- a/core/java/android/content/pm/PackageCleanItem.java +++ b/core/java/android/content/pm/PackageCleanItem.java @@ -21,10 +21,12 @@ import android.os.Parcelable; /** @hide */ public class PackageCleanItem { + public final int userId; public final String packageName; public final boolean andCode; - public PackageCleanItem(String packageName, boolean andCode) { + public PackageCleanItem(int userId, String packageName, boolean andCode) { + this.userId = userId; this.packageName = packageName; this.andCode = andCode; } @@ -37,7 +39,8 @@ public class PackageCleanItem { try { if (obj != null) { PackageCleanItem other = (PackageCleanItem)obj; - return packageName.equals(other.packageName) && andCode == other.andCode; + return userId == other.userId && packageName.equals(other.packageName) + && andCode == other.andCode; } } catch (ClassCastException e) { } @@ -47,6 +50,7 @@ public class PackageCleanItem { @Override public int hashCode() { int result = 17; + result = 31 * result + userId; result = 31 * result + packageName.hashCode(); result = 31 * result + (andCode ? 1 : 0); return result; @@ -57,6 +61,7 @@ public class PackageCleanItem { } public void writeToParcel(Parcel dest, int parcelableFlags) { + dest.writeInt(userId); dest.writeString(packageName); dest.writeInt(andCode ? 1 : 0); } @@ -73,6 +78,7 @@ public class PackageCleanItem { }; private PackageCleanItem(Parcel source) { + userId = source.readInt(); packageName = source.readString(); andCode = source.readInt() != 0; } diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index b36bd55..24a9d71 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -35,6 +35,7 @@ import android.content.res.ObbInfo; import android.content.res.ObbScanner; import android.net.Uri; import android.os.Environment; +import android.os.Environment.UserEnvironment; import android.os.FileUtils; import android.os.IBinder; import android.os.ParcelFileDescriptor; @@ -268,15 +269,16 @@ public class DefaultContainerService extends IntentService { @Override protected void onHandleIntent(Intent intent) { if (PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE.equals(intent.getAction())) { - IPackageManager pm = IPackageManager.Stub.asInterface( + final IPackageManager pm = IPackageManager.Stub.asInterface( ServiceManager.getService("package")); - PackageCleanItem pkg = null; + PackageCleanItem item = null; try { - while ((pkg=pm.nextPackageToClean(pkg)) != null) { - eraseFiles(Environment.getExternalStorageAppDataDirectory(pkg.packageName)); - eraseFiles(Environment.getExternalStorageAppMediaDirectory(pkg.packageName)); - if (pkg.andCode) { - eraseFiles(Environment.getExternalStorageAppObbDirectory(pkg.packageName)); + while ((item = pm.nextPackageToClean(item)) != null) { + final UserEnvironment userEnv = new UserEnvironment(item.userId); + eraseFiles(userEnv.getExternalStorageAppDataDirectory(item.packageName)); + eraseFiles(userEnv.getExternalStorageAppMediaDirectory(item.packageName)); + if (item.andCode) { + eraseFiles(userEnv.getExternalStorageAppObbDirectory(item.packageName)); } } } catch (RemoteException e) { diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 4b4febd..4800e7db 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -413,7 +413,6 @@ public class PackageManagerService extends IPackageManager.Stub { // package uri's from external media onto secure containers // or internal storage. private IMediaContainerService mContainerService = null; - private int mContainerServiceUserId; static final int SEND_PENDING_BROADCAST = 1; static final int MCS_BOUND = 3; @@ -482,15 +481,8 @@ public class PackageManagerService extends IPackageManager.Stub { " DefaultContainerService"); Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); - mContainerServiceUserId = 0; - if (mPendingInstalls.size() > 0) { - mContainerServiceUserId = mPendingInstalls.get(0).getUser().getIdentifier(); - if (mContainerServiceUserId == UserHandle.USER_ALL) { - mContainerServiceUserId = 0; - } - } if (mContext.bindService(service, mDefContainerConn, - Context.BIND_AUTO_CREATE, mContainerServiceUserId)) { + Context.BIND_AUTO_CREATE, UserHandle.USER_OWNER)) { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); mBound = true; return true; @@ -567,15 +559,6 @@ public class PackageManagerService extends IPackageManager.Stub { } else if (mPendingInstalls.size() > 0) { HandlerParams params = mPendingInstalls.get(0); if (params != null) { - // Check if we're connected to the correct service, if it's an install - // request. - final int installFor = params.getUser().getIdentifier(); - if (installFor != mContainerServiceUserId - && (installFor == UserHandle.USER_ALL - && mContainerServiceUserId != 0)) { - mHandler.sendEmptyMessage(MCS_RECONNECT); - return; - } if (params.startCopy()) { // We are done... look for more work or to // go idle. @@ -693,20 +676,23 @@ public class PackageManagerService extends IPackageManager.Stub { } case START_CLEANING_PACKAGE: { Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); - PackageCleanItem item = new PackageCleanItem((String)msg.obj, - msg.arg2 != 0); + final String packageName = (String)msg.obj; + final int userId = msg.arg1; + final boolean andCode = msg.arg2 != 0; synchronized (mPackages) { - if (msg.arg1 == UserHandle.USER_ALL) { + if (userId == UserHandle.USER_ALL) { int[] users = sUserManager.getUserIds(); for (int user : users) { - mSettings.addPackageToCleanLPw(user, item); + mSettings.addPackageToCleanLPw( + new PackageCleanItem(user, packageName, andCode)); } } else { - mSettings.addPackageToCleanLPw(msg.arg1, item); + mSettings.addPackageToCleanLPw( + new PackageCleanItem(userId, packageName, andCode)); } } Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); - startCleaningPackages(-1); + startCleaningPackages(); } break; case POST_INSTALL: { if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); @@ -4193,10 +4179,14 @@ public class PackageManagerService extends IPackageManager.Stub { // Add the new setting to mPackages mPackages.put(pkg.applicationInfo.packageName, pkg); // Make sure we don't accidentally delete its data. - for (int i=0; i<mSettings.mPackagesToBeCleaned.size(); i++) { - mSettings.mPackagesToBeCleaned.valueAt(i).remove(pkgName); + final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); + while (iter.hasNext()) { + PackageCleanItem item = iter.next(); + if (pkgName.equals(item.packageName)) { + iter.remove(); + } } - + // Take care of first install / last update times. if (currentTime != 0) { if (pkgSetting.firstInstallTime == 0) { @@ -5443,7 +5433,6 @@ public class PackageManagerService extends IPackageManager.Stub { public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { // writer - final int userId = UserHandle.getCallingUserId(); synchronized (mPackages) { if (!isExternalMediaAvailable()) { // If the external storage is no longer mounted at this point, @@ -5451,23 +5440,13 @@ public class PackageManagerService extends IPackageManager.Stub { // packages files and can not delete any more. Bail. return null; } - ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned.get(userId); - if (pkgs != null) { - if (lastPackage != null) { - pkgs.remove(lastPackage); - } - if (pkgs.size() > 0) { - return pkgs.get(0); - } + final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; + if (lastPackage != null) { + pkgs.remove(lastPackage); + } + if (pkgs.size() > 0) { + return pkgs.get(0); } - mSettings.mPackagesToBeCleaned.remove(userId); - } - // Move on to the next user to clean. - long ident = Binder.clearCallingIdentity(); - try { - startCleaningPackages(userId); - } finally { - Binder.restoreCallingIdentity(ident); } return null; } @@ -5483,34 +5462,22 @@ public class PackageManagerService extends IPackageManager.Stub { userId, andCode ? 1 : 0, packageName)); } - void startCleaningPackages(int lastUser) { + void startCleaningPackages() { // reader - int nextUser = -1; synchronized (mPackages) { if (!isExternalMediaAvailable()) { return; } - final int N = mSettings.mPackagesToBeCleaned.size(); - if (N <= 0) { + if (mSettings.mPackagesToBeCleaned.isEmpty()) { return; } - for (int i=0; i<N; i++) { - int user = mSettings.mPackagesToBeCleaned.keyAt(i); - if (user > lastUser) { - nextUser = user; - break; - } - } - if (nextUser < 0) { - nextUser = mSettings.mPackagesToBeCleaned.keyAt(0); - } } Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); intent.setComponent(DEFAULT_CONTAINER_COMPONENT); IActivityManager am = ActivityManagerNative.getDefault(); if (am != null) { try { - am.startService(null, intent, null, nextUser); + am.startService(null, intent, null, UserHandle.USER_OWNER); } catch (RemoteException e) { } } @@ -8399,10 +8366,11 @@ public class PackageManagerService extends IPackageManager.Stub { } else { users = new int[] { userId }; } - for (int curUser : users) { - ClearStorageConnection conn = new ClearStorageConnection(); - if (mContext.bindService(containerIntent, conn, Context.BIND_AUTO_CREATE, curUser)) { - try { + final ClearStorageConnection conn = new ClearStorageConnection(); + if (mContext.bindService( + containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.USER_OWNER)) { + try { + for (int curUser : users) { long timeout = SystemClock.uptimeMillis() + 5000; synchronized (conn) { long now = SystemClock.uptimeMillis(); @@ -8438,9 +8406,9 @@ public class PackageManagerService extends IPackageManager.Stub { } catch (RemoteException e) { } } - } finally { - mContext.unbindService(conn); } + } finally { + mContext.unbindService(conn); } } } @@ -9596,7 +9564,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (DEBUG_SD_INSTALL) Log.i(TAG, "Loading packages"); loadMediaPackages(processCids, uidArr, removeCids); - startCleaningPackages(-1); + startCleaningPackages(); } else { if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading packages"); diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java index 23e54678..2fb853a 100644 --- a/services/java/com/android/server/pm/Settings.java +++ b/services/java/com/android/server/pm/Settings.java @@ -159,8 +159,7 @@ final class Settings { // Packages that have been uninstalled and still need their external // storage data deleted. - final SparseArray<ArrayList<PackageCleanItem>> mPackagesToBeCleaned - = new SparseArray<ArrayList<PackageCleanItem>>(); + final ArrayList<PackageCleanItem> mPackagesToBeCleaned = new ArrayList<PackageCleanItem>(); // Packages that have been renamed since they were first installed. // Keys are the new names of the packages, values are the original @@ -1257,18 +1256,13 @@ final class Settings { } if (mPackagesToBeCleaned.size() > 0) { - for (int i=0; i<mPackagesToBeCleaned.size(); i++) { - final int userId = mPackagesToBeCleaned.keyAt(i); - final String userStr = Integer.toString(userId); - final ArrayList<PackageCleanItem> pkgs = mPackagesToBeCleaned.valueAt(i); - for (int j=0; j<pkgs.size(); j++) { - serializer.startTag(null, "cleaning-package"); - PackageCleanItem item = pkgs.get(j); - serializer.attribute(null, ATTR_NAME, item.packageName); - serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false"); - serializer.attribute(null, ATTR_USER, userStr); - serializer.endTag(null, "cleaning-package"); - } + for (PackageCleanItem item : mPackagesToBeCleaned) { + final String userStr = Integer.toString(item.userId); + serializer.startTag(null, "cleaning-package"); + serializer.attribute(null, ATTR_NAME, item.packageName); + serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false"); + serializer.attribute(null, ATTR_USER, userStr); + serializer.endTag(null, "cleaning-package"); } } @@ -1524,14 +1518,9 @@ final class Settings { return ret; } - void addPackageToCleanLPw(int userId, PackageCleanItem pkg) { - ArrayList<PackageCleanItem> pkgs = mPackagesToBeCleaned.get(userId); - if (pkgs == null) { - pkgs = new ArrayList<PackageCleanItem>(); - mPackagesToBeCleaned.put(userId, pkgs); - } - if (!pkgs.contains(pkg)) { - pkgs.add(pkg); + void addPackageToCleanLPw(PackageCleanItem pkg) { + if (!mPackagesToBeCleaned.contains(pkg)) { + mPackagesToBeCleaned.add(pkg); } } @@ -1615,18 +1604,18 @@ final class Settings { String userStr = parser.getAttributeValue(null, ATTR_USER); String codeStr = parser.getAttributeValue(null, ATTR_CODE); if (name != null) { - int user = 0; + int userId = 0; boolean andCode = true; try { if (userStr != null) { - user = Integer.parseInt(userStr); + userId = Integer.parseInt(userStr); } } catch (NumberFormatException e) { } if (codeStr != null) { andCode = Boolean.parseBoolean(codeStr); } - addPackageToCleanLPw(user, new PackageCleanItem(name, andCode)); + addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode)); } } else if (tagName.equals("renamed-package")) { String nname = parser.getAttributeValue(null, "new"); |