From 954289d9a9b1a26b1621037a427269bdbd67d5bc Mon Sep 17 00:00:00 2001 From: Filip Gruszczynski Date: Thu, 26 Feb 2015 15:46:47 -0800 Subject: [PATCH] Allow polling for WindowInsets. Change-Id: I36feb2403b1bcf6de5d8808734c46999a38e7403 --- api/current.txt | 1 + api/system-current.txt | 1 + core/java/android/view/View.java | 13 +++++++++ core/java/android/view/ViewRootImpl.java | 35 ++++++++++++++++++++---- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/api/current.txt b/api/current.txt index 11db5c30aca7f..20ff37a7d24c4 100644 --- a/api/current.txt +++ b/api/current.txt @@ -34147,6 +34147,7 @@ package android.view { method protected float getRightFadingEdgeStrength(); method protected int getRightPaddingOffset(); method public android.view.View getRootView(); + method public android.view.WindowInsets getRootWindowInsets(); method public float getRotation(); method public float getRotationX(); method public float getRotationY(); diff --git a/api/system-current.txt b/api/system-current.txt index da5986f50249d..11ae5524195d1 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -36315,6 +36315,7 @@ package android.view { method protected float getRightFadingEdgeStrength(); method protected int getRightPaddingOffset(); method public android.view.View getRootView(); + method public android.view.WindowInsets getRootWindowInsets(); method public float getRotation(); method public float getRotationX(); method public float getRotationY(); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 085a3f23dcd76..4f2d4a65e1e82 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -6563,6 +6563,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } + /** + * Provide original WindowInsets that are dispatched to the view hierarchy. The insets are + * only available if the view is attached. + * + * @return WindowInsets from the top of the view hierarchy or null if View is detached + */ + public WindowInsets getRootWindowInsets() { + if (mAttachInfo != null) { + return mAttachInfo.mViewRootImpl.getWindowInsets(false /* forceConstruct */); + } + return null; + } + /** * @hide Compute the insets that should be consumed by this view and the ones * that should propagate to those under it. diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 14b867e2ab3bf..c6f5d8ac13a39 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -265,6 +265,8 @@ public final class ViewRootImpl implements ViewParent, final Rect mDispatchContentInsets = new Rect(); final Rect mDispatchStableInsets = new Rect(); + private WindowInsets mLastWindowInsets; + final Configuration mLastConfiguration = new Configuration(); final Configuration mPendingConfiguration = new Configuration(); @@ -550,6 +552,11 @@ public final class ViewRootImpl implements ViewParent, mPendingContentInsets.set(mAttachInfo.mContentInsets); mPendingStableInsets.set(mAttachInfo.mStableInsets); mPendingVisibleInsets.set(0, 0, 0, 0); + try { + relayoutWindow(attrs, getHostVisibility(), false); + } catch (RemoteException e) { + if (DEBUG_LAYOUT) Log.e(TAG, "failed to relayoutWindow", e); + } if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow); if (res < WindowManagerGlobal.ADD_OKAY) { mAttachInfo.mRootView = null; @@ -1227,13 +1234,29 @@ public final class ViewRootImpl implements ViewParent, m.postTranslate(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop); } + /* package */ WindowInsets getWindowInsets(boolean forceConstruct) { + if (mLastWindowInsets == null || forceConstruct) { + mDispatchContentInsets.set(mAttachInfo.mContentInsets); + mDispatchStableInsets.set(mAttachInfo.mStableInsets); + Rect contentInsets = mDispatchContentInsets; + Rect stableInsets = mDispatchStableInsets; + // For dispatch we preserve old logic, but for direct requests from Views we allow to + // immediately use pending insets. + if (!forceConstruct + && (!mPendingContentInsets.equals(contentInsets) || + !mPendingStableInsets.equals(stableInsets))) { + contentInsets = mPendingContentInsets; + stableInsets = mPendingStableInsets; + } + final boolean isRound = (mIsEmulator && mIsCircularEmulator) || mWindowIsRound; + mLastWindowInsets = new WindowInsets(contentInsets, + null /* windowDecorInsets */, stableInsets, isRound); + } + return mLastWindowInsets; + } + void dispatchApplyInsets(View host) { - mDispatchContentInsets.set(mAttachInfo.mContentInsets); - mDispatchStableInsets.set(mAttachInfo.mStableInsets); - final boolean isRound = (mIsEmulator && mIsCircularEmulator) || mWindowIsRound; - host.dispatchApplyWindowInsets(new WindowInsets( - mDispatchContentInsets, null /* windowDecorInsets */, - mDispatchStableInsets, isRound)); + host.dispatchApplyWindowInsets(getWindowInsets(true /* forceConstruct */)); } private void performTraversals() {