Loading core/java/android/app/servertransaction/WindowStateInsetsControlChangeItem.java 0 → 100644 +156 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app.servertransaction; import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ClientTransactionHandler; import android.os.Parcel; import android.os.RemoteException; import android.os.Trace; import android.util.Log; import android.view.IWindow; import android.view.InsetsSourceControl; import android.view.InsetsState; import java.util.Objects; /** * Message to deliver window insets control change info. * @hide */ public class WindowStateInsetsControlChangeItem extends ClientTransactionItem { private static final String TAG = "WindowStateInsetsControlChangeItem"; private IWindow mWindow; private InsetsState mInsetsState; private InsetsSourceControl.Array mActiveControls; @Override public void execute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "windowInsetsControlChanged"); if (mWindow instanceof InsetsControlChangeListener listener) { listener.onExecutingWindowStateInsetsControlChangeItem(); } try { mWindow.insetsControlChanged(mInsetsState, mActiveControls); } catch (RemoteException e) { // Should be a local call. // An exception could happen if the process is restarted. It is safe to ignore since // the window should no longer exist. Log.w(TAG, "The original window no longer exists in the new process", e); } Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); } // ObjectPoolItem implementation private WindowStateInsetsControlChangeItem() {} /** Obtains an instance initialized with provided params. */ public static WindowStateInsetsControlChangeItem obtain(@NonNull IWindow window, @NonNull InsetsState insetsState, @NonNull InsetsSourceControl.Array activeControls) { WindowStateInsetsControlChangeItem instance = ObjectPool.obtain(WindowStateInsetsControlChangeItem.class); if (instance == null) { instance = new WindowStateInsetsControlChangeItem(); } instance.mWindow = requireNonNull(window); instance.mInsetsState = new InsetsState(insetsState, true /* copySources */); instance.mActiveControls = new InsetsSourceControl.Array(activeControls); return instance; } @Override public void recycle() { mWindow = null; mInsetsState = null; mActiveControls = null; ObjectPool.recycle(this); } // Parcelable implementation /** Writes to Parcel. */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeStrongBinder(mWindow.asBinder()); dest.writeTypedObject(mInsetsState, flags); dest.writeTypedObject(mActiveControls, flags); } /** Reads from Parcel. */ private WindowStateInsetsControlChangeItem(@NonNull Parcel in) { mWindow = IWindow.Stub.asInterface(in.readStrongBinder()); mInsetsState = in.readTypedObject(InsetsState.CREATOR); mActiveControls = in.readTypedObject(InsetsSourceControl.Array.CREATOR); } public static final @NonNull Creator<WindowStateInsetsControlChangeItem> CREATOR = new Creator<>() { public WindowStateInsetsControlChangeItem createFromParcel(@NonNull Parcel in) { return new WindowStateInsetsControlChangeItem(in); } public WindowStateInsetsControlChangeItem[] newArray(int size) { return new WindowStateInsetsControlChangeItem[size]; } }; @Override public boolean equals(@Nullable Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final WindowStateInsetsControlChangeItem other = (WindowStateInsetsControlChangeItem) o; return Objects.equals(mWindow, other.mWindow) && Objects.equals(mInsetsState, other.mInsetsState) && Objects.equals(mActiveControls, other.mActiveControls); } @Override public int hashCode() { int result = 17; result = 31 * result + Objects.hashCode(mWindow); result = 31 * result + Objects.hashCode(mInsetsState); result = 31 * result + Objects.hashCode(mActiveControls); return result; } @Override public String toString() { return "WindowStateInsetsControlChangeItem{window=" + mWindow + "}"; } /** The interface for IWindow to perform insets control change directly if possible. */ public interface InsetsControlChangeListener { /** * Notifies that IWindow#insetsControlChanged is going to be called from * WindowStateInsetsControlChangeItem. */ void onExecutingWindowStateInsetsControlChangeItem(); } } core/java/android/view/InsetsSourceControl.java +22 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.util.proto.ProtoOutputStream; import android.view.WindowInsets.Type.InsetsType; import java.io.PrintWriter; import java.util.Arrays; import java.util.Objects; import java.util.function.Consumer; Loading Loading @@ -268,6 +269,10 @@ public class InsetsSourceControl implements Parcelable { public Array() { } public Array(@NonNull Array other) { mControls = other.mControls; } public Array(Parcel in) { readFromParcel(in); } Loading Loading @@ -303,5 +308,22 @@ public class InsetsSourceControl implements Parcelable { return new Array[size]; } }; @Override public boolean equals(@Nullable Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final InsetsSourceControl.Array other = (InsetsSourceControl.Array) o; return Arrays.equals(mControls, other.mControls); } @Override public int hashCode() { return Arrays.hashCode(mControls); } } } core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.platform.test.annotations.Presubmit; import android.util.ArrayMap; import android.util.MergedConfiguration; import android.view.IWindow; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.window.ActivityWindowInfo; import android.window.ClientWindowFrames; Loading Loading @@ -85,6 +86,7 @@ public class ClientTransactionItemTest { private ClientWindowFrames mFrames; private MergedConfiguration mMergedConfiguration; private ActivityWindowInfo mActivityWindowInfo; private InsetsSourceControl.Array mActiveControls; @Before public void setup() { Loading @@ -97,6 +99,7 @@ public class ClientTransactionItemTest { mFrames = new ClientWindowFrames(); mMergedConfiguration = new MergedConfiguration(mGlobalConfig, mConfiguration); mActivityWindowInfo = new ActivityWindowInfo(); mActiveControls = new InsetsSourceControl.Array(); doReturn(mActivity).when(mHandler).getActivity(mActivityToken); doReturn(mActivitiesToBeDestroyed).when(mHandler).getActivitiesToBeDestroyed(); Loading Loading @@ -164,4 +167,13 @@ public class ClientTransactionItemTest { true /* alwaysConsumeSystemBars */, 123 /* displayId */, 321 /* syncSeqId */, true /* dragResizing */, mActivityWindowInfo); } @Test public void testWindowStateInsetsControlChangeItem_execute() throws RemoteException { final WindowStateInsetsControlChangeItem item = WindowStateInsetsControlChangeItem.obtain( mWindow, mInsetsState, mActiveControls); item.execute(mHandler, mPendingActions); verify(mWindow).insetsControlChanged(mInsetsState, mActiveControls); } } Loading
core/java/android/app/servertransaction/WindowStateInsetsControlChangeItem.java 0 → 100644 +156 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app.servertransaction; import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ClientTransactionHandler; import android.os.Parcel; import android.os.RemoteException; import android.os.Trace; import android.util.Log; import android.view.IWindow; import android.view.InsetsSourceControl; import android.view.InsetsState; import java.util.Objects; /** * Message to deliver window insets control change info. * @hide */ public class WindowStateInsetsControlChangeItem extends ClientTransactionItem { private static final String TAG = "WindowStateInsetsControlChangeItem"; private IWindow mWindow; private InsetsState mInsetsState; private InsetsSourceControl.Array mActiveControls; @Override public void execute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "windowInsetsControlChanged"); if (mWindow instanceof InsetsControlChangeListener listener) { listener.onExecutingWindowStateInsetsControlChangeItem(); } try { mWindow.insetsControlChanged(mInsetsState, mActiveControls); } catch (RemoteException e) { // Should be a local call. // An exception could happen if the process is restarted. It is safe to ignore since // the window should no longer exist. Log.w(TAG, "The original window no longer exists in the new process", e); } Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); } // ObjectPoolItem implementation private WindowStateInsetsControlChangeItem() {} /** Obtains an instance initialized with provided params. */ public static WindowStateInsetsControlChangeItem obtain(@NonNull IWindow window, @NonNull InsetsState insetsState, @NonNull InsetsSourceControl.Array activeControls) { WindowStateInsetsControlChangeItem instance = ObjectPool.obtain(WindowStateInsetsControlChangeItem.class); if (instance == null) { instance = new WindowStateInsetsControlChangeItem(); } instance.mWindow = requireNonNull(window); instance.mInsetsState = new InsetsState(insetsState, true /* copySources */); instance.mActiveControls = new InsetsSourceControl.Array(activeControls); return instance; } @Override public void recycle() { mWindow = null; mInsetsState = null; mActiveControls = null; ObjectPool.recycle(this); } // Parcelable implementation /** Writes to Parcel. */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeStrongBinder(mWindow.asBinder()); dest.writeTypedObject(mInsetsState, flags); dest.writeTypedObject(mActiveControls, flags); } /** Reads from Parcel. */ private WindowStateInsetsControlChangeItem(@NonNull Parcel in) { mWindow = IWindow.Stub.asInterface(in.readStrongBinder()); mInsetsState = in.readTypedObject(InsetsState.CREATOR); mActiveControls = in.readTypedObject(InsetsSourceControl.Array.CREATOR); } public static final @NonNull Creator<WindowStateInsetsControlChangeItem> CREATOR = new Creator<>() { public WindowStateInsetsControlChangeItem createFromParcel(@NonNull Parcel in) { return new WindowStateInsetsControlChangeItem(in); } public WindowStateInsetsControlChangeItem[] newArray(int size) { return new WindowStateInsetsControlChangeItem[size]; } }; @Override public boolean equals(@Nullable Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final WindowStateInsetsControlChangeItem other = (WindowStateInsetsControlChangeItem) o; return Objects.equals(mWindow, other.mWindow) && Objects.equals(mInsetsState, other.mInsetsState) && Objects.equals(mActiveControls, other.mActiveControls); } @Override public int hashCode() { int result = 17; result = 31 * result + Objects.hashCode(mWindow); result = 31 * result + Objects.hashCode(mInsetsState); result = 31 * result + Objects.hashCode(mActiveControls); return result; } @Override public String toString() { return "WindowStateInsetsControlChangeItem{window=" + mWindow + "}"; } /** The interface for IWindow to perform insets control change directly if possible. */ public interface InsetsControlChangeListener { /** * Notifies that IWindow#insetsControlChanged is going to be called from * WindowStateInsetsControlChangeItem. */ void onExecutingWindowStateInsetsControlChangeItem(); } }
core/java/android/view/InsetsSourceControl.java +22 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.util.proto.ProtoOutputStream; import android.view.WindowInsets.Type.InsetsType; import java.io.PrintWriter; import java.util.Arrays; import java.util.Objects; import java.util.function.Consumer; Loading Loading @@ -268,6 +269,10 @@ public class InsetsSourceControl implements Parcelable { public Array() { } public Array(@NonNull Array other) { mControls = other.mControls; } public Array(Parcel in) { readFromParcel(in); } Loading Loading @@ -303,5 +308,22 @@ public class InsetsSourceControl implements Parcelable { return new Array[size]; } }; @Override public boolean equals(@Nullable Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final InsetsSourceControl.Array other = (InsetsSourceControl.Array) o; return Arrays.equals(mControls, other.mControls); } @Override public int hashCode() { return Arrays.hashCode(mControls); } } }
core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.platform.test.annotations.Presubmit; import android.util.ArrayMap; import android.util.MergedConfiguration; import android.view.IWindow; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.window.ActivityWindowInfo; import android.window.ClientWindowFrames; Loading Loading @@ -85,6 +86,7 @@ public class ClientTransactionItemTest { private ClientWindowFrames mFrames; private MergedConfiguration mMergedConfiguration; private ActivityWindowInfo mActivityWindowInfo; private InsetsSourceControl.Array mActiveControls; @Before public void setup() { Loading @@ -97,6 +99,7 @@ public class ClientTransactionItemTest { mFrames = new ClientWindowFrames(); mMergedConfiguration = new MergedConfiguration(mGlobalConfig, mConfiguration); mActivityWindowInfo = new ActivityWindowInfo(); mActiveControls = new InsetsSourceControl.Array(); doReturn(mActivity).when(mHandler).getActivity(mActivityToken); doReturn(mActivitiesToBeDestroyed).when(mHandler).getActivitiesToBeDestroyed(); Loading Loading @@ -164,4 +167,13 @@ public class ClientTransactionItemTest { true /* alwaysConsumeSystemBars */, 123 /* displayId */, 321 /* syncSeqId */, true /* dragResizing */, mActivityWindowInfo); } @Test public void testWindowStateInsetsControlChangeItem_execute() throws RemoteException { final WindowStateInsetsControlChangeItem item = WindowStateInsetsControlChangeItem.obtain( mWindow, mInsetsState, mActiveControls); item.execute(mHandler, mPendingActions); verify(mWindow).insetsControlChanged(mInsetsState, mActiveControls); } }