KeyguardViewStateManager.java revision 70aa528b73fc54fe7896ac1ae349569d83caba59
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.internal.policy.impl.keyguard; 17 18import android.os.Handler; 19import android.os.Looper; 20import android.view.View; 21 22public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChallengeScrolledListener { 23 24 private KeyguardWidgetPager mPagedView; 25 private ChallengeLayout mChallengeLayout; 26 private Runnable mHideHintsRunnable; 27 private int[] mTmpPoint = new int[2]; 28 private int[] mTmpLoc = new int[2]; 29 30 private KeyguardSecurityView mKeyguardSecurityContainer; 31 private static final int SCREEN_ON_HINT_DURATION = 1000; 32 private static final int SCREEN_ON_RING_HINT_DELAY = 300; 33 Handler mMainQueue = new Handler(Looper.myLooper()); 34 35 int mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE; 36 37 // Paged view state 38 private int mPageListeningToSlider = -1; 39 private int mCurrentPage = -1; 40 41 int mChallengeTop = 0; 42 43 public KeyguardViewStateManager() { 44 } 45 46 public void setPagedView(KeyguardWidgetPager pagedView) { 47 mPagedView = pagedView; 48 } 49 50 public void setChallengeLayout(ChallengeLayout layout) { 51 mChallengeLayout = layout; 52 } 53 54 public boolean isChallengeShowing() { 55 if (mChallengeLayout != null) { 56 return mChallengeLayout.isChallengeShowing(); 57 } 58 return false; 59 } 60 61 public boolean isChallengeOverlapping() { 62 if (mChallengeLayout != null) { 63 return mChallengeLayout.isChallengeOverlapping(); 64 } 65 return false; 66 } 67 68 public void setSecurityViewContainer(KeyguardSecurityView container) { 69 mKeyguardSecurityContainer = container; 70 } 71 72 public void onPageBeginMoving() { 73 if (mChallengeLayout.isChallengeShowing()) { 74 mChallengeLayout.showChallenge(false); 75 } 76 if (mHideHintsRunnable != null) { 77 mMainQueue.removeCallbacks(mHideHintsRunnable); 78 mHideHintsRunnable = null; 79 } 80 } 81 82 public void onPageEndMoving() { 83 } 84 85 public void showBouncer(boolean show) { 86 mChallengeLayout.showBouncer(); 87 } 88 89 public void onPageSwitch(View newPage, int newPageIndex) { 90 // Reset the previous page size and ensure the current page is sized appropriately. 91 // We only modify the page state if it is not currently under control by the slider. 92 // This prevents conflicts. 93 if (mPagedView != null && mChallengeLayout != null) { 94 KeyguardWidgetFrame prevPage = mPagedView.getWidgetPageAt(mCurrentPage); 95 if (prevPage != null && mCurrentPage != mPageListeningToSlider) { 96 prevPage.resetSize(); 97 } 98 99 KeyguardWidgetFrame newCurPage = mPagedView.getWidgetPageAt(newPageIndex); 100 boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping(); 101 if (challengeOverlapping && !newCurPage.isSmall() 102 && mPageListeningToSlider != newPageIndex) { 103 newCurPage.shrinkWidget(); 104 } 105 } 106 mCurrentPage = newPageIndex; 107 } 108 109 private int getChallengeTopRelativeToFrame(KeyguardWidgetFrame frame, int top) { 110 mTmpPoint[0] = 0; 111 mTmpPoint[1] = top; 112 mapPoint((View) mChallengeLayout, frame, mTmpPoint); 113 return mTmpPoint[1]; 114 } 115 116 /** 117 * Simple method to map a point from one view's coordinates to another's. Note: this method 118 * doesn't account for transforms, so if the views will be transformed, this should not be used. 119 * 120 * @param fromView The view to which the point is relative 121 * @param toView The view into which the point should be mapped 122 * @param pt The point 123 */ 124 private void mapPoint(View fromView, View toView, int pt[]) { 125 fromView.getLocationInWindow(mTmpLoc); 126 127 int x = mTmpLoc[0]; 128 int y = mTmpLoc[1]; 129 130 toView.getLocationInWindow(mTmpLoc); 131 int vX = mTmpLoc[0]; 132 int vY = mTmpLoc[1]; 133 134 pt[0] += x - vX; 135 pt[1] += y - vY; 136 } 137 138 @Override 139 public void onScrollStateChanged(int scrollState) { 140 if (mPagedView == null || mChallengeLayout == null) return; 141 boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping(); 142 143 if (scrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) { 144 KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider); 145 if (frame == null) return; 146 147 if (!challengeOverlapping) { 148 frame.resetSize(); 149 } 150 frame.onChallengeActive(mChallengeLayout.isChallengeShowing()); 151 frame.hideFrame(this); 152 153 if (challengeOverlapping) { 154 mPagedView.setOnlyAllowEdgeSwipes(true); 155 } else { 156 mPagedView.setOnlyAllowEdgeSwipes(false); 157 } 158 159 if (mChallengeLayout.isChallengeShowing()) { 160 mKeyguardSecurityContainer.onResume(); 161 } else { 162 mKeyguardSecurityContainer.onPause(); 163 } 164 mPageListeningToSlider = -1; 165 } else if (mLastScrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) { 166 // Whether dragging or settling, if the last state was idle, we use this signal 167 // to update the current page who will receive events from the sliding challenge. 168 // We resize the frame as appropriate. 169 mPageListeningToSlider = mPagedView.getNextPage(); 170 KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider); 171 if (frame == null) return; 172 173 frame.showFrame(this); 174 175 // As soon as the security begins sliding, the widget becomes small (if it wasn't 176 // small to begin with). 177 if (!frame.isSmall()) { 178 // We need to fetch the final page, in case the pages are in motion. 179 mPageListeningToSlider = mPagedView.getNextPage(); 180 frame.shrinkWidget(); 181 } 182 // View is on the move. Pause the security view until it completes. 183 mKeyguardSecurityContainer.onPause(); 184 185 frame.onChallengeActive(true); 186 } 187 mLastScrollState = scrollState; 188 } 189 190 @Override 191 public void onScrollPositionChanged(float scrollPosition, int challengeTop) { 192 mChallengeTop = challengeTop; 193 KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider); 194 if (frame != null) { 195 frame.adjustFrame(getChallengeTopRelativeToFrame(frame, mChallengeTop)); 196 } 197 } 198 199 public void showUsabilityHints() { 200 mMainQueue.postDelayed( new Runnable() { 201 @Override 202 public void run() { 203 mKeyguardSecurityContainer.showUsabilityHint(); 204 } 205 } , SCREEN_ON_RING_HINT_DELAY); 206 mPagedView.showInitialPageHints(); 207 mHideHintsRunnable = new Runnable() { 208 @Override 209 public void run() { 210 mPagedView.hideOutlinesAndSidePages(); 211 mHideHintsRunnable = null; 212 } 213 }; 214 215 mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION); 216 } 217} 218