Merge "OMS: Update PM on main thread with lock" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
094d0adb13
@@ -103,7 +103,6 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -312,7 +311,7 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
// Initialize any users that can't be switched to, as their state would
|
// Initialize any users that can't be switched to, as their state would
|
||||||
// never be setup in onSwitchUser(). We will switch to the system user right
|
// never be setup in onSwitchUser(). We will switch to the system user right
|
||||||
// after this, and its state will be setup there.
|
// after this, and its state will be setup there.
|
||||||
updatePackageManager(mImpl.updateOverlaysForUser(users.get(i).id));
|
updatePackageManagerLocked(mImpl.updateOverlaysForUser(users.get(i).id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,9 +328,8 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
// ensure overlays in the settings are up-to-date, and propagate
|
// ensure overlays in the settings are up-to-date, and propagate
|
||||||
// any asset changes to the rest of the system
|
// any asset changes to the rest of the system
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
updateActivityManager(updatePackageManager(mImpl.updateOverlaysForUser(newUserId)));
|
updateTargetPackagesLocked(mImpl.updateOverlaysForUser(newUserId));
|
||||||
}
|
}
|
||||||
persistSettings();
|
|
||||||
} finally {
|
} finally {
|
||||||
traceEnd(TRACE_TAG_RRO);
|
traceEnd(TRACE_TAG_RRO);
|
||||||
}
|
}
|
||||||
@@ -415,7 +413,8 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
packageName, userId);
|
packageName, userId);
|
||||||
if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
|
if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
|
||||||
try {
|
try {
|
||||||
updateTargetPackages(mImpl.onPackageAdded(packageName, userId));
|
updateTargetPackagesLocked(
|
||||||
|
mImpl.onPackageAdded(packageName, userId));
|
||||||
} catch (OperationFailedException e) {
|
} catch (OperationFailedException e) {
|
||||||
Slog.e(TAG, "onPackageAdded internal error", e);
|
Slog.e(TAG, "onPackageAdded internal error", e);
|
||||||
}
|
}
|
||||||
@@ -437,7 +436,8 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
packageName, userId);
|
packageName, userId);
|
||||||
if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
|
if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
|
||||||
try {
|
try {
|
||||||
updateTargetPackages(mImpl.onPackageChanged(packageName, userId));
|
updateTargetPackagesLocked(
|
||||||
|
mImpl.onPackageChanged(packageName, userId));
|
||||||
} catch (OperationFailedException e) {
|
} catch (OperationFailedException e) {
|
||||||
Slog.e(TAG, "onPackageChanged internal error", e);
|
Slog.e(TAG, "onPackageChanged internal error", e);
|
||||||
}
|
}
|
||||||
@@ -459,7 +459,8 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
packageName, userId);
|
packageName, userId);
|
||||||
if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
|
if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
|
||||||
try {
|
try {
|
||||||
updateTargetPackages(mImpl.onPackageReplacing(packageName, userId));
|
updateTargetPackagesLocked(
|
||||||
|
mImpl.onPackageReplacing(packageName, userId));
|
||||||
} catch (OperationFailedException e) {
|
} catch (OperationFailedException e) {
|
||||||
Slog.e(TAG, "onPackageReplacing internal error", e);
|
Slog.e(TAG, "onPackageReplacing internal error", e);
|
||||||
}
|
}
|
||||||
@@ -481,7 +482,8 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
packageName, userId);
|
packageName, userId);
|
||||||
if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
|
if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
|
||||||
try {
|
try {
|
||||||
updateTargetPackages(mImpl.onPackageReplaced(packageName, userId));
|
updateTargetPackagesLocked(
|
||||||
|
mImpl.onPackageReplaced(packageName, userId));
|
||||||
} catch (OperationFailedException e) {
|
} catch (OperationFailedException e) {
|
||||||
Slog.e(TAG, "onPackageReplaced internal error", e);
|
Slog.e(TAG, "onPackageReplaced internal error", e);
|
||||||
}
|
}
|
||||||
@@ -500,7 +502,7 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
for (int userId : userIds) {
|
for (int userId : userIds) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mPackageManager.onPackageRemoved(packageName, userId);
|
mPackageManager.onPackageRemoved(packageName, userId);
|
||||||
updateTargetPackages(mImpl.onPackageRemoved(packageName, userId));
|
updateTargetPackagesLocked(mImpl.onPackageRemoved(packageName, userId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -519,7 +521,7 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
try {
|
try {
|
||||||
traceBegin(TRACE_TAG_RRO, "OMS ACTION_USER_ADDED");
|
traceBegin(TRACE_TAG_RRO, "OMS ACTION_USER_ADDED");
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
updatePackageManager(mImpl.updateOverlaysForUser(userId));
|
updatePackageManagerLocked(mImpl.updateOverlaysForUser(userId));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
traceEnd(TRACE_TAG_RRO);
|
traceEnd(TRACE_TAG_RRO);
|
||||||
@@ -624,7 +626,8 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
try {
|
try {
|
||||||
updateTargetPackages(mImpl.setEnabled(overlay, enable, realUserId));
|
updateTargetPackagesLocked(
|
||||||
|
mImpl.setEnabled(overlay, enable, realUserId));
|
||||||
return true;
|
return true;
|
||||||
} catch (OperationFailedException e) {
|
} catch (OperationFailedException e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -656,9 +659,10 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
try {
|
try {
|
||||||
mImpl.setEnabledExclusive(overlay,
|
mImpl.setEnabledExclusive(
|
||||||
false /* withinCategory */, realUserId)
|
overlay, false /* withinCategory */, realUserId)
|
||||||
.ifPresent(OverlayManagerService.this::updateTargetPackages);
|
.ifPresent(
|
||||||
|
OverlayManagerService.this::updateTargetPackagesLocked);
|
||||||
return true;
|
return true;
|
||||||
} catch (OperationFailedException e) {
|
} catch (OperationFailedException e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -693,7 +697,7 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
try {
|
try {
|
||||||
mImpl.setEnabledExclusive(overlay,
|
mImpl.setEnabledExclusive(overlay,
|
||||||
true /* withinCategory */, realUserId)
|
true /* withinCategory */, realUserId)
|
||||||
.ifPresent(OverlayManagerService.this::updateTargetPackages);
|
.ifPresent(OverlayManagerService.this::updateTargetPackagesLocked);
|
||||||
return true;
|
return true;
|
||||||
} catch (OperationFailedException e) {
|
} catch (OperationFailedException e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -728,7 +732,7 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
try {
|
try {
|
||||||
mImpl.setPriority(overlay, parentOverlay, realUserId)
|
mImpl.setPriority(overlay, parentOverlay, realUserId)
|
||||||
.ifPresent(OverlayManagerService.this::updateTargetPackages);
|
.ifPresent(OverlayManagerService.this::updateTargetPackagesLocked);
|
||||||
return true;
|
return true;
|
||||||
} catch (OperationFailedException e) {
|
} catch (OperationFailedException e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -759,7 +763,8 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
try {
|
try {
|
||||||
updateTargetPackages(mImpl.setHighestPriority(overlay, realUserId));
|
updateTargetPackagesLocked(
|
||||||
|
mImpl.setHighestPriority(overlay, realUserId));
|
||||||
return true;
|
return true;
|
||||||
} catch (OperationFailedException e) {
|
} catch (OperationFailedException e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -791,7 +796,7 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
try {
|
try {
|
||||||
mImpl.setLowestPriority(overlay, realUserId)
|
mImpl.setLowestPriority(overlay, realUserId)
|
||||||
.ifPresent(OverlayManagerService.this::updateTargetPackages);
|
.ifPresent(OverlayManagerService.this::updateTargetPackagesLocked);
|
||||||
return true;
|
return true;
|
||||||
} catch (OperationFailedException e) {
|
} catch (OperationFailedException e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -945,27 +950,12 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
throw new IllegalArgumentException("null transaction");
|
throw new IllegalArgumentException("null transaction");
|
||||||
}
|
}
|
||||||
|
|
||||||
// map: userId -> set<package-name>: target packages of overlays in
|
|
||||||
// this transaction
|
|
||||||
final SparseArray<Set<String>> transactionTargets = new SparseArray<>();
|
|
||||||
|
|
||||||
// map: userId -> set<package-name>: packages that need to reload
|
|
||||||
// their resources due to changes to the overlays in this
|
|
||||||
// transaction
|
|
||||||
final SparseArray<List<String>> affectedPackagesToUpdate = new SparseArray<>();
|
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
// execute the requests (as calling user)
|
// execute the requests (as calling user)
|
||||||
|
Set<PackageAndUser> affectedPackagesToUpdate = null;
|
||||||
for (final OverlayManagerTransaction.Request request : transaction) {
|
for (final OverlayManagerTransaction.Request request : transaction) {
|
||||||
executeRequest(request).forEach(
|
affectedPackagesToUpdate = CollectionUtils.addAll(affectedPackagesToUpdate,
|
||||||
target -> {
|
executeRequest(request));
|
||||||
Set<String> userTargets = transactionTargets.get(target.userId);
|
|
||||||
if (userTargets == null) {
|
|
||||||
userTargets = new ArraySet<>();
|
|
||||||
transactionTargets.put(target.userId, userTargets);
|
|
||||||
}
|
|
||||||
userTargets.add(target.packageName);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// past the point of no return: the entire transaction has been
|
// past the point of no return: the entire transaction has been
|
||||||
@@ -973,37 +963,11 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
// system_server
|
// system_server
|
||||||
final long ident = Binder.clearCallingIdentity();
|
final long ident = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
persistSettings();
|
updateTargetPackagesLocked(affectedPackagesToUpdate);
|
||||||
|
|
||||||
// inform the package manager about the new paths
|
|
||||||
for (int index = 0; index < transactionTargets.size(); index++) {
|
|
||||||
final int userId = transactionTargets.keyAt(index);
|
|
||||||
final List<String> affectedTargets =
|
|
||||||
updatePackageManager(transactionTargets.valueAt(index), userId);
|
|
||||||
affectedPackagesToUpdate.put(userId, affectedTargets);
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
Binder.restoreCallingIdentity(ident);
|
Binder.restoreCallingIdentity(ident);
|
||||||
}
|
}
|
||||||
} // synchronized (mLock)
|
}
|
||||||
|
|
||||||
FgThread.getHandler().post(() -> {
|
|
||||||
final long ident = Binder.clearCallingIdentity();
|
|
||||||
try {
|
|
||||||
// schedule apps to refresh
|
|
||||||
updateActivityManager(affectedPackagesToUpdate);
|
|
||||||
|
|
||||||
// broadcast the ACTION_OVERLAY_CHANGED intents
|
|
||||||
for (int index = 0; index < transactionTargets.size(); index++) {
|
|
||||||
final int userId = transactionTargets.keyAt(index);
|
|
||||||
for (String pkg: transactionTargets.valueAt(index)) {
|
|
||||||
broadcastActionOverlayChanged(pkg, userId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(ident);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1382,32 +1346,37 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTargetPackages(@Nullable PackageAndUser updatedTarget) {
|
private void updateTargetPackagesLocked(@Nullable PackageAndUser updatedTarget) {
|
||||||
if (updatedTarget != null) {
|
if (updatedTarget != null) {
|
||||||
updateTargetPackages(Set.of(updatedTarget));
|
updateTargetPackagesLocked(Set.of(updatedTarget));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTargetPackages(@Nullable Set<PackageAndUser> updatedTargets) {
|
private void updateTargetPackagesLocked(@Nullable Set<PackageAndUser> updatedTargets) {
|
||||||
if (CollectionUtils.isEmpty(updatedTargets)) {
|
if (CollectionUtils.isEmpty(updatedTargets)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
persistSettings();
|
persistSettingsLocked();
|
||||||
final SparseArray<ArraySet<String>> userTargets = groupTargetsByUserId(updatedTargets);
|
final SparseArray<ArraySet<String>> userTargets = groupTargetsByUserId(updatedTargets);
|
||||||
FgThread.getHandler().post(() -> {
|
for (int i = 0, n = userTargets.size(); i < n; i++) {
|
||||||
for (int i = 0, n = userTargets.size(); i < n; i++) {
|
final ArraySet<String> targets = userTargets.valueAt(i);
|
||||||
final ArraySet<String> targets = userTargets.valueAt(i);
|
final int userId = userTargets.keyAt(i);
|
||||||
final int userId = userTargets.keyAt(i);
|
final List<String> affectedPackages = updatePackageManagerLocked(targets, userId);
|
||||||
|
if (affectedPackages.isEmpty()) {
|
||||||
|
// The package manager paths are already up-to-date.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Update the overlay paths in package manager.
|
FgThread.getHandler().post(() -> {
|
||||||
final List<String> affectedPackages = updatePackageManager(targets, userId);
|
// Send configuration changed events for all target packages that have been affected
|
||||||
|
// by overlay state changes.
|
||||||
updateActivityManager(affectedPackages, userId);
|
updateActivityManager(affectedPackages, userId);
|
||||||
|
|
||||||
// Overlays targeting shared libraries may cause more packages to need to be
|
// Do not send broadcasts for all affected targets. Overlays targeting the framework
|
||||||
// refreshed.
|
// or shared libraries may cause too many broadcasts to be sent at once.
|
||||||
broadcastActionOverlayChanged(targets, userId);
|
broadcastActionOverlayChanged(targets, userId);
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -1430,20 +1399,17 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
|
|
||||||
private static void broadcastActionOverlayChanged(@NonNull final Set<String> targetPackages,
|
private static void broadcastActionOverlayChanged(@NonNull final Set<String> targetPackages,
|
||||||
final int userId) {
|
final int userId) {
|
||||||
CollectionUtils.forEach(targetPackages,
|
CollectionUtils.forEach(targetPackages, target -> {
|
||||||
target -> broadcastActionOverlayChanged(target, userId));
|
final Intent intent = new Intent(ACTION_OVERLAY_CHANGED,
|
||||||
}
|
Uri.fromParts("package", target, null));
|
||||||
|
intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
|
||||||
private static void broadcastActionOverlayChanged(String targetPackage, final int userId) {
|
try {
|
||||||
final Intent intent = new Intent(ACTION_OVERLAY_CHANGED,
|
ActivityManager.getService().broadcastIntent(null, intent, null, null, 0, null,
|
||||||
Uri.fromParts("package", targetPackage, null));
|
null, null, android.app.AppOpsManager.OP_NONE, null, false, false, userId);
|
||||||
intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
|
} catch (RemoteException e) {
|
||||||
try {
|
Slog.e(TAG, "broadcastActionOverlayChanged remote exception", e);
|
||||||
ActivityManager.getService().broadcastIntent(null, intent, null, null, 0, null, null,
|
}
|
||||||
null, android.app.AppOpsManager.OP_NONE, null, false, false, userId);
|
});
|
||||||
} catch (RemoteException e) {
|
|
||||||
// Intentionally left empty.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1455,18 +1421,13 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
try {
|
try {
|
||||||
am.scheduleApplicationInfoChanged(targetPackageNames, userId);
|
am.scheduleApplicationInfoChanged(targetPackageNames, userId);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// Intentionally left empty.
|
Slog.e(TAG, "updateActivityManager remote exception", e);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateActivityManager(@NonNull SparseArray<List<String>> targetPackageNames) {
|
|
||||||
for (int i = 0, n = targetPackageNames.size(); i < n; i++) {
|
|
||||||
updateActivityManager(targetPackageNames.valueAt(i), targetPackageNames.keyAt(i));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private SparseArray<List<String>> updatePackageManager(@Nullable Set<PackageAndUser> targets) {
|
private SparseArray<List<String>> updatePackageManagerLocked(
|
||||||
|
@Nullable Set<PackageAndUser> targets) {
|
||||||
if (CollectionUtils.isEmpty(targets)) {
|
if (CollectionUtils.isEmpty(targets)) {
|
||||||
return new SparseArray<>();
|
return new SparseArray<>();
|
||||||
}
|
}
|
||||||
@@ -1474,7 +1435,7 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
final SparseArray<ArraySet<String>> userTargets = groupTargetsByUserId(targets);
|
final SparseArray<ArraySet<String>> userTargets = groupTargetsByUserId(targets);
|
||||||
for (int i = 0, n = userTargets.size(); i < n; i++) {
|
for (int i = 0, n = userTargets.size(); i < n; i++) {
|
||||||
final int userId = userTargets.keyAt(i);
|
final int userId = userTargets.keyAt(i);
|
||||||
affectedTargets.put(userId, updatePackageManager(userTargets.valueAt(i), userId));
|
affectedTargets.put(userId, updatePackageManagerLocked(userTargets.valueAt(i), userId));
|
||||||
}
|
}
|
||||||
return affectedTargets;
|
return affectedTargets;
|
||||||
}
|
}
|
||||||
@@ -1485,10 +1446,10 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
* targetPackageNames: the target themselves and shared libraries)
|
* targetPackageNames: the target themselves and shared libraries)
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
private List<String> updatePackageManager(@NonNull Collection<String> targetPackageNames,
|
private List<String> updatePackageManagerLocked(@NonNull Collection<String> targetPackageNames,
|
||||||
final int userId) {
|
final int userId) {
|
||||||
try {
|
try {
|
||||||
traceBegin(TRACE_TAG_RRO, "OMS#updatePackageManager " + targetPackageNames);
|
traceBegin(TRACE_TAG_RRO, "OMS#updatePackageManagerLocked " + targetPackageNames);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "Update package manager about changed overlays");
|
Slog.d(TAG, "Update package manager about changed overlays");
|
||||||
}
|
}
|
||||||
@@ -1535,20 +1496,18 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void persistSettings() {
|
private void persistSettingsLocked() {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "Writing overlay settings");
|
Slog.d(TAG, "Writing overlay settings");
|
||||||
}
|
}
|
||||||
synchronized (mLock) {
|
FileOutputStream stream = null;
|
||||||
FileOutputStream stream = null;
|
try {
|
||||||
try {
|
stream = mSettingsFile.startWrite();
|
||||||
stream = mSettingsFile.startWrite();
|
mSettings.persist(stream);
|
||||||
mSettings.persist(stream);
|
mSettingsFile.finishWrite(stream);
|
||||||
mSettingsFile.finishWrite(stream);
|
} catch (IOException | XmlPullParserException e) {
|
||||||
} catch (IOException | XmlPullParserException e) {
|
mSettingsFile.failWrite(stream);
|
||||||
mSettingsFile.failWrite(stream);
|
Slog.e(TAG, "failed to persist overlay state", e);
|
||||||
Slog.e(TAG, "failed to persist overlay state", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user