Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 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 | */ |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 16 | package com.android.keyguard; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 17 | |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 18 | import android.animation.Animator; |
| 19 | import android.animation.AnimatorListenerAdapter; |
| 20 | import android.animation.AnimatorSet; |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 21 | import android.animation.ObjectAnimator; |
Adam Cohen | 6fb841f | 2012-10-24 13:15:38 -0700 | [diff] [blame] | 22 | import android.animation.PropertyValuesHolder; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 23 | import android.animation.TimeInterpolator; |
Adam Cohen | 4ddcd57 | 2012-11-01 17:36:32 -0700 | [diff] [blame] | 24 | import android.appwidget.AppWidgetHostView; |
Jim Miller | 5111726 | 2012-11-04 17:58:09 -0800 | [diff] [blame] | 25 | import android.appwidget.AppWidgetManager; |
Adam Cohen | 4ddcd57 | 2012-11-01 17:36:32 -0700 | [diff] [blame] | 26 | import android.appwidget.AppWidgetProviderInfo; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 27 | import android.content.Context; |
Winson Chung | f8f5966 | 2012-10-30 12:03:18 -0700 | [diff] [blame] | 28 | import android.os.Handler; |
| 29 | import android.os.HandlerThread; |
Jeff Sharkey | 06c5f8a | 2012-12-04 09:53:44 -0800 | [diff] [blame] | 30 | import android.text.format.DateFormat; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 31 | import android.util.AttributeSet; |
Jim Miller | bdca3c0 | 2012-10-29 19:11:50 -0700 | [diff] [blame] | 32 | import android.util.Slog; |
Jim Miller | f2dfc35 | 2012-08-29 18:42:21 -0700 | [diff] [blame] | 33 | import android.view.Gravity; |
Jim Miller | c1aa6a5 | 2012-09-28 19:37:26 -0700 | [diff] [blame] | 34 | import android.view.MotionEvent; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 35 | import android.view.View; |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 36 | import android.view.View.OnLongClickListener; |
Adam Cohen | 4ddcd57 | 2012-11-01 17:36:32 -0700 | [diff] [blame] | 37 | import android.view.ViewGroup; |
Svetoslav Ganov | c4842c1 | 2012-10-31 14:33:32 -0700 | [diff] [blame] | 38 | import android.view.accessibility.AccessibilityEvent; |
| 39 | import android.view.accessibility.AccessibilityManager; |
Winson Chung | 70c2f87 | 2012-11-07 21:47:12 -0800 | [diff] [blame] | 40 | import android.view.animation.DecelerateInterpolator; |
Jim Miller | f2dfc35 | 2012-08-29 18:42:21 -0700 | [diff] [blame] | 41 | import android.widget.FrameLayout; |
Jeff Sharkey | 06c5f8a | 2012-12-04 09:53:44 -0800 | [diff] [blame] | 42 | import android.widget.TextClock; |
Jim Miller | 4d20ed3 | 2013-10-19 01:00:16 +0000 | [diff] [blame] | 43 | |
Michael Jurka | 1254f2f | 2012-10-25 11:44:31 -0700 | [diff] [blame] | 44 | import com.android.internal.widget.LockPatternUtils; |
Svetoslav Ganov | 6526fdd | 2012-10-02 16:21:20 -0700 | [diff] [blame] | 45 | |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 46 | import java.util.ArrayList; |
Jeff Sharkey | 06c5f8a | 2012-12-04 09:53:44 -0800 | [diff] [blame] | 47 | import java.util.TimeZone; |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 48 | |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 49 | public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwitchListener, |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 50 | OnLongClickListener, ChallengeLayout.OnBouncerStateChangedListener { |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 51 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 52 | ZInterpolator mZInterpolator = new ZInterpolator(0.5f); |
Jim Miller | f2dfc35 | 2012-08-29 18:42:21 -0700 | [diff] [blame] | 53 | private static float CAMERA_DISTANCE = 10000; |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 54 | protected static float OVERSCROLL_MAX_ROTATION = 30; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 55 | private static final boolean PERFORM_OVERSCROLL_ROTATION = true; |
Adam Cohen | 9ec871d | 2012-10-24 19:25:44 -0700 | [diff] [blame] | 56 | |
Jeff Sharkey | 06c5f8a | 2012-12-04 09:53:44 -0800 | [diff] [blame] | 57 | private static final int FLAG_HAS_LOCAL_HOUR = 0x1; |
| 58 | private static final int FLAG_HAS_LOCAL_MINUTE = 0x2; |
| 59 | |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 60 | protected KeyguardViewStateManager mViewStateManager; |
Michael Jurka | 1254f2f | 2012-10-25 11:44:31 -0700 | [diff] [blame] | 61 | private LockPatternUtils mLockPatternUtils; |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 62 | |
| 63 | // Related to the fading in / out background outlines |
Adam Cohen | db1c5d5 | 2012-11-03 17:10:07 -0700 | [diff] [blame] | 64 | public static final int CHILDREN_OUTLINE_FADE_OUT_DURATION = 375; |
| 65 | public static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 100; |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 66 | protected AnimatorSet mChildrenOutlineFadeAnimation; |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 67 | protected int mScreenCenter; |
Adam Cohen | 8a7785c | 2012-10-29 22:01:33 -0700 | [diff] [blame] | 68 | private boolean mHasMeasure = false; |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 69 | boolean showHintsAfterLayout = false; |
Jim Miller | f2dfc35 | 2012-08-29 18:42:21 -0700 | [diff] [blame] | 70 | |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 71 | private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000; |
Jim Miller | bdca3c0 | 2012-10-29 19:11:50 -0700 | [diff] [blame] | 72 | private static final String TAG = "KeyguardWidgetPager"; |
Adam Cohen | 6f72b1c | 2012-11-05 15:20:30 -0800 | [diff] [blame] | 73 | private boolean mCenterSmallWidgetsVertically; |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 74 | |
| 75 | private int mPage = 0; |
| 76 | private Callbacks mCallbacks; |
| 77 | |
Adam Cohen | 8caabad | 2012-11-04 17:23:25 -0800 | [diff] [blame] | 78 | private int mWidgetToResetAfterFadeOut; |
Adam Cohen | 2b0501b | 2012-11-21 16:49:13 -0800 | [diff] [blame] | 79 | protected boolean mShowingInitialHints = false; |
Adam Cohen | db1c5d5 | 2012-11-03 17:10:07 -0700 | [diff] [blame] | 80 | |
Winson Chung | 4752e7d | 2012-11-20 17:06:04 -0800 | [diff] [blame] | 81 | // A temporary handle to the Add-Widget view |
| 82 | private View mAddWidgetView; |
| 83 | private int mLastWidthMeasureSpec; |
| 84 | private int mLastHeightMeasureSpec; |
| 85 | |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 86 | // Bouncer |
Winson Chung | 70c2f87 | 2012-11-07 21:47:12 -0800 | [diff] [blame] | 87 | private int mBouncerZoomInOutDuration = 250; |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 88 | private float BOUNCER_SCALE_FACTOR = 0.67f; |
| 89 | |
John Spurlock | 37d84ae | 2012-11-04 11:11:47 -0500 | [diff] [blame] | 90 | // Background worker thread: used here for persistence, also made available to widget frames |
| 91 | private final HandlerThread mBackgroundWorkerThread; |
| 92 | private final Handler mBackgroundWorkerHandler; |
Jim Miller | 8de9e44 | 2013-09-20 14:21:50 -0700 | [diff] [blame] | 93 | private boolean mCameraEventInProgress; |
Winson Chung | f8f5966 | 2012-10-30 12:03:18 -0700 | [diff] [blame] | 94 | |
Jim Miller | f2dfc35 | 2012-08-29 18:42:21 -0700 | [diff] [blame] | 95 | public KeyguardWidgetPager(Context context, AttributeSet attrs) { |
| 96 | this(context, attrs, 0); |
| 97 | } |
| 98 | |
| 99 | public KeyguardWidgetPager(Context context) { |
| 100 | this(null, null, 0); |
| 101 | } |
| 102 | |
| 103 | public KeyguardWidgetPager(Context context, AttributeSet attrs, int defStyle) { |
| 104 | super(context, attrs, defStyle); |
Svetoslav Ganov | 6526fdd | 2012-10-02 16:21:20 -0700 | [diff] [blame] | 105 | if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { |
| 106 | setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); |
| 107 | } |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 108 | |
| 109 | setPageSwitchListener(this); |
Winson Chung | efc4925 | 2012-10-26 15:41:27 -0700 | [diff] [blame] | 110 | |
John Spurlock | 37d84ae | 2012-11-04 11:11:47 -0500 | [diff] [blame] | 111 | mBackgroundWorkerThread = new HandlerThread("KeyguardWidgetPager Worker"); |
| 112 | mBackgroundWorkerThread.start(); |
| 113 | mBackgroundWorkerHandler = new Handler(mBackgroundWorkerThread.getLooper()); |
Jim Miller | f2dfc35 | 2012-08-29 18:42:21 -0700 | [diff] [blame] | 114 | } |
| 115 | |
Winson Chung | e72855e | 2012-11-01 18:05:04 -0700 | [diff] [blame] | 116 | @Override |
| 117 | protected void onDetachedFromWindow() { |
| 118 | super.onDetachedFromWindow(); |
| 119 | |
John Spurlock | 37d84ae | 2012-11-04 11:11:47 -0500 | [diff] [blame] | 120 | // Clean up the worker thread |
| 121 | mBackgroundWorkerThread.quit(); |
Winson Chung | e72855e | 2012-11-01 18:05:04 -0700 | [diff] [blame] | 122 | } |
| 123 | |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 124 | public void setViewStateManager(KeyguardViewStateManager viewStateManager) { |
| 125 | mViewStateManager = viewStateManager; |
| 126 | } |
| 127 | |
Michael Jurka | 1254f2f | 2012-10-25 11:44:31 -0700 | [diff] [blame] | 128 | public void setLockPatternUtils(LockPatternUtils l) { |
| 129 | mLockPatternUtils = l; |
| 130 | } |
| 131 | |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 132 | @Override |
John Spurlock | bb5c941 | 2012-10-31 09:46:15 -0400 | [diff] [blame] | 133 | public void onPageSwitching(View newPage, int newPageIndex) { |
| 134 | if (mViewStateManager != null) { |
| 135 | mViewStateManager.onPageSwitching(newPage, newPageIndex); |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | @Override |
| 140 | public void onPageSwitched(View newPage, int newPageIndex) { |
Jeff Sharkey | 06c5f8a | 2012-12-04 09:53:44 -0800 | [diff] [blame] | 141 | boolean showingClock = false; |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 142 | if (newPage instanceof ViewGroup) { |
| 143 | ViewGroup vg = (ViewGroup) newPage; |
| 144 | if (vg.getChildAt(0) instanceof KeyguardStatusView) { |
Jeff Sharkey | 06c5f8a | 2012-12-04 09:53:44 -0800 | [diff] [blame] | 145 | showingClock = true; |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 146 | } |
| 147 | } |
| 148 | |
Jeff Sharkey | 06c5f8a | 2012-12-04 09:53:44 -0800 | [diff] [blame] | 149 | if (newPage != null && |
| 150 | findClockInHierarchy(newPage) == (FLAG_HAS_LOCAL_HOUR | FLAG_HAS_LOCAL_MINUTE)) { |
| 151 | showingClock = true; |
| 152 | } |
| 153 | |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 154 | // Disable the status bar clock if we're showing the default status widget |
Jeff Sharkey | 06c5f8a | 2012-12-04 09:53:44 -0800 | [diff] [blame] | 155 | if (showingClock) { |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 156 | setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_CLOCK); |
| 157 | } else { |
| 158 | setSystemUiVisibility(getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_CLOCK); |
| 159 | } |
| 160 | |
| 161 | // Extend the display timeout if the user switches pages |
| 162 | if (mPage != newPageIndex) { |
John Spurlock | 86b6357 | 2012-10-24 11:24:25 -0400 | [diff] [blame] | 163 | int oldPageIndex = mPage; |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 164 | mPage = newPageIndex; |
Chris Wren | 32c557c | 2012-10-29 11:16:42 -0400 | [diff] [blame] | 165 | userActivity(); |
John Spurlock | 86b6357 | 2012-10-24 11:24:25 -0400 | [diff] [blame] | 166 | KeyguardWidgetFrame oldWidgetPage = getWidgetPageAt(oldPageIndex); |
| 167 | if (oldWidgetPage != null) { |
| 168 | oldWidgetPage.onActive(false); |
| 169 | } |
| 170 | KeyguardWidgetFrame newWidgetPage = getWidgetPageAt(newPageIndex); |
| 171 | if (newWidgetPage != null) { |
| 172 | newWidgetPage.onActive(true); |
Svetoslav | 4293e23 | 2013-04-25 13:25:06 -0700 | [diff] [blame] | 173 | newWidgetPage.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); |
Svetoslav Ganov | c4842c1 | 2012-10-31 14:33:32 -0700 | [diff] [blame] | 174 | newWidgetPage.requestAccessibilityFocus(); |
John Spurlock | 86b6357 | 2012-10-24 11:24:25 -0400 | [diff] [blame] | 175 | } |
Svetoslav Ganov | 45942ca | 2012-10-31 19:46:24 -0700 | [diff] [blame] | 176 | if (mParent != null && AccessibilityManager.getInstance(mContext).isEnabled()) { |
| 177 | AccessibilityEvent event = AccessibilityEvent.obtain( |
| 178 | AccessibilityEvent.TYPE_VIEW_SCROLLED); |
| 179 | onInitializeAccessibilityEvent(event); |
| 180 | onPopulateAccessibilityEvent(event); |
| 181 | mParent.requestSendAccessibilityEvent(this, event); |
| 182 | } |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 183 | } |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 184 | if (mViewStateManager != null) { |
John Spurlock | bb5c941 | 2012-10-31 09:46:15 -0400 | [diff] [blame] | 185 | mViewStateManager.onPageSwitched(newPage, newPageIndex); |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 186 | } |
Svetoslav Ganov | c4842c1 | 2012-10-31 14:33:32 -0700 | [diff] [blame] | 187 | } |
| 188 | |
| 189 | @Override |
Jim Miller | caf24fc | 2013-09-10 18:37:01 -0700 | [diff] [blame] | 190 | public void onPageBeginWarp() { |
Jim Miller | c162dd0 | 2013-09-25 18:57:43 -0700 | [diff] [blame] | 191 | showOutlinesAndSidePages(); |
Jim Miller | caf24fc | 2013-09-10 18:37:01 -0700 | [diff] [blame] | 192 | mViewStateManager.onPageBeginWarp(); |
| 193 | } |
| 194 | |
| 195 | @Override |
| 196 | public void onPageEndWarp() { |
Jim Miller | 6b0afad | 2013-10-28 19:08:42 -0700 | [diff] [blame] | 197 | // if we're moving to the warp page, then immediately hide the other widgets. |
| 198 | int duration = getPageWarpIndex() == getNextPage() ? 0 : -1; |
| 199 | animateOutlinesAndSidePages(false, duration); |
Jim Miller | caf24fc | 2013-09-10 18:37:01 -0700 | [diff] [blame] | 200 | mViewStateManager.onPageEndWarp(); |
| 201 | } |
| 202 | |
| 203 | @Override |
Svetoslav Ganov | c4842c1 | 2012-10-31 14:33:32 -0700 | [diff] [blame] | 204 | public void sendAccessibilityEvent(int eventType) { |
| 205 | if (eventType != AccessibilityEvent.TYPE_VIEW_SCROLLED || isPageMoving()) { |
| 206 | super.sendAccessibilityEvent(eventType); |
| 207 | } |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 208 | } |
| 209 | |
Svetoslav Ganov | a90a18d | 2012-11-06 15:22:11 -0800 | [diff] [blame] | 210 | private void updateWidgetFramesImportantForAccessibility() { |
| 211 | final int pageCount = getPageCount(); |
| 212 | for (int i = 0; i < pageCount; i++) { |
| 213 | KeyguardWidgetFrame frame = getWidgetPageAt(i); |
| 214 | updateWidgetFrameImportantForAccessibility(frame); |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | private void updateWidgetFrameImportantForAccessibility(KeyguardWidgetFrame frame) { |
| 219 | if (frame.getContentAlpha() <= 0) { |
| 220 | frame.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); |
| 221 | } else { |
| 222 | frame.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); |
| 223 | } |
| 224 | } |
| 225 | |
Chris Wren | 32c557c | 2012-10-29 11:16:42 -0400 | [diff] [blame] | 226 | private void userActivity() { |
| 227 | if (mCallbacks != null) { |
| 228 | mCallbacks.onUserActivityTimeoutChanged(); |
| 229 | mCallbacks.userActivity(); |
| 230 | } |
| 231 | } |
| 232 | |
John Spurlock | 4b976ea | 2012-10-28 12:34:11 -0400 | [diff] [blame] | 233 | @Override |
| 234 | public boolean onTouchEvent(MotionEvent ev) { |
John Spurlock | f70239a | 2012-11-04 09:42:42 -0500 | [diff] [blame] | 235 | return captureUserInteraction(ev) || super.onTouchEvent(ev); |
| 236 | } |
| 237 | |
| 238 | @Override |
| 239 | public boolean onInterceptTouchEvent(MotionEvent ev) { |
| 240 | return captureUserInteraction(ev) || super.onInterceptTouchEvent(ev); |
| 241 | } |
| 242 | |
| 243 | private boolean captureUserInteraction(MotionEvent ev) { |
John Spurlock | 4b976ea | 2012-10-28 12:34:11 -0400 | [diff] [blame] | 244 | KeyguardWidgetFrame currentWidgetPage = getWidgetPageAt(getCurrentPage()); |
John Spurlock | f70239a | 2012-11-04 09:42:42 -0500 | [diff] [blame] | 245 | return currentWidgetPage != null && currentWidgetPage.onUserInteraction(ev); |
John Spurlock | 4b976ea | 2012-10-28 12:34:11 -0400 | [diff] [blame] | 246 | } |
| 247 | |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 248 | public void showPagingFeedback() { |
| 249 | // Nothing yet. |
| 250 | } |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 251 | |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 252 | public long getUserActivityTimeout() { |
| 253 | View page = getPageAt(mPage); |
| 254 | if (page instanceof ViewGroup) { |
| 255 | ViewGroup vg = (ViewGroup) page; |
| 256 | View view = vg.getChildAt(0); |
| 257 | if (!(view instanceof KeyguardStatusView) |
| 258 | && !(view instanceof KeyguardMultiUserSelectorView)) { |
| 259 | return CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT; |
| 260 | } |
| 261 | } |
| 262 | return -1; |
| 263 | } |
| 264 | |
| 265 | public void setCallbacks(Callbacks callbacks) { |
| 266 | mCallbacks = callbacks; |
| 267 | } |
| 268 | |
| 269 | public interface Callbacks { |
| 270 | public void userActivity(); |
| 271 | public void onUserActivityTimeoutChanged(); |
Winson Chung | 40f8211 | 2012-11-08 11:54:55 -0800 | [diff] [blame] | 272 | public void onAddView(View v); |
Michael Jurka | 75b5cfb | 2012-11-15 18:22:47 -0800 | [diff] [blame] | 273 | public void onRemoveView(View v, boolean deletePermanently); |
Winson Chung | 4752e7d | 2012-11-20 17:06:04 -0800 | [diff] [blame] | 274 | public void onRemoveViewAnimationCompleted(); |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 275 | } |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 276 | |
| 277 | public void addWidget(View widget) { |
| 278 | addWidget(widget, -1); |
| 279 | } |
| 280 | |
Michael Jurka | 75b5cfb | 2012-11-15 18:22:47 -0800 | [diff] [blame] | 281 | public void onRemoveView(View v, final boolean deletePermanently) { |
Winson Chung | f8f5966 | 2012-10-30 12:03:18 -0700 | [diff] [blame] | 282 | final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId(); |
Michael Jurka | eb963f0 | 2012-11-08 00:32:29 -0800 | [diff] [blame] | 283 | if (mCallbacks != null) { |
Michael Jurka | 75b5cfb | 2012-11-15 18:22:47 -0800 | [diff] [blame] | 284 | mCallbacks.onRemoveView(v, deletePermanently); |
Michael Jurka | eb963f0 | 2012-11-08 00:32:29 -0800 | [diff] [blame] | 285 | } |
John Spurlock | 37d84ae | 2012-11-04 11:11:47 -0500 | [diff] [blame] | 286 | mBackgroundWorkerHandler.post(new Runnable() { |
Winson Chung | f8f5966 | 2012-10-30 12:03:18 -0700 | [diff] [blame] | 287 | @Override |
| 288 | public void run() { |
| 289 | mLockPatternUtils.removeAppWidget(appWidgetId); |
| 290 | } |
| 291 | }); |
Michael Jurka | 1254f2f | 2012-10-25 11:44:31 -0700 | [diff] [blame] | 292 | } |
| 293 | |
Winson Chung | 4752e7d | 2012-11-20 17:06:04 -0800 | [diff] [blame] | 294 | @Override |
| 295 | public void onRemoveViewAnimationCompleted() { |
| 296 | if (mCallbacks != null) { |
| 297 | mCallbacks.onRemoveViewAnimationCompleted(); |
| 298 | } |
| 299 | } |
| 300 | |
Winson Chung | f8f5966 | 2012-10-30 12:03:18 -0700 | [diff] [blame] | 301 | public void onAddView(View v, final int index) { |
| 302 | final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId(); |
| 303 | final int[] pagesRange = new int[mTempVisiblePagesRange.length]; |
| 304 | getVisiblePages(pagesRange); |
| 305 | boundByReorderablePages(true, pagesRange); |
Winson Chung | 40f8211 | 2012-11-08 11:54:55 -0800 | [diff] [blame] | 306 | if (mCallbacks != null) { |
| 307 | mCallbacks.onAddView(v); |
| 308 | } |
Michael Jurka | 1254f2f | 2012-10-25 11:44:31 -0700 | [diff] [blame] | 309 | // Subtract from the index to take into account pages before the reorderable |
| 310 | // pages (e.g. the "add widget" page) |
John Spurlock | 37d84ae | 2012-11-04 11:11:47 -0500 | [diff] [blame] | 311 | mBackgroundWorkerHandler.post(new Runnable() { |
Winson Chung | f8f5966 | 2012-10-30 12:03:18 -0700 | [diff] [blame] | 312 | @Override |
| 313 | public void run() { |
| 314 | mLockPatternUtils.addAppWidget(appWidgetId, index - pagesRange[0]); |
| 315 | } |
| 316 | }); |
Michael Jurka | 1254f2f | 2012-10-25 11:44:31 -0700 | [diff] [blame] | 317 | } |
| 318 | |
Jim Miller | f2dfc35 | 2012-08-29 18:42:21 -0700 | [diff] [blame] | 319 | /* |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 320 | * We wrap widgets in a special frame which handles drawing the over scroll foreground. |
Jim Miller | f2dfc35 | 2012-08-29 18:42:21 -0700 | [diff] [blame] | 321 | */ |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 322 | public void addWidget(View widget, int pageIndex) { |
| 323 | KeyguardWidgetFrame frame; |
| 324 | // All views contained herein should be wrapped in a KeyguardWidgetFrame |
| 325 | if (!(widget instanceof KeyguardWidgetFrame)) { |
| 326 | frame = new KeyguardWidgetFrame(getContext()); |
| 327 | FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, |
| 328 | LayoutParams.MATCH_PARENT); |
| 329 | lp.gravity = Gravity.TOP; |
Adam Cohen | 4ddcd57 | 2012-11-01 17:36:32 -0700 | [diff] [blame] | 330 | |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 331 | // The framework adds a default padding to AppWidgetHostView. We don't need this padding |
| 332 | // for the Keyguard, so we override it to be 0. |
| 333 | widget.setPadding(0, 0, 0, 0); |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 334 | frame.addView(widget, lp); |
Adam Cohen | 4ddcd57 | 2012-11-01 17:36:32 -0700 | [diff] [blame] | 335 | |
| 336 | // We set whether or not this widget supports vertical resizing. |
| 337 | if (widget instanceof AppWidgetHostView) { |
| 338 | AppWidgetHostView awhv = (AppWidgetHostView) widget; |
| 339 | AppWidgetProviderInfo info = awhv.getAppWidgetInfo(); |
| 340 | if ((info.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) { |
| 341 | frame.setWidgetLockedSmall(false); |
| 342 | } else { |
| 343 | // Lock the widget to be small. |
| 344 | frame.setWidgetLockedSmall(true); |
Adam Cohen | 6f72b1c | 2012-11-05 15:20:30 -0800 | [diff] [blame] | 345 | if (mCenterSmallWidgetsVertically) { |
| 346 | lp.gravity = Gravity.CENTER; |
| 347 | } |
Adam Cohen | 4ddcd57 | 2012-11-01 17:36:32 -0700 | [diff] [blame] | 348 | } |
| 349 | } |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 350 | } else { |
| 351 | frame = (KeyguardWidgetFrame) widget; |
| 352 | } |
| 353 | |
| 354 | ViewGroup.LayoutParams pageLp = new ViewGroup.LayoutParams( |
| 355 | ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); |
| 356 | frame.setOnLongClickListener(this); |
John Spurlock | 37d84ae | 2012-11-04 11:11:47 -0500 | [diff] [blame] | 357 | frame.setWorkerHandler(mBackgroundWorkerHandler); |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 358 | |
| 359 | if (pageIndex == -1) { |
| 360 | addView(frame, pageLp); |
| 361 | } else { |
| 362 | addView(frame, pageIndex, pageLp); |
| 363 | } |
Svetoslav Ganov | c4842c1 | 2012-10-31 14:33:32 -0700 | [diff] [blame] | 364 | |
| 365 | // Update the frame content description. |
| 366 | View content = (widget == frame) ? frame.getContent() : widget; |
| 367 | if (content != null) { |
| 368 | String contentDescription = mContext.getString( |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 369 | R.string.keyguard_accessibility_widget, |
Svetoslav Ganov | c4842c1 | 2012-10-31 14:33:32 -0700 | [diff] [blame] | 370 | content.getContentDescription()); |
| 371 | frame.setContentDescription(contentDescription); |
| 372 | } |
Svetoslav Ganov | a90a18d | 2012-11-06 15:22:11 -0800 | [diff] [blame] | 373 | updateWidgetFrameImportantForAccessibility(frame); |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 374 | } |
| 375 | |
Jim Miller | bdca3c0 | 2012-10-29 19:11:50 -0700 | [diff] [blame] | 376 | /** |
| 377 | * Use addWidget() instead. |
| 378 | * @deprecated |
| 379 | */ |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 380 | @Override |
| 381 | public void addView(View child, int index) { |
| 382 | enforceKeyguardWidgetFrame(child); |
| 383 | super.addView(child, index); |
| 384 | } |
| 385 | |
Jim Miller | bdca3c0 | 2012-10-29 19:11:50 -0700 | [diff] [blame] | 386 | /** |
| 387 | * Use addWidget() instead. |
| 388 | * @deprecated |
| 389 | */ |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 390 | @Override |
| 391 | public void addView(View child, int width, int height) { |
| 392 | enforceKeyguardWidgetFrame(child); |
| 393 | super.addView(child, width, height); |
| 394 | } |
| 395 | |
Jim Miller | bdca3c0 | 2012-10-29 19:11:50 -0700 | [diff] [blame] | 396 | /** |
| 397 | * Use addWidget() instead. |
| 398 | * @deprecated |
| 399 | */ |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 400 | @Override |
| 401 | public void addView(View child, LayoutParams params) { |
| 402 | enforceKeyguardWidgetFrame(child); |
| 403 | super.addView(child, params); |
| 404 | } |
| 405 | |
Jim Miller | bdca3c0 | 2012-10-29 19:11:50 -0700 | [diff] [blame] | 406 | /** |
| 407 | * Use addWidget() instead. |
| 408 | * @deprecated |
| 409 | */ |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 410 | @Override |
| 411 | public void addView(View child, int index, LayoutParams params) { |
| 412 | enforceKeyguardWidgetFrame(child); |
| 413 | super.addView(child, index, params); |
| 414 | } |
| 415 | |
| 416 | private void enforceKeyguardWidgetFrame(View child) { |
| 417 | if (!(child instanceof KeyguardWidgetFrame)) { |
| 418 | throw new IllegalArgumentException( |
| 419 | "KeyguardWidgetPager children must be KeyguardWidgetFrames"); |
| 420 | } |
| 421 | } |
| 422 | |
| 423 | public KeyguardWidgetFrame getWidgetPageAt(int index) { |
| 424 | // This is always a valid cast as we've guarded the ability to |
| 425 | return (KeyguardWidgetFrame) getChildAt(index); |
Jim Miller | f2dfc35 | 2012-08-29 18:42:21 -0700 | [diff] [blame] | 426 | } |
| 427 | |
Jim Miller | c1aa6a5 | 2012-09-28 19:37:26 -0700 | [diff] [blame] | 428 | protected void onUnhandledTap(MotionEvent ev) { |
Jim Miller | 838906b | 2012-10-19 18:41:25 -0700 | [diff] [blame] | 429 | showPagingFeedback(); |
Jim Miller | c1aa6a5 | 2012-09-28 19:37:26 -0700 | [diff] [blame] | 430 | } |
| 431 | |
Jim Miller | eeadda5 | 2012-10-02 17:32:38 -0700 | [diff] [blame] | 432 | @Override |
| 433 | protected void onPageBeginMoving() { |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 434 | if (mViewStateManager != null) { |
| 435 | mViewStateManager.onPageBeginMoving(); |
| 436 | } |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 437 | if (!isReordering(false)) { |
| 438 | showOutlinesAndSidePages(); |
| 439 | } |
Chris Wren | 32c557c | 2012-10-29 11:16:42 -0400 | [diff] [blame] | 440 | userActivity(); |
Jim Miller | eeadda5 | 2012-10-02 17:32:38 -0700 | [diff] [blame] | 441 | } |
| 442 | |
| 443 | @Override |
| 444 | protected void onPageEndMoving() { |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 445 | if (mViewStateManager != null) { |
| 446 | mViewStateManager.onPageEndMoving(); |
| 447 | } |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 448 | |
| 449 | // In the reordering case, the pages will be faded appropriately on completion |
| 450 | // of the zoom in animation. |
| 451 | if (!isReordering(false)) { |
| 452 | hideOutlinesAndSidePages(); |
| 453 | } |
Jim Miller | eeadda5 | 2012-10-02 17:32:38 -0700 | [diff] [blame] | 454 | } |
| 455 | |
Adam Cohen | 5d47a8d | 2012-11-03 19:10:56 -0700 | [diff] [blame] | 456 | protected void enablePageContentLayers() { |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 457 | int children = getChildCount(); |
| 458 | for (int i = 0; i < children; i++) { |
| 459 | getWidgetPageAt(i).enableHardwareLayersForContent(); |
| 460 | } |
| 461 | } |
| 462 | |
Adam Cohen | 5d47a8d | 2012-11-03 19:10:56 -0700 | [diff] [blame] | 463 | protected void disablePageContentLayers() { |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 464 | int children = getChildCount(); |
| 465 | for (int i = 0; i < children; i++) { |
| 466 | getWidgetPageAt(i).disableHardwareLayersForContent(); |
| 467 | } |
| 468 | } |
| 469 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 470 | /* |
| 471 | * This interpolator emulates the rate at which the perceived scale of an object changes |
| 472 | * as its distance from a camera increases. When this interpolator is applied to a scale |
| 473 | * animation on a view, it evokes the sense that the object is shrinking due to moving away |
| 474 | * from the camera. |
| 475 | */ |
| 476 | static class ZInterpolator implements TimeInterpolator { |
| 477 | private float focalLength; |
| 478 | |
| 479 | public ZInterpolator(float foc) { |
| 480 | focalLength = foc; |
| 481 | } |
| 482 | |
| 483 | public float getInterpolation(float input) { |
| 484 | return (1.0f - focalLength / (focalLength + input)) / |
| 485 | (1.0f - focalLength / (focalLength + 1.0f)); |
| 486 | } |
| 487 | } |
| 488 | |
Jim Miller | f2dfc35 | 2012-08-29 18:42:21 -0700 | [diff] [blame] | 489 | @Override |
| 490 | protected void overScroll(float amount) { |
| 491 | acceleratedOverScroll(amount); |
| 492 | } |
| 493 | |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 494 | float backgroundAlphaInterpolator(float r) { |
Adam Cohen | 9ec871d | 2012-10-24 19:25:44 -0700 | [diff] [blame] | 495 | return Math.min(1f, r); |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 496 | } |
| 497 | |
| 498 | private void updatePageAlphaValues(int screenCenter) { |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 499 | } |
| 500 | |
Adam Cohen | 2b0501b | 2012-11-21 16:49:13 -0800 | [diff] [blame] | 501 | public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) { |
Jim Miller | c162dd0 | 2013-09-25 18:57:43 -0700 | [diff] [blame] | 502 | if (isWarping()) { |
Jim Miller | f4db8f9 | 2013-09-20 14:21:50 -0700 | [diff] [blame] | 503 | return index == getPageWarpIndex() ? 1.0f : 0.0f; |
| 504 | } |
Adam Cohen | 2b0501b | 2012-11-21 16:49:13 -0800 | [diff] [blame] | 505 | if (showSidePages) { |
| 506 | return 1f; |
| 507 | } else { |
| 508 | return index == mCurrentPage ? 1.0f : 0f; |
| 509 | } |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 510 | } |
| 511 | |
Adam Cohen | 2b0501b | 2012-11-21 16:49:13 -0800 | [diff] [blame] | 512 | public float getOutlineAlphaForPage(int screenCenter, int index, boolean showSidePages) { |
| 513 | if (showSidePages) { |
| 514 | return getAlphaForPage(screenCenter, index, showSidePages) |
| 515 | * KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER; |
| 516 | } else { |
| 517 | return 0f; |
| 518 | } |
Adam Powell | cfc3086 | 2012-10-29 18:21:31 -0700 | [diff] [blame] | 519 | } |
| 520 | |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 521 | protected boolean isOverScrollChild(int index, float scrollProgress) { |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 522 | boolean isInOverscroll = mOverScrollX < 0 || mOverScrollX > mMaxScrollX; |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 523 | return (isInOverscroll && (index == 0 && scrollProgress < 0 || |
| 524 | index == getChildCount() - 1 && scrollProgress > 0)); |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 525 | } |
| 526 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 527 | @Override |
| 528 | protected void screenScrolled(int screenCenter) { |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 529 | mScreenCenter = screenCenter; |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 530 | updatePageAlphaValues(screenCenter); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 531 | for (int i = 0; i < getChildCount(); i++) { |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 532 | KeyguardWidgetFrame v = getWidgetPageAt(i); |
| 533 | if (v == mDragView) continue; |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 534 | if (v != null) { |
| 535 | float scrollProgress = getScrollProgress(screenCenter, v, i); |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 536 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 537 | v.setCameraDistance(mDensity * CAMERA_DISTANCE); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 538 | |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 539 | if (isOverScrollChild(i, scrollProgress) && PERFORM_OVERSCROLL_ROTATION) { |
Adam Cohen | d51700b3 | 2012-11-07 16:26:46 -0800 | [diff] [blame] | 540 | float pivotX = v.getMeasuredWidth() / 2; |
| 541 | float pivotY = v.getMeasuredHeight() / 2; |
| 542 | v.setPivotX(pivotX); |
| 543 | v.setPivotY(pivotY); |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 544 | v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress); |
| 545 | v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0); |
| 546 | } else { |
| 547 | v.setRotationY(0f); |
| 548 | v.setOverScrollAmount(0, false); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 549 | } |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 550 | |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 551 | float alpha = v.getAlpha(); |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 552 | // If the view has 0 alpha, we set it to be invisible so as to prevent |
| 553 | // it from accepting touches |
| 554 | if (alpha == 0) { |
| 555 | v.setVisibility(INVISIBLE); |
| 556 | } else if (v.getVisibility() != VISIBLE) { |
| 557 | v.setVisibility(VISIBLE); |
| 558 | } |
| 559 | } |
| 560 | } |
| 561 | } |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 562 | |
Jim Miller | 5111726 | 2012-11-04 17:58:09 -0800 | [diff] [blame] | 563 | public boolean isWidgetPage(int pageIndex) { |
| 564 | if (pageIndex < 0 || pageIndex >= getChildCount()) { |
| 565 | return false; |
| 566 | } |
| 567 | View v = getChildAt(pageIndex); |
| 568 | if (v != null && v instanceof KeyguardWidgetFrame) { |
| 569 | KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v; |
| 570 | return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID; |
| 571 | } |
| 572 | return false; |
| 573 | } |
| 574 | |
Winson Chung | c065a5d | 2012-11-07 17:17:33 -0800 | [diff] [blame] | 575 | /** |
| 576 | * Returns the bounded set of pages that are re-orderable. The range is fully inclusive. |
| 577 | */ |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 578 | @Override |
Winson Chung | efc4925 | 2012-10-26 15:41:27 -0700 | [diff] [blame] | 579 | void boundByReorderablePages(boolean isReordering, int[] range) { |
| 580 | if (isReordering) { |
Jim Miller | 5111726 | 2012-11-04 17:58:09 -0800 | [diff] [blame] | 581 | // Remove non-widget pages from the range |
Winson Chung | c065a5d | 2012-11-07 17:17:33 -0800 | [diff] [blame] | 582 | while (range[1] >= range[0] && !isWidgetPage(range[1])) { |
Jim Miller | 5111726 | 2012-11-04 17:58:09 -0800 | [diff] [blame] | 583 | range[1]--; |
| 584 | } |
Winson Chung | c065a5d | 2012-11-07 17:17:33 -0800 | [diff] [blame] | 585 | while (range[0] <= range[1] && !isWidgetPage(range[0])) { |
Winson Chung | efc4925 | 2012-10-26 15:41:27 -0700 | [diff] [blame] | 586 | range[0]++; |
| 587 | } |
Winson Chung | efc4925 | 2012-10-26 15:41:27 -0700 | [diff] [blame] | 588 | } |
| 589 | } |
| 590 | |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 591 | protected void reorderStarting() { |
| 592 | showOutlinesAndSidePages(); |
| 593 | } |
| 594 | |
Winson Chung | efc4925 | 2012-10-26 15:41:27 -0700 | [diff] [blame] | 595 | @Override |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 596 | protected void onStartReordering() { |
| 597 | super.onStartReordering(); |
Adam Cohen | 5d47a8d | 2012-11-03 19:10:56 -0700 | [diff] [blame] | 598 | enablePageContentLayers(); |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 599 | reorderStarting(); |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 600 | } |
| 601 | |
| 602 | @Override |
| 603 | protected void onEndReordering() { |
| 604 | super.onEndReordering(); |
Adam Cohen | 6fb841f | 2012-10-24 13:15:38 -0700 | [diff] [blame] | 605 | hideOutlinesAndSidePages(); |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 606 | } |
| 607 | |
Adam Cohen | 6fb841f | 2012-10-24 13:15:38 -0700 | [diff] [blame] | 608 | void showOutlinesAndSidePages() { |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 609 | animateOutlinesAndSidePages(true); |
| 610 | } |
Adam Cohen | 6fb841f | 2012-10-24 13:15:38 -0700 | [diff] [blame] | 611 | |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 612 | void hideOutlinesAndSidePages() { |
| 613 | animateOutlinesAndSidePages(false); |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 614 | } |
| 615 | |
Jim Miller | e5fb5e4 | 2013-04-10 16:10:06 -0700 | [diff] [blame] | 616 | void updateChildrenContentAlpha(float sidePageAlpha) { |
Adam Cohen | 45adaa7 | 2012-11-02 22:00:57 -0700 | [diff] [blame] | 617 | int count = getChildCount(); |
| 618 | for (int i = 0; i < count; i++) { |
| 619 | KeyguardWidgetFrame child = getWidgetPageAt(i); |
| 620 | if (i != mCurrentPage) { |
Jim Miller | e5fb5e4 | 2013-04-10 16:10:06 -0700 | [diff] [blame] | 621 | child.setBackgroundAlpha(sidePageAlpha); |
Adam Cohen | 45adaa7 | 2012-11-02 22:00:57 -0700 | [diff] [blame] | 622 | child.setContentAlpha(0f); |
| 623 | } else { |
| 624 | child.setBackgroundAlpha(0f); |
| 625 | child.setContentAlpha(1f); |
| 626 | } |
Adam Cohen | 8a7785c | 2012-10-29 22:01:33 -0700 | [diff] [blame] | 627 | } |
| 628 | } |
| 629 | |
Jim Miller | e5fb5e4 | 2013-04-10 16:10:06 -0700 | [diff] [blame] | 630 | public void showInitialPageHints() { |
| 631 | mShowingInitialHints = true; |
| 632 | updateChildrenContentAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER); |
| 633 | } |
| 634 | |
Adam Cohen | 8a7785c | 2012-10-29 22:01:33 -0700 | [diff] [blame] | 635 | @Override |
Svetoslav Ganov | a90a18d | 2012-11-06 15:22:11 -0800 | [diff] [blame] | 636 | void setCurrentPage(int currentPage) { |
| 637 | super.setCurrentPage(currentPage); |
Jim Miller | e5fb5e4 | 2013-04-10 16:10:06 -0700 | [diff] [blame] | 638 | updateChildrenContentAlpha(0.0f); |
Svetoslav Ganov | a90a18d | 2012-11-06 15:22:11 -0800 | [diff] [blame] | 639 | updateWidgetFramesImportantForAccessibility(); |
| 640 | } |
| 641 | |
| 642 | @Override |
Adam Cohen | 8a7785c | 2012-10-29 22:01:33 -0700 | [diff] [blame] | 643 | public void onAttachedToWindow() { |
| 644 | super.onAttachedToWindow(); |
| 645 | mHasMeasure = false; |
Adam Cohen | 8a7785c | 2012-10-29 22:01:33 -0700 | [diff] [blame] | 646 | } |
| 647 | |
Adam Cohen | 8a7785c | 2012-10-29 22:01:33 -0700 | [diff] [blame] | 648 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
Winson Chung | 4752e7d | 2012-11-20 17:06:04 -0800 | [diff] [blame] | 649 | mLastWidthMeasureSpec = widthMeasureSpec; |
| 650 | mLastHeightMeasureSpec = heightMeasureSpec; |
| 651 | |
Adam Cohen | 8a7785c | 2012-10-29 22:01:33 -0700 | [diff] [blame] | 652 | int maxChallengeTop = -1; |
| 653 | View parent = (View) getParent(); |
| 654 | boolean challengeShowing = false; |
| 655 | // Widget pages need to know where the top of the sliding challenge is so that they |
| 656 | // now how big the widget should be when the challenge is up. We compute it here and |
| 657 | // then propagate it to each of our children. |
| 658 | if (parent.getParent() instanceof SlidingChallengeLayout) { |
| 659 | SlidingChallengeLayout scl = (SlidingChallengeLayout) parent.getParent(); |
| 660 | int top = scl.getMaxChallengeTop(); |
| 661 | |
| 662 | // This is a bit evil, but we need to map a coordinate relative to the SCL into a |
| 663 | // coordinate relative to our children, hence we subtract the top padding.s |
| 664 | maxChallengeTop = top - getPaddingTop(); |
| 665 | challengeShowing = scl.isChallengeShowing(); |
Adam Cohen | 8a7785c | 2012-10-29 22:01:33 -0700 | [diff] [blame] | 666 | |
Adam Cohen | 4ddcd57 | 2012-11-01 17:36:32 -0700 | [diff] [blame] | 667 | int count = getChildCount(); |
| 668 | for (int i = 0; i < count; i++) { |
| 669 | KeyguardWidgetFrame frame = getWidgetPageAt(i); |
| 670 | frame.setMaxChallengeTop(maxChallengeTop); |
| 671 | // On the very first measure pass, if the challenge is showing, we need to make sure |
| 672 | // that the widget on the current page is small. |
| 673 | if (challengeShowing && i == mCurrentPage && !mHasMeasure) { |
Jim Miller | 6b0afad | 2013-10-28 19:08:42 -0700 | [diff] [blame] | 674 | frame.shrinkWidget(true); |
Adam Cohen | 4ddcd57 | 2012-11-01 17:36:32 -0700 | [diff] [blame] | 675 | } |
Adam Cohen | 8a7785c | 2012-10-29 22:01:33 -0700 | [diff] [blame] | 676 | } |
| 677 | } |
| 678 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
Adam Cohen | 4ddcd57 | 2012-11-01 17:36:32 -0700 | [diff] [blame] | 679 | mHasMeasure = true; |
Adam Cohen | 6fb841f | 2012-10-24 13:15:38 -0700 | [diff] [blame] | 680 | } |
| 681 | |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 682 | void animateOutlinesAndSidePages(final boolean show) { |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 683 | animateOutlinesAndSidePages(show, -1); |
| 684 | } |
| 685 | |
Adam Cohen | 8caabad | 2012-11-04 17:23:25 -0800 | [diff] [blame] | 686 | public void setWidgetToResetOnPageFadeOut(int widget) { |
Adam Cohen | db1c5d5 | 2012-11-03 17:10:07 -0700 | [diff] [blame] | 687 | mWidgetToResetAfterFadeOut = widget; |
| 688 | } |
| 689 | |
Adam Cohen | 8caabad | 2012-11-04 17:23:25 -0800 | [diff] [blame] | 690 | public int getWidgetToResetOnPageFadeOut() { |
| 691 | return mWidgetToResetAfterFadeOut; |
| 692 | } |
| 693 | |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 694 | void animateOutlinesAndSidePages(final boolean show, int duration) { |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 695 | if (mChildrenOutlineFadeAnimation != null) { |
| 696 | mChildrenOutlineFadeAnimation.cancel(); |
| 697 | mChildrenOutlineFadeAnimation = null; |
| 698 | } |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 699 | int count = getChildCount(); |
| 700 | PropertyValuesHolder alpha; |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 701 | ArrayList<Animator> anims = new ArrayList<Animator>(); |
Adam Cohen | 6fb841f | 2012-10-24 13:15:38 -0700 | [diff] [blame] | 702 | |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 703 | if (duration == -1) { |
| 704 | duration = show ? CHILDREN_OUTLINE_FADE_IN_DURATION : |
| 705 | CHILDREN_OUTLINE_FADE_OUT_DURATION; |
| 706 | } |
Adam Cohen | e364313 | 2012-10-28 18:29:17 -0700 | [diff] [blame] | 707 | |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 708 | int curPage = getNextPage(); |
| 709 | for (int i = 0; i < count; i++) { |
| 710 | float finalContentAlpha; |
| 711 | if (show) { |
Adam Cohen | 2b0501b | 2012-11-21 16:49:13 -0800 | [diff] [blame] | 712 | finalContentAlpha = getAlphaForPage(mScreenCenter, i, true); |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 713 | } else if (!show && i == curPage) { |
| 714 | finalContentAlpha = 1f; |
| 715 | } else { |
| 716 | finalContentAlpha = 0f; |
| 717 | } |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 718 | KeyguardWidgetFrame child = getWidgetPageAt(i); |
Adam Cohen | 45adaa7 | 2012-11-02 22:00:57 -0700 | [diff] [blame] | 719 | |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 720 | alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalContentAlpha); |
Adam Cohen | e364313 | 2012-10-28 18:29:17 -0700 | [diff] [blame] | 721 | ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha); |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 722 | anims.add(a); |
Adam Cohen | e364313 | 2012-10-28 18:29:17 -0700 | [diff] [blame] | 723 | |
Adam Cohen | 2b0501b | 2012-11-21 16:49:13 -0800 | [diff] [blame] | 724 | float finalOutlineAlpha = show ? getOutlineAlphaForPage(mScreenCenter, i, true) : 0f; |
Adam Cohen | e364313 | 2012-10-28 18:29:17 -0700 | [diff] [blame] | 725 | child.fadeFrame(this, show, finalOutlineAlpha, duration); |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 726 | } |
| 727 | |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 728 | mChildrenOutlineFadeAnimation = new AnimatorSet(); |
| 729 | mChildrenOutlineFadeAnimation.playTogether(anims); |
| 730 | |
| 731 | mChildrenOutlineFadeAnimation.setDuration(duration); |
| 732 | mChildrenOutlineFadeAnimation.addListener(new AnimatorListenerAdapter() { |
| 733 | @Override |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 734 | public void onAnimationStart(Animator animation) { |
| 735 | if (show) { |
Adam Cohen | 5d47a8d | 2012-11-03 19:10:56 -0700 | [diff] [blame] | 736 | enablePageContentLayers(); |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 737 | } |
| 738 | } |
Adam Cohen | db1c5d5 | 2012-11-03 17:10:07 -0700 | [diff] [blame] | 739 | |
Adam Cohen | 70009e4 | 2012-10-30 16:48:22 -0700 | [diff] [blame] | 740 | @Override |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 741 | public void onAnimationEnd(Animator animation) { |
| 742 | if (!show) { |
Adam Cohen | 5d47a8d | 2012-11-03 19:10:56 -0700 | [diff] [blame] | 743 | disablePageContentLayers(); |
Adam Cohen | 8caabad | 2012-11-04 17:23:25 -0800 | [diff] [blame] | 744 | KeyguardWidgetFrame frame = getWidgetPageAt(mWidgetToResetAfterFadeOut); |
| 745 | if (frame != null && !(frame == getWidgetPageAt(mCurrentPage) && |
| 746 | mViewStateManager.isChallengeOverlapping())) { |
| 747 | frame.resetSize(); |
Adam Cohen | db1c5d5 | 2012-11-03 17:10:07 -0700 | [diff] [blame] | 748 | } |
Adam Cohen | 8caabad | 2012-11-04 17:23:25 -0800 | [diff] [blame] | 749 | mWidgetToResetAfterFadeOut = -1; |
Adam Cohen | 2b0501b | 2012-11-21 16:49:13 -0800 | [diff] [blame] | 750 | mShowingInitialHints = false; |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 751 | } |
Svetoslav Ganov | a90a18d | 2012-11-06 15:22:11 -0800 | [diff] [blame] | 752 | updateWidgetFramesImportantForAccessibility(); |
Adam Cohen | f9048cd | 2012-10-27 16:36:10 -0700 | [diff] [blame] | 753 | } |
| 754 | }); |
| 755 | mChildrenOutlineFadeAnimation.start(); |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 756 | } |
| 757 | |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 758 | @Override |
| 759 | public boolean onLongClick(View v) { |
Winson Chung | 9dc9923 | 2012-10-29 17:43:18 -0700 | [diff] [blame] | 760 | // Disallow long pressing to reorder if the challenge is showing |
Winson Chung | 70aa528 | 2012-10-30 10:56:37 -0700 | [diff] [blame] | 761 | boolean isChallengeOverlapping = mViewStateManager.isChallengeShowing() && |
| 762 | mViewStateManager.isChallengeOverlapping(); |
| 763 | if (!isChallengeOverlapping && startReordering()) { |
Jim Miller | 19a5267 | 2012-10-23 19:52:04 -0700 | [diff] [blame] | 764 | return true; |
| 765 | } |
| 766 | return false; |
Jim Miller | d6523da | 2012-10-21 16:47:02 -0700 | [diff] [blame] | 767 | } |
Jim Miller | bdca3c0 | 2012-10-29 19:11:50 -0700 | [diff] [blame] | 768 | |
| 769 | public void removeWidget(View view) { |
| 770 | if (view instanceof KeyguardWidgetFrame) { |
| 771 | removeView(view); |
| 772 | } else { |
| 773 | // Assume view was wrapped by a KeyguardWidgetFrame in KeyguardWidgetPager#addWidget(). |
| 774 | // This supports legacy hard-coded "widgets" like KeyguardTransportControlView. |
| 775 | int pos = getWidgetPageIndex(view); |
| 776 | if (pos != -1) { |
| 777 | KeyguardWidgetFrame frame = (KeyguardWidgetFrame) getChildAt(pos); |
| 778 | frame.removeView(view); |
| 779 | removeView(frame); |
| 780 | } else { |
| 781 | Slog.w(TAG, "removeWidget() can't find:" + view); |
| 782 | } |
| 783 | } |
| 784 | } |
| 785 | |
| 786 | public int getWidgetPageIndex(View view) { |
| 787 | if (view instanceof KeyguardWidgetFrame) { |
| 788 | return indexOfChild(view); |
| 789 | } else { |
| 790 | // View was wrapped by a KeyguardWidgetFrame by KeyguardWidgetPager#addWidget() |
| 791 | return indexOfChild((KeyguardWidgetFrame)view.getParent()); |
| 792 | } |
| 793 | } |
Winson Chung | f3b9ec8 | 2012-11-01 14:48:51 -0700 | [diff] [blame] | 794 | |
| 795 | @Override |
| 796 | protected void setPageHoveringOverDeleteDropTarget(int viewIndex, boolean isHovering) { |
| 797 | KeyguardWidgetFrame child = getWidgetPageAt(viewIndex); |
| 798 | child.setIsHoveringOverDeleteDropTarget(isHovering); |
| 799 | } |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 800 | |
| 801 | // ChallengeLayout.OnBouncerStateChangedListener |
| 802 | @Override |
| 803 | public void onBouncerStateChanged(boolean bouncerActive) { |
| 804 | if (bouncerActive) { |
| 805 | zoomOutToBouncer(); |
| 806 | } else { |
| 807 | zoomInFromBouncer(); |
| 808 | } |
| 809 | } |
| 810 | |
Winson Chung | 70c2f87 | 2012-11-07 21:47:12 -0800 | [diff] [blame] | 811 | void setBouncerAnimationDuration(int duration) { |
| 812 | mBouncerZoomInOutDuration = duration; |
| 813 | } |
| 814 | |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 815 | // Zoom in after the bouncer is dismissed |
| 816 | void zoomInFromBouncer() { |
| 817 | if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) { |
| 818 | mZoomInOutAnim.cancel(); |
| 819 | } |
| 820 | final View currentPage = getPageAt(getCurrentPage()); |
| 821 | if (currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f) { |
| 822 | mZoomInOutAnim = new AnimatorSet(); |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 823 | mZoomInOutAnim.playTogether( |
| 824 | ObjectAnimator.ofFloat(currentPage, "scaleX", 1f), |
| 825 | ObjectAnimator.ofFloat(currentPage , "scaleY", 1f)); |
Winson Chung | 70c2f87 | 2012-11-07 21:47:12 -0800 | [diff] [blame] | 826 | mZoomInOutAnim.setDuration(mBouncerZoomInOutDuration); |
| 827 | mZoomInOutAnim.setInterpolator(new DecelerateInterpolator(1.5f)); |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 828 | mZoomInOutAnim.start(); |
| 829 | } |
John Spurlock | 0552c5d | 2012-11-15 08:04:45 -0500 | [diff] [blame] | 830 | if (currentPage instanceof KeyguardWidgetFrame) { |
| 831 | ((KeyguardWidgetFrame)currentPage).onBouncerShowing(false); |
| 832 | } |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 833 | } |
| 834 | |
| 835 | // Zoom out after the bouncer is initiated |
| 836 | void zoomOutToBouncer() { |
| 837 | if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) { |
| 838 | mZoomInOutAnim.cancel(); |
| 839 | } |
Winson Chung | 70c2f87 | 2012-11-07 21:47:12 -0800 | [diff] [blame] | 840 | int curPage = getCurrentPage(); |
| 841 | View currentPage = getPageAt(curPage); |
| 842 | if (shouldSetTopAlignedPivotForWidget(curPage)) { |
| 843 | currentPage.setPivotY(0); |
| 844 | // Note: we are working around the issue that setting the x-pivot to the same value as it |
| 845 | // was does not actually work. |
| 846 | currentPage.setPivotX(0); |
| 847 | currentPage.setPivotX(currentPage.getMeasuredWidth() / 2); |
| 848 | } |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 849 | if (!(currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f)) { |
| 850 | mZoomInOutAnim = new AnimatorSet(); |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 851 | mZoomInOutAnim.playTogether( |
| 852 | ObjectAnimator.ofFloat(currentPage, "scaleX", BOUNCER_SCALE_FACTOR), |
| 853 | ObjectAnimator.ofFloat(currentPage, "scaleY", BOUNCER_SCALE_FACTOR)); |
Winson Chung | 70c2f87 | 2012-11-07 21:47:12 -0800 | [diff] [blame] | 854 | mZoomInOutAnim.setDuration(mBouncerZoomInOutDuration); |
| 855 | mZoomInOutAnim.setInterpolator(new DecelerateInterpolator(1.5f)); |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 856 | mZoomInOutAnim.start(); |
| 857 | } |
John Spurlock | 0552c5d | 2012-11-15 08:04:45 -0500 | [diff] [blame] | 858 | if (currentPage instanceof KeyguardWidgetFrame) { |
| 859 | ((KeyguardWidgetFrame)currentPage).onBouncerShowing(true); |
| 860 | } |
Winson Chung | 48275d2 | 2012-11-05 10:56:31 -0800 | [diff] [blame] | 861 | } |
Winson Chung | 6cf53bb | 2012-11-05 17:55:42 -0800 | [diff] [blame] | 862 | |
Winson Chung | 4752e7d | 2012-11-20 17:06:04 -0800 | [diff] [blame] | 863 | void setAddWidgetEnabled(boolean enabled) { |
| 864 | if (mAddWidgetView != null && enabled) { |
| 865 | addView(mAddWidgetView, 0); |
| 866 | // We need to force measure the PagedView so that the calls to update the scroll |
| 867 | // position below work |
| 868 | measure(mLastWidthMeasureSpec, mLastHeightMeasureSpec); |
| 869 | // Bump up the current page to account for the addition of the new page |
| 870 | setCurrentPage(mCurrentPage + 1); |
| 871 | mAddWidgetView = null; |
| 872 | } else if (mAddWidgetView == null && !enabled) { |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 873 | View addWidget = findViewById(R.id.keyguard_add_widget); |
Winson Chung | 4752e7d | 2012-11-20 17:06:04 -0800 | [diff] [blame] | 874 | if (addWidget != null) { |
| 875 | mAddWidgetView = addWidget; |
| 876 | removeView(addWidget); |
| 877 | } |
| 878 | } |
| 879 | } |
| 880 | |
Winson Chung | 6cf53bb | 2012-11-05 17:55:42 -0800 | [diff] [blame] | 881 | boolean isAddPage(int pageIndex) { |
| 882 | View v = getChildAt(pageIndex); |
Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 883 | return v != null && v.getId() == R.id.keyguard_add_widget; |
Winson Chung | 6cf53bb | 2012-11-05 17:55:42 -0800 | [diff] [blame] | 884 | } |
| 885 | |
| 886 | boolean isCameraPage(int pageIndex) { |
| 887 | View v = getChildAt(pageIndex); |
| 888 | return v != null && v instanceof CameraWidgetFrame; |
| 889 | } |
| 890 | |
| 891 | @Override |
| 892 | protected boolean shouldSetTopAlignedPivotForWidget(int childIndex) { |
| 893 | return !isCameraPage(childIndex) && super.shouldSetTopAlignedPivotForWidget(childIndex); |
| 894 | } |
Jeff Sharkey | 06c5f8a | 2012-12-04 09:53:44 -0800 | [diff] [blame] | 895 | |
| 896 | /** |
| 897 | * Search given {@link View} hierarchy for {@link TextClock} instances that |
| 898 | * show various time components. Returns combination of |
| 899 | * {@link #FLAG_HAS_LOCAL_HOUR} and {@link #FLAG_HAS_LOCAL_MINUTE}. |
| 900 | */ |
| 901 | private static int findClockInHierarchy(View view) { |
| 902 | if (view instanceof TextClock) { |
| 903 | return getClockFlags((TextClock) view); |
| 904 | } else if (view instanceof ViewGroup) { |
| 905 | int flags = 0; |
| 906 | final ViewGroup group = (ViewGroup) view; |
| 907 | final int size = group.getChildCount(); |
| 908 | for (int i = 0; i < size; i++) { |
| 909 | flags |= findClockInHierarchy(group.getChildAt(i)); |
| 910 | } |
| 911 | return flags; |
| 912 | } else { |
| 913 | return 0; |
| 914 | } |
| 915 | } |
| 916 | |
| 917 | /** |
| 918 | * Return combination of {@link #FLAG_HAS_LOCAL_HOUR} and |
| 919 | * {@link #FLAG_HAS_LOCAL_MINUTE} describing the time represented described |
| 920 | * by the given {@link TextClock}. |
| 921 | */ |
| 922 | private static int getClockFlags(TextClock clock) { |
| 923 | int flags = 0; |
| 924 | |
| 925 | final String timeZone = clock.getTimeZone(); |
| 926 | if (timeZone != null && !TimeZone.getDefault().equals(TimeZone.getTimeZone(timeZone))) { |
| 927 | // Ignore clocks showing another timezone |
| 928 | return 0; |
| 929 | } |
| 930 | |
| 931 | final CharSequence format = clock.getFormat(); |
| 932 | final char hour = clock.is24HourModeEnabled() ? DateFormat.HOUR_OF_DAY |
| 933 | : DateFormat.HOUR; |
| 934 | |
| 935 | if (DateFormat.hasDesignator(format, hour)) { |
| 936 | flags |= FLAG_HAS_LOCAL_HOUR; |
| 937 | } |
| 938 | if (DateFormat.hasDesignator(format, DateFormat.MINUTE)) { |
| 939 | flags |= FLAG_HAS_LOCAL_MINUTE; |
| 940 | } |
| 941 | |
| 942 | return flags; |
| 943 | } |
Jim Miller | caf24fc | 2013-09-10 18:37:01 -0700 | [diff] [blame] | 944 | |
| 945 | public void handleExternalCameraEvent(MotionEvent event) { |
| 946 | beginCameraEvent(); |
| 947 | int cameraPage = getPageCount() - 1; |
| 948 | boolean endWarp = false; |
Jim Miller | 8de9e44 | 2013-09-20 14:21:50 -0700 | [diff] [blame] | 949 | if (isCameraPage(cameraPage) || mCameraEventInProgress) { |
Jim Miller | caf24fc | 2013-09-10 18:37:01 -0700 | [diff] [blame] | 950 | switch (event.getAction()) { |
| 951 | case MotionEvent.ACTION_DOWN: |
Jim Miller | 8de9e44 | 2013-09-20 14:21:50 -0700 | [diff] [blame] | 952 | // Once we start dispatching camera events, we must continue to do so |
| 953 | // to keep event dispatch happy. |
| 954 | mCameraEventInProgress = true; |
Jim Miller | caf24fc | 2013-09-10 18:37:01 -0700 | [diff] [blame] | 955 | userActivity(); |
Jim Miller | c162dd0 | 2013-09-25 18:57:43 -0700 | [diff] [blame] | 956 | startPageWarp(cameraPage); |
Jim Miller | caf24fc | 2013-09-10 18:37:01 -0700 | [diff] [blame] | 957 | break; |
| 958 | case MotionEvent.ACTION_UP: |
| 959 | case MotionEvent.ACTION_CANCEL: |
Jim Miller | 8de9e44 | 2013-09-20 14:21:50 -0700 | [diff] [blame] | 960 | mCameraEventInProgress = false; |
Jim Miller | c162dd0 | 2013-09-25 18:57:43 -0700 | [diff] [blame] | 961 | endWarp = isWarping(); |
Jim Miller | caf24fc | 2013-09-10 18:37:01 -0700 | [diff] [blame] | 962 | break; |
| 963 | } |
| 964 | dispatchTouchEvent(event); |
| 965 | // This has to happen after the event has been handled by the real widget pager |
Jim Miller | c162dd0 | 2013-09-25 18:57:43 -0700 | [diff] [blame] | 966 | if (endWarp) stopPageWarp(); |
Jim Miller | caf24fc | 2013-09-10 18:37:01 -0700 | [diff] [blame] | 967 | } |
| 968 | endCameraEvent(); |
| 969 | } |
| 970 | |
Jim Miller | dcb3d84 | 2012-08-23 19:18:12 -0700 | [diff] [blame] | 971 | } |