From 8a7785c7aa2df74203276299e10b0d9056cd0560 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Mon, 29 Oct 2012 22:01:33 -0700 Subject: [PATCH] Cleaning up the way in which the challenge influences widget size on first measure pass -> This change ensures that on first draw, the widget is the appropriate size if the security challenge is covering it. -> This change is in preparation for some new policy surrounding widget sizing -- with this new policy, a given widget may need to be small even if the page is not being covered by the challenge. Hence, we propogate this small size to all the pages, whether or not they are covered. The pages will eventually use this. -> Ensure that paging hints are shown correctly (with the new sticky widget logic the page can be switched, and we weren't always seeing the appropriate hints). -> Also ensuring that the page is set correctly on first draw -- generally this change should make it so everything is right on the first draw. Change-Id: I7e03be9b027aed0ebb0fada05652b4226fd23897 --- .../keyguard/KeyguardViewStateManager.java | 34 ++++------ .../impl/keyguard/KeyguardWidgetFrame.java | 10 ++- .../impl/keyguard/KeyguardWidgetPager.java | 62 ++++++++++++++++++- .../impl/keyguard/SlidingChallengeLayout.java | 31 ++++++---- 4 files changed, 100 insertions(+), 37 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java index 78d0e7ed3ec11..85245ba439b1c 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java @@ -24,8 +24,10 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle private KeyguardWidgetPager mPagedView; private ChallengeLayout mChallengeLayout; private Runnable mHideHintsRunnable; - private KeyguardSecurityView mKeyguardSecurityContainer; private int[] mTmpPoint = new int[2]; + private int[] mTmpLoc = new int[2]; + + private KeyguardSecurityView mKeyguardSecurityContainer; private static final int SCREEN_ON_HINT_DURATION = 1000; private static final int SCREEN_ON_RING_HINT_DELAY = 300; Handler mMainQueue = new Handler(Looper.myLooper()); @@ -91,7 +93,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping(); if (challengeOverlapping && !newCurPage.isSmall() && mPageListeningToSlider != newPageIndex) { - shrinkWidget(newCurPage); + newCurPage.shrinkWidget(); } } mCurrentPage = newPageIndex; @@ -104,15 +106,6 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle return mTmpPoint[1]; } - private void shrinkWidget(KeyguardWidgetFrame frame) { - if (frame != null && mChallengeLayout != null && - mChallengeLayout instanceof SlidingChallengeLayout) { - SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout; - int top = scl.getMaxChallengeTop(); - frame.shrinkWidget(getChallengeTopRelativeToFrame(frame, top)); - } - } - /** * Simple method to map a point from one view's coordinates to another's. Note: this method * doesn't account for transforms, so if the views will be transformed, this should not be used. @@ -121,15 +114,15 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle * @param toView The view into which the point should be mapped * @param pt The point */ - public void mapPoint(View fromView, View toView, int pt[]) { - int[] loc = new int[2]; - fromView.getLocationInWindow(loc); - int x = loc[0]; - int y = loc[1]; + private void mapPoint(View fromView, View toView, int pt[]) { + fromView.getLocationInWindow(mTmpLoc); - toView.getLocationInWindow(loc); - int vX = loc[0]; - int vY = loc[1]; + int x = mTmpLoc[0]; + int y = mTmpLoc[1]; + + toView.getLocationInWindow(mTmpLoc); + int vX = mTmpLoc[0]; + int vY = mTmpLoc[1]; pt[0] += x - vX; pt[1] += y - vY; @@ -177,8 +170,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle if (!frame.isSmall()) { // We need to fetch the final page, in case the pages are in motion. mPageListeningToSlider = mPagedView.getNextPage(); - System.out.println("Shrink widget from scroll state changed!"); - shrinkWidget(frame); + frame.shrinkWidget(); } // View is on the move. Pause the security view until it completes. mKeyguardSecurityContainer.onPause(); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java index 7871fcba3fca6..e9c90a77b55b5 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java @@ -62,6 +62,7 @@ public class KeyguardWidgetFrame extends FrameLayout { private float mBackgroundAlphaMultiplier = 1.0f; private Drawable mBackgroundDrawable; private Rect mBackgroundRect = new Rect(); + private static int mSmallWidgetHeight; // Multiple callers may try and adjust the alpha of the frame. When a caller shows // the outlines, we give that caller control, and nobody else can fade them out. @@ -97,6 +98,10 @@ public class KeyguardWidgetFrame extends FrameLayout { cancelLongPress(); } + public void setMaxChallengeTop(int top) { + mSmallWidgetHeight = top - getPaddingTop(); + } + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // Watch for longpress events at this level to make sure @@ -276,7 +281,6 @@ public class KeyguardWidgetFrame extends FrameLayout { * @param height The height of the widget, -1 for full height */ private void setWidgetHeight(int height) { - System.out.println("Set widget height: " + this + " : " + height); boolean needLayout = false; View widget = getContent(); if (widget != null) { @@ -299,9 +303,9 @@ public class KeyguardWidgetFrame extends FrameLayout { setChallengeTop(challengeTop, false); } - public void shrinkWidget(int challengeTop) { + public void shrinkWidget() { mIsSmall = true; - setChallengeTop(challengeTop, true); + setChallengeTop(mSmallWidgetHeight, true); } public void resetSize() { diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java index 30f4a37e5dd05..6d83eb06330a0 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java @@ -56,6 +56,9 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit private float mChildrenOutlineAlpha = 0; private float mSidePagesAlpha = 1f; protected int mScreenCenter; + private boolean mHasLayout = false; + private boolean mHasMeasure = false; + private boolean mShowHintsOnLayout = false; private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000; @@ -435,7 +438,64 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit } public void showInitialPageHints() { - showOutlinesAndSidePages(); + if (mHasLayout) { + showOutlinesAndSidePages(); + } else { + // The layout hints depend on layout being run once + mShowHintsOnLayout = true; + } + } + + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + mHasMeasure = false; + mHasLayout = false; + } + + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + if (mShowHintsOnLayout) { + post(new Runnable() { + @Override + public void run() { + showOutlinesAndSidePages(); + } + }); + mShowHintsOnLayout = false; + } + mHasLayout = true; + } + + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int maxChallengeTop = -1; + View parent = (View) getParent(); + boolean challengeShowing = false; + // Widget pages need to know where the top of the sliding challenge is so that they + // now how big the widget should be when the challenge is up. We compute it here and + // then propagate it to each of our children. + if (parent.getParent() instanceof SlidingChallengeLayout) { + SlidingChallengeLayout scl = (SlidingChallengeLayout) parent.getParent(); + int top = scl.getMaxChallengeTop(); + + // This is a bit evil, but we need to map a coordinate relative to the SCL into a + // coordinate relative to our children, hence we subtract the top padding.s + maxChallengeTop = top - getPaddingTop(); + challengeShowing = scl.isChallengeShowing(); + } + + int count = getChildCount(); + for (int i = 0; i < count; i++) { + KeyguardWidgetFrame frame = getWidgetPageAt(i); + frame.setMaxChallengeTop(maxChallengeTop); + + // On the very first measure pass, if the challenge is showing, we need to make sure + // that the widget on the current page is small. + if (challengeShowing && i == mCurrentPage && !mHasMeasure) { + frame.shrinkWidget(); + } + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); } void animateOutlinesAndSidePages(final boolean show) { diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java index 43edbad2c6eff..35eccbb1e8052 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java @@ -681,6 +681,9 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout final View oldChallengeView = mChallengeView; mChallengeView = null; final int count = getChildCount(); + + // First iteration through the children finds special children and sets any associated + // state. for (int i = 0; i < count; i++) { final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); @@ -699,10 +702,22 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) { setScrimView(child); } - if (child.getVisibility() == GONE) continue; + } - measureChildWithMargins(child, widthSpec, 0, heightSpec, 0); + // We want to measure the challenge view first, for various reasons that I'd rather + // not get into here. + if (mChallengeView != null) { + measureChildWithMargins(mChallengeView, widthSpec, 0, heightSpec, 0); + } + + // Measure the rest of the children + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + // Don't measure the challenge view twice! + if (child != mChallengeView) { + measureChildWithMargins(child, widthSpec, 0, heightSpec, 0); + } } } @@ -747,14 +762,6 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } if (!mHasLayout) { - // We want to trigger the initial listener updates outside of layout pass, - // in case the listeners trigger requestLayout(). - post(new Runnable() { - @Override - public void run() { - sendInitialListenerUpdates(); - } - }); if (mFrameDrawable != null) { mFrameDrawable.setAlpha(0); } @@ -845,7 +852,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout if (mChallengeView == null) return 0; final int layoutBottom = getLayoutBottom(); - final int challengeHeight = mChallengeView.getHeight(); + final int challengeHeight = mChallengeView.getMeasuredHeight(); return layoutBottom - challengeHeight; } @@ -895,7 +902,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout final int bottomMargin = (mChallengeView == null) ? 0 : ((LayoutParams) mChallengeView.getLayoutParams()).bottomMargin; - final int layoutBottom = getHeight() - getPaddingBottom() - bottomMargin; + final int layoutBottom = getMeasuredHeight() - getPaddingBottom() - bottomMargin; return layoutBottom; }