Loading core/java/android/app/servertransaction/WindowStateInsetsControlChangeItem.java +6 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading core/java/android/view/InsetsSourceControl.java +37 −5 Original line number Diff line number Diff line Loading @@ -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) { /** 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; Loading core/java/android/view/ViewRootImpl.java +62 −42 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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(); Loading Loading @@ -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); Loading @@ -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 */); } // TODO(b/339380439): no need to post if the call is from InsetsControlChangeItem // 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; } // 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 Loading services/core/java/com/android/server/wm/WindowManagerService.java +10 −19 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { 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. outControls[i] = new InsetsSourceControl(controls[i]); outControls[i].setParcelableFlags(PARCELABLE_WRITE_RETURN_VALUE); } } outArray.set(outControls); } outArray.setParcelableFlags(PARCELABLE_WRITE_RETURN_VALUE); } private void tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator) { Loading services/core/java/com/android/server/wm/WindowState.java +2 −1 Original line number Diff line number Diff line Loading @@ -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)); Loading Loading
core/java/android/app/servertransaction/WindowStateInsetsControlChangeItem.java +6 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading
core/java/android/view/InsetsSourceControl.java +37 −5 Original line number Diff line number Diff line Loading @@ -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) { /** 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; Loading
core/java/android/view/ViewRootImpl.java +62 −42 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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(); Loading Loading @@ -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); Loading @@ -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 */); } // TODO(b/339380439): no need to post if the call is from InsetsControlChangeItem // 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; } // 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 Loading
services/core/java/com/android/server/wm/WindowManagerService.java +10 −19 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { 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. outControls[i] = new InsetsSourceControl(controls[i]); outControls[i].setParcelableFlags(PARCELABLE_WRITE_RETURN_VALUE); } } outArray.set(outControls); } outArray.setParcelableFlags(PARCELABLE_WRITE_RETURN_VALUE); } private void tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator) { Loading
services/core/java/com/android/server/wm/WindowState.java +2 −1 Original line number Diff line number Diff line Loading @@ -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)); Loading