-> 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
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());
boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
if (challengeOverlapping && !newCurPage.isSmall()
&& mPageListeningToSlider != newPageIndex) {
- shrinkWidget(newCurPage);
+ newCurPage.shrinkWidget();
}
}
mCurrentPage = newPageIndex;
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.
* @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);
+
+ int x = mTmpLoc[0];
+ int y = mTmpLoc[1];
- toView.getLocationInWindow(loc);
- int vX = loc[0];
- int vY = loc[1];
+ toView.getLocationInWindow(mTmpLoc);
+ int vX = mTmpLoc[0];
+ int vY = mTmpLoc[1];
pt[0] += x - vX;
pt[1] += y - vY;
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();
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.
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
* @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) {
setChallengeTop(challengeTop, false);
}
- public void shrinkWidget(int challengeTop) {
+ public void shrinkWidget() {
mIsSmall = true;
- setChallengeTop(challengeTop, true);
+ setChallengeTop(mSmallWidgetHeight, true);
}
public void resetSize() {
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;
}
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) {
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();
} else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
setScrimView(child);
}
-
if (child.getVisibility() == GONE) continue;
+ }
+
+ // 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);
+ }
- measureChildWithMargins(child, 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);
+ }
}
}
}
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);
}
if (mChallengeView == null) return 0;
final int layoutBottom = getLayoutBottom();
- final int challengeHeight = mChallengeView.getHeight();
+ final int challengeHeight = mChallengeView.getMeasuredHeight();
return layoutBottom - challengeHeight;
}
final int bottomMargin = (mChallengeView == null)
? 0
: ((LayoutParams) mChallengeView.getLayoutParams()).bottomMargin;
- final int layoutBottom = getHeight() - getPaddingBottom() - bottomMargin;
+ final int layoutBottom = getMeasuredHeight() - getPaddingBottom() - bottomMargin;
return layoutBottom;
}