Merge "Do not update RM config with previous sequence" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-07-02 20:34:13 +00:00
committed by Android (Google) Code Review
2 changed files with 82 additions and 76 deletions

View File

@@ -1169,7 +1169,7 @@ public final class ActivityThread extends ClientTransactionHandler
} }
public void scheduleApplicationInfoChanged(ApplicationInfo ai) { public void scheduleApplicationInfoChanged(ApplicationInfo ai) {
mResourcesManager.updatePendingAppInfoUpdates(ai); mResourcesManager.appendPendingAppInfoUpdate(new String[]{ai.sourceDir}, ai);
mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai); mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai);
sendMessage(H.APPLICATION_INFO_CHANGED, ai); sendMessage(H.APPLICATION_INFO_CHANGED, ai);
} }
@@ -6001,16 +6001,12 @@ public final class ActivityThread extends ClientTransactionHandler
resApk = ref != null ? ref.get() : null; resApk = ref != null ? ref.get() : null;
} }
final String[] oldResDirs = new String[2];
if (apk != null) { if (apk != null) {
oldResDirs[0] = apk.getResDir();
final ArrayList<String> oldPaths = new ArrayList<>(); final ArrayList<String> oldPaths = new ArrayList<>();
LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths); LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths);
apk.updateApplicationInfo(ai, oldPaths); apk.updateApplicationInfo(ai, oldPaths);
} }
if (resApk != null) { if (resApk != null) {
oldResDirs[1] = resApk.getResDir();
final ArrayList<String> oldPaths = new ArrayList<>(); final ArrayList<String> oldPaths = new ArrayList<>();
LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths); LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths);
resApk.updateApplicationInfo(ai, oldPaths); resApk.updateApplicationInfo(ai, oldPaths);
@@ -6018,7 +6014,7 @@ public final class ActivityThread extends ClientTransactionHandler
synchronized (mResourcesManager) { synchronized (mResourcesManager) {
// Update all affected Resources objects to use new ResourcesImpl // Update all affected Resources objects to use new ResourcesImpl
mResourcesManager.applyNewResourceDirs(ai, oldResDirs); mResourcesManager.applyAllPendingAppInfoUpdates();
} }
} }
@@ -6274,7 +6270,9 @@ public final class ActivityThread extends ClientTransactionHandler
synchronized (mResourcesManager) { synchronized (mResourcesManager) {
// Update affected Resources objects to use new ResourcesImpl // Update affected Resources objects to use new ResourcesImpl
mResourcesManager.applyNewResourceDirs(aInfo, oldResDirs); mResourcesManager.appendPendingAppInfoUpdate(oldResDirs,
aInfo);
mResourcesManager.applyAllPendingAppInfoUpdates();
} }
} catch (RemoteException e) { } catch (RemoteException e) {
} }

View File

@@ -42,6 +42,7 @@ import android.util.ArrayMap;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.util.Pair;
import android.util.Slog; import android.util.Slog;
import android.view.Display; import android.view.Display;
import android.view.DisplayAdjustments; import android.view.DisplayAdjustments;
@@ -101,7 +102,7 @@ public class ResourcesManager {
* ApplicationInfo changes that need to be applied to Resources when the next configuration * ApplicationInfo changes that need to be applied to Resources when the next configuration
* change occurs. * change occurs.
*/ */
private ArrayList<ApplicationInfo> mPendingAppInfoUpdates; private ArrayList<Pair<String[], ApplicationInfo>> mPendingAppInfoUpdates;
/** /**
* A mapping of ResourceImpls and their configurations. These are heavy weight objects * A mapping of ResourceImpls and their configurations. These are heavy weight objects
@@ -1273,19 +1274,33 @@ public class ResourcesManager {
return newKey; return newKey;
} }
public void updatePendingAppInfoUpdates(@NonNull ApplicationInfo appInfo) { public void appendPendingAppInfoUpdate(@NonNull String[] oldSourceDirs,
@NonNull ApplicationInfo appInfo) {
synchronized (mLock) { synchronized (mLock) {
if (mPendingAppInfoUpdates == null) { if (mPendingAppInfoUpdates == null) {
mPendingAppInfoUpdates = new ArrayList<>(); mPendingAppInfoUpdates = new ArrayList<>();
} }
// Clear previous app info changes for the package to prevent multiple ResourcesImpl // Clear previous app info changes for a package to prevent multiple ResourcesImpl
// recreations when only the last recreation will be used. // recreations when the recreation caused by this update completely overrides the
// previous pending changes.
for (int i = mPendingAppInfoUpdates.size() - 1; i >= 0; i--) { for (int i = mPendingAppInfoUpdates.size() - 1; i >= 0; i--) {
if (appInfo.sourceDir.equals(mPendingAppInfoUpdates.get(i).sourceDir)) { if (ArrayUtils.containsAll(oldSourceDirs, mPendingAppInfoUpdates.get(i).first)) {
mPendingAppInfoUpdates.remove(i); mPendingAppInfoUpdates.remove(i);
} }
} }
mPendingAppInfoUpdates.add(appInfo); mPendingAppInfoUpdates.add(new Pair<>(oldSourceDirs, appInfo));
}
}
public final void applyAllPendingAppInfoUpdates() {
synchronized (mLock) {
if (mPendingAppInfoUpdates != null) {
for (int i = 0, n = mPendingAppInfoUpdates.size(); i < n; i++) {
final Pair<String[], ApplicationInfo> appInfo = mPendingAppInfoUpdates.get(i);
applyNewResourceDirsLocked(appInfo.first, appInfo.second);
}
mPendingAppInfoUpdates = null;
}
} }
} }
@@ -1302,18 +1317,7 @@ public class ResourcesManager {
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
"ResourcesManager#applyConfigurationToResources"); "ResourcesManager#applyConfigurationToResources");
final boolean assetsUpdated = mPendingAppInfoUpdates != null if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
&& config.assetsSeq > mResConfiguration.assetsSeq;
if (assetsUpdated) {
for (int i = 0, n = mPendingAppInfoUpdates.size(); i < n; i++) {
final ApplicationInfo appInfo = mPendingAppInfoUpdates.get(i);
applyNewResourceDirs(appInfo, new String[]{appInfo.sourceDir});
}
mPendingAppInfoUpdates = null;
}
if (!assetsUpdated && !mResConfiguration.isOtherSeqNewer(config)
&& compat == null) {
if (DEBUG || DEBUG_CONFIGURATION) { if (DEBUG || DEBUG_CONFIGURATION) {
Slog.v(TAG, "Skipping new config: curSeq=" Slog.v(TAG, "Skipping new config: curSeq="
+ mResConfiguration.seq + ", newSeq=" + config.seq); + mResConfiguration.seq + ", newSeq=" + config.seq);
@@ -1330,6 +1334,13 @@ public class ResourcesManager {
| ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE; | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
} }
// If a application info update was scheduled to occur in this process but has not
// occurred yet, apply it now so the resources objects will have updated paths when
// the assets sequence changes.
if ((changes & ActivityInfo.CONFIG_ASSETS_PATHS) != 0) {
applyAllPendingAppInfoUpdates();
}
DisplayMetrics displayMetrics = getDisplayMetrics(); DisplayMetrics displayMetrics = getDisplayMetrics();
if (adjustments != null) { if (adjustments != null) {
// Currently the only case where the adjustment takes effect is to simulate // Currently the only case where the adjustment takes effect is to simulate
@@ -1353,7 +1364,7 @@ public class ResourcesManager {
} }
} }
return assetsUpdated || changes != 0; return changes != 0;
} finally { } finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
} }
@@ -1440,61 +1451,58 @@ public class ResourcesManager {
} }
} }
// TODO(adamlesinski): Make this accept more than just overlay directories. private void applyNewResourceDirsLocked(@Nullable final String[] oldSourceDirs,
void applyNewResourceDirs(@NonNull final ApplicationInfo appInfo, @NonNull final ApplicationInfo appInfo) {
@Nullable final String[] oldPaths) { try {
synchronized (mLock) { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
try { "ResourcesManager#applyNewResourceDirsLocked");
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
"ResourcesManager#applyNewResourceDirsLocked");
String baseCodePath = appInfo.getBaseCodePath(); String baseCodePath = appInfo.getBaseCodePath();
final int myUid = Process.myUid(); final int myUid = Process.myUid();
String[] newSplitDirs = appInfo.uid == myUid String[] newSplitDirs = appInfo.uid == myUid
? appInfo.splitSourceDirs ? appInfo.splitSourceDirs
: appInfo.splitPublicSourceDirs; : appInfo.splitPublicSourceDirs;
// ApplicationInfo is mutable, so clone the arrays to prevent outside modification // ApplicationInfo is mutable, so clone the arrays to prevent outside modification
String[] copiedSplitDirs = ArrayUtils.cloneOrNull(newSplitDirs); String[] copiedSplitDirs = ArrayUtils.cloneOrNull(newSplitDirs);
String[] copiedResourceDirs = combinedOverlayPaths(appInfo.resourceDirs, String[] copiedResourceDirs = combinedOverlayPaths(appInfo.resourceDirs,
appInfo.overlayPaths); appInfo.overlayPaths);
if (appInfo.uid == myUid) { if (appInfo.uid == myUid) {
addApplicationPathsLocked(baseCodePath, copiedSplitDirs); addApplicationPathsLocked(baseCodePath, copiedSplitDirs);
}
final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>();
final int implCount = mResourceImpls.size();
for (int i = 0; i < implCount; i++) {
final ResourcesKey key = mResourceImpls.keyAt(i);
final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
if (impl == null) {
continue;
}
if (key.mResDir == null
|| key.mResDir.equals(baseCodePath)
|| ArrayUtils.contains(oldPaths, key.mResDir)) {
updatedResourceKeys.put(impl, new ResourcesKey(
baseCodePath,
copiedSplitDirs,
copiedResourceDirs,
key.mLibDirs,
key.mDisplayId,
key.mOverrideConfiguration,
key.mCompatInfo,
key.mLoaders
));
}
}
redirectResourcesToNewImplLocked(updatedResourceKeys);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
} }
final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>();
final int implCount = mResourceImpls.size();
for (int i = 0; i < implCount; i++) {
final ResourcesKey key = mResourceImpls.keyAt(i);
final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
if (impl == null) {
continue;
}
if (key.mResDir == null
|| key.mResDir.equals(baseCodePath)
|| ArrayUtils.contains(oldSourceDirs, key.mResDir)) {
updatedResourceKeys.put(impl, new ResourcesKey(
baseCodePath,
copiedSplitDirs,
copiedResourceDirs,
key.mLibDirs,
key.mDisplayId,
key.mOverrideConfiguration,
key.mCompatInfo,
key.mLoaders
));
}
}
redirectResourcesToNewImplLocked(updatedResourceKeys);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
} }
} }