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