blob: e47edf3021e9d1f8534b9f6dff00fd184d7ffb13 [file] [log] [blame]
Jim Millerb5f3b702012-10-21 19:09:23 -07001/*
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 */
Jim Miller5ecd8112013-01-09 18:50:26 -080016package com.android.keyguard;
Jim Millerd6523da2012-10-21 16:47:02 -070017
John Spurlock56d007b2013-10-28 18:40:56 -040018import android.animation.Animator;
19import android.animation.Animator.AnimatorListener;
20import android.animation.AnimatorListenerAdapter;
Adam Cohen6fb841f2012-10-24 13:15:38 -070021import android.os.Handler;
22import android.os.Looper;
Jim Millerd6523da2012-10-21 16:47:02 -070023import android.view.View;
24
Winson Chung48275d22012-11-05 10:56:31 -080025public class KeyguardViewStateManager implements
26 SlidingChallengeLayout.OnChallengeScrolledListener,
27 ChallengeLayout.OnBouncerStateChangedListener {
Jim Millerd6523da2012-10-21 16:47:02 -070028
Jim Millerc162dd02013-09-25 18:57:43 -070029 private static final String TAG = "KeyguardViewStateManager";
Adam Cohen7f6bb6e2012-11-04 14:00:05 -080030 private KeyguardWidgetPager mKeyguardWidgetPager;
Jim Miller19a52672012-10-23 19:52:04 -070031 private ChallengeLayout mChallengeLayout;
Adam Cohend6f89602012-11-06 11:46:25 -080032 private KeyguardHostView mKeyguardHostView;
Jim Millerd6523da2012-10-21 16:47:02 -070033 private int[] mTmpPoint = new int[2];
Adam Cohen8a7785c2012-10-29 22:01:33 -070034 private int[] mTmpLoc = new int[2];
35
36 private KeyguardSecurityView mKeyguardSecurityContainer;
Adam Cohen6fb841f2012-10-24 13:15:38 -070037 private static final int SCREEN_ON_HINT_DURATION = 1000;
Adam Cohen47c6cfa2012-10-27 18:29:52 -070038 private static final int SCREEN_ON_RING_HINT_DELAY = 300;
Jim Millercaf24fc2013-09-10 18:37:01 -070039 private static final boolean SHOW_INITIAL_PAGE_HINTS = false;
Adam Cohen6fb841f2012-10-24 13:15:38 -070040 Handler mMainQueue = new Handler(Looper.myLooper());
Jim Millerd6523da2012-10-21 16:47:02 -070041
Adam Cohene3643132012-10-28 18:29:17 -070042 int mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE;
43
44 // Paged view state
45 private int mPageListeningToSlider = -1;
46 private int mCurrentPage = -1;
Adam Cohen8caabad2012-11-04 17:23:25 -080047 private int mPageIndexOnPageBeginMoving = -1;
Adam Cohene3643132012-10-28 18:29:17 -070048
Jim Millerd6523da2012-10-21 16:47:02 -070049 int mChallengeTop = 0;
50
John Spurlock56d007b2013-10-28 18:40:56 -040051 private final AnimatorListener mPauseListener = new AnimatorListenerAdapter() {
52 public void onAnimationEnd(Animator animation) {
53 mKeyguardSecurityContainer.onPause();
54 }
55 };
56
57 private final AnimatorListener mResumeListener = new AnimatorListenerAdapter() {
58 public void onAnimationEnd(Animator animation) {
59 if (((View)mKeyguardSecurityContainer).isShown()) {
60 mKeyguardSecurityContainer.onResume(0);
61 }
62 }
63 };
64
Adam Cohend6f89602012-11-06 11:46:25 -080065 public KeyguardViewStateManager(KeyguardHostView hostView) {
66 mKeyguardHostView = hostView;
Jim Millerd6523da2012-10-21 16:47:02 -070067 }
68
69 public void setPagedView(KeyguardWidgetPager pagedView) {
Adam Cohen7f6bb6e2012-11-04 14:00:05 -080070 mKeyguardWidgetPager = pagedView;
71 updateEdgeSwiping();
Jim Millerd6523da2012-10-21 16:47:02 -070072 }
73
Jim Miller19a52672012-10-23 19:52:04 -070074 public void setChallengeLayout(ChallengeLayout layout) {
75 mChallengeLayout = layout;
Adam Cohen7f6bb6e2012-11-04 14:00:05 -080076 updateEdgeSwiping();
77 }
78
79 private void updateEdgeSwiping() {
80 if (mChallengeLayout != null && mKeyguardWidgetPager != null) {
81 if (mChallengeLayout.isChallengeOverlapping()) {
82 mKeyguardWidgetPager.setOnlyAllowEdgeSwipes(true);
83 } else {
84 mKeyguardWidgetPager.setOnlyAllowEdgeSwipes(false);
85 }
86 }
Jim Millerd6523da2012-10-21 16:47:02 -070087 }
88
Winson Chung9dc99232012-10-29 17:43:18 -070089 public boolean isChallengeShowing() {
90 if (mChallengeLayout != null) {
91 return mChallengeLayout.isChallengeShowing();
92 }
93 return false;
94 }
95
Winson Chung70aa5282012-10-30 10:56:37 -070096 public boolean isChallengeOverlapping() {
97 if (mChallengeLayout != null) {
98 return mChallengeLayout.isChallengeOverlapping();
99 }
100 return false;
101 }
102
Adam Cohen6fb841f2012-10-24 13:15:38 -0700103 public void setSecurityViewContainer(KeyguardSecurityView container) {
104 mKeyguardSecurityContainer = container;
105 }
106
Jim Millerb5f3b702012-10-21 19:09:23 -0700107 public void showBouncer(boolean show) {
Jim Miller19a52672012-10-23 19:52:04 -0700108 mChallengeLayout.showBouncer();
Jim Millerb5f3b702012-10-21 19:09:23 -0700109 }
110
Chris Wrenc0ae9e62012-11-05 13:16:31 -0500111 public boolean isBouncing() {
112 return mChallengeLayout.isBouncing();
113 }
114
Adam Cohen70009e42012-10-30 16:48:22 -0700115 public void fadeOutSecurity(int duration) {
John Spurlock56d007b2013-10-28 18:40:56 -0400116 ((View) mKeyguardSecurityContainer).animate().alpha(0f).setDuration(duration)
Jim Miller6b0afad2013-10-28 19:08:42 -0700117 .setListener(mPauseListener);
Adam Cohen70009e42012-10-30 16:48:22 -0700118 }
119
120 public void fadeInSecurity(int duration) {
John Spurlock56d007b2013-10-28 18:40:56 -0400121 ((View) mKeyguardSecurityContainer).animate().alpha(1f).setDuration(duration)
Jim Miller6b0afad2013-10-28 19:08:42 -0700122 .setListener(mResumeListener);
Adam Cohen70009e42012-10-30 16:48:22 -0700123 }
124
Adam Cohen8caabad2012-11-04 17:23:25 -0800125 public void onPageBeginMoving() {
126 if (mChallengeLayout.isChallengeOverlapping() &&
127 mChallengeLayout instanceof SlidingChallengeLayout) {
128 SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
Jim Miller6b0afad2013-10-28 19:08:42 -0700129 scl.fadeOutChallenge();
Adam Cohen8caabad2012-11-04 17:23:25 -0800130 mPageIndexOnPageBeginMoving = mKeyguardWidgetPager.getCurrentPage();
131 }
Michael Jurka14138892012-11-07 13:45:53 -0800132 // We use mAppWidgetToShow to show a particular widget after you add it--
133 // once the user swipes a page we clear that behavior
134 if (mKeyguardHostView != null) {
135 mKeyguardHostView.clearAppWidgetToShow();
Jim Miller4eeb4f62012-11-08 00:04:29 -0800136 mKeyguardHostView.setOnDismissAction(null);
Michael Jurka14138892012-11-07 13:45:53 -0800137 }
Adam Cohen8caabad2012-11-04 17:23:25 -0800138 if (mHideHintsRunnable != null) {
139 mMainQueue.removeCallbacks(mHideHintsRunnable);
140 mHideHintsRunnable = null;
141 }
142 }
143
144 public void onPageEndMoving() {
145 mPageIndexOnPageBeginMoving = -1;
146 }
147
John Spurlockbb5c9412012-10-31 09:46:15 -0400148 public void onPageSwitching(View newPage, int newPageIndex) {
Adam Cohen7f6bb6e2012-11-04 14:00:05 -0800149 if (mKeyguardWidgetPager != null && mChallengeLayout instanceof SlidingChallengeLayout) {
John Spurlockbb5c9412012-10-31 09:46:15 -0400150 boolean isCameraPage = newPage instanceof CameraWidgetFrame;
Jim Millerc816b8e2013-11-12 19:52:12 -0800151 if (isCameraPage) {
152 CameraWidgetFrame camera = (CameraWidgetFrame) newPage;
153 camera.setUseFastTransition(mKeyguardWidgetPager.isWarping());
154 }
Jim Millerc162dd02013-09-25 18:57:43 -0700155 SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
156 scl.setChallengeInteractive(!isCameraPage);
Jim Millerfadccf12013-10-13 17:26:39 -0700157 final int currentFlags = mKeyguardWidgetPager.getSystemUiVisibility();
158 final int newFlags = isCameraPage ? (currentFlags | View.STATUS_BAR_DISABLE_SEARCH)
159 : (currentFlags & ~View.STATUS_BAR_DISABLE_SEARCH);
160 mKeyguardWidgetPager.setSystemUiVisibility(newFlags);
John Spurlockbb5c9412012-10-31 09:46:15 -0400161 }
Adam Cohen8caabad2012-11-04 17:23:25 -0800162
163 // If the page we're settling to is the same as we started on, and the action of
164 // moving the page hid the security, we restore it immediately.
165 if (mPageIndexOnPageBeginMoving == mKeyguardWidgetPager.getNextPage() &&
166 mChallengeLayout instanceof SlidingChallengeLayout) {
167 SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
168 scl.fadeInChallenge();
169 mKeyguardWidgetPager.setWidgetToResetOnPageFadeOut(-1);
170 }
171 mPageIndexOnPageBeginMoving = -1;
John Spurlockbb5c9412012-10-31 09:46:15 -0400172 }
173
174 public void onPageSwitched(View newPage, int newPageIndex) {
Adam Cohene3643132012-10-28 18:29:17 -0700175 // Reset the previous page size and ensure the current page is sized appropriately.
176 // We only modify the page state if it is not currently under control by the slider.
177 // This prevents conflicts.
Adam Cohen4ddcd572012-11-01 17:36:32 -0700178
179 // If the page hasn't switched, don't bother with any of this
Adam Cohen25228802012-11-04 13:20:26 -0800180 if (mCurrentPage == newPageIndex) return;
Adam Cohen4ddcd572012-11-01 17:36:32 -0700181
Adam Cohen7f6bb6e2012-11-04 14:00:05 -0800182 if (mKeyguardWidgetPager != null && mChallengeLayout != null) {
183 KeyguardWidgetFrame prevPage = mKeyguardWidgetPager.getWidgetPageAt(mCurrentPage);
Adam Cohen8caabad2012-11-04 17:23:25 -0800184 if (prevPage != null && mCurrentPage != mPageListeningToSlider && mCurrentPage
185 != mKeyguardWidgetPager.getWidgetToResetOnPageFadeOut()) {
Adam Cohene3643132012-10-28 18:29:17 -0700186 prevPage.resetSize();
Jim Millerd6523da2012-10-21 16:47:02 -0700187 }
188
Adam Cohen7f6bb6e2012-11-04 14:00:05 -0800189 KeyguardWidgetFrame newCurPage = mKeyguardWidgetPager.getWidgetPageAt(newPageIndex);
Adam Cohene3643132012-10-28 18:29:17 -0700190 boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
191 if (challengeOverlapping && !newCurPage.isSmall()
192 && mPageListeningToSlider != newPageIndex) {
Jim Miller6b0afad2013-10-28 19:08:42 -0700193 newCurPage.shrinkWidget(true);
Jim Millerd6523da2012-10-21 16:47:02 -0700194 }
195 }
Adam Cohen8caabad2012-11-04 17:23:25 -0800196
Adam Cohene3643132012-10-28 18:29:17 -0700197 mCurrentPage = newPageIndex;
Jim Millerd6523da2012-10-21 16:47:02 -0700198 }
199
Jim Millercaf24fc2013-09-10 18:37:01 -0700200 public void onPageBeginWarp() {
Jim Millerc162dd02013-09-25 18:57:43 -0700201 fadeOutSecurity(SlidingChallengeLayout.CHALLENGE_FADE_OUT_DURATION);
202 View frame = mKeyguardWidgetPager.getPageAt(mKeyguardWidgetPager.getPageWarpIndex());
203 ((KeyguardWidgetFrame)frame).showFrame(this);
Jim Millercaf24fc2013-09-10 18:37:01 -0700204 }
205
206 public void onPageEndWarp() {
Jim Millerc162dd02013-09-25 18:57:43 -0700207 fadeInSecurity(SlidingChallengeLayout.CHALLENGE_FADE_IN_DURATION);
208 View frame = mKeyguardWidgetPager.getPageAt(mKeyguardWidgetPager.getPageWarpIndex());
209 ((KeyguardWidgetFrame)frame).hideFrame(this);
Jim Millercaf24fc2013-09-10 18:37:01 -0700210 }
211
Adam Cohene3643132012-10-28 18:29:17 -0700212 private int getChallengeTopRelativeToFrame(KeyguardWidgetFrame frame, int top) {
Jim Millerd6523da2012-10-21 16:47:02 -0700213 mTmpPoint[0] = 0;
Adam Cohene3643132012-10-28 18:29:17 -0700214 mTmpPoint[1] = top;
Jim Miller19a52672012-10-23 19:52:04 -0700215 mapPoint((View) mChallengeLayout, frame, mTmpPoint);
Adam Cohene3643132012-10-28 18:29:17 -0700216 return mTmpPoint[1];
217 }
218
Jim Millerd6523da2012-10-21 16:47:02 -0700219 /**
220 * Simple method to map a point from one view's coordinates to another's. Note: this method
221 * doesn't account for transforms, so if the views will be transformed, this should not be used.
222 *
223 * @param fromView The view to which the point is relative
224 * @param toView The view into which the point should be mapped
225 * @param pt The point
226 */
Adam Cohen8a7785c2012-10-29 22:01:33 -0700227 private void mapPoint(View fromView, View toView, int pt[]) {
228 fromView.getLocationInWindow(mTmpLoc);
Jim Millerd6523da2012-10-21 16:47:02 -0700229
Adam Cohen8a7785c2012-10-29 22:01:33 -0700230 int x = mTmpLoc[0];
231 int y = mTmpLoc[1];
232
233 toView.getLocationInWindow(mTmpLoc);
234 int vX = mTmpLoc[0];
235 int vY = mTmpLoc[1];
Jim Millerd6523da2012-10-21 16:47:02 -0700236
237 pt[0] += x - vX;
238 pt[1] += y - vY;
239 }
240
Adam Cohen08c83ef2012-11-08 00:25:47 -0800241 private void userActivity() {
242 if (mKeyguardHostView != null) {
243 mKeyguardHostView.onUserActivityTimeoutChanged();
244 mKeyguardHostView.userActivity();
245 }
246 }
247
Jim Millerd6523da2012-10-21 16:47:02 -0700248 @Override
249 public void onScrollStateChanged(int scrollState) {
Adam Cohen7f6bb6e2012-11-04 14:00:05 -0800250 if (mKeyguardWidgetPager == null || mChallengeLayout == null) return;
Winson Chung48275d22012-11-05 10:56:31 -0800251
Adam Cohene3643132012-10-28 18:29:17 -0700252 boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
253
Jim Millerd6523da2012-10-21 16:47:02 -0700254 if (scrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
Adam Cohen7f6bb6e2012-11-04 14:00:05 -0800255 KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
Adam Cohene3643132012-10-28 18:29:17 -0700256 if (frame == null) return;
Jim Millerd6523da2012-10-21 16:47:02 -0700257
Adam Cohene3643132012-10-28 18:29:17 -0700258 if (!challengeOverlapping) {
Adam Cohen7f6bb6e2012-11-04 14:00:05 -0800259 if (!mKeyguardWidgetPager.isPageMoving()) {
Adam Cohendb1c5d52012-11-03 17:10:07 -0700260 frame.resetSize();
Adam Cohen08c83ef2012-11-08 00:25:47 -0800261 userActivity();
Adam Cohendb1c5d52012-11-03 17:10:07 -0700262 } else {
Adam Cohen8caabad2012-11-04 17:23:25 -0800263 mKeyguardWidgetPager.setWidgetToResetOnPageFadeOut(mPageListeningToSlider);
Adam Cohendb1c5d52012-11-03 17:10:07 -0700264 }
Jim Millerd6523da2012-10-21 16:47:02 -0700265 }
Adam Cohen44dc1412012-11-07 20:50:39 -0800266 if (frame.isSmall()) {
267 // This is to make sure that if the scroller animation gets cut off midway
268 // that the frame doesn't stay in a partial down position.
269 frame.setFrameHeight(frame.getSmallFrameHeight());
270 }
Adam Cohend51700b32012-11-07 16:26:46 -0800271 if (scrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
272 frame.hideFrame(this);
273 }
Adam Cohen7f6bb6e2012-11-04 14:00:05 -0800274 updateEdgeSwiping();
Jim Millerd6523da2012-10-21 16:47:02 -0700275
Jim Millerbbba68a2012-10-24 22:21:40 -0700276 if (mChallengeLayout.isChallengeShowing()) {
Chris Wrena042ac92012-11-07 11:37:06 -0500277 mKeyguardSecurityContainer.onResume(KeyguardSecurityView.VIEW_REVEALED);
Jim Millerbbba68a2012-10-24 22:21:40 -0700278 } else {
279 mKeyguardSecurityContainer.onPause();
280 }
Adam Cohene3643132012-10-28 18:29:17 -0700281 mPageListeningToSlider = -1;
282 } else if (mLastScrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
283 // Whether dragging or settling, if the last state was idle, we use this signal
284 // to update the current page who will receive events from the sliding challenge.
285 // We resize the frame as appropriate.
Adam Cohen7f6bb6e2012-11-04 14:00:05 -0800286 mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
287 KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
Adam Cohene3643132012-10-28 18:29:17 -0700288 if (frame == null) return;
289
Winson Chung48275d22012-11-05 10:56:31 -0800290 // Skip showing the frame and shrinking the widget if we are
291 if (!mChallengeLayout.isBouncing()) {
Adam Cohend51700b32012-11-07 16:26:46 -0800292 if (scrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
293 frame.showFrame(this);
294 }
Adam Cohene3643132012-10-28 18:29:17 -0700295
Winson Chung48275d22012-11-05 10:56:31 -0800296 // As soon as the security begins sliding, the widget becomes small (if it wasn't
297 // small to begin with).
298 if (!frame.isSmall()) {
299 // We need to fetch the final page, in case the pages are in motion.
300 mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
Adam Cohen44dc1412012-11-07 20:50:39 -0800301 frame.shrinkWidget(false);
Winson Chung48275d22012-11-05 10:56:31 -0800302 }
303 } else {
304 if (!frame.isSmall()) {
305 // We need to fetch the final page, in case the pages are in motion.
306 mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
307 }
Adam Cohene3643132012-10-28 18:29:17 -0700308 }
Winson Chung48275d22012-11-05 10:56:31 -0800309
Jim Millerbbba68a2012-10-24 22:21:40 -0700310 // View is on the move. Pause the security view until it completes.
311 mKeyguardSecurityContainer.onPause();
Jim Millerd6523da2012-10-21 16:47:02 -0700312 }
Adam Cohene3643132012-10-28 18:29:17 -0700313 mLastScrollState = scrollState;
314 }
315
316 @Override
317 public void onScrollPositionChanged(float scrollPosition, int challengeTop) {
318 mChallengeTop = challengeTop;
Adam Cohen7f6bb6e2012-11-04 14:00:05 -0800319 KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
Adam Cohen44dc1412012-11-07 20:50:39 -0800320 if (frame != null && mLastScrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
Adam Cohene3643132012-10-28 18:29:17 -0700321 frame.adjustFrame(getChallengeTopRelativeToFrame(frame, mChallengeTop));
322 }
Jim Millerd6523da2012-10-21 16:47:02 -0700323 }
324
Adam Cohen196cde92012-11-02 15:25:32 -0700325 private Runnable mHideHintsRunnable = new Runnable() {
326 @Override
327 public void run() {
Adam Cohen7f6bb6e2012-11-04 14:00:05 -0800328 if (mKeyguardWidgetPager != null) {
329 mKeyguardWidgetPager.hideOutlinesAndSidePages();
Adam Cohen196cde92012-11-02 15:25:32 -0700330 }
331 }
332 };
333
Adam Cohen6fb841f2012-10-24 13:15:38 -0700334 public void showUsabilityHints() {
Adam Cohen47c6cfa2012-10-27 18:29:52 -0700335 mMainQueue.postDelayed( new Runnable() {
336 @Override
337 public void run() {
338 mKeyguardSecurityContainer.showUsabilityHint();
339 }
340 } , SCREEN_ON_RING_HINT_DELAY);
Jim Millercaf24fc2013-09-10 18:37:01 -0700341 if (SHOW_INITIAL_PAGE_HINTS) {
342 mKeyguardWidgetPager.showInitialPageHints();
343 }
Adam Cohen196cde92012-11-02 15:25:32 -0700344 if (mHideHintsRunnable != null) {
345 mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION);
346 }
Adam Cohen6fb841f2012-10-24 13:15:38 -0700347 }
Jim Millere0566da2012-10-30 14:57:29 -0700348
Winson Chung48275d22012-11-05 10:56:31 -0800349 // ChallengeLayout.OnBouncerStateChangedListener
350 @Override
351 public void onBouncerStateChanged(boolean bouncerActive) {
352 if (bouncerActive) {
353 mKeyguardWidgetPager.zoomOutToBouncer();
354 } else {
355 mKeyguardWidgetPager.zoomInFromBouncer();
Jim Miller4eeb4f62012-11-08 00:04:29 -0800356 if (mKeyguardHostView != null) {
357 mKeyguardHostView.setOnDismissAction(null);
358 }
Winson Chung48275d22012-11-05 10:56:31 -0800359 }
360 }
Jim Millerd6523da2012-10-21 16:47:02 -0700361}