Skip to content

Commit 37d84ae

Browse files
author
John Spurlock
committed
Render camera widget on a background thread.
Bug:7470978 Change-Id: Ieace005ac42d39ac4c146673910e6681f38e8f56
1 parent f70239a commit 37d84ae

File tree

3 files changed

+63
-28
lines changed

3 files changed

+63
-28
lines changed

policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -152,37 +152,62 @@ private static View inflateGenericWidgetView(Context context) {
152152
}
153153

154154
public void render() {
155+
final Throwable[] thrown = new Throwable[1];
156+
final Bitmap[] offscreen = new Bitmap[1];
155157
try {
156-
int width = getRootView().getWidth();
157-
int height = getRootView().getHeight();
158+
final int width = getRootView().getWidth();
159+
final int height = getRootView().getHeight();
158160
if (mRenderedSize.x == width && mRenderedSize.y == height) {
159-
if (DEBUG) Log.d(TAG, String.format("already rendered at size=%sx%s",
161+
if (DEBUG) Log.d(TAG, String.format("Already rendered at size=%sx%s",
160162
width, height));
161163
return;
162164
}
163165
if (width == 0 || height == 0) {
164166
return;
165167
}
166-
if (DEBUG) Log.d(TAG, String.format("render size=%sx%s instance=%s at %s",
167-
width, height,
168-
Integer.toHexString(hashCode()),
169-
SystemClock.uptimeMillis()));
170-
171-
Bitmap offscreen = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
172-
Canvas c = new Canvas(offscreen);
168+
final long start = SystemClock.uptimeMillis();
169+
offscreen[0] = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
170+
final Canvas c = new Canvas(offscreen[0]);
173171
mWidgetView.measure(
174172
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
175173
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
176174
mWidgetView.layout(0, 0, width, height);
177175
mWidgetView.draw(c);
178-
((ImageView)getChildAt(0)).setImageBitmap(offscreen);
176+
177+
final long end = SystemClock.uptimeMillis();
178+
if (DEBUG) Log.d(TAG, String.format(
179+
"Rendered camera widget in %sms size=%sx%s instance=%s at %s",
180+
end - start,
181+
width, height,
182+
Integer.toHexString(hashCode()),
183+
end));
179184
mRenderedSize.set(width, height);
180185
} catch (Throwable t) {
181-
Log.w(TAG, "Error rendering camera widget", t);
182-
removeAllViews();
183-
View genericView = inflateGenericWidgetView(mContext);
184-
addView(genericView);
186+
thrown[0] = t;
185187
}
188+
189+
mHandler.post(new Runnable() {
190+
@Override
191+
public void run() {
192+
if (thrown[0] == null) {
193+
try {
194+
((ImageView) getChildAt(0)).setImageBitmap(offscreen[0]);
195+
} catch (Throwable t) {
196+
thrown[0] = t;
197+
}
198+
}
199+
if (thrown[0] == null)
200+
return;
201+
202+
Log.w(TAG, "Error rendering camera widget", thrown[0]);
203+
try {
204+
removeAllViews();
205+
final View genericView = inflateGenericWidgetView(mContext);
206+
addView(genericView);
207+
} catch (Throwable t) {
208+
Log.w(TAG, "Error inflating generic camera widget", t);
209+
}
210+
}});
186211
}
187212

188213
private void transitionToCamera() {
@@ -332,7 +357,8 @@ private void reset() {
332357
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
333358
if (DEBUG) Log.d(TAG, String.format("onSizeChanged new=%sx%s old=%sx%s at %s",
334359
w, h, oldw, oldh, SystemClock.uptimeMillis()));
335-
mHandler.post(mRenderRunnable);
360+
final Handler worker = getWorkerHandler();
361+
(worker != null ? worker : mHandler).post(mRenderRunnable);
336362
super.onSizeChanged(w, h, oldw, oldh);
337363
}
338364

policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import android.graphics.Rect;
3232
import android.graphics.Shader;
3333
import android.graphics.drawable.Drawable;
34+
import android.os.Handler;
3435
import android.util.AttributeSet;
3536
import android.view.MotionEvent;
3637
import android.view.View;
@@ -61,6 +62,7 @@ public class KeyguardWidgetFrame extends FrameLayout {
6162
private CheckLongPressHelper mLongPressHelper;
6263
private Animator mFrameFade;
6364
private boolean mIsSmall = false;
65+
private Handler mWorkerHandler;
6466

6567
private float mBackgroundAlpha;
6668
private float mContentAlpha;
@@ -465,4 +467,12 @@ public boolean onUserInteraction(MotionEvent event) {
465467
// hook for subclasses
466468
return false;
467469
}
470+
471+
public void setWorkerHandler(Handler workerHandler) {
472+
mWorkerHandler = workerHandler;
473+
}
474+
475+
public Handler getWorkerHandler() {
476+
return mWorkerHandler;
477+
}
468478
}

policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
7272

7373
private KeyguardWidgetFrame mWidgetToResetAfterFadeOut;
7474

75-
// Background threads to deal with persistence
76-
private HandlerThread mBgPersistenceWorkerThread;
77-
private Handler mBgPersistenceWorkerHandler;
75+
// Background worker thread: used here for persistence, also made available to widget frames
76+
private final HandlerThread mBackgroundWorkerThread;
77+
private final Handler mBackgroundWorkerHandler;
7878

7979
public KeyguardWidgetPager(Context context, AttributeSet attrs) {
8080
this(context, attrs, 0);
@@ -94,19 +94,17 @@ public KeyguardWidgetPager(Context context, AttributeSet attrs, int defStyle) {
9494

9595
Resources r = getResources();
9696
mCameraWidgetEnabled = r.getBoolean(R.bool.kg_enable_camera_default_widget);
97-
mBgPersistenceWorkerThread = new HandlerThread("KeyguardWidgetPager Persistence");
98-
mBgPersistenceWorkerThread.start();
99-
mBgPersistenceWorkerHandler = new Handler(mBgPersistenceWorkerThread.getLooper());
97+
mBackgroundWorkerThread = new HandlerThread("KeyguardWidgetPager Worker");
98+
mBackgroundWorkerThread.start();
99+
mBackgroundWorkerHandler = new Handler(mBackgroundWorkerThread.getLooper());
100100
}
101101

102102
@Override
103103
protected void onDetachedFromWindow() {
104104
super.onDetachedFromWindow();
105105

106-
// Clean up the persistence worker thread
107-
if (mBgPersistenceWorkerThread != null) {
108-
mBgPersistenceWorkerThread.quit();
109-
}
106+
// Clean up the worker thread
107+
mBackgroundWorkerThread.quit();
110108
}
111109

112110
public void setViewStateManager(KeyguardViewStateManager viewStateManager) {
@@ -230,7 +228,7 @@ public void addWidget(View widget) {
230228

231229
public void onRemoveView(View v) {
232230
final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
233-
mBgPersistenceWorkerHandler.post(new Runnable() {
231+
mBackgroundWorkerHandler.post(new Runnable() {
234232
@Override
235233
public void run() {
236234
mLockPatternUtils.removeAppWidget(appWidgetId);
@@ -245,7 +243,7 @@ public void onAddView(View v, final int index) {
245243
boundByReorderablePages(true, pagesRange);
246244
// Subtract from the index to take into account pages before the reorderable
247245
// pages (e.g. the "add widget" page)
248-
mBgPersistenceWorkerHandler.post(new Runnable() {
246+
mBackgroundWorkerHandler.post(new Runnable() {
249247
@Override
250248
public void run() {
251249
mLockPatternUtils.addAppWidget(appWidgetId, index - pagesRange[0]);
@@ -288,6 +286,7 @@ public void addWidget(View widget, int pageIndex) {
288286
ViewGroup.LayoutParams pageLp = new ViewGroup.LayoutParams(
289287
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
290288
frame.setOnLongClickListener(this);
289+
frame.setWorkerHandler(mBackgroundWorkerHandler);
291290

292291
if (pageIndex == -1) {
293292
addView(frame, pageLp);

0 commit comments

Comments
 (0)