summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chris Li <lihongyu@google.com> 2024-05-24 04:14:32 +0000
committer Chris Li <lihongyu@google.com> 2024-05-30 03:25:11 +0000
commite03a31758c55168111ef1dbd3017277aa0f2a3e1 (patch)
treeee38b24933f5ad1ef49073fe2af6ac89c0509199
parent85ae83ecd587e0f48a90453ce72e8ee37a3ddc4f (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
-rw-r--r--core/java/android/app/servertransaction/WindowStateInsetsControlChangeItem.java7
-rw-r--r--core/java/android/view/InsetsSourceControl.java42
-rw-r--r--core/java/android/view/ViewRootImpl.java104
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java29
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java3
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));