diff options
author | 2024-05-24 04:14:32 +0000 | |
---|---|---|
committer | 2024-05-30 03:25:11 +0000 | |
commit | e03a31758c55168111ef1dbd3017277aa0f2a3e1 (patch) | |
tree | ee38b24933f5ad1ef49073fe2af6ac89c0509199 | |
parent | 85ae83ecd587e0f48a90453ce72e8ee37a3ddc4f (diff) |
Avoid redundant post message from WindowStateInsetsControlChangeItem
Bug: 339380439
Test: refactor, pass existing tests
Flag: com.android.window.flags.insets_control_changed_item
Change-Id: I7beaca1b2ee7fb3f72c4419dc8dc87e38709be5f
5 files changed, 117 insertions, 68 deletions
diff --git a/core/java/android/app/servertransaction/WindowStateInsetsControlChangeItem.java b/core/java/android/app/servertransaction/WindowStateInsetsControlChangeItem.java index 1c8e497edd0a..ed18a057118c 100644 --- a/core/java/android/app/servertransaction/WindowStateInsetsControlChangeItem.java +++ b/core/java/android/app/servertransaction/WindowStateInsetsControlChangeItem.java @@ -69,7 +69,12 @@ public class WindowStateInsetsControlChangeItem extends WindowStateTransactionIt } instance.setWindow(window); instance.mInsetsState = new InsetsState(insetsState, true /* copySources */); - instance.mActiveControls = new InsetsSourceControl.Array(activeControls); + instance.mActiveControls = new InsetsSourceControl.Array( + activeControls, true /* copyControls */); + // This source control is an extra copy if the client is not local. By setting + // PARCELABLE_WRITE_RETURN_VALUE, the leash will be released at the end of + // SurfaceControl.writeToParcel. + instance.mActiveControls.setParcelableFlags(PARCELABLE_WRITE_RETURN_VALUE); return instance; } diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java index 4e5cb58a00b5..588e9e0a3b12 100644 --- a/core/java/android/view/InsetsSourceControl.java +++ b/core/java/android/view/InsetsSourceControl.java @@ -269,22 +269,54 @@ public class InsetsSourceControl implements Parcelable { public Array() { } - public Array(@NonNull Array other) { - mControls = other.mControls; + /** + * @param copyControls whether or not to make a copy of the each {@link InsetsSourceControl} + */ + public Array(@NonNull Array other, boolean copyControls) { + setTo(other, copyControls); } - public Array(Parcel in) { + public Array(@NonNull Parcel in) { readFromParcel(in); } - public void set(@Nullable InsetsSourceControl[] controls) { - mControls = controls; + /** Updates the current Array to the given Array. */ + public void setTo(@NonNull Array other, boolean copyControls) { + set(other.mControls, copyControls); } + /** Updates the current controls to the given controls. */ + public void set(@Nullable InsetsSourceControl[] controls, boolean copyControls) { + if (controls == null || !copyControls) { + mControls = controls; + return; + } + // Make a copy of the array. + mControls = new InsetsSourceControl[controls.length]; + for (int i = mControls.length - 1; i >= 0; i--) { + if (controls[i] != null) { + mControls[i] = new InsetsSourceControl(controls[i]); + } + } + } + + /** Gets the controls. */ public @Nullable InsetsSourceControl[] get() { return mControls; } + /** Sets the given flags to all controls. */ + public void setParcelableFlags(int parcelableFlags) { + if (mControls == null) { + return; + } + for (InsetsSourceControl control : mControls) { + if (control != null) { + control.setParcelableFlags(parcelableFlags); + } + } + } + @Override public int describeContents() { return 0; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 139285a44817..b54e052cf538 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2276,6 +2276,33 @@ public final class ViewRootImpl implements ViewParent, requestLayout(); } + /** Handles messages {@link #MSG_INSETS_CONTROL_CHANGED}. */ + private void handleInsetsControlChanged(@NonNull InsetsState insetsState, + @NonNull InsetsSourceControl.Array activeControls) { + final InsetsSourceControl[] controls = activeControls.get(); + + if (mTranslator != null) { + mTranslator.translateInsetsStateInScreenToAppWindow(insetsState); + mTranslator.translateSourceControlsInScreenToAppWindow(controls); + } + + // Deliver state change before control change, such that: + // a) When gaining control, controller can compare with server state to evaluate + // whether it needs to run animation. + // b) When loosing control, controller can restore server state by taking last + // dispatched state as truth. + mInsetsController.onStateChanged(insetsState); + if (mAdded) { + mInsetsController.onControlsChanged(controls); + } else if (controls != null) { + for (InsetsSourceControl control : controls) { + if (control != null) { + control.release(SurfaceControl::release); + } + } + } + } + private final DisplayListener mDisplayListener = new DisplayListener() { @Override public void onDisplayChanged(int displayId) { @@ -6591,24 +6618,11 @@ public final class ViewRootImpl implements ViewParent, break; } case MSG_INSETS_CONTROL_CHANGED: { - SomeArgs args = (SomeArgs) msg.obj; - - // Deliver state change before control change, such that: - // a) When gaining control, controller can compare with server state to evaluate - // whether it needs to run animation. - // b) When loosing control, controller can restore server state by taking last - // dispatched state as truth. - mInsetsController.onStateChanged((InsetsState) args.arg1); - InsetsSourceControl[] controls = (InsetsSourceControl[]) args.arg2; - if (mAdded) { - mInsetsController.onControlsChanged(controls); - } else if (controls != null) { - for (InsetsSourceControl control : controls) { - if (control != null) { - control.release(SurfaceControl::release); - } - } - } + final SomeArgs args = (SomeArgs) msg.obj; + final InsetsState insetsState = (InsetsState) args.arg1; + final InsetsSourceControl.Array activeControls = + (InsetsSourceControl.Array) args.arg2; + handleInsetsControlChanged(insetsState, activeControls); args.recycle(); break; } @@ -9828,25 +9842,9 @@ public final class ViewRootImpl implements ViewParent, mHandler.sendMessage(msg); } - private void dispatchInsetsControlChanged(InsetsState insetsState, - InsetsSourceControl[] activeControls) { - if (Binder.getCallingPid() == android.os.Process.myPid()) { - insetsState = new InsetsState(insetsState, true /* copySource */); - if (activeControls != null) { - for (int i = activeControls.length - 1; i >= 0; i--) { - activeControls[i] = new InsetsSourceControl(activeControls[i]); - } - } - } - if (mTranslator != null) { - mTranslator.translateInsetsStateInScreenToAppWindow(insetsState); - mTranslator.translateSourceControlsInScreenToAppWindow(activeControls); - } - if (insetsState != null && insetsState.isSourceOrDefaultVisible(ID_IME, Type.ime())) { - ImeTracing.getInstance().triggerClientDump("ViewRootImpl#dispatchInsetsControlChanged", - getInsetsController().getHost().getInputMethodManager(), null /* icProto */); - } - SomeArgs args = SomeArgs.obtain(); + private void dispatchInsetsControlChanged(@NonNull InsetsState insetsState, + @NonNull InsetsSourceControl.Array activeControls) { + final SomeArgs args = SomeArgs.obtain(); args.arg1 = insetsState; args.arg2 = activeControls; mHandler.obtainMessage(MSG_INSETS_CONTROL_CHANGED, args).sendToTarget(); @@ -11289,9 +11287,9 @@ public final class ViewRootImpl implements ViewParent, return; } // The the parameters from WindowStateResizeItem are already copied. - final boolean needCopy = + final boolean needsCopy = !isFromResizeItem && (Binder.getCallingPid() == Process.myPid()); - if (needCopy) { + if (needsCopy) { insetsState = new InsetsState(insetsState, true /* copySource */); frames = new ClientWindowFrames(frames); mergedConfiguration = new MergedConfiguration(mergedConfiguration); @@ -11307,10 +11305,32 @@ public final class ViewRootImpl implements ViewParent, final boolean isFromInsetsControlChangeItem = mIsFromTransactionItem; mIsFromTransactionItem = false; final ViewRootImpl viewAncestor = mViewAncestor.get(); - if (viewAncestor != null) { - viewAncestor.dispatchInsetsControlChanged(insetsState, activeControls.get()); + if (viewAncestor == null) { + return; + } + if (insetsState.isSourceOrDefaultVisible(ID_IME, Type.ime())) { + ImeTracing.getInstance().triggerClientDump( + "ViewRootImpl#dispatchInsetsControlChanged", + viewAncestor.getInsetsController().getHost().getInputMethodManager(), + null /* icProto */); + } + // If the UI thread is the same as the current thread that is dispatching + // WindowStateInsetsControlChangeItem, then it can run directly. + if (isFromInsetsControlChangeItem && viewAncestor.mHandler.getLooper() + == ActivityThread.currentActivityThread().getLooper()) { + viewAncestor.handleInsetsControlChanged(insetsState, activeControls); + return; } - // TODO(b/339380439): no need to post if the call is from InsetsControlChangeItem + // The parameters from WindowStateInsetsControlChangeItem are already copied. + final boolean needsCopy = + !isFromInsetsControlChangeItem && (Binder.getCallingPid() == Process.myPid()); + if (needsCopy) { + insetsState = new InsetsState(insetsState, true /* copySource */); + activeControls = new InsetsSourceControl.Array( + activeControls, true /* copyControls */); + } + + viewAncestor.dispatchInsetsControlChanged(insetsState, activeControls); } @Override diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 0bf1c88d5b4f..94a22394cf41 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1525,7 +1525,7 @@ public class WindowManagerService extends IWindowManager.Stub InputChannel outInputChannel, InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame, float[] outSizeCompatScale) { - outActiveControls.set(null); + outActiveControls.set(null, false /* copyControls */); int[] appOp = new int[1]; final boolean isRoundedCornerOverlay = (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0; @@ -2317,7 +2317,7 @@ public class WindowManagerService extends IWindowManager.Stub InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls, Bundle outBundle, WindowRelayoutResult outRelayoutResult) { if (outActiveControls != null) { - outActiveControls.set(null); + outActiveControls.set(null, false /* copyControls */); } int result = 0; boolean configChanged = false; @@ -2745,23 +2745,14 @@ public class WindowManagerService extends IWindowManager.Stub private void getInsetsSourceControls(WindowState win, InsetsSourceControl.Array outArray) { final InsetsSourceControl[] controls = win.getDisplayContent().getInsetsStateController().getControlsForDispatch(win); - if (controls != null) { - final int length = controls.length; - final InsetsSourceControl[] outControls = new InsetsSourceControl[length]; - for (int i = 0; i < length; i++) { - // We will leave the critical section before returning the leash to the client, - // so we need to copy the leash to prevent others release the one that we are - // about to return. - if (controls[i] != null) { - // This source control is an extra copy if the client is not local. By setting - // PARCELABLE_WRITE_RETURN_VALUE, the leash will be released at the end of - // SurfaceControl.writeToParcel. - outControls[i] = new InsetsSourceControl(controls[i]); - outControls[i].setParcelableFlags(PARCELABLE_WRITE_RETURN_VALUE); - } - } - outArray.set(outControls); - } + // We will leave the critical section before returning the leash to the client, + // so we need to copy the leash to prevent others release the one that we are + // about to return. + outArray.set(controls, true /* copyControls */); + // This source control is an extra copy if the client is not local. By setting + // PARCELABLE_WRITE_RETURN_VALUE, the leash will be released at the end of + // SurfaceControl.writeToParcel. + outArray.setParcelableFlags(PARCELABLE_WRITE_RETURN_VALUE); } private void tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 6953c60d0d74..d7c49ac81a6c 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3820,7 +3820,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP final InsetsStateController stateController = getDisplayContent().getInsetsStateController(); final InsetsState insetsState = getCompatInsetsState(); - mLastReportedActiveControls.set(stateController.getControlsForDispatch(this)); + mLastReportedActiveControls.set(stateController.getControlsForDispatch(this), + false /* copyControls */); if (Flags.insetsControlChangedItem()) { getProcess().scheduleClientTransactionItem(WindowStateInsetsControlChangeItem.obtain( mClient, insetsState, mLastReportedActiveControls)); |