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
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user