blob: 81f6221e024bd0a74bb655baef9f34c1aa6d88f9 [file] [log] [blame]
Jim Millerf2dfc352012-08-29 18:42:21 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
Jim Millerf2dfc352012-08-29 18:42:21 -070018
Adam Cohene3643132012-10-28 18:29:17 -070019import android.animation.Animator;
20import android.animation.ObjectAnimator;
21import android.animation.PropertyValuesHolder;
Michael Jurka1254f2f2012-10-25 11:44:31 -070022import android.appwidget.AppWidgetHostView;
Michael Jurka67a871d2012-11-01 18:26:01 -070023import android.appwidget.AppWidgetManager;
Jim Millerf2dfc352012-08-29 18:42:21 -070024import android.content.Context;
25import android.content.res.Resources;
26import android.graphics.Canvas;
Adam Cohen61cd69c2012-10-02 21:42:54 -070027import android.graphics.LinearGradient;
Jim Millerf2dfc352012-08-29 18:42:21 -070028import android.graphics.Paint;
29import android.graphics.PorterDuff;
30import android.graphics.PorterDuffXfermode;
31import android.graphics.Rect;
Adam Cohen61cd69c2012-10-02 21:42:54 -070032import android.graphics.Shader;
Jim Millerd6523da2012-10-21 16:47:02 -070033import android.graphics.drawable.Drawable;
John Spurlock37d84ae2012-11-04 11:11:47 -050034import android.os.Handler;
Jim Millerf2dfc352012-08-29 18:42:21 -070035import android.util.AttributeSet;
Jim Miller5d2da7132012-10-02 18:38:09 -070036import android.view.MotionEvent;
Jim Millerd6523da2012-10-21 16:47:02 -070037import android.view.View;
Jim Millerf2dfc352012-08-29 18:42:21 -070038import android.widget.FrameLayout;
39
Jim Millerf2dfc352012-08-29 18:42:21 -070040public class KeyguardWidgetFrame extends FrameLayout {
41 private final static PorterDuffXfermode sAddBlendMode =
42 new PorterDuffXfermode(PorterDuff.Mode.ADD);
Jim Millerf2dfc352012-08-29 18:42:21 -070043
Adam Powellcfc30862012-10-29 18:21:31 -070044 static final float OUTLINE_ALPHA_MULTIPLIER = 0.6f;
Winson Chungf3b9ec82012-11-01 14:48:51 -070045 static final int HOVER_OVER_DELETE_DROP_TARGET_OVERLAY_COLOR = 0x99FF0000;
46
47 // Temporarily disable this for the time being until we know why the gfx is messing up
48 static final boolean ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY = true;
Adam Powellcfc30862012-10-29 18:21:31 -070049
Adam Cohen61cd69c2012-10-02 21:42:54 -070050 private int mGradientColor;
51 private LinearGradient mForegroundGradient;
52 private LinearGradient mLeftToRightGradient;
53 private LinearGradient mRightToLeftGradient;
54 private Paint mGradientPaint = new Paint();
55 boolean mLeftToRight = true;
56
Adam Cohen66b9fb1662012-09-05 16:23:58 -070057 private float mOverScrollAmount = 0f;
Jim Millerf2dfc352012-08-29 18:42:21 -070058 private final Rect mForegroundRect = new Rect();
59 private int mForegroundAlpha = 0;
Jim Miller19a52672012-10-23 19:52:04 -070060 private CheckLongPressHelper mLongPressHelper;
Adam Cohene3643132012-10-28 18:29:17 -070061 private Animator mFrameFade;
62 private boolean mIsSmall = false;
John Spurlock37d84ae2012-11-04 11:11:47 -050063 private Handler mWorkerHandler;
Jim Millerf2dfc352012-08-29 18:42:21 -070064
Jim Millerd6523da2012-10-21 16:47:02 -070065 private float mBackgroundAlpha;
Adam Cohenf9048cd2012-10-27 16:36:10 -070066 private float mContentAlpha;
Adam Cohen6fb841f2012-10-24 13:15:38 -070067 private float mBackgroundAlphaMultiplier = 1.0f;
Jim Millerd6523da2012-10-21 16:47:02 -070068 private Drawable mBackgroundDrawable;
69 private Rect mBackgroundRect = new Rect();
Adam Cohen4ddcd572012-11-01 17:36:32 -070070
71 // These variables are all needed in order to size things properly before we're actually
72 // measured.
Adam Cohen5be14de2012-10-30 11:19:48 -070073 private int mSmallWidgetHeight;
Adam Cohen4ddcd572012-11-01 17:36:32 -070074 private int mSmallFrameHeight;
75 private boolean mWidgetLockedSmall = false;
76 private int mMaxChallengeTop = -1;
Adam Cohen5d47a8d2012-11-03 19:10:56 -070077 private int mFrameStrokeAdjustment;
Adam Cohenc276e822012-11-08 13:01:08 -080078 private boolean mPerformAppWidgetSizeUpdateOnBootComplete;
Adam Cohen4ddcd572012-11-01 17:36:32 -070079
80 // This will hold the width value before we've actually been measured
81 private int mFrameHeight;
Jim Millerd6523da2012-10-21 16:47:02 -070082
Winson Chungf3b9ec82012-11-01 14:48:51 -070083 private boolean mIsHoveringOverDeleteDropTarget;
84
Adam Cohene3643132012-10-28 18:29:17 -070085 // Multiple callers may try and adjust the alpha of the frame. When a caller shows
86 // the outlines, we give that caller control, and nobody else can fade them out.
87 // This prevents animation conflicts.
88 private Object mBgAlphaController;
89
Jim Millerf2dfc352012-08-29 18:42:21 -070090 public KeyguardWidgetFrame(Context context) {
91 this(context, null, 0);
92 }
93
94 public KeyguardWidgetFrame(Context context, AttributeSet attrs) {
95 this(context, attrs, 0);
96 }
97
98 public KeyguardWidgetFrame(Context context, AttributeSet attrs, int defStyle) {
99 super(context, attrs, defStyle);
Jim Miller5d2da7132012-10-02 18:38:09 -0700100
Jim Miller19a52672012-10-23 19:52:04 -0700101 mLongPressHelper = new CheckLongPressHelper(this);
Jim Miller5d2da7132012-10-02 18:38:09 -0700102
Adam Cohen7ffa8c02012-10-01 19:03:46 -0700103 Resources res = context.getResources();
Jim Millerd6523da2012-10-21 16:47:02 -0700104 // TODO: this padding should really correspond to the padding embedded in the background
Jim Miller022554e2012-10-22 19:03:06 -0700105 // drawable (ie. outlines).
Adam Cohen5d47a8d2012-11-03 19:10:56 -0700106 float density = res.getDisplayMetrics().density;
Jim Millerd6523da2012-10-21 16:47:02 -0700107 int padding = (int) (res.getDisplayMetrics().density * 8);
108 setPadding(padding, padding, padding, padding);
109
Adam Cohend51700b32012-11-07 16:26:46 -0800110 mFrameStrokeAdjustment = 2 + (int) (2 * density);
Adam Cohen5d47a8d2012-11-03 19:10:56 -0700111
Adam Cohen6f72b1c2012-11-05 15:20:30 -0800112 // This will be overriden on phones based on the current security mode, however on tablets
113 // we need to specify a height.
114 mSmallWidgetHeight =
Jim Miller5ecd8112013-01-09 18:50:26 -0800115 res.getDimensionPixelSize(R.dimen.kg_small_widget_height);
Adam Cohend51700b32012-11-07 16:26:46 -0800116 mBackgroundDrawable = res.getDrawable(R.drawable.kg_widget_bg_padded);
Jim Miller5ecd8112013-01-09 18:50:26 -0800117 mGradientColor = res.getColor(R.color.kg_widget_pager_gradient);
Adam Cohen61cd69c2012-10-02 21:42:54 -0700118 mGradientPaint.setXfermode(sAddBlendMode);
Jim Millerf2dfc352012-08-29 18:42:21 -0700119 }
120
Jim Miller19a52672012-10-23 19:52:04 -0700121 @Override
Adam Cohene3643132012-10-28 18:29:17 -0700122 protected void onDetachedFromWindow() {
Adam Cohenc276e822012-11-08 13:01:08 -0800123 super.onDetachedFromWindow();
Adam Cohene3643132012-10-28 18:29:17 -0700124 cancelLongPress();
Adam Cohenc276e822012-11-08 13:01:08 -0800125 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
126
Adam Cohene3643132012-10-28 18:29:17 -0700127 }
128
Adam Cohenc276e822012-11-08 13:01:08 -0800129 @Override
130 protected void onAttachedToWindow() {
131 super.onAttachedToWindow();
132 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
133 }
134
135 private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
136 new KeyguardUpdateMonitorCallback() {
137 @Override
138 public void onBootCompleted() {
139 if (mPerformAppWidgetSizeUpdateOnBootComplete) {
140 performAppWidgetSizeCallbacksIfNecessary();
141 mPerformAppWidgetSizeUpdateOnBootComplete = false;
142 }
143 }
144 };
145
Winson Chungf3b9ec82012-11-01 14:48:51 -0700146 void setIsHoveringOverDeleteDropTarget(boolean isHovering) {
147 if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
148 if (mIsHoveringOverDeleteDropTarget != isHovering) {
149 mIsHoveringOverDeleteDropTarget = isHovering;
150 invalidate();
151 }
152 }
153 }
154
Adam Cohene3643132012-10-28 18:29:17 -0700155 @Override
Jim Miller19a52672012-10-23 19:52:04 -0700156 public boolean onInterceptTouchEvent(MotionEvent ev) {
157 // Watch for longpress events at this level to make sure
158 // users can always pick up this widget
159 switch (ev.getAction()) {
160 case MotionEvent.ACTION_DOWN:
161 mLongPressHelper.postCheckForLongPress(ev);
162 break;
163 case MotionEvent.ACTION_MOVE:
164 mLongPressHelper.onMove(ev);
165 break;
166 case MotionEvent.ACTION_POINTER_DOWN:
167 case MotionEvent.ACTION_UP:
168 case MotionEvent.ACTION_CANCEL:
169 mLongPressHelper.cancelLongPress();
170 break;
171 }
172
173 // Otherwise continue letting touch events fall through to children
174 return false;
Jim Miller5d2da7132012-10-02 18:38:09 -0700175 }
176
177 @Override
Jim Miller19a52672012-10-23 19:52:04 -0700178 public boolean onTouchEvent(MotionEvent ev) {
179 // Watch for longpress events at this level to make sure
180 // users can always pick up this widget
181 switch (ev.getAction()) {
182 case MotionEvent.ACTION_MOVE:
183 mLongPressHelper.onMove(ev);
184 break;
185 case MotionEvent.ACTION_POINTER_DOWN:
186 case MotionEvent.ACTION_UP:
187 case MotionEvent.ACTION_CANCEL:
188 mLongPressHelper.cancelLongPress();
189 break;
Jim Miller5d2da7132012-10-02 18:38:09 -0700190 }
Jim Miller19a52672012-10-23 19:52:04 -0700191
192 // We return true here to ensure that we will get cancel / up signal
193 // even if none of our children have requested touch.
Jim Miller5d2da7132012-10-02 18:38:09 -0700194 return true;
195 }
196
Jim Millerf2dfc352012-08-29 18:42:21 -0700197 @Override
Jim Miller19a52672012-10-23 19:52:04 -0700198 public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
199 super.requestDisallowInterceptTouchEvent(disallowIntercept);
200 cancelLongPress();
201 }
202
203 @Override
204 public void cancelLongPress() {
205 super.cancelLongPress();
206 mLongPressHelper.cancelLongPress();
207 }
208
Adam Cohenf9048cd2012-10-27 16:36:10 -0700209
210 private void drawGradientOverlay(Canvas c) {
211 mGradientPaint.setShader(mForegroundGradient);
212 mGradientPaint.setAlpha(mForegroundAlpha);
213 c.drawRect(mForegroundRect, mGradientPaint);
214 }
215
Winson Chungf3b9ec82012-11-01 14:48:51 -0700216 private void drawHoveringOverDeleteOverlay(Canvas c) {
217 if (mIsHoveringOverDeleteDropTarget) {
218 c.drawColor(HOVER_OVER_DELETE_DROP_TARGET_OVERLAY_COLOR);
219 }
220 }
221
Adam Cohenf9048cd2012-10-27 16:36:10 -0700222 protected void drawBg(Canvas canvas) {
223 if (mBackgroundAlpha > 0.0f) {
224 Drawable bg = mBackgroundDrawable;
225
226 bg.setAlpha((int) (mBackgroundAlpha * mBackgroundAlphaMultiplier * 255));
227 bg.setBounds(mBackgroundRect);
228 bg.draw(canvas);
229 }
230 }
231
Jim Miller19a52672012-10-23 19:52:04 -0700232 @Override
Jim Millerf2dfc352012-08-29 18:42:21 -0700233 protected void dispatchDraw(Canvas canvas) {
Winson Chungf3b9ec82012-11-01 14:48:51 -0700234 if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
235 canvas.save();
236 }
Jim Millerd6523da2012-10-21 16:47:02 -0700237 drawBg(canvas);
Jim Millerf2dfc352012-08-29 18:42:21 -0700238 super.dispatchDraw(canvas);
Adam Cohen61cd69c2012-10-02 21:42:54 -0700239 drawGradientOverlay(canvas);
Winson Chungf3b9ec82012-11-01 14:48:51 -0700240 if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
241 drawHoveringOverDeleteOverlay(canvas);
242 canvas.restore();
243 }
Adam Cohen61cd69c2012-10-02 21:42:54 -0700244 }
245
Jim Millerd6523da2012-10-21 16:47:02 -0700246 /**
247 * Because this view has fading outlines, it is essential that we enable hardware
248 * layers on the content (child) so that updating the alpha of the outlines doesn't
249 * result in the content layer being recreated.
250 */
251 public void enableHardwareLayersForContent() {
252 View widget = getContent();
253 if (widget != null) {
254 widget.setLayerType(LAYER_TYPE_HARDWARE, null);
255 }
256 }
257
258 /**
259 * Because this view has fading outlines, it is essential that we enable hardware
260 * layers on the content (child) so that updating the alpha of the outlines doesn't
261 * result in the content layer being recreated.
262 */
263 public void disableHardwareLayersForContent() {
264 View widget = getContent();
265 if (widget != null) {
266 widget.setLayerType(LAYER_TYPE_NONE, null);
267 }
268 }
269
Adam Cohenf9048cd2012-10-27 16:36:10 -0700270 public void enableHardwareLayers() {
271 setLayerType(LAYER_TYPE_HARDWARE, null);
272 }
273
274 public void disableHardwareLayers() {
275 setLayerType(LAYER_TYPE_NONE, null);
276 }
277
Jim Millerd6523da2012-10-21 16:47:02 -0700278 public View getContent() {
279 return getChildAt(0);
280 }
281
Michael Jurka1254f2f2012-10-25 11:44:31 -0700282 public int getContentAppWidgetId() {
283 View content = getContent();
284 if (content instanceof AppWidgetHostView) {
285 return ((AppWidgetHostView) content).getAppWidgetId();
Michael Jurka67a871d2012-11-01 18:26:01 -0700286 } else if (content instanceof KeyguardStatusView) {
Michael Jurka1254f2f2012-10-25 11:44:31 -0700287 return ((KeyguardStatusView) content).getAppWidgetId();
Michael Jurka67a871d2012-11-01 18:26:01 -0700288 } else {
289 return AppWidgetManager.INVALID_APPWIDGET_ID;
Michael Jurka1254f2f2012-10-25 11:44:31 -0700290 }
291 }
292
Jim Millerd6523da2012-10-21 16:47:02 -0700293 public float getBackgroundAlpha() {
294 return mBackgroundAlpha;
295 }
296
297 public void setBackgroundAlphaMultiplier(float multiplier) {
Adam Cohenf9048cd2012-10-27 16:36:10 -0700298 if (Float.compare(mBackgroundAlphaMultiplier, multiplier) != 0) {
Jim Millerd6523da2012-10-21 16:47:02 -0700299 mBackgroundAlphaMultiplier = multiplier;
300 invalidate();
301 }
302 }
303
304 public float getBackgroundAlphaMultiplier() {
305 return mBackgroundAlphaMultiplier;
306 }
307
308 public void setBackgroundAlpha(float alpha) {
Adam Cohenf9048cd2012-10-27 16:36:10 -0700309 if (Float.compare(mBackgroundAlpha, alpha) != 0) {
Jim Millerd6523da2012-10-21 16:47:02 -0700310 mBackgroundAlpha = alpha;
311 invalidate();
312 }
313 }
314
Adam Cohenf9048cd2012-10-27 16:36:10 -0700315 public float getContentAlpha() {
316 return mContentAlpha;
317 }
318
Adam Cohen6fb841f2012-10-24 13:15:38 -0700319 public void setContentAlpha(float alpha) {
Adam Cohenf9048cd2012-10-27 16:36:10 -0700320 mContentAlpha = alpha;
Adam Cohen6fb841f2012-10-24 13:15:38 -0700321 View content = getContent();
322 if (content != null) {
323 content.setAlpha(alpha);
324 }
325 }
326
Jim Millerd6523da2012-10-21 16:47:02 -0700327 /**
328 * Depending on whether the security is up, the widget size needs to change
329 *
330 * @param height The height of the widget, -1 for full height
331 */
Adam Cohene3643132012-10-28 18:29:17 -0700332 private void setWidgetHeight(int height) {
Jim Millerd6523da2012-10-21 16:47:02 -0700333 boolean needLayout = false;
334 View widget = getContent();
335 if (widget != null) {
336 LayoutParams lp = (LayoutParams) widget.getLayoutParams();
337 if (lp.height != height) {
338 needLayout = true;
339 lp.height = height;
340 }
341 }
342 if (needLayout) {
343 requestLayout();
344 }
345 }
346
Adam Cohen4ddcd572012-11-01 17:36:32 -0700347 public void setMaxChallengeTop(int top) {
348 boolean dirty = mMaxChallengeTop != top;
Adam Cohen44dc1412012-11-07 20:50:39 -0800349 mMaxChallengeTop = top;
Adam Cohen4ddcd572012-11-01 17:36:32 -0700350 mSmallWidgetHeight = top - getPaddingTop();
351 mSmallFrameHeight = top + getPaddingBottom();
352 if (dirty && mIsSmall) {
353 setWidgetHeight(mSmallWidgetHeight);
354 setFrameHeight(mSmallFrameHeight);
355 } else if (dirty && mWidgetLockedSmall) {
356 setWidgetHeight(mSmallWidgetHeight);
357 }
358 }
359
Adam Cohene3643132012-10-28 18:29:17 -0700360 public boolean isSmall() {
361 return mIsSmall;
362 }
363
364 public void adjustFrame(int challengeTop) {
Adam Cohen4ddcd572012-11-01 17:36:32 -0700365 int frameHeight = challengeTop + getPaddingBottom();
366 setFrameHeight(frameHeight);
Adam Cohene3643132012-10-28 18:29:17 -0700367 }
368
Adam Cohen44dc1412012-11-07 20:50:39 -0800369 public void shrinkWidget(boolean alsoShrinkFrame) {
Adam Cohene3643132012-10-28 18:29:17 -0700370 mIsSmall = true;
Adam Cohen4ddcd572012-11-01 17:36:32 -0700371 setWidgetHeight(mSmallWidgetHeight);
Adam Cohen44dc1412012-11-07 20:50:39 -0800372
373 if (alsoShrinkFrame) {
374 setFrameHeight(mSmallFrameHeight);
375 }
376 }
377
378 public int getSmallFrameHeight() {
379 return mSmallFrameHeight;
380 }
381
382 public void shrinkWidget() {
383 shrinkWidget(true);
Adam Cohen4ddcd572012-11-01 17:36:32 -0700384 }
385
386 public void setWidgetLockedSmall(boolean locked) {
Adam Cohen86006bb2012-11-02 00:13:24 -0700387 if (locked) {
388 setWidgetHeight(mSmallWidgetHeight);
389 }
Adam Cohen4ddcd572012-11-01 17:36:32 -0700390 mWidgetLockedSmall = locked;
Jim Millerd6523da2012-10-21 16:47:02 -0700391 }
392
393 public void resetSize() {
Adam Cohene3643132012-10-28 18:29:17 -0700394 mIsSmall = false;
Adam Cohen4ddcd572012-11-01 17:36:32 -0700395 if (!mWidgetLockedSmall) {
396 setWidgetHeight(LayoutParams.MATCH_PARENT);
397 }
Adam Cohene3643132012-10-28 18:29:17 -0700398 setFrameHeight(getMeasuredHeight());
Jim Millerd6523da2012-10-21 16:47:02 -0700399 }
400
Adam Cohene3643132012-10-28 18:29:17 -0700401 public void setFrameHeight(int height) {
Adam Cohen4ddcd572012-11-01 17:36:32 -0700402 mFrameHeight = height;
403 mBackgroundRect.set(0, 0, getMeasuredWidth(), Math.min(mFrameHeight, getMeasuredHeight()));
Adam Cohend51700b32012-11-07 16:26:46 -0800404 mForegroundRect.set(mFrameStrokeAdjustment, mFrameStrokeAdjustment,getMeasuredWidth() -
405 mFrameStrokeAdjustment, Math.min(getMeasuredHeight(), mFrameHeight) -
406 mFrameStrokeAdjustment);
407 updateGradient();
Adam Cohene3643132012-10-28 18:29:17 -0700408 invalidate();
409 }
410
411 public void hideFrame(Object caller) {
Adam Cohendb1c5d52012-11-03 17:10:07 -0700412 fadeFrame(caller, false, 0f, KeyguardWidgetPager.CHILDREN_OUTLINE_FADE_OUT_DURATION);
Adam Cohene3643132012-10-28 18:29:17 -0700413 }
414
415 public void showFrame(Object caller) {
Adam Cohendb1c5d52012-11-03 17:10:07 -0700416 fadeFrame(caller, true, OUTLINE_ALPHA_MULTIPLIER,
417 KeyguardWidgetPager.CHILDREN_OUTLINE_FADE_IN_DURATION);
Adam Cohene3643132012-10-28 18:29:17 -0700418 }
419
420 public void fadeFrame(Object caller, boolean takeControl, float alpha, int duration) {
421 if (takeControl) {
422 mBgAlphaController = caller;
423 }
424
Adam Cohen2b0501b2012-11-21 16:49:13 -0800425 if (mBgAlphaController != caller && mBgAlphaController != null) {
426 return;
427 }
Adam Cohene3643132012-10-28 18:29:17 -0700428
429 if (mFrameFade != null) {
430 mFrameFade.cancel();
431 mFrameFade = null;
432 }
433 PropertyValuesHolder bgAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", alpha);
434 mFrameFade = ObjectAnimator.ofPropertyValuesHolder(this, bgAlpha);
435 mFrameFade.setDuration(duration);
436 mFrameFade.start();
437 }
438
Adam Cohend51700b32012-11-07 16:26:46 -0800439 private void updateGradient() {
Adam Cohen61cd69c2012-10-02 21:42:54 -0700440 float x0 = mLeftToRight ? 0 : mForegroundRect.width();
441 float x1 = mLeftToRight ? mForegroundRect.width(): 0;
442 mLeftToRightGradient = new LinearGradient(x0, 0f, x1, 0f,
443 mGradientColor, 0, Shader.TileMode.CLAMP);
444 mRightToLeftGradient = new LinearGradient(x1, 0f, x0, 0f,
445 mGradientColor, 0, Shader.TileMode.CLAMP);
Adam Cohend51700b32012-11-07 16:26:46 -0800446 }
447
448 @Override
449 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
450 super.onSizeChanged(w, h, oldw, oldh);
Adam Cohen4ddcd572012-11-01 17:36:32 -0700451
452 if (!mIsSmall) {
453 mFrameHeight = h;
454 }
455
Adam Cohend51700b32012-11-07 16:26:46 -0800456 // mFrameStrokeAdjustment is a cludge to prevent the overlay from drawing outside the
457 // rounded rect background.
458 mForegroundRect.set(mFrameStrokeAdjustment, mFrameStrokeAdjustment,
459 w - mFrameStrokeAdjustment, Math.min(h, mFrameHeight) - mFrameStrokeAdjustment);
460
Adam Cohen4ddcd572012-11-01 17:36:32 -0700461 mBackgroundRect.set(0, 0, getMeasuredWidth(), Math.min(h, mFrameHeight));
Adam Cohend51700b32012-11-07 16:26:46 -0800462 updateGradient();
Adam Cohene3643132012-10-28 18:29:17 -0700463 invalidate();
Jim Millerf2dfc352012-08-29 18:42:21 -0700464 }
465
Adam Cohen4ddcd572012-11-01 17:36:32 -0700466 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
467 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
468 performAppWidgetSizeCallbacksIfNecessary();
469 }
470
471 private void performAppWidgetSizeCallbacksIfNecessary() {
472 View content = getContent();
473 if (!(content instanceof AppWidgetHostView)) return;
474
Adam Cohenc276e822012-11-08 13:01:08 -0800475 if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
476 mPerformAppWidgetSizeUpdateOnBootComplete = true;
477 return;
Adam Cohen4ddcd572012-11-01 17:36:32 -0700478 }
479
Adam Cohenc276e822012-11-08 13:01:08 -0800480 // TODO: there's no reason to force the AppWidgetHostView to catch duplicate size calls.
481 // We can do that even more cheaply here. It's not an issue right now since we're in the
482 // system process and hence no binder calls.
Adam Cohen4ddcd572012-11-01 17:36:32 -0700483 AppWidgetHostView awhv = (AppWidgetHostView) content;
484 float density = getResources().getDisplayMetrics().density;
485
486 int width = (int) (content.getMeasuredWidth() / density);
487 int height = (int) (content.getMeasuredHeight() / density);
488 awhv.updateAppWidgetSize(null, width, height, width, height, true);
489 }
490
Jim Millerf2dfc352012-08-29 18:42:21 -0700491 void setOverScrollAmount(float r, boolean left) {
Adam Cohen66b9fb1662012-09-05 16:23:58 -0700492 if (Float.compare(mOverScrollAmount, r) != 0) {
493 mOverScrollAmount = r;
Adam Cohen61cd69c2012-10-02 21:42:54 -0700494 mForegroundGradient = left ? mLeftToRightGradient : mRightToLeftGradient;
Adam Cohen5d47a8d2012-11-03 19:10:56 -0700495 mForegroundAlpha = (int) Math.round((0.5f * r * 255));
496
497 // We bump up the alpha of the outline to hide the fact that the overlay is drawing
498 // over the rounded part of the frame.
Adam Cohen934d0832012-11-03 20:02:33 -0700499 float bgAlpha = Math.min(OUTLINE_ALPHA_MULTIPLIER + r * (1 - OUTLINE_ALPHA_MULTIPLIER),
500 1f);
501 setBackgroundAlpha(bgAlpha);
Adam Cohen66b9fb1662012-09-05 16:23:58 -0700502 invalidate();
503 }
Jim Millerf2dfc352012-08-29 18:42:21 -0700504 }
John Spurlock86b63572012-10-24 11:24:25 -0400505
506 public void onActive(boolean isActive) {
507 // hook for subclasses
508 }
John Spurlock4b976ea2012-10-28 12:34:11 -0400509
John Spurlockbb5c9412012-10-31 09:46:15 -0400510 public boolean onUserInteraction(MotionEvent event) {
John Spurlock4b976ea2012-10-28 12:34:11 -0400511 // hook for subclasses
512 return false;
513 }
John Spurlock37d84ae2012-11-04 11:11:47 -0500514
John Spurlock0552c5d2012-11-15 08:04:45 -0500515 public void onBouncerShowing(boolean showing) {
516 // hook for subclasses
517 }
518
John Spurlock37d84ae2012-11-04 11:11:47 -0500519 public void setWorkerHandler(Handler workerHandler) {
520 mWorkerHandler = workerHandler;
521 }
522
523 public Handler getWorkerHandler() {
524 return mWorkerHandler;
525 }
John Spurlock0552c5d2012-11-15 08:04:45 -0500526
Jim Millerf2dfc352012-08-29 18:42:21 -0700527}