Loading data/etc/services.core.protolog.json +50 −38 Original line number Diff line number Diff line Loading @@ -121,6 +121,12 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-1973119651": { "message": "SyncGroup %d: Adding to group: %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "-1963461591": { "message": "Removing %s from %s", "level": "VERBOSE", Loading Loading @@ -157,14 +163,20 @@ "group": "WM_DEBUG_STARTING_WINDOW", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "-1918702467": { "message": "onSyncFinishedDrawing %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/WindowContainer.java" }, "-1915280162": { "message": "Attempted to add wallpaper window with bad token %s. Aborting.", "level": "WARN", "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-1910833551": { "message": "SyncSet{%x:%d} Start for %s", "-1905191109": { "message": "SyncGroup %d: Finished!", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" Loading Loading @@ -607,12 +619,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-1387080937": { "message": "SyncSet{%x:%d} Child ready, now ready=%b and waiting on %d transactions", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "-1376035390": { "message": "No task found", "level": "DEBUG", Loading Loading @@ -643,12 +649,6 @@ "group": "WM_DEBUG_BOOT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-1340783230": { "message": "SyncSet{%x:%d} Added %s. now waiting on %d transactions", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "-1340540100": { "message": "Creating SnapshotStartingData", "level": "VERBOSE", Loading Loading @@ -1177,12 +1177,6 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DragState.java" }, "-678300709": { "message": "SyncSet{%x:%d} Trying to add %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "-677449371": { "message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b", "level": "DEBUG", Loading Loading @@ -1591,6 +1585,12 @@ "group": "WM_DEBUG_STATES", "at": "com\/android\/server\/wm\/Task.java" }, "-230587670": { "message": "SyncGroup %d: Unfinished container: %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "-198463978": { "message": "updateRotationUnchecked: alwaysSendConfiguration=%b forceRelayout=%b", "level": "VERBOSE", Loading Loading @@ -2089,6 +2089,12 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "371173718": { "message": "finishSync cancel=%b for %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/WindowContainer.java" }, "371641947": { "message": "Window Manager Crash %s", "level": "WTF", Loading Loading @@ -2233,6 +2239,12 @@ "group": "WM_DEBUG_BOOT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "550717438": { "message": "SyncGroup %d: Started for listener: %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "556758086": { "message": "Applying new update lock state '%s' for %s", "level": "DEBUG", Loading Loading @@ -2269,12 +2281,6 @@ "group": "WM_DEBUG_IME", "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java" }, "590184240": { "message": "- NOT adding to sync: visible=%b hasListener=%b", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/WindowContainer.java" }, "594260577": { "message": "createWallpaperAnimations()", "level": "DEBUG", Loading Loading @@ -2599,6 +2605,18 @@ "group": "WM_DEBUG_LOCKTASK", "at": "com\/android\/server\/wm\/LockTaskController.java" }, "959486822": { "message": "setSyncGroup #%d on %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/WindowContainer.java" }, "966569777": { "message": "SyncGroup %d: onSurfacePlacement checking %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "969323241": { "message": "Sending new config to %s, config: %s", "level": "VERBOSE", Loading @@ -2623,12 +2641,6 @@ "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, "1000601037": { "message": "SyncSet{%x:%d} Set ready", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "1001509841": { "message": "Auto-PIP allowed, entering PIP mode directly: %s", "level": "DEBUG", Loading Loading @@ -3163,6 +3175,12 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "1689989893": { "message": "SyncGroup %d: Set ready", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "1696210756": { "message": "Launch on display check: allow launch on public display", "level": "DEBUG", Loading Loading @@ -3391,12 +3409,6 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "2001924866": { "message": "SyncSet{%x:%d} Finished. Reporting %d containers to %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "2016061474": { "message": "Prepare app transition: transit=%s %s alwaysKeepCurrent=%b displayId=%d Callers=%s", "level": "VERBOSE", Loading services/core/java/com/android/server/wm/ActivityRecord.java +13 −0 Original line number Diff line number Diff line Loading @@ -7878,4 +7878,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A pictureInPictureArgs.copyOnlySet(p); getTask().getRootTask().onPictureInPictureParamsChanged(); } @Override boolean isSyncFinished() { if (!super.isSyncFinished()) return false; if (!isVisibleRequested()) return true; // If visibleRequested, wait for at-least one visible child. for (int i = mChildren.size() - 1; i >= 0; --i) { if (mChildren.get(i).isVisibleRequested()) { return true; } } return false; } } services/core/java/com/android/server/wm/BLASTSyncEngine.java +89 −61 Original line number Diff line number Diff line Loading @@ -18,13 +18,13 @@ package com.android.server.wm; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SYNC_ENGINE; import android.util.ArrayMap; import android.annotation.NonNull; import android.util.ArraySet; import android.util.SparseArray; import android.view.SurfaceControl; import com.android.internal.protolog.common.ProtoLog; import java.util.Set; /** * Utility class for collecting WindowContainers that will merge transactions. * For example to use to synchronously resize all the children of a window container Loading @@ -45,94 +45,122 @@ import java.util.Set; * 5. If there were no sub windows anywhere in the hierarchy to wait on, then * transactionReady is immediately invoked, otherwise all the windows are poked * to redraw and to deliver a buffer to {@link WindowState#finishDrawing}. * Once all this drawing is complete the WindowContainer that's ready will be added to the * set of ready WindowContainers. When the final onTransactionReady is called, it will merge * the transactions of the all the WindowContainers and will be delivered to the * TransactionReadyListener * Once all this drawing is complete, all the transactions will be merged and delivered * to TransactionReadyListener. * * This works primarily by setting-up state and then watching/waiting for the registered subtrees * to enter into a "finished" state (either by receiving drawn content or by disappearing). This * checks the subtrees during surface-placement. */ class BLASTSyncEngine { private static final String TAG = "BLASTSyncEngine"; interface TransactionReadyListener { void onTransactionReady(int mSyncId, Set<WindowContainer> windowContainersReady); }; // Holds state associated with a single synchronous set of operations. class SyncState implements TransactionReadyListener { int mSyncId; int mRemainingTransactions; TransactionReadyListener mListener; void onTransactionReady(int mSyncId, SurfaceControl.Transaction transaction); } /** * Holds state associated with a single synchronous set of operations. */ class SyncGroup { final int mSyncId; final TransactionReadyListener mListener; boolean mReady = false; Set<WindowContainer> mWindowContainersReady = new ArraySet<>(); final ArraySet<WindowContainer> mRootMembers = new ArraySet<>(); private SurfaceControl.Transaction mOrphanTransaction = null; private void tryFinish() { if (mRemainingTransactions == 0 && mReady) { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Finished. Reporting %d " + "containers to %s", BLASTSyncEngine.this.hashCode(), mSyncId, mWindowContainersReady.size(), mListener); mListener.onTransactionReady(mSyncId, mWindowContainersReady); mPendingSyncs.remove(mSyncId); private SyncGroup(TransactionReadyListener listener, int id) { mSyncId = id; mListener = listener; } /** * Gets a transaction to dump orphaned operations into. Orphaned operations are operations * that were on the mSyncTransactions of "root" subtrees which have been removed during the * sync period. */ @NonNull SurfaceControl.Transaction getOrphanTransaction() { if (mOrphanTransaction == null) { // Lazy since this isn't common mOrphanTransaction = mWm.mTransactionFactory.get(); } return mOrphanTransaction; } public void onTransactionReady(int syncId, Set<WindowContainer> windowContainersReady) { mRemainingTransactions--; ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Child ready, now ready=%b" + " and waiting on %d transactions", BLASTSyncEngine.this.hashCode(), mSyncId, mReady, mRemainingTransactions); mWindowContainersReady.addAll(windowContainersReady); tryFinish(); private void onSurfacePlacement() { if (!mReady) return; ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: onSurfacePlacement checking %s", mSyncId, mRootMembers); for (int i = mRootMembers.size() - 1; i >= 0; --i) { final WindowContainer wc = mRootMembers.valueAt(i); if (!wc.isSyncFinished()) { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Unfinished container: %s", mSyncId, wc); return; } } ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Finished!", mSyncId); SurfaceControl.Transaction merged = mWm.mTransactionFactory.get(); if (mOrphanTransaction != null) { merged.merge(mOrphanTransaction); } for (WindowContainer wc : mRootMembers) { wc.finishSync(merged, false /* cancel */); } mListener.onTransactionReady(mSyncId, merged); mActiveSyncs.remove(mSyncId); } void setReady() { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Set ready", BLASTSyncEngine.this.hashCode(), mSyncId); private void setReady() { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Set ready", mSyncId); mReady = true; tryFinish(); mWm.mWindowPlacerLocked.requestTraversal(); } boolean addToSync(WindowContainer wc) { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Trying to add %s", BLASTSyncEngine.this.hashCode(), mSyncId, wc); if (wc.prepareForSync(this, mSyncId)) { mRemainingTransactions++; ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Added %s. now waiting " + "on %d transactions", BLASTSyncEngine.this.hashCode(), mSyncId, wc, mRemainingTransactions); return true; private void addToSync(WindowContainer wc) { if (!mRootMembers.add(wc)) { return; } return false; ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Adding to group: %s", mSyncId, wc); wc.setSyncGroup(this); wc.prepareSync(); mWm.mWindowPlacerLocked.requestTraversal(); } SyncState(TransactionReadyListener l, int id) { mListener = l; mSyncId = id; mRemainingTransactions = 0; void onCancelSync(WindowContainer wc) { mRootMembers.remove(wc); } } }; private final WindowManagerService mWm; private int mNextSyncId = 0; private final SparseArray<SyncGroup> mActiveSyncs = new SparseArray<>(); private final ArrayMap<Integer, SyncState> mPendingSyncs = new ArrayMap<>(); BLASTSyncEngine() { BLASTSyncEngine(WindowManagerService wms) { mWm = wms; } int startSyncSet(TransactionReadyListener listener) { final int id = mNextSyncId++; final SyncState s = new SyncState(listener, id); mPendingSyncs.put(id, s); ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Start for %s", hashCode(), id, listener); final SyncGroup s = new SyncGroup(listener, id); mActiveSyncs.put(id, s); ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Started for listener: %s", id, listener); return id; } boolean addToSyncSet(int id, WindowContainer wc) { final SyncState st = mPendingSyncs.get(id); return st.addToSync(wc); void addToSyncSet(int id, WindowContainer wc) { mActiveSyncs.get(id).addToSync(wc); } void setReady(int id) { final SyncState st = mPendingSyncs.get(id); st.setReady(); mActiveSyncs.get(id).setReady(); } void onSurfacePlacement() { // backwards since each state can remove itself if finished for (int i = mActiveSyncs.size() - 1; i >= 0; --i) { mActiveSyncs.valueAt(i).onSurfacePlacement(); } } } services/core/java/com/android/server/wm/RootWindowContainer.java +1 −0 Original line number Diff line number Diff line Loading @@ -863,6 +863,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> mWmService.openSurfaceTransaction(); try { applySurfaceChangesTransaction(); mWmService.mSyncEngine.onSurfacePlacement(); } catch (RuntimeException e) { Slog.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { Loading services/core/java/com/android/server/wm/Transition.java +12 −16 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; Loading @@ -31,7 +32,6 @@ import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.view.Display; import android.view.SurfaceControl; import android.view.WindowManager; import android.view.animation.Animation; Loading @@ -43,7 +43,6 @@ import com.android.internal.protolog.common.ProtoLog; import java.util.ArrayList; import java.util.Map; import java.util.Set; /** * Represents a logical transition. Loading @@ -70,6 +69,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe private int mSyncId; private @WindowManager.TransitionFlags int mFlags; private final TransitionController mController; private final BLASTSyncEngine mSyncEngine; final ArrayMap<WindowContainer, ChangeInfo> mParticipants = new ArrayMap<>(); private int mState = STATE_COLLECTING; private boolean mReadyCalled = false; Loading @@ -79,7 +79,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe mType = type; mFlags = flags; mController = controller; mSyncId = mController.mSyncEngine.startSyncSet(this); mSyncEngine = mController.mAtm.mWindowManager.mSyncEngine; mSyncId = mSyncEngine.startSyncSet(this); } /** Loading @@ -104,10 +105,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe if (mSyncId < 0) return; ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Collecting in transition %d: %s", mSyncId, wc); // Add to sync set before checking contains because it may not have added it at other // times (eg. if wc was previously invisible). mController.mSyncEngine.addToSyncSet(mSyncId, wc); if (mParticipants.containsKey(wc)) return; mSyncEngine.addToSyncSet(mSyncId, wc); mParticipants.put(wc, new ChangeInfo()); } Loading @@ -125,8 +124,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Finish collecting in transition %d", mSyncId); mController.mSyncEngine.setReady(mSyncId); mController.mAtm.mWindowManager.mWindowPlacerLocked.requestTraversal(); mSyncEngine.setReady(mSyncId); } /** The transition has finished animating and is ready to finalize WM state */ Loading @@ -146,7 +144,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } @Override public void onTransactionReady(int syncId, Set<WindowContainer> windowContainersReady) { public void onTransactionReady(int syncId, SurfaceControl.Transaction transaction) { if (syncId != mSyncId) { Slog.e(TAG, "Unexpected Sync ID " + syncId + ". Expected " + mSyncId); return; Loading @@ -155,10 +153,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe mController.moveToPlaying(this); final TransitionInfo info = calculateTransitionInfo(mType, mParticipants); SurfaceControl.Transaction mergedTransaction = new SurfaceControl.Transaction(); int displayId = Display.DEFAULT_DISPLAY; for (WindowContainer container : windowContainersReady) { container.mergeBlastSyncTransaction(mergedTransaction); int displayId = DEFAULT_DISPLAY; for (WindowContainer container : mParticipants.keySet()) { displayId = container.mDisplayContent.getDisplayId(); } Loading @@ -168,14 +164,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe try { ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Calling onTransitionReady: %s", info); mController.getTransitionPlayer().onTransitionReady(this, info, mergedTransaction); mController.getTransitionPlayer().onTransitionReady(this, info, transaction); } catch (RemoteException e) { // If there's an exception when trying to send the mergedTransaction to the // client, we should immediately apply it here so the transactions aren't lost. mergedTransaction.apply(); transaction.apply(); } } else { mergedTransaction.apply(); transaction.apply(); } mSyncId = -1; } Loading Loading
data/etc/services.core.protolog.json +50 −38 Original line number Diff line number Diff line Loading @@ -121,6 +121,12 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-1973119651": { "message": "SyncGroup %d: Adding to group: %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "-1963461591": { "message": "Removing %s from %s", "level": "VERBOSE", Loading Loading @@ -157,14 +163,20 @@ "group": "WM_DEBUG_STARTING_WINDOW", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "-1918702467": { "message": "onSyncFinishedDrawing %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/WindowContainer.java" }, "-1915280162": { "message": "Attempted to add wallpaper window with bad token %s. Aborting.", "level": "WARN", "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-1910833551": { "message": "SyncSet{%x:%d} Start for %s", "-1905191109": { "message": "SyncGroup %d: Finished!", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" Loading Loading @@ -607,12 +619,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-1387080937": { "message": "SyncSet{%x:%d} Child ready, now ready=%b and waiting on %d transactions", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "-1376035390": { "message": "No task found", "level": "DEBUG", Loading Loading @@ -643,12 +649,6 @@ "group": "WM_DEBUG_BOOT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-1340783230": { "message": "SyncSet{%x:%d} Added %s. now waiting on %d transactions", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "-1340540100": { "message": "Creating SnapshotStartingData", "level": "VERBOSE", Loading Loading @@ -1177,12 +1177,6 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DragState.java" }, "-678300709": { "message": "SyncSet{%x:%d} Trying to add %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "-677449371": { "message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b", "level": "DEBUG", Loading Loading @@ -1591,6 +1585,12 @@ "group": "WM_DEBUG_STATES", "at": "com\/android\/server\/wm\/Task.java" }, "-230587670": { "message": "SyncGroup %d: Unfinished container: %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "-198463978": { "message": "updateRotationUnchecked: alwaysSendConfiguration=%b forceRelayout=%b", "level": "VERBOSE", Loading Loading @@ -2089,6 +2089,12 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "371173718": { "message": "finishSync cancel=%b for %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/WindowContainer.java" }, "371641947": { "message": "Window Manager Crash %s", "level": "WTF", Loading Loading @@ -2233,6 +2239,12 @@ "group": "WM_DEBUG_BOOT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "550717438": { "message": "SyncGroup %d: Started for listener: %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "556758086": { "message": "Applying new update lock state '%s' for %s", "level": "DEBUG", Loading Loading @@ -2269,12 +2281,6 @@ "group": "WM_DEBUG_IME", "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java" }, "590184240": { "message": "- NOT adding to sync: visible=%b hasListener=%b", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/WindowContainer.java" }, "594260577": { "message": "createWallpaperAnimations()", "level": "DEBUG", Loading Loading @@ -2599,6 +2605,18 @@ "group": "WM_DEBUG_LOCKTASK", "at": "com\/android\/server\/wm\/LockTaskController.java" }, "959486822": { "message": "setSyncGroup #%d on %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/WindowContainer.java" }, "966569777": { "message": "SyncGroup %d: onSurfacePlacement checking %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "969323241": { "message": "Sending new config to %s, config: %s", "level": "VERBOSE", Loading @@ -2623,12 +2641,6 @@ "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, "1000601037": { "message": "SyncSet{%x:%d} Set ready", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "1001509841": { "message": "Auto-PIP allowed, entering PIP mode directly: %s", "level": "DEBUG", Loading Loading @@ -3163,6 +3175,12 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "1689989893": { "message": "SyncGroup %d: Set ready", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "1696210756": { "message": "Launch on display check: allow launch on public display", "level": "DEBUG", Loading Loading @@ -3391,12 +3409,6 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, "2001924866": { "message": "SyncSet{%x:%d} Finished. Reporting %d containers to %s", "level": "VERBOSE", "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, "2016061474": { "message": "Prepare app transition: transit=%s %s alwaysKeepCurrent=%b displayId=%d Callers=%s", "level": "VERBOSE", Loading
services/core/java/com/android/server/wm/ActivityRecord.java +13 −0 Original line number Diff line number Diff line Loading @@ -7878,4 +7878,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A pictureInPictureArgs.copyOnlySet(p); getTask().getRootTask().onPictureInPictureParamsChanged(); } @Override boolean isSyncFinished() { if (!super.isSyncFinished()) return false; if (!isVisibleRequested()) return true; // If visibleRequested, wait for at-least one visible child. for (int i = mChildren.size() - 1; i >= 0; --i) { if (mChildren.get(i).isVisibleRequested()) { return true; } } return false; } }
services/core/java/com/android/server/wm/BLASTSyncEngine.java +89 −61 Original line number Diff line number Diff line Loading @@ -18,13 +18,13 @@ package com.android.server.wm; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SYNC_ENGINE; import android.util.ArrayMap; import android.annotation.NonNull; import android.util.ArraySet; import android.util.SparseArray; import android.view.SurfaceControl; import com.android.internal.protolog.common.ProtoLog; import java.util.Set; /** * Utility class for collecting WindowContainers that will merge transactions. * For example to use to synchronously resize all the children of a window container Loading @@ -45,94 +45,122 @@ import java.util.Set; * 5. If there were no sub windows anywhere in the hierarchy to wait on, then * transactionReady is immediately invoked, otherwise all the windows are poked * to redraw and to deliver a buffer to {@link WindowState#finishDrawing}. * Once all this drawing is complete the WindowContainer that's ready will be added to the * set of ready WindowContainers. When the final onTransactionReady is called, it will merge * the transactions of the all the WindowContainers and will be delivered to the * TransactionReadyListener * Once all this drawing is complete, all the transactions will be merged and delivered * to TransactionReadyListener. * * This works primarily by setting-up state and then watching/waiting for the registered subtrees * to enter into a "finished" state (either by receiving drawn content or by disappearing). This * checks the subtrees during surface-placement. */ class BLASTSyncEngine { private static final String TAG = "BLASTSyncEngine"; interface TransactionReadyListener { void onTransactionReady(int mSyncId, Set<WindowContainer> windowContainersReady); }; // Holds state associated with a single synchronous set of operations. class SyncState implements TransactionReadyListener { int mSyncId; int mRemainingTransactions; TransactionReadyListener mListener; void onTransactionReady(int mSyncId, SurfaceControl.Transaction transaction); } /** * Holds state associated with a single synchronous set of operations. */ class SyncGroup { final int mSyncId; final TransactionReadyListener mListener; boolean mReady = false; Set<WindowContainer> mWindowContainersReady = new ArraySet<>(); final ArraySet<WindowContainer> mRootMembers = new ArraySet<>(); private SurfaceControl.Transaction mOrphanTransaction = null; private void tryFinish() { if (mRemainingTransactions == 0 && mReady) { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Finished. Reporting %d " + "containers to %s", BLASTSyncEngine.this.hashCode(), mSyncId, mWindowContainersReady.size(), mListener); mListener.onTransactionReady(mSyncId, mWindowContainersReady); mPendingSyncs.remove(mSyncId); private SyncGroup(TransactionReadyListener listener, int id) { mSyncId = id; mListener = listener; } /** * Gets a transaction to dump orphaned operations into. Orphaned operations are operations * that were on the mSyncTransactions of "root" subtrees which have been removed during the * sync period. */ @NonNull SurfaceControl.Transaction getOrphanTransaction() { if (mOrphanTransaction == null) { // Lazy since this isn't common mOrphanTransaction = mWm.mTransactionFactory.get(); } return mOrphanTransaction; } public void onTransactionReady(int syncId, Set<WindowContainer> windowContainersReady) { mRemainingTransactions--; ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Child ready, now ready=%b" + " and waiting on %d transactions", BLASTSyncEngine.this.hashCode(), mSyncId, mReady, mRemainingTransactions); mWindowContainersReady.addAll(windowContainersReady); tryFinish(); private void onSurfacePlacement() { if (!mReady) return; ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: onSurfacePlacement checking %s", mSyncId, mRootMembers); for (int i = mRootMembers.size() - 1; i >= 0; --i) { final WindowContainer wc = mRootMembers.valueAt(i); if (!wc.isSyncFinished()) { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Unfinished container: %s", mSyncId, wc); return; } } ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Finished!", mSyncId); SurfaceControl.Transaction merged = mWm.mTransactionFactory.get(); if (mOrphanTransaction != null) { merged.merge(mOrphanTransaction); } for (WindowContainer wc : mRootMembers) { wc.finishSync(merged, false /* cancel */); } mListener.onTransactionReady(mSyncId, merged); mActiveSyncs.remove(mSyncId); } void setReady() { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Set ready", BLASTSyncEngine.this.hashCode(), mSyncId); private void setReady() { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Set ready", mSyncId); mReady = true; tryFinish(); mWm.mWindowPlacerLocked.requestTraversal(); } boolean addToSync(WindowContainer wc) { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Trying to add %s", BLASTSyncEngine.this.hashCode(), mSyncId, wc); if (wc.prepareForSync(this, mSyncId)) { mRemainingTransactions++; ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Added %s. now waiting " + "on %d transactions", BLASTSyncEngine.this.hashCode(), mSyncId, wc, mRemainingTransactions); return true; private void addToSync(WindowContainer wc) { if (!mRootMembers.add(wc)) { return; } return false; ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Adding to group: %s", mSyncId, wc); wc.setSyncGroup(this); wc.prepareSync(); mWm.mWindowPlacerLocked.requestTraversal(); } SyncState(TransactionReadyListener l, int id) { mListener = l; mSyncId = id; mRemainingTransactions = 0; void onCancelSync(WindowContainer wc) { mRootMembers.remove(wc); } } }; private final WindowManagerService mWm; private int mNextSyncId = 0; private final SparseArray<SyncGroup> mActiveSyncs = new SparseArray<>(); private final ArrayMap<Integer, SyncState> mPendingSyncs = new ArrayMap<>(); BLASTSyncEngine() { BLASTSyncEngine(WindowManagerService wms) { mWm = wms; } int startSyncSet(TransactionReadyListener listener) { final int id = mNextSyncId++; final SyncState s = new SyncState(listener, id); mPendingSyncs.put(id, s); ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncSet{%x:%d} Start for %s", hashCode(), id, listener); final SyncGroup s = new SyncGroup(listener, id); mActiveSyncs.put(id, s); ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Started for listener: %s", id, listener); return id; } boolean addToSyncSet(int id, WindowContainer wc) { final SyncState st = mPendingSyncs.get(id); return st.addToSync(wc); void addToSyncSet(int id, WindowContainer wc) { mActiveSyncs.get(id).addToSync(wc); } void setReady(int id) { final SyncState st = mPendingSyncs.get(id); st.setReady(); mActiveSyncs.get(id).setReady(); } void onSurfacePlacement() { // backwards since each state can remove itself if finished for (int i = mActiveSyncs.size() - 1; i >= 0; --i) { mActiveSyncs.valueAt(i).onSurfacePlacement(); } } }
services/core/java/com/android/server/wm/RootWindowContainer.java +1 −0 Original line number Diff line number Diff line Loading @@ -863,6 +863,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> mWmService.openSurfaceTransaction(); try { applySurfaceChangesTransaction(); mWmService.mSyncEngine.onSurfacePlacement(); } catch (RuntimeException e) { Slog.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { Loading
services/core/java/com/android/server/wm/Transition.java +12 −16 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; Loading @@ -31,7 +32,6 @@ import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.view.Display; import android.view.SurfaceControl; import android.view.WindowManager; import android.view.animation.Animation; Loading @@ -43,7 +43,6 @@ import com.android.internal.protolog.common.ProtoLog; import java.util.ArrayList; import java.util.Map; import java.util.Set; /** * Represents a logical transition. Loading @@ -70,6 +69,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe private int mSyncId; private @WindowManager.TransitionFlags int mFlags; private final TransitionController mController; private final BLASTSyncEngine mSyncEngine; final ArrayMap<WindowContainer, ChangeInfo> mParticipants = new ArrayMap<>(); private int mState = STATE_COLLECTING; private boolean mReadyCalled = false; Loading @@ -79,7 +79,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe mType = type; mFlags = flags; mController = controller; mSyncId = mController.mSyncEngine.startSyncSet(this); mSyncEngine = mController.mAtm.mWindowManager.mSyncEngine; mSyncId = mSyncEngine.startSyncSet(this); } /** Loading @@ -104,10 +105,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe if (mSyncId < 0) return; ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Collecting in transition %d: %s", mSyncId, wc); // Add to sync set before checking contains because it may not have added it at other // times (eg. if wc was previously invisible). mController.mSyncEngine.addToSyncSet(mSyncId, wc); if (mParticipants.containsKey(wc)) return; mSyncEngine.addToSyncSet(mSyncId, wc); mParticipants.put(wc, new ChangeInfo()); } Loading @@ -125,8 +124,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Finish collecting in transition %d", mSyncId); mController.mSyncEngine.setReady(mSyncId); mController.mAtm.mWindowManager.mWindowPlacerLocked.requestTraversal(); mSyncEngine.setReady(mSyncId); } /** The transition has finished animating and is ready to finalize WM state */ Loading @@ -146,7 +144,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } @Override public void onTransactionReady(int syncId, Set<WindowContainer> windowContainersReady) { public void onTransactionReady(int syncId, SurfaceControl.Transaction transaction) { if (syncId != mSyncId) { Slog.e(TAG, "Unexpected Sync ID " + syncId + ". Expected " + mSyncId); return; Loading @@ -155,10 +153,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe mController.moveToPlaying(this); final TransitionInfo info = calculateTransitionInfo(mType, mParticipants); SurfaceControl.Transaction mergedTransaction = new SurfaceControl.Transaction(); int displayId = Display.DEFAULT_DISPLAY; for (WindowContainer container : windowContainersReady) { container.mergeBlastSyncTransaction(mergedTransaction); int displayId = DEFAULT_DISPLAY; for (WindowContainer container : mParticipants.keySet()) { displayId = container.mDisplayContent.getDisplayId(); } Loading @@ -168,14 +164,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe try { ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Calling onTransitionReady: %s", info); mController.getTransitionPlayer().onTransitionReady(this, info, mergedTransaction); mController.getTransitionPlayer().onTransitionReady(this, info, transaction); } catch (RemoteException e) { // If there's an exception when trying to send the mergedTransaction to the // client, we should immediately apply it here so the transactions aren't lost. mergedTransaction.apply(); transaction.apply(); } } else { mergedTransaction.apply(); transaction.apply(); } mSyncId = -1; } Loading