diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 4c23f3991c580..d824ea037c1eb 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -1125,7 +1125,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe continue; } targets.add(wc); - targets.mValidParticipants.add(wc); } ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " Initial targets: %s", targets.mArray); @@ -1143,15 +1142,17 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe private static void populateParentChanges(Targets targets, ArrayMap changes) { final ArrayList> intermediates = new ArrayList<>(); - for (int i = targets.mValidParticipants.size() - 1; i >= 0; --i) { - WindowContainer wc = targets.mValidParticipants.get(i); - // Go up if the participant has been represented by its parent. - while (targets.mArray.indexOfValue(wc) < 0 && wc.getParent() != null) { - wc = wc.getParent(); - } + // Make a copy to iterate because the original array may be modified. + final ArrayList> targetList = new ArrayList<>(targets.mArray.size()); + for (int i = targets.mArray.size() - 1; i >= 0; --i) { + targetList.add(targets.mArray.valueAt(i)); + } + for (int i = targetList.size() - 1; i >= 0; --i) { + final WindowContainer wc = targetList.get(i); // Wallpaper must belong to the top (regardless of how nested it is in DisplayAreas). final boolean skipIntermediateReports = isWallpaper(wc); intermediates.clear(); + boolean foundParentInTargets = false; // Collect the intermediate parents between target and top changed parent. for (WindowContainer p = wc.getParent(); p != null; p = p.getParent()) { final ChangeInfo parentChange = changes.get(p); @@ -1165,19 +1166,19 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe // The chain above the parent was processed. break; } - if (targets.mValidParticipants.contains(p)) { + if (targetList.contains(p)) { if (skipIntermediateReports) { changes.get(wc).mParent = p; } else { intermediates.add(p); } - // The parent reaches a participant. + foundParentInTargets = true; break; } else if (reportIfNotTop(p) && !skipIntermediateReports) { intermediates.add(p); } } - if (intermediates.isEmpty()) continue; + if (!foundParentInTargets || intermediates.isEmpty()) continue; // Add any always-report parents along the way. changes.get(wc).mParent = intermediates.get(0); for (int j = 0; j < intermediates.size() - 1; j++) { @@ -1655,8 +1656,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe private static class Targets { /** All targets. Its keys (depth) are sorted in ascending order naturally. */ final SparseArray> mArray = new SparseArray<>(); - /** The initial participants which have changes. */ - final ArrayList> mValidParticipants = new ArrayList<>(); /** The targets which were represented by their parent. */ private ArrayList> mRemovedTargets; private int mDepthFactor;