Diff overlays between PackageManagerService and OverlayManagerService
When uninstalling an update to a system app, PMS re-creates the PackageSetting object, and OMS doesn't get notified of the change. This makes OMS diff the known valid overlays with the resourceDirs in the target's ApplicationInfo and forces a reload when they disagree. Bug: 124363683 Test: manual ran Wellbeing reproduction steps in bug Change-Id: Ib080d8593d12596ae8f8a729cc9740462c4b9b69
This commit is contained in:
@@ -44,7 +44,7 @@ public final class OverlayInfo implements Parcelable {
|
||||
STATE_DISABLED,
|
||||
STATE_ENABLED,
|
||||
STATE_ENABLED_STATIC,
|
||||
STATE_TARGET_UPGRADING,
|
||||
// @Deprecated STATE_TARGET_UPGRADING,
|
||||
STATE_OVERLAY_UPGRADING,
|
||||
})
|
||||
/** @hide */
|
||||
@@ -96,7 +96,14 @@ public final class OverlayInfo implements Parcelable {
|
||||
* The target package is currently being upgraded; the state will change
|
||||
* once the package installation has finished.
|
||||
* @hide
|
||||
*
|
||||
* @deprecated No longer used. Caused invalid transitions from enabled -> upgrading -> enabled,
|
||||
* where an update is propagated when nothing has changed. Can occur during --dont-kill
|
||||
* installs when code and resources are hot swapped and the Activity should not be relaunched.
|
||||
* In all other cases, the process and therefore Activity is killed, so the state loop is
|
||||
* irrelevant.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int STATE_TARGET_UPGRADING = 4;
|
||||
|
||||
/**
|
||||
|
||||
@@ -422,8 +422,6 @@ public final class OverlayManagerService extends SystemService {
|
||||
final OverlayInfo oi = mImpl.getOverlayInfo(packageName, userId);
|
||||
if (oi != null) {
|
||||
mImpl.onOverlayPackageUpgrading(packageName, userId);
|
||||
} else {
|
||||
mImpl.onTargetPackageUpgrading(packageName, userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import static android.content.om.OverlayInfo.STATE_ENABLED_STATIC;
|
||||
import static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
|
||||
import static android.content.om.OverlayInfo.STATE_NO_IDMAP;
|
||||
import static android.content.om.OverlayInfo.STATE_OVERLAY_UPGRADING;
|
||||
import static android.content.om.OverlayInfo.STATE_TARGET_UPGRADING;
|
||||
|
||||
import static com.android.server.om.OverlayManagerService.DEBUG;
|
||||
import static com.android.server.om.OverlayManagerService.TAG;
|
||||
@@ -30,12 +29,15 @@ import static com.android.server.om.OverlayManagerService.TAG;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.om.OverlayInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
@@ -54,8 +56,14 @@ import java.util.Set;
|
||||
* @see OverlayManagerService
|
||||
*/
|
||||
final class OverlayManagerServiceImpl {
|
||||
// Flags to use in conjunction with updateState.
|
||||
|
||||
/**
|
||||
* @deprecated Not used. See {@link android.content.om.OverlayInfo#STATE_TARGET_UPGRADING}.
|
||||
*/
|
||||
@Deprecated
|
||||
private static final int FLAG_TARGET_IS_UPGRADING = 1 << 0;
|
||||
|
||||
// Flags to use in conjunction with updateState.
|
||||
private static final int FLAG_OVERLAY_IS_UPGRADING = 1 << 1;
|
||||
|
||||
private final PackageManagerHelper mPackageManager;
|
||||
@@ -247,9 +255,7 @@ final class OverlayManagerServiceImpl {
|
||||
Slog.d(TAG, "onTargetPackageAdded packageName=" + packageName + " userId=" + userId);
|
||||
}
|
||||
|
||||
if (updateAllOverlaysForTarget(packageName, userId, 0)) {
|
||||
mListener.onOverlaysChanged(packageName, userId);
|
||||
}
|
||||
updateAndRefreshOverlaysForTarget(packageName, userId, 0);
|
||||
}
|
||||
|
||||
void onTargetPackageChanged(@NonNull final String packageName, final int userId) {
|
||||
@@ -257,16 +263,7 @@ final class OverlayManagerServiceImpl {
|
||||
Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId);
|
||||
}
|
||||
|
||||
updateAllOverlaysForTarget(packageName, userId, 0);
|
||||
}
|
||||
|
||||
void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId="
|
||||
+ userId);
|
||||
}
|
||||
|
||||
updateAllOverlaysForTarget(packageName, userId, FLAG_TARGET_IS_UPGRADING);
|
||||
updateAndRefreshOverlaysForTarget(packageName, userId, 0);
|
||||
}
|
||||
|
||||
void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) {
|
||||
@@ -274,7 +271,7 @@ final class OverlayManagerServiceImpl {
|
||||
Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId);
|
||||
}
|
||||
|
||||
updateAllOverlaysForTarget(packageName, userId, 0);
|
||||
updateAndRefreshOverlaysForTarget(packageName, userId, 0);
|
||||
}
|
||||
|
||||
void onTargetPackageRemoved(@NonNull final String packageName, final int userId) {
|
||||
@@ -282,22 +279,27 @@ final class OverlayManagerServiceImpl {
|
||||
Slog.d(TAG, "onTargetPackageRemoved packageName=" + packageName + " userId=" + userId);
|
||||
}
|
||||
|
||||
if (updateAllOverlaysForTarget(packageName, userId, 0)) {
|
||||
mListener.onOverlaysChanged(packageName, userId);
|
||||
}
|
||||
updateAndRefreshOverlaysForTarget(packageName, userId, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the state of any overlays for this target.
|
||||
*
|
||||
* Returns true if the system should refresh the app's overlay paths (i.e.
|
||||
* if the settings were modified for this target, or there is at least one
|
||||
* enabled framework overlay).
|
||||
*/
|
||||
private boolean updateAllOverlaysForTarget(@NonNull final String targetPackageName,
|
||||
private void updateAndRefreshOverlaysForTarget(@NonNull final String targetPackageName,
|
||||
final int userId, final int flags) {
|
||||
final List<OverlayInfo> ois = new ArrayList<>();
|
||||
|
||||
// Framework overlays added first because order matters when resolving a resource
|
||||
if (!"android".equals(targetPackageName)) {
|
||||
ois.addAll(mSettings.getOverlaysForTarget("android", userId));
|
||||
}
|
||||
|
||||
// Then add the targeted, non-framework overlays which have higher priority
|
||||
ois.addAll(mSettings.getOverlaysForTarget(targetPackageName, userId));
|
||||
|
||||
final List<String> enabledBaseCodePaths = new ArrayList<>(ois.size());
|
||||
|
||||
boolean modified = false;
|
||||
final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(targetPackageName, userId);
|
||||
final int n = ois.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
final OverlayInfo oi = ois.get(i);
|
||||
@@ -313,13 +315,35 @@ final class OverlayManagerServiceImpl {
|
||||
Slog.e(TAG, "failed to update settings", e);
|
||||
modified |= mSettings.remove(oi.packageName, userId);
|
||||
}
|
||||
|
||||
if (oi.isEnabled() && overlayPackage.applicationInfo != null) {
|
||||
enabledBaseCodePaths.add(overlayPackage.applicationInfo.getBaseCodePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for enabled framework overlays
|
||||
modified = modified || !getEnabledOverlayPackageNames("android", userId).isEmpty();
|
||||
if (!modified) {
|
||||
PackageInfo packageInfo = mPackageManager.getPackageInfo(targetPackageName, userId);
|
||||
ApplicationInfo appInfo = packageInfo == null ? null : packageInfo.applicationInfo;
|
||||
String[] resourceDirs = appInfo == null ? null : appInfo.resourceDirs;
|
||||
|
||||
return modified;
|
||||
// If the lists aren't the same length, the enabled overlays have changed
|
||||
if (ArrayUtils.size(resourceDirs) != enabledBaseCodePaths.size()) {
|
||||
modified = true;
|
||||
} else if (resourceDirs != null) {
|
||||
// If any element isn't equal, an overlay or the order of overlays has changed
|
||||
for (int index = 0; index < resourceDirs.length; index++) {
|
||||
if (!resourceDirs[index].equals(enabledBaseCodePaths.get(index))) {
|
||||
modified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
mListener.onOverlaysChanged(targetPackageName, userId);
|
||||
}
|
||||
}
|
||||
|
||||
void onOverlayPackageAdded(@NonNull final String packageName, final int userId) {
|
||||
@@ -670,10 +694,6 @@ final class OverlayManagerServiceImpl {
|
||||
@Nullable final PackageInfo overlayPackage, final int userId, final int flags)
|
||||
throws OverlayManagerSettings.BadKeyException {
|
||||
|
||||
if ((flags & FLAG_TARGET_IS_UPGRADING) != 0) {
|
||||
return STATE_TARGET_UPGRADING;
|
||||
}
|
||||
|
||||
if ((flags & FLAG_OVERLAY_IS_UPGRADING) != 0) {
|
||||
return STATE_OVERLAY_UPGRADING;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user