Loading core/java/android/view/IWindowSession.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -250,4 +250,10 @@ interface IWindowSession { */ void updateTapExcludeRegion(IWindow window, int regionId, int left, int top, int width, int height); /** * Called when the client has changed the local insets state, and now the server should reflect * that new state. */ void insetsModified(IWindow window, in InsetsState state); } core/java/android/view/InsetsController.java +31 −0 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Rect; import android.os.RemoteException; import android.util.ArraySet; import android.util.Log; import android.util.SparseArray; import android.view.SurfaceControl.Transaction; import android.view.WindowInsets.Type.InsetType; Loading @@ -36,7 +38,11 @@ import java.util.ArrayList; */ public class InsetsController implements WindowInsetsController { private final String TAG = "InsetsControllerImpl"; private final InsetsState mState = new InsetsState(); private final InsetsState mTmpState = new InsetsState(); private final Rect mFrame = new Rect(); private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>(); private final ViewRootImpl mViewRoot; Loading @@ -61,8 +67,12 @@ public class InsetsController implements WindowInsetsController { return false; } mState.set(state); mTmpState.set(state, true /* copySources */); applyLocalVisibilityOverride(); mViewRoot.notifyInsetsChanged(); if (!mState.equals(mTmpState)) { sendStateToWindowManager(); } return true; } Loading Loading @@ -163,6 +173,27 @@ public class InsetsController implements WindowInsetsController { @VisibleForTesting public void notifyVisibilityChanged() { mViewRoot.notifyInsetsChanged(); sendStateToWindowManager(); } /** * Sends the local visibility state back to window manager. */ private void sendStateToWindowManager() { InsetsState tmpState = new InsetsState(); for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i); if (consumer.getControl() != null) { tmpState.addSource(mState.getSource(consumer.getType())); } } // TODO: Put this on a dispatcher thread. try { mViewRoot.mWindowSession.insetsModified(mViewRoot.mWindow, tmpState); } catch (RemoteException e) { Log.e(TAG, "Failed to call insetsModified", e); } } void dump(String prefix, PrintWriter pw) { Loading core/java/android/view/InsetsSource.java +4 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,10 @@ public class InsetsSource implements Parcelable { return mFrame; } public boolean isVisible() { return mVisible; } /** * Calculates the insets this source will cause to a client window. * Loading core/java/android/view/InsetsSourceConsumer.java +20 −14 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ public class InsetsSourceConsumer { private final InsetsState mState; private final InsetsController mController; private @Nullable InsetsSourceControl mSourceControl; private boolean mHidden; private boolean mVisible; public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state, Supplier<Transaction> transactionSupplier, InsetsController controller) { Loading @@ -43,6 +43,7 @@ public class InsetsSourceConsumer { mState = state; mTransactionSupplier = transactionSupplier; mController = controller; mVisible = InsetsState.getDefaultVisibly(type); } public void setControl(@Nullable InsetsSourceControl control) { Loading @@ -51,9 +52,10 @@ public class InsetsSourceConsumer { } mSourceControl = control; applyHiddenToControl(); applyLocalVisibilityOverride(); if (applyLocalVisibilityOverride()) { mController.notifyVisibilityChanged(); } } @VisibleForTesting public InsetsSourceControl getControl() { Loading @@ -66,28 +68,32 @@ public class InsetsSourceConsumer { @VisibleForTesting public void show() { setHidden(false); setVisible(true); } @VisibleForTesting public void hide() { setHidden(true); setVisible(false); } void applyLocalVisibilityOverride() { boolean applyLocalVisibilityOverride() { // If we don't have control, we are not able to change the visibility. if (mSourceControl == null) { return; return false; } if (mState.getSource(mType).isVisible() == mVisible) { return false; } mState.getSource(mType).setVisible(!mHidden); mState.getSource(mType).setVisible(mVisible); return true; } private void setHidden(boolean hidden) { if (mHidden == hidden) { private void setVisible(boolean visible) { if (mVisible == visible) { return; } mHidden = hidden; mVisible = visible; applyHiddenToControl(); applyLocalVisibilityOverride(); mController.notifyVisibilityChanged(); Loading @@ -100,10 +106,10 @@ public class InsetsSourceConsumer { // TODO: Animation final Transaction t = mTransactionSupplier.get(); if (mHidden) { t.hide(mSourceControl.getLeash()); } else { if (mVisible) { t.show(mSourceControl.getLeash()); } else { t.hide(mSourceControl.getLeash()); } t.apply(); } Loading core/java/android/view/InsetsState.java +27 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.view.WindowInsets.Type.InsetType; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; /** * Holder for state of system windows that cause window insets for all other windows in the system. Loading Loading @@ -200,6 +201,18 @@ public class InsetsState implements Parcelable { } } public void addSource(InsetsSource source) { mSources.put(source.getType(), source); } public int getSourcesCount() { return mSources.size(); } public InsetsSource sourceAt(int index) { return mSources.valueAt(index); } public static @InternalInsetType ArraySet<Integer> toInternalType(@InsetType int insetTypes) { final ArraySet<Integer> result = new ArraySet<>(); if ((insetTypes & Type.TOP_BAR) != 0) { Loading @@ -216,6 +229,20 @@ public class InsetsState implements Parcelable { return result; } public static boolean getDefaultVisibly(@InsetType int type) { switch (type) { case TYPE_TOP_BAR: case TYPE_SIDE_BAR_1: case TYPE_SIDE_BAR_2: case TYPE_SIDE_BAR_3: return true; case TYPE_IME: return false; default: return true; } } public void dump(String prefix, PrintWriter pw) { pw.println(prefix + "InsetsState"); for (int i = mSources.size() - 1; i >= 0; i--) { Loading Loading
core/java/android/view/IWindowSession.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -250,4 +250,10 @@ interface IWindowSession { */ void updateTapExcludeRegion(IWindow window, int regionId, int left, int top, int width, int height); /** * Called when the client has changed the local insets state, and now the server should reflect * that new state. */ void insetsModified(IWindow window, in InsetsState state); }
core/java/android/view/InsetsController.java +31 −0 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Rect; import android.os.RemoteException; import android.util.ArraySet; import android.util.Log; import android.util.SparseArray; import android.view.SurfaceControl.Transaction; import android.view.WindowInsets.Type.InsetType; Loading @@ -36,7 +38,11 @@ import java.util.ArrayList; */ public class InsetsController implements WindowInsetsController { private final String TAG = "InsetsControllerImpl"; private final InsetsState mState = new InsetsState(); private final InsetsState mTmpState = new InsetsState(); private final Rect mFrame = new Rect(); private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>(); private final ViewRootImpl mViewRoot; Loading @@ -61,8 +67,12 @@ public class InsetsController implements WindowInsetsController { return false; } mState.set(state); mTmpState.set(state, true /* copySources */); applyLocalVisibilityOverride(); mViewRoot.notifyInsetsChanged(); if (!mState.equals(mTmpState)) { sendStateToWindowManager(); } return true; } Loading Loading @@ -163,6 +173,27 @@ public class InsetsController implements WindowInsetsController { @VisibleForTesting public void notifyVisibilityChanged() { mViewRoot.notifyInsetsChanged(); sendStateToWindowManager(); } /** * Sends the local visibility state back to window manager. */ private void sendStateToWindowManager() { InsetsState tmpState = new InsetsState(); for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i); if (consumer.getControl() != null) { tmpState.addSource(mState.getSource(consumer.getType())); } } // TODO: Put this on a dispatcher thread. try { mViewRoot.mWindowSession.insetsModified(mViewRoot.mWindow, tmpState); } catch (RemoteException e) { Log.e(TAG, "Failed to call insetsModified", e); } } void dump(String prefix, PrintWriter pw) { Loading
core/java/android/view/InsetsSource.java +4 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,10 @@ public class InsetsSource implements Parcelable { return mFrame; } public boolean isVisible() { return mVisible; } /** * Calculates the insets this source will cause to a client window. * Loading
core/java/android/view/InsetsSourceConsumer.java +20 −14 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ public class InsetsSourceConsumer { private final InsetsState mState; private final InsetsController mController; private @Nullable InsetsSourceControl mSourceControl; private boolean mHidden; private boolean mVisible; public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state, Supplier<Transaction> transactionSupplier, InsetsController controller) { Loading @@ -43,6 +43,7 @@ public class InsetsSourceConsumer { mState = state; mTransactionSupplier = transactionSupplier; mController = controller; mVisible = InsetsState.getDefaultVisibly(type); } public void setControl(@Nullable InsetsSourceControl control) { Loading @@ -51,9 +52,10 @@ public class InsetsSourceConsumer { } mSourceControl = control; applyHiddenToControl(); applyLocalVisibilityOverride(); if (applyLocalVisibilityOverride()) { mController.notifyVisibilityChanged(); } } @VisibleForTesting public InsetsSourceControl getControl() { Loading @@ -66,28 +68,32 @@ public class InsetsSourceConsumer { @VisibleForTesting public void show() { setHidden(false); setVisible(true); } @VisibleForTesting public void hide() { setHidden(true); setVisible(false); } void applyLocalVisibilityOverride() { boolean applyLocalVisibilityOverride() { // If we don't have control, we are not able to change the visibility. if (mSourceControl == null) { return; return false; } if (mState.getSource(mType).isVisible() == mVisible) { return false; } mState.getSource(mType).setVisible(!mHidden); mState.getSource(mType).setVisible(mVisible); return true; } private void setHidden(boolean hidden) { if (mHidden == hidden) { private void setVisible(boolean visible) { if (mVisible == visible) { return; } mHidden = hidden; mVisible = visible; applyHiddenToControl(); applyLocalVisibilityOverride(); mController.notifyVisibilityChanged(); Loading @@ -100,10 +106,10 @@ public class InsetsSourceConsumer { // TODO: Animation final Transaction t = mTransactionSupplier.get(); if (mHidden) { t.hide(mSourceControl.getLeash()); } else { if (mVisible) { t.show(mSourceControl.getLeash()); } else { t.hide(mSourceControl.getLeash()); } t.apply(); } Loading
core/java/android/view/InsetsState.java +27 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.view.WindowInsets.Type.InsetType; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; /** * Holder for state of system windows that cause window insets for all other windows in the system. Loading Loading @@ -200,6 +201,18 @@ public class InsetsState implements Parcelable { } } public void addSource(InsetsSource source) { mSources.put(source.getType(), source); } public int getSourcesCount() { return mSources.size(); } public InsetsSource sourceAt(int index) { return mSources.valueAt(index); } public static @InternalInsetType ArraySet<Integer> toInternalType(@InsetType int insetTypes) { final ArraySet<Integer> result = new ArraySet<>(); if ((insetTypes & Type.TOP_BAR) != 0) { Loading @@ -216,6 +229,20 @@ public class InsetsState implements Parcelable { return result; } public static boolean getDefaultVisibly(@InsetType int type) { switch (type) { case TYPE_TOP_BAR: case TYPE_SIDE_BAR_1: case TYPE_SIDE_BAR_2: case TYPE_SIDE_BAR_3: return true; case TYPE_IME: return false; default: return true; } } public void dump(String prefix, PrintWriter pw) { pw.println(prefix + "InsetsState"); for (int i = mSources.size() - 1; i >= 0; i--) { Loading