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; }