KeyguardViewStateManager.java revision 196cde973fd1635f0ac3150caab40287aacb9846
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 int[] mTmpPoint = new int[2]; 27 private int[] mTmpLoc = new int[2]; 28 29 private KeyguardSecurityView mKeyguardSecurityContainer; 30 private static final int SCREEN_ON_HINT_DURATION = 1000; 31 private static final int SCREEN_ON_RING_HINT_DELAY = 300; 32 Handler mMainQueue = new Handler(Looper.myLooper()); 33 34 // transport control states 35 static final int TRANSPORT_GONE = 0; 36 static final int TRANSPORT_INVISIBLE = 1; 37 static final int TRANSPORT_VISIBLE = 2; 38 39 private int mTransportState = TRANSPORT_GONE; 40 41 int mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE; 42 43 // Paged view state 44 private int mPageListeningToSlider = -1; 45 private int mCurrentPage = -1; 46 47 int mChallengeTop = 0; 48 49 public KeyguardViewStateManager() { 50 } 51 52 public void setPagedView(KeyguardWidgetPager pagedView) { 53 mPagedView = pagedView; 54 } 55 56 public void setChallengeLayout(ChallengeLayout layout) { 57 mChallengeLayout = layout; 58 } 59 60 public boolean isChallengeShowing() { 61 if (mChallengeLayout != null) { 62 return mChallengeLayout.isChallengeShowing(); 63 } 64 return false; 65 } 66 67 public boolean isChallengeOverlapping() { 68 if (mChallengeLayout != null) { 69 return mChallengeLayout.isChallengeOverlapping(); 70 } 71 return false; 72 } 73 74 public void setSecurityViewContainer(KeyguardSecurityView container) { 75 mKeyguardSecurityContainer = container; 76 } 77 78 public void onPageBeginMoving() { 79 if (mChallengeLayout.isChallengeShowing()) { 80 mChallengeLayout.showChallenge(false); 81 } 82 if (mHideHintsRunnable != null) { 83 mMainQueue.removeCallbacks(mHideHintsRunnable); 84 mHideHintsRunnable = null; 85 } 86 } 87 88 public void onPageEndMoving() { 89 } 90 91 public void showBouncer(boolean show) { 92 mChallengeLayout.showBouncer(); 93 } 94 95 public void fadeOutSecurity(int duration) { 96 ((View) mKeyguardSecurityContainer).animate().alpha(0).setDuration(duration); 97 } 98 99 public void fadeInSecurity(int duration) { 100 ((View) mKeyguardSecurityContainer).animate().alpha(1f).setDuration(duration); 101 } 102 103 public void onPageSwitching(View newPage, int newPageIndex) { 104 if (mPagedView != null && mChallengeLayout instanceof SlidingChallengeLayout) { 105 boolean isCameraPage = newPage instanceof CameraWidgetFrame; 106 ((SlidingChallengeLayout) mChallengeLayout).setChallengeInteractive(!isCameraPage); 107 } 108 } 109 110 public void onPageSwitched(View newPage, int newPageIndex) { 111 // Reset the previous page size and ensure the current page is sized appropriately. 112 // We only modify the page state if it is not currently under control by the slider. 113 // This prevents conflicts. 114 115 // If the page hasn't switched, don't bother with any of this 116 if (mCurrentPage != newPageIndex) return; 117 118 if (mPagedView != null && mChallengeLayout != null) { 119 KeyguardWidgetFrame prevPage = mPagedView.getWidgetPageAt(mCurrentPage); 120 if (prevPage != null && mCurrentPage != mPageListeningToSlider) { 121 prevPage.resetSize(); 122 } 123 124 KeyguardWidgetFrame newCurPage = mPagedView.getWidgetPageAt(newPageIndex); 125 boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping(); 126 if (challengeOverlapping && !newCurPage.isSmall() 127 && mPageListeningToSlider != newPageIndex) { 128 newCurPage.shrinkWidget(); 129 } 130 } 131 mCurrentPage = newPageIndex; 132 } 133 134 private int getChallengeTopRelativeToFrame(KeyguardWidgetFrame frame, int top) { 135 mTmpPoint[0] = 0; 136 mTmpPoint[1] = top; 137 mapPoint((View) mChallengeLayout, frame, mTmpPoint); 138 return mTmpPoint[1]; 139 } 140 141 /** 142 * Simple method to map a point from one view's coordinates to another's. Note: this method 143 * doesn't account for transforms, so if the views will be transformed, this should not be used. 144 * 145 * @param fromView The view to which the point is relative 146 * @param toView The view into which the point should be mapped 147 * @param pt The point 148 */ 149 private void mapPoint(View fromView, View toView, int pt[]) { 150 fromView.getLocationInWindow(mTmpLoc); 151 152 int x = mTmpLoc[0]; 153 int y = mTmpLoc[1]; 154 155 toView.getLocationInWindow(mTmpLoc); 156 int vX = mTmpLoc[0]; 157 int vY = mTmpLoc[1]; 158 159 pt[0] += x - vX; 160 pt[1] += y - vY; 161 } 162 163 @Override 164 public void onScrollStateChanged(int scrollState) { 165 if (mPagedView == null || mChallengeLayout == null) return; 166 boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping(); 167 168 if (scrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) { 169 KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider); 170 if (frame == null) return; 171 172 if (!challengeOverlapping) { 173 frame.resetSize(); 174 } 175 frame.hideFrame(this); 176 177 if (challengeOverlapping) { 178 mPagedView.setOnlyAllowEdgeSwipes(true); 179 } else { 180 mPagedView.setOnlyAllowEdgeSwipes(false); 181 } 182 183 if (mChallengeLayout.isChallengeShowing()) { 184 mKeyguardSecurityContainer.onResume(); 185 } else { 186 mKeyguardSecurityContainer.onPause(); 187 } 188 mPageListeningToSlider = -1; 189 } else if (mLastScrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) { 190 // Whether dragging or settling, if the last state was idle, we use this signal 191 // to update the current page who will receive events from the sliding challenge. 192 // We resize the frame as appropriate. 193 mPageListeningToSlider = mPagedView.getNextPage(); 194 KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider); 195 if (frame == null) return; 196 197 frame.showFrame(this); 198 199 // As soon as the security begins sliding, the widget becomes small (if it wasn't 200 // small to begin with). 201 if (!frame.isSmall()) { 202 // We need to fetch the final page, in case the pages are in motion. 203 mPageListeningToSlider = mPagedView.getNextPage(); 204 frame.shrinkWidget(); 205 } 206 // View is on the move. Pause the security view until it completes. 207 mKeyguardSecurityContainer.onPause(); 208 } 209 mLastScrollState = scrollState; 210 } 211 212 @Override 213 public void onScrollPositionChanged(float scrollPosition, int challengeTop) { 214 mChallengeTop = challengeTop; 215 KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider); 216 if (frame != null) { 217 frame.adjustFrame(getChallengeTopRelativeToFrame(frame, mChallengeTop)); 218 } 219 } 220 221 private Runnable mHideHintsRunnable = new Runnable() { 222 @Override 223 public void run() { 224 if (mPagedView != null) { 225 mPagedView.hideOutlinesAndSidePages(); 226 } 227 } 228 }; 229 230 public void showUsabilityHints() { 231 mMainQueue.postDelayed( new Runnable() { 232 @Override 233 public void run() { 234 mKeyguardSecurityContainer.showUsabilityHint(); 235 } 236 } , SCREEN_ON_RING_HINT_DELAY); 237 mPagedView.showInitialPageHints(); 238 if (mHideHintsRunnable != null) { 239 mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION); 240 } 241 } 242 243 public void setTransportState(int state) { 244 mTransportState = state; 245 } 246 247 public int getTransportState() { 248 return mTransportState; 249 } 250} 251