Loading services/core/java/com/android/server/wm/WindowOrganizerController.java +146 −138 Original line number Diff line number Diff line Loading @@ -104,13 +104,55 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub @Override public void applyTransaction(WindowContainerTransaction t) { applyTransaction(t, null /*callback*/, null /*transition*/); enforceTaskPermission("applyTransaction()"); if (t == null) { throw new IllegalArgumentException("Null transaction passed to applySyncTransaction"); } final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { applyTransaction(t, -1 /*syncId*/, null /*transition*/); } } finally { Binder.restoreCallingIdentity(ident); } } @Override public int applySyncTransaction(WindowContainerTransaction t, IWindowContainerTransactionCallback callback) { return applyTransaction(t, callback, null /*transition*/); enforceTaskPermission("applySyncTransaction()"); if (t == null) { throw new IllegalArgumentException("Null transaction passed to applySyncTransaction"); } final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { /** * If callback is non-null we are looking to synchronize this transaction by * collecting all the results in to a SurfaceFlinger transaction and then delivering * that to the given transaction ready callback. See {@link BLASTSyncEngine} for the * details of the operation. But at a high level we create a sync operation with a * given ID and an associated callback. Then we notify each WindowContainer in this * WindowContainer transaction that it is participating in a sync operation with * that ID. Once everything is notified we tell the BLASTSyncEngine "setSyncReady" * which means that we have added everything to the set. At any point after this, * all the WindowContainers will eventually finish applying their changes and notify * the BLASTSyncEngine which will deliver the Transaction to the callback. */ int syncId = -1; if (callback != null) { syncId = startSyncWithOrganizer(callback); } applyTransaction(t, syncId, null /*transition*/); if (syncId >= 0) { setSyncReady(syncId); } return syncId; } } finally { Binder.restoreCallingIdentity(ident); } } @Override Loading @@ -131,7 +173,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub if (t == null) { t = new WindowContainerTransaction(); } applyTransaction(t, null /*callback*/, transition); applyTransaction(t, -1 /*syncId*/, transition); return transition; } } finally { Loading @@ -148,10 +190,16 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub try { synchronized (mGlobalLock) { int syncId = -1; if (t != null) { syncId = applyTransaction(t, callback, null /*transition*/); if (t != null && callback != null) { syncId = startSyncWithOrganizer(callback); } getTransitionController().finishTransition(transitionToken); if (t != null) { applyTransaction(t, syncId, null /*transition*/); } if (syncId >= 0) { setSyncReady(syncId); } return syncId; } } finally { Loading @@ -160,49 +208,20 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } /** * @param callback If non-null, this will be a sync-transaction. * @param syncId If non-null, this will be a sync-transaction. * @param transition A transition to collect changes into. * @return a BLAST sync-id if this is a non-transition, sync transaction. */ private int applyTransaction(@NonNull WindowContainerTransaction t, @Nullable IWindowContainerTransactionCallback callback, private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId, @Nullable Transition transition) { enforceTaskPermission("applySyncTransaction()"); int syncId = -1; if (t == null) { throw new IllegalArgumentException( "Null transaction passed to applySyncTransaction"); } final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { int effects = 0; /** * If callback is non-null we are looking to synchronize this transaction by * collecting all the results in to a SurfaceFlinger transaction and then delivering * that to the given transaction ready callback. See {@link BLASTSyncEngine} for the * details of the operation. But at a high level we create a sync operation with a * given ID and an associated callback. Then we notify each WindowContainer in this * WindowContainer transaction that it is participating in a sync operation with * that ID. Once everything is notified we tell the BLASTSyncEngine "setSyncReady" * which means that we have added everything to the set. At any point after this, * all the WindowContainers will eventually finish applying their changes and notify * the BLASTSyncEngine which will deliver the Transaction to the callback. */ if (callback != null) { syncId = startSyncWithOrganizer(callback); } ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId); ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId); mService.deferWindowLayout(); try { ArraySet<WindowContainer> haveConfigChanges = new ArraySet<>(); Iterator<Map.Entry<IBinder, WindowContainerTransaction.Change>> entries = t.getChanges().entrySet().iterator(); while (entries.hasNext()) { final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next(); final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next(); final WindowContainer wc = WindowContainer.fromBinder(entry.getKey()); if (wc == null || !wc.isAttached()) { Slog.e(TAG, "Attempt to operate on detached container: " + wc); Loading Loading @@ -249,16 +268,14 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub // this after hierarchy ops so we have the final organized state. entries = t.getChanges().entrySet().iterator(); while (entries.hasNext()) { final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next(); final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next(); final Task task = WindowContainer.fromBinder(entry.getKey()).asTask(); final Rect surfaceBounds = entry.getValue().getBoundsChangeSurfaceBounds(); if (task == null || !task.isAttached() || surfaceBounds == null) { continue; } if (!task.isOrganized()) { final Task parent = task.getParent() != null ? task.getParent().asTask() : null; final Task parent = task.getParent() != null ? task.getParent().asTask() : null; // Also allow direct children of created-by-organizer tasks to be // controlled. In the future, these will become organized anyways. if (parent == null || !parent.mCreatedByOrganizer) { Loading @@ -278,8 +295,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) { // Already calls ensureActivityConfig mService.mRootWindowContainer.ensureActivitiesVisible( null, 0, PRESERVE_WINDOWS); mService.mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); } else if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) { final PooledConsumer f = PooledLambda.obtainConsumer( ActivityRecord::ensureActivityConfiguration, Loading @@ -299,15 +315,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } } finally { mService.continueWindowLayout(); if (syncId >= 0) { setSyncReady(syncId); } } } } finally { Binder.restoreCallingIdentity(ident); } return syncId; } private int applyChanges(WindowContainer container, WindowContainerTransaction.Change change) { Loading Loading
services/core/java/com/android/server/wm/WindowOrganizerController.java +146 −138 Original line number Diff line number Diff line Loading @@ -104,13 +104,55 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub @Override public void applyTransaction(WindowContainerTransaction t) { applyTransaction(t, null /*callback*/, null /*transition*/); enforceTaskPermission("applyTransaction()"); if (t == null) { throw new IllegalArgumentException("Null transaction passed to applySyncTransaction"); } final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { applyTransaction(t, -1 /*syncId*/, null /*transition*/); } } finally { Binder.restoreCallingIdentity(ident); } } @Override public int applySyncTransaction(WindowContainerTransaction t, IWindowContainerTransactionCallback callback) { return applyTransaction(t, callback, null /*transition*/); enforceTaskPermission("applySyncTransaction()"); if (t == null) { throw new IllegalArgumentException("Null transaction passed to applySyncTransaction"); } final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { /** * If callback is non-null we are looking to synchronize this transaction by * collecting all the results in to a SurfaceFlinger transaction and then delivering * that to the given transaction ready callback. See {@link BLASTSyncEngine} for the * details of the operation. But at a high level we create a sync operation with a * given ID and an associated callback. Then we notify each WindowContainer in this * WindowContainer transaction that it is participating in a sync operation with * that ID. Once everything is notified we tell the BLASTSyncEngine "setSyncReady" * which means that we have added everything to the set. At any point after this, * all the WindowContainers will eventually finish applying their changes and notify * the BLASTSyncEngine which will deliver the Transaction to the callback. */ int syncId = -1; if (callback != null) { syncId = startSyncWithOrganizer(callback); } applyTransaction(t, syncId, null /*transition*/); if (syncId >= 0) { setSyncReady(syncId); } return syncId; } } finally { Binder.restoreCallingIdentity(ident); } } @Override Loading @@ -131,7 +173,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub if (t == null) { t = new WindowContainerTransaction(); } applyTransaction(t, null /*callback*/, transition); applyTransaction(t, -1 /*syncId*/, transition); return transition; } } finally { Loading @@ -148,10 +190,16 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub try { synchronized (mGlobalLock) { int syncId = -1; if (t != null) { syncId = applyTransaction(t, callback, null /*transition*/); if (t != null && callback != null) { syncId = startSyncWithOrganizer(callback); } getTransitionController().finishTransition(transitionToken); if (t != null) { applyTransaction(t, syncId, null /*transition*/); } if (syncId >= 0) { setSyncReady(syncId); } return syncId; } } finally { Loading @@ -160,49 +208,20 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } /** * @param callback If non-null, this will be a sync-transaction. * @param syncId If non-null, this will be a sync-transaction. * @param transition A transition to collect changes into. * @return a BLAST sync-id if this is a non-transition, sync transaction. */ private int applyTransaction(@NonNull WindowContainerTransaction t, @Nullable IWindowContainerTransactionCallback callback, private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId, @Nullable Transition transition) { enforceTaskPermission("applySyncTransaction()"); int syncId = -1; if (t == null) { throw new IllegalArgumentException( "Null transaction passed to applySyncTransaction"); } final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { int effects = 0; /** * If callback is non-null we are looking to synchronize this transaction by * collecting all the results in to a SurfaceFlinger transaction and then delivering * that to the given transaction ready callback. See {@link BLASTSyncEngine} for the * details of the operation. But at a high level we create a sync operation with a * given ID and an associated callback. Then we notify each WindowContainer in this * WindowContainer transaction that it is participating in a sync operation with * that ID. Once everything is notified we tell the BLASTSyncEngine "setSyncReady" * which means that we have added everything to the set. At any point after this, * all the WindowContainers will eventually finish applying their changes and notify * the BLASTSyncEngine which will deliver the Transaction to the callback. */ if (callback != null) { syncId = startSyncWithOrganizer(callback); } ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId); ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId); mService.deferWindowLayout(); try { ArraySet<WindowContainer> haveConfigChanges = new ArraySet<>(); Iterator<Map.Entry<IBinder, WindowContainerTransaction.Change>> entries = t.getChanges().entrySet().iterator(); while (entries.hasNext()) { final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next(); final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next(); final WindowContainer wc = WindowContainer.fromBinder(entry.getKey()); if (wc == null || !wc.isAttached()) { Slog.e(TAG, "Attempt to operate on detached container: " + wc); Loading Loading @@ -249,16 +268,14 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub // this after hierarchy ops so we have the final organized state. entries = t.getChanges().entrySet().iterator(); while (entries.hasNext()) { final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next(); final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next(); final Task task = WindowContainer.fromBinder(entry.getKey()).asTask(); final Rect surfaceBounds = entry.getValue().getBoundsChangeSurfaceBounds(); if (task == null || !task.isAttached() || surfaceBounds == null) { continue; } if (!task.isOrganized()) { final Task parent = task.getParent() != null ? task.getParent().asTask() : null; final Task parent = task.getParent() != null ? task.getParent().asTask() : null; // Also allow direct children of created-by-organizer tasks to be // controlled. In the future, these will become organized anyways. if (parent == null || !parent.mCreatedByOrganizer) { Loading @@ -278,8 +295,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) { // Already calls ensureActivityConfig mService.mRootWindowContainer.ensureActivitiesVisible( null, 0, PRESERVE_WINDOWS); mService.mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); } else if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) { final PooledConsumer f = PooledLambda.obtainConsumer( ActivityRecord::ensureActivityConfiguration, Loading @@ -299,15 +315,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } } finally { mService.continueWindowLayout(); if (syncId >= 0) { setSyncReady(syncId); } } } } finally { Binder.restoreCallingIdentity(ident); } return syncId; } private int applyChanges(WindowContainer container, WindowContainerTransaction.Change change) { Loading