Loading core/java/android/view/InsetsController.java +24 −2 Original line number Diff line number Diff line Loading @@ -38,9 +38,14 @@ public class InsetsController implements WindowInsetsController { private final InsetsState mState = new InsetsState(); private final Rect mFrame = new Rect(); private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>(); private final ViewRootImpl mViewRoot; private final SparseArray<InsetsSourceControl> mTmpControlArray = new SparseArray<>(); public InsetsController(ViewRootImpl viewRoot) { mViewRoot = viewRoot; } void onFrameChanged(Rect frame) { mFrame.set(frame); } Loading @@ -49,8 +54,14 @@ public class InsetsController implements WindowInsetsController { return mState; } public void setState(InsetsState state) { boolean onStateChanged(InsetsState state) { if (mState.equals(state)) { return false; } mState.set(state); applyLocalVisibilityOverride(); mViewRoot.notifyInsetsChanged(); return true; } /** Loading Loading @@ -105,17 +116,28 @@ public class InsetsController implements WindowInsetsController { } } private void applyLocalVisibilityOverride() { for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { final InsetsSourceConsumer controller = mSourceConsumers.valueAt(i); controller.applyLocalVisibilityOverride(); } } @VisibleForTesting public @NonNull InsetsSourceConsumer getSourceConsumer(@InternalInsetType int type) { InsetsSourceConsumer controller = mSourceConsumers.get(type); if (controller != null) { return controller; } controller = new InsetsSourceConsumer(type, mState, Transaction::new); controller = new InsetsSourceConsumer(type, mState, Transaction::new, this); mSourceConsumers.put(type, controller); return controller; } void notifyVisibilityChanged() { mViewRoot.notifyInsetsChanged(); } void dump(String prefix, PrintWriter pw) { pw.println(prefix); pw.println("InsetsController:"); mState.dump(prefix + " ", pw); Loading core/java/android/view/InsetsSourceConsumer.java +23 −8 Original line number Diff line number Diff line Loading @@ -33,27 +33,31 @@ public class InsetsSourceConsumer { private final Supplier<Transaction> mTransactionSupplier; private final @InternalInsetType int mType; private final InsetsState mState; private @Nullable InsetsSourceControl mControl; private final InsetsController mController; private @Nullable InsetsSourceControl mSourceControl; private boolean mHidden; public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state, Supplier<Transaction> transactionSupplier) { Supplier<Transaction> transactionSupplier, InsetsController controller) { mType = type; mState = state; mTransactionSupplier = transactionSupplier; mController = controller; } public void setControl(@Nullable InsetsSourceControl control) { if (mControl == control) { if (mSourceControl == control) { return; } mControl = control; mSourceControl = control; applyHiddenToControl(); applyLocalVisibilityOverride(); mController.notifyVisibilityChanged(); } @VisibleForTesting public InsetsSourceControl getControl() { return mControl; return mSourceControl; } int getType() { Loading @@ -70,25 +74,36 @@ public class InsetsSourceConsumer { setHidden(true); } void applyLocalVisibilityOverride() { // If we don't have control, we are not able to change the visibility. if (mSourceControl == null) { return; } mState.getSource(mType).setVisible(!mHidden); } private void setHidden(boolean hidden) { if (mHidden == hidden) { return; } mHidden = hidden; applyHiddenToControl(); applyLocalVisibilityOverride(); mController.notifyVisibilityChanged(); } private void applyHiddenToControl() { if (mControl == null) { if (mSourceControl == null) { return; } // TODO: Animation final Transaction t = mTransactionSupplier.get(); if (mHidden) { t.hide(mControl.getLeash()); t.hide(mSourceControl.getLeash()); } else { t.show(mControl.getLeash()); t.show(mSourceControl.getLeash()); } t.apply(); } Loading core/java/android/view/ViewRootImpl.java +21 −27 Original line number Diff line number Diff line Loading @@ -462,7 +462,7 @@ public final class ViewRootImpl implements ViewParent, final DisplayCutout.ParcelableWrapper mPendingDisplayCutout = new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT); boolean mPendingAlwaysConsumeNavBar; private InsetsState mPendingInsets = new InsetsState(); private InsetsState mTempInsets = new InsetsState(); final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets = new ViewTreeObserver.InternalInsetsInfo(); Loading Loading @@ -550,7 +550,7 @@ public final class ViewRootImpl implements ViewParent, InputEventConsistencyVerifier.isInstrumentationEnabled() ? new InputEventConsistencyVerifier(this, 0) : null; private final InsetsController mInsetsController = new InsetsController(); private final InsetsController mInsetsController = new InsetsController(this); static final class SystemUiVisibilityInfo { int seq; Loading Loading @@ -821,7 +821,7 @@ public final class ViewRootImpl implements ViewParent, getHostVisibility(), mDisplay.getDisplayId(), mTmpFrame, mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel, mInsetsController.getState()); mTempInsets); setFrame(mTmpFrame); } catch (RemoteException e) { mAdded = false; Loading Loading @@ -849,7 +849,7 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mAlwaysConsumeNavBar = (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR) != 0; mPendingAlwaysConsumeNavBar = mAttachInfo.mAlwaysConsumeNavBar; mPendingInsets = mInsetsController.getState(); mInsetsController.onStateChanged(mTempInsets); if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow); if (res < WindowManagerGlobal.ADD_OKAY) { mAttachInfo.mRootView = null; Loading Loading @@ -1342,6 +1342,19 @@ public final class ViewRootImpl implements ViewParent, scheduleTraversals(); } void notifyInsetsChanged() { if (!USE_NEW_INSETS) { return; } mApplyInsetsRequested = true; // If this changes during traversal, no need to schedule another one as it will dispatch it // during the current traversal. if (!mIsInTraversal) { scheduleTraversals(); } } @Override public void requestLayout() { if (!mHandlingLayoutInLayoutRequest) { Loading Loading @@ -2027,9 +2040,6 @@ public final class ViewRootImpl implements ViewParent, if (mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar) { insetsChanged = true; } if (!mPendingInsets.equals(mInsetsController.getState())) { insetsChanged = true; } if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) { windowSizeMayChange = true; Loading Loading @@ -2223,8 +2233,6 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mStableInsets); final boolean cutoutChanged = !mPendingDisplayCutout.equals( mAttachInfo.mDisplayCutout); final boolean insetsStateChanged = !mPendingInsets.equals( mInsetsController.getState()); final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets); final boolean surfaceSizeChanged = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0; Loading Loading @@ -2262,10 +2270,6 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mAlwaysConsumeNavBar = mPendingAlwaysConsumeNavBar; contentInsetsChanged = true; } if (insetsStateChanged) { mInsetsController.setState(mPendingInsets); contentInsetsChanged = true; } if (contentInsetsChanged || mLastSystemUiVisibility != mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested || mLastOverscanRequested != mAttachInfo.mOverscanRequested Loading Loading @@ -4375,22 +4379,12 @@ public final class ViewRootImpl implements ViewParent, } break; case MSG_INSETS_CHANGED: mPendingInsets = (InsetsState) msg.obj; // TODO: Full traversal not needed here. if (USE_NEW_INSETS) { requestLayout(); } mInsetsController.onStateChanged((InsetsState) msg.obj); break; case MSG_INSETS_CONTROL_CHANGED: { SomeArgs args = (SomeArgs) msg.obj; mPendingInsets = (InsetsState) args.arg1; mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2); // TODO: Full traversal not necessarily needed here. if (USE_NEW_INSETS) { requestLayout(); } mInsetsController.onStateChanged((InsetsState) args.arg1); break; } case MSG_WINDOW_MOVED: Loading Loading @@ -6791,7 +6785,7 @@ public final class ViewRootImpl implements ViewParent, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber, mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets, mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout, mPendingMergedConfiguration, mSurface, mPendingInsets); mPendingMergedConfiguration, mSurface, mTempInsets); mPendingAlwaysConsumeNavBar = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0; Loading @@ -6808,7 +6802,7 @@ public final class ViewRootImpl implements ViewParent, mTranslator.translateRectInScreenToAppWindow(mPendingStableInsets); } setFrame(mTmpFrame); mInsetsController.onStateChanged(mTempInsets); return relayoutResult; } Loading core/tests/coretests/src/android/view/InsetsControllerTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.view; import static android.view.InsetsState.TYPE_TOP_BAR; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNull; import static org.mockito.Mockito.mock; import android.platform.test.annotations.Presubmit; import android.support.test.filters.FlakyTest; Loading @@ -33,7 +34,7 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class InsetsControllerTest { private InsetsController mController = new InsetsController(); private InsetsController mController = new InsetsController(mock(ViewRootImpl.class)); private SurfaceSession mSession = new SurfaceSession(); private SurfaceControl mLeash; Loading core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ public class InsetsSourceConsumerTest { .setName("testSurface") .build(); mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, new InsetsState(), () -> mMockTransaction); () -> mMockTransaction, mMockController); mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash)); } Loading Loading
core/java/android/view/InsetsController.java +24 −2 Original line number Diff line number Diff line Loading @@ -38,9 +38,14 @@ public class InsetsController implements WindowInsetsController { private final InsetsState mState = new InsetsState(); private final Rect mFrame = new Rect(); private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>(); private final ViewRootImpl mViewRoot; private final SparseArray<InsetsSourceControl> mTmpControlArray = new SparseArray<>(); public InsetsController(ViewRootImpl viewRoot) { mViewRoot = viewRoot; } void onFrameChanged(Rect frame) { mFrame.set(frame); } Loading @@ -49,8 +54,14 @@ public class InsetsController implements WindowInsetsController { return mState; } public void setState(InsetsState state) { boolean onStateChanged(InsetsState state) { if (mState.equals(state)) { return false; } mState.set(state); applyLocalVisibilityOverride(); mViewRoot.notifyInsetsChanged(); return true; } /** Loading Loading @@ -105,17 +116,28 @@ public class InsetsController implements WindowInsetsController { } } private void applyLocalVisibilityOverride() { for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { final InsetsSourceConsumer controller = mSourceConsumers.valueAt(i); controller.applyLocalVisibilityOverride(); } } @VisibleForTesting public @NonNull InsetsSourceConsumer getSourceConsumer(@InternalInsetType int type) { InsetsSourceConsumer controller = mSourceConsumers.get(type); if (controller != null) { return controller; } controller = new InsetsSourceConsumer(type, mState, Transaction::new); controller = new InsetsSourceConsumer(type, mState, Transaction::new, this); mSourceConsumers.put(type, controller); return controller; } void notifyVisibilityChanged() { mViewRoot.notifyInsetsChanged(); } void dump(String prefix, PrintWriter pw) { pw.println(prefix); pw.println("InsetsController:"); mState.dump(prefix + " ", pw); Loading
core/java/android/view/InsetsSourceConsumer.java +23 −8 Original line number Diff line number Diff line Loading @@ -33,27 +33,31 @@ public class InsetsSourceConsumer { private final Supplier<Transaction> mTransactionSupplier; private final @InternalInsetType int mType; private final InsetsState mState; private @Nullable InsetsSourceControl mControl; private final InsetsController mController; private @Nullable InsetsSourceControl mSourceControl; private boolean mHidden; public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state, Supplier<Transaction> transactionSupplier) { Supplier<Transaction> transactionSupplier, InsetsController controller) { mType = type; mState = state; mTransactionSupplier = transactionSupplier; mController = controller; } public void setControl(@Nullable InsetsSourceControl control) { if (mControl == control) { if (mSourceControl == control) { return; } mControl = control; mSourceControl = control; applyHiddenToControl(); applyLocalVisibilityOverride(); mController.notifyVisibilityChanged(); } @VisibleForTesting public InsetsSourceControl getControl() { return mControl; return mSourceControl; } int getType() { Loading @@ -70,25 +74,36 @@ public class InsetsSourceConsumer { setHidden(true); } void applyLocalVisibilityOverride() { // If we don't have control, we are not able to change the visibility. if (mSourceControl == null) { return; } mState.getSource(mType).setVisible(!mHidden); } private void setHidden(boolean hidden) { if (mHidden == hidden) { return; } mHidden = hidden; applyHiddenToControl(); applyLocalVisibilityOverride(); mController.notifyVisibilityChanged(); } private void applyHiddenToControl() { if (mControl == null) { if (mSourceControl == null) { return; } // TODO: Animation final Transaction t = mTransactionSupplier.get(); if (mHidden) { t.hide(mControl.getLeash()); t.hide(mSourceControl.getLeash()); } else { t.show(mControl.getLeash()); t.show(mSourceControl.getLeash()); } t.apply(); } Loading
core/java/android/view/ViewRootImpl.java +21 −27 Original line number Diff line number Diff line Loading @@ -462,7 +462,7 @@ public final class ViewRootImpl implements ViewParent, final DisplayCutout.ParcelableWrapper mPendingDisplayCutout = new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT); boolean mPendingAlwaysConsumeNavBar; private InsetsState mPendingInsets = new InsetsState(); private InsetsState mTempInsets = new InsetsState(); final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets = new ViewTreeObserver.InternalInsetsInfo(); Loading Loading @@ -550,7 +550,7 @@ public final class ViewRootImpl implements ViewParent, InputEventConsistencyVerifier.isInstrumentationEnabled() ? new InputEventConsistencyVerifier(this, 0) : null; private final InsetsController mInsetsController = new InsetsController(); private final InsetsController mInsetsController = new InsetsController(this); static final class SystemUiVisibilityInfo { int seq; Loading Loading @@ -821,7 +821,7 @@ public final class ViewRootImpl implements ViewParent, getHostVisibility(), mDisplay.getDisplayId(), mTmpFrame, mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel, mInsetsController.getState()); mTempInsets); setFrame(mTmpFrame); } catch (RemoteException e) { mAdded = false; Loading Loading @@ -849,7 +849,7 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mAlwaysConsumeNavBar = (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR) != 0; mPendingAlwaysConsumeNavBar = mAttachInfo.mAlwaysConsumeNavBar; mPendingInsets = mInsetsController.getState(); mInsetsController.onStateChanged(mTempInsets); if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow); if (res < WindowManagerGlobal.ADD_OKAY) { mAttachInfo.mRootView = null; Loading Loading @@ -1342,6 +1342,19 @@ public final class ViewRootImpl implements ViewParent, scheduleTraversals(); } void notifyInsetsChanged() { if (!USE_NEW_INSETS) { return; } mApplyInsetsRequested = true; // If this changes during traversal, no need to schedule another one as it will dispatch it // during the current traversal. if (!mIsInTraversal) { scheduleTraversals(); } } @Override public void requestLayout() { if (!mHandlingLayoutInLayoutRequest) { Loading Loading @@ -2027,9 +2040,6 @@ public final class ViewRootImpl implements ViewParent, if (mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar) { insetsChanged = true; } if (!mPendingInsets.equals(mInsetsController.getState())) { insetsChanged = true; } if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) { windowSizeMayChange = true; Loading Loading @@ -2223,8 +2233,6 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mStableInsets); final boolean cutoutChanged = !mPendingDisplayCutout.equals( mAttachInfo.mDisplayCutout); final boolean insetsStateChanged = !mPendingInsets.equals( mInsetsController.getState()); final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets); final boolean surfaceSizeChanged = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0; Loading Loading @@ -2262,10 +2270,6 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mAlwaysConsumeNavBar = mPendingAlwaysConsumeNavBar; contentInsetsChanged = true; } if (insetsStateChanged) { mInsetsController.setState(mPendingInsets); contentInsetsChanged = true; } if (contentInsetsChanged || mLastSystemUiVisibility != mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested || mLastOverscanRequested != mAttachInfo.mOverscanRequested Loading Loading @@ -4375,22 +4379,12 @@ public final class ViewRootImpl implements ViewParent, } break; case MSG_INSETS_CHANGED: mPendingInsets = (InsetsState) msg.obj; // TODO: Full traversal not needed here. if (USE_NEW_INSETS) { requestLayout(); } mInsetsController.onStateChanged((InsetsState) msg.obj); break; case MSG_INSETS_CONTROL_CHANGED: { SomeArgs args = (SomeArgs) msg.obj; mPendingInsets = (InsetsState) args.arg1; mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2); // TODO: Full traversal not necessarily needed here. if (USE_NEW_INSETS) { requestLayout(); } mInsetsController.onStateChanged((InsetsState) args.arg1); break; } case MSG_WINDOW_MOVED: Loading Loading @@ -6791,7 +6785,7 @@ public final class ViewRootImpl implements ViewParent, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber, mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets, mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout, mPendingMergedConfiguration, mSurface, mPendingInsets); mPendingMergedConfiguration, mSurface, mTempInsets); mPendingAlwaysConsumeNavBar = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0; Loading @@ -6808,7 +6802,7 @@ public final class ViewRootImpl implements ViewParent, mTranslator.translateRectInScreenToAppWindow(mPendingStableInsets); } setFrame(mTmpFrame); mInsetsController.onStateChanged(mTempInsets); return relayoutResult; } Loading
core/tests/coretests/src/android/view/InsetsControllerTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.view; import static android.view.InsetsState.TYPE_TOP_BAR; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNull; import static org.mockito.Mockito.mock; import android.platform.test.annotations.Presubmit; import android.support.test.filters.FlakyTest; Loading @@ -33,7 +34,7 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class InsetsControllerTest { private InsetsController mController = new InsetsController(); private InsetsController mController = new InsetsController(mock(ViewRootImpl.class)); private SurfaceSession mSession = new SurfaceSession(); private SurfaceControl mLeash; Loading
core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ public class InsetsSourceConsumerTest { .setName("testSurface") .build(); mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, new InsetsState(), () -> mMockTransaction); () -> mMockTransaction, mMockController); mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash)); } Loading