summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2019-04-12 18:40:47 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-04-12 18:40:47 +0000
commitd7c6b89b32c88e204c7197a649f6fe36efa479a3 (patch)
tree97688e31c62b8a5ce28c9f2d7ed80725cee0c96f
parentbd39e731f3e11436f893ca4d6013b764aa4c5914 (diff)
parentb2f366cbd573a98bcef0eae20a5e1af1cf3de51b (diff)
Merge "Avoid taking a lock when we shouldn't" into qt-dev
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java266
1 files changed, 157 insertions, 109 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 5eae9c7ad99c..c1587dc9f86f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1990,31 +1990,31 @@ public class PackageManagerService extends IPackageManager.Stub
// Work that needs to happen on first install within each user
if (firstUserIds != null && firstUserIds.length > 0) {
- synchronized (mPackages) {
- for (int userId : firstUserIds) {
- // If this app is a browser and it's newly-installed for some
- // users, clear any default-browser state in those users. The
- // app's nature doesn't depend on the user, so we can just check
- // its browser nature in any user and generalize.
- if (packageIsBrowser(packageName, userId)) {
- // If this browser is restored from user's backup, do not clear
- // default-browser state for this user
+ for (int userId : firstUserIds) {
+ // If this app is a browser and it's newly-installed for some
+ // users, clear any default-browser state in those users. The
+ // app's nature doesn't depend on the user, so we can just check
+ // its browser nature in any user and generalize.
+ if (packageIsBrowser(packageName, userId)) {
+ // If this browser is restored from user's backup, do not clear
+ // default-browser state for this user
+ synchronized (mPackages) {
final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting.getInstallReason(userId)
!= PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
setDefaultBrowserAsyncLPw(null, userId);
}
}
+ }
- // We may also need to apply pending (restored) runtime permission grants
- // within these users.
- mPermissionManager.restoreDelayedRuntimePermissions(packageName,
- UserHandle.of(userId));
+ // We may also need to apply pending (restored) runtime permission grants
+ // within these users.
+ mPermissionManager.restoreDelayedRuntimePermissions(packageName,
+ UserHandle.of(userId));
- // Persistent preferred activity might have came into effect due to this
- // install.
- updateDefaultHomeLPw(userId);
- }
+ // Persistent preferred activity might have came into effect due to this
+ // install.
+ updateDefaultHomeNotLocked(userId);
}
}
@@ -5158,7 +5158,7 @@ public class PackageManagerService extends IPackageManager.Stub
getPackagesUsingSharedLibraryLPr(libInfo, flags, userId),
(libInfo.getDependencies() == null
? null
- : new ArrayList(libInfo.getDependencies())));
+ : new ArrayList<>(libInfo.getDependencies())));
if (result == null) {
result = new ArrayList<>();
@@ -6475,8 +6475,8 @@ public class PackageManagerService extends IPackageManager.Stub
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
userId);
// Find any earlier preferred or last chosen entries and nuke them
- findPreferredActivity(intent, resolvedType,
- flags, query, 0, false, true, false, userId);
+ findPreferredActivityNotLocked(
+ intent, resolvedType, flags, query, 0, false, true, false, userId);
// Add the new activity as the last chosen for this filter
addPreferredActivityInternal(filter, match, null, activity, false, userId,
"Setting last chosen");
@@ -6491,8 +6491,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
userId);
- return findPreferredActivity(intent, resolvedType, flags, query, 0,
- false, false, false, userId);
+ return findPreferredActivityNotLocked(
+ intent, resolvedType, flags, query, 0, false, false, false, userId);
}
/**
@@ -6605,7 +6605,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
// If we have saved a preference for a preferred activity for
// this Intent, use that.
- ResolveInfo ri = findPreferredActivity(intent, resolvedType,
+ ResolveInfo ri = findPreferredActivityNotLocked(intent, resolvedType,
flags, query, r0.priority, true, false, debug, userId);
if (ri != null) {
return ri;
@@ -6744,9 +6744,14 @@ public class PackageManagerService extends IPackageManager.Stub
}
// TODO: handle preferred activities missing while user has amnesia
- ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
+ /** <b>must not hold {@link #mPackages}</b> */
+ ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
List<ResolveInfo> query, int priority, boolean always,
boolean removeMatches, boolean debug, int userId) {
+ if (Thread.holdsLock(mPackages)) {
+ Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
+ + " is holding mPackages", new Throwable());
+ }
if (!sUserManager.exists(userId)) return null;
final int callingUid = Binder.getCallingUid();
// Do NOT hold the packages lock; this calls up into the settings provider which
@@ -18599,10 +18604,10 @@ public class PackageManagerService extends IPackageManager.Stub
int removedAppId = -1;
// writer
- synchronized (mPackages) {
- boolean installedStateChanged = false;
- if (deletedPs != null) {
- if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
+ boolean installedStateChanged = false;
+ if (deletedPs != null) {
+ if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
+ synchronized (mPackages) {
clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
clearDefaultBrowserIfNeeded(packageName);
mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
@@ -18633,26 +18638,34 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
}
- clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
}
- // make sure to preserve per-user disabled state if this removal was just
- // a downgrade of a system app to the factory package
- if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
+ final SparseBooleanArray changedUsers = new SparseBooleanArray();
+ clearPackagePreferredActivitiesLPw(
+ deletedPs.name, changedUsers, UserHandle.USER_ALL);
+ if (changedUsers.size() > 0) {
+ updateDefaultHomeNotLocked(changedUsers);
+ postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
+ }
+ }
+ // make sure to preserve per-user disabled state if this removal was just
+ // a downgrade of a system app to the factory package
+ if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
+ if (DEBUG_REMOVE) {
+ Slog.d(TAG, "Propagating install state across downgrade");
+ }
+ for (int userId : allUserHandles) {
+ final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
if (DEBUG_REMOVE) {
- Slog.d(TAG, "Propagating install state across downgrade");
+ Slog.d(TAG, " user " + userId + " => " + installed);
}
- for (int userId : allUserHandles) {
- final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
- if (DEBUG_REMOVE) {
- Slog.d(TAG, " user " + userId + " => " + installed);
- }
- if (installed != deletedPs.getInstalled(userId)) {
- installedStateChanged = true;
- }
- deletedPs.setInstalled(installed, userId);
+ if (installed != deletedPs.getInstalled(userId)) {
+ installedStateChanged = true;
}
+ deletedPs.setInstalled(installed, userId);
}
}
+ }
+ synchronized (mPackages) {
// can downgrade to reader
if (writeSettings) {
// Save settings now
@@ -19330,10 +19343,17 @@ public class PackageManagerService extends IPackageManager.Stub
destroyAppDataLIF(pkg, nextUserId,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
- synchronized (mPackages) {
- if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
+ removeKeystoreDataIfNeeded(nextUserId, ps.appId);
+ final SparseBooleanArray changedUsers = new SparseBooleanArray();
+ clearPackagePreferredActivitiesLPw(ps.name, changedUsers, nextUserId);
+ if (changedUsers.size() > 0) {
+ updateDefaultHomeNotLocked(changedUsers);
+ postPreferredActivityChangedBroadcast(nextUserId);
+ synchronized (mPackages) {
scheduleWritePackageRestrictionsLocked(nextUserId);
}
+ }
+ synchronized (mPackages) {
resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
}
// Also delete contributed media, when requested
@@ -19796,33 +19816,34 @@ public class PackageManagerService extends IPackageManager.Stub
int callingUid = Binder.getCallingUid();
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
+ if (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
+ != PackageManager.PERMISSION_GRANTED) {
+ if (getUidTargetSdkVersionLockedLPr(callingUid)
+ < Build.VERSION_CODES.FROYO) {
+ Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
+ + callingUid);
+ return;
+ }
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+ }
if (filter.countActions() == 0) {
Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
return;
}
- synchronized (mPackages) {
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
- != PackageManager.PERMISSION_GRANTED) {
- if (getUidTargetSdkVersionLockedLPr(callingUid)
- < Build.VERSION_CODES.FROYO) {
- Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
- + callingUid);
- return;
- }
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
- }
-
- PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
+ if (DEBUG_PREFERRED) {
Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
+ userId + ":");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
+ }
+ if (!updateDefaultHomeNotLocked(userId)) {
+ postPreferredActivityChangedBroadcast(userId);
+ }
+ synchronized (mPackages) {
+ final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
scheduleWritePackageRestrictionsLocked(userId);
- if (!updateDefaultHomeLPw(userId)) {
- postPreferredActivityChangedBroadcast(userId);
- }
}
}
@@ -19963,25 +19984,24 @@ public class PackageManagerService extends IPackageManager.Stub
&& filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
return;
}
- int user = UserHandle.getCallingUserId();
- if (clearPackagePreferredActivitiesLPw(packageName, user)) {
- scheduleWritePackageRestrictionsLocked(user);
+ }
+ int callingUserId = UserHandle.getCallingUserId();
+ final SparseBooleanArray changedUsers = new SparseBooleanArray();
+ clearPackagePreferredActivitiesLPw(packageName, changedUsers, callingUserId);
+ if (changedUsers.size() > 0) {
+ updateDefaultHomeNotLocked(changedUsers);
+ postPreferredActivityChangedBroadcast(callingUserId);
+ synchronized (mPackages) {
+ scheduleWritePackageRestrictionsLocked(callingUserId);
}
}
}
/** This method takes a specific user id as well as UserHandle.USER_ALL. */
@GuardedBy("mPackages")
- boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
- return clearPackagePreferredActivitiesLPw(packageName, false, userId);
- }
-
- /** This method takes a specific user id as well as UserHandle.USER_ALL. */
- @GuardedBy("mPackages")
- private boolean clearPackagePreferredActivitiesLPw(String packageName,
- boolean skipUpdateDefaultHome, int userId) {
+ private void clearPackagePreferredActivitiesLPw(String packageName,
+ @NonNull SparseBooleanArray outUserChanged, int userId) {
ArrayList<PreferredActivity> removed = null;
- boolean changed = false;
for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
@@ -20007,16 +20027,9 @@ public class PackageManagerService extends IPackageManager.Stub
PreferredActivity pa = removed.get(j);
pir.removeFilter(pa);
}
- changed = true;
- if (!skipUpdateDefaultHome) {
- updateDefaultHomeLPw(thisUserId);
- }
+ outUserChanged.setValueAt(thisUserId, true);
}
}
- if (changed) {
- postPreferredActivityChangedBroadcast(userId);
- }
- return changed;
}
/** This method takes a specific user id as well as UserHandle.USER_ALL. */
@@ -20069,21 +20082,27 @@ public class PackageManagerService extends IPackageManager.Stub
final long identity = Binder.clearCallingIdentity();
// writer
try {
+ final SparseBooleanArray changedUsers = new SparseBooleanArray();
+ clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
+ if (changedUsers.size() > 0) {
+ postPreferredActivityChangedBroadcast(userId);
+ }
synchronized (mPackages) {
- clearPackagePreferredActivitiesLPw(null, true, userId);
mSettings.applyDefaultPreferredAppsLPw(userId);
- updateDefaultHomeLPw(userId);
- // TODO: We have to reset the default SMS and Phone. This requires
- // significant refactoring to keep all default apps in the package
- // manager (cleaner but more work) or have the services provide
- // callbacks to the package manager to request a default app reset.
- setDefaultBrowserPackageName(null, userId);
clearIntentFilterVerificationsLPw(userId);
primeDomainVerificationsLPw(userId);
resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
- scheduleWritePackageRestrictionsLocked(userId);
}
+ updateDefaultHomeNotLocked(userId);
+ // TODO: We have to reset the default SMS and Phone. This requires
+ // significant refactoring to keep all default apps in the package
+ // manager (cleaner but more work) or have the services provide
+ // callbacks to the package manager to request a default app reset.
+ setDefaultBrowserPackageName(null, userId);
resetNetworkPolicies(userId);
+ synchronized (mPackages) {
+ scheduleWritePackageRestrictionsLocked(userId);
+ }
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -20133,15 +20152,17 @@ public class PackageManagerService extends IPackageManager.Stub
Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
return;
}
- synchronized (mPackages) {
- Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
- ":");
+ if (DEBUG_PREFERRED) {
+ Slog.i(TAG, "Adding persistent preferred activity " + activity
+ + " for user " + userId + ":");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
+ }
+ updateDefaultHomeNotLocked(userId);
+ postPreferredActivityChangedBroadcast(userId);
+ synchronized (mPackages) {
mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
new PersistentPreferredActivity(filter, activity));
scheduleWritePackageRestrictionsLocked(userId);
- postPreferredActivityChangedBroadcast(userId);
- updateDefaultHomeLPw(userId);
}
}
@@ -20181,11 +20202,12 @@ public class PackageManagerService extends IPackageManager.Stub
changed = true;
}
}
-
- if (changed) {
+ }
+ if (changed) {
+ updateDefaultHomeNotLocked(userId);
+ postPreferredActivityChangedBroadcast(userId);
+ synchronized (mPackages) {
scheduleWritePackageRestrictionsLocked(userId);
- postPreferredActivityChangedBroadcast(userId);
- updateDefaultHomeLPw(userId);
}
}
}
@@ -20273,8 +20295,8 @@ public class PackageManagerService extends IPackageManager.Stub
(readParser, readUserId) -> {
synchronized (mPackages) {
mSettings.readPreferredActivitiesLPw(readParser, readUserId);
- updateDefaultHomeLPw(readUserId);
}
+ updateDefaultHomeNotLocked(readUserId);
});
} catch (Exception e) {
if (DEBUG_BACKUP) {
@@ -20601,29 +20623,55 @@ public class PackageManagerService extends IPackageManager.Stub
return null;
}
+ /** <b>must not hold {@link #mPackages}</b> */
+ private void updateDefaultHomeNotLocked(SparseBooleanArray userIds) {
+ if (Thread.holdsLock(mPackages)) {
+ Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
+ + " is holding mPackages", new Throwable());
+ }
+ for (int i = userIds.size() - 1; i >= 0; --i) {
+ final int userId = userIds.keyAt(i);
+ updateDefaultHomeNotLocked(userId);
+ }
+ }
+
/**
+ * <b>must not hold {@link #mPackages}</b>
+ *
* @return Whether the ACTION_PREFERRED_ACTIVITY_CHANGED broadcast has been scheduled.
*/
- private boolean updateDefaultHomeLPw(int userId) {
- Intent intent = getHomeIntent();
- List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
+ private boolean updateDefaultHomeNotLocked(int userId) {
+ if (Thread.holdsLock(mPackages)) {
+ Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
+ + " is holding mPackages", new Throwable());
+ }
+ final Intent intent = getHomeIntent();
+ final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
PackageManager.GET_META_DATA, userId);
- ResolveInfo preferredResolveInfo = findPreferredActivity(intent, null, 0, resolveInfos,
- 0, true, false, false, userId);
- String packageName = preferredResolveInfo != null
+ final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
+ intent, null, 0, resolveInfos, 0, true, false, false, userId);
+ final String packageName = preferredResolveInfo != null
&& preferredResolveInfo.activityInfo != null
? preferredResolveInfo.activityInfo.packageName : null;
- String currentPackageName = mDefaultHomeProvider.getDefaultHome(userId);
+ final PackageManagerInternal.DefaultHomeProvider provider;
+ synchronized (mPackages) {
+ provider = mDefaultHomeProvider;
+ }
+ if (provider == null) {
+ Slog.e(TAG, "Default home provider has not been set");
+ return false;
+ }
+ final String currentPackageName = provider.getDefaultHome(userId);
if (TextUtils.equals(currentPackageName, packageName)) {
return false;
}
- String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
+ final String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
if (callingPackages != null && ArrayUtils.contains(callingPackages,
mRequiredPermissionControllerPackage)) {
// PermissionController manages default home directly.
return false;
}
- mDefaultHomeProvider.setDefaultHomeAsync(packageName, userId, (successful) -> {
+ provider.setDefaultHomeAsync(packageName, userId, (successful) -> {
if (successful) {
postPreferredActivityChangedBroadcast(userId);
}