summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/WidgetPreviewLoader.java
diff options
context:
space:
mode:
authorAdrian Roos <roosa@google.com>2014-04-15 21:07:49 +0200
committerAdrian Roos <roosa@google.com>2014-04-16 14:16:14 +0200
commit65d60e21ec22e3bf03ba39f7a0be24df2cc914a2 (patch)
treea90b06404e267423b5b4522f9bdf6968d4150d3c /src/com/android/launcher3/WidgetPreviewLoader.java
parentb6ecd7815970fd2080b1856259d25f6a0ab7f48f (diff)
downloadandroid_packages_apps_Trebuchet-65d60e21ec22e3bf03ba39f7a0be24df2cc914a2.tar.gz
android_packages_apps_Trebuchet-65d60e21ec22e3bf03ba39f7a0be24df2cc914a2.tar.bz2
android_packages_apps_Trebuchet-65d60e21ec22e3bf03ba39f7a0be24df2cc914a2.zip
Fix skia crash in widget preview loading
This fix works making sure all drawables are mutated before drawing them in the background. Mutation has to be executed on the main thread because that operation is not thread safe. Bug: 12525890 Change-Id: Id7bdf9cf48d3e7b7f31938bdea4a3bf1632cf337
Diffstat (limited to 'src/com/android/launcher3/WidgetPreviewLoader.java')
-rw-r--r--src/com/android/launcher3/WidgetPreviewLoader.java27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 36152f807..5dad2a860 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -35,6 +35,8 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
abstract class SoftReferenceThreadLocal<T> {
private ThreadLocal<SoftReference<T>> mThreadLocal;
@@ -137,6 +139,8 @@ public class WidgetPreviewLoader {
private final ArrayList<SoftReference<Bitmap>> mUnusedBitmaps;
private final static HashSet<String> sInvalidPackages;
+ private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
+
static {
sInvalidPackages = new HashSet<String>();
}
@@ -492,7 +496,8 @@ public class WidgetPreviewLoader {
Drawable drawable = null;
if (previewImage != 0) {
- drawable = mPackageManager.getDrawable(packageName, previewImage, null);
+ drawable = mutateOnMainThread(
+ mPackageManager.getDrawable(packageName, previewImage, null));
if (drawable == null) {
Log.w(TAG, "Can't load widget preview drawable 0x" +
Integer.toHexString(previewImage) + " for provider: " + provider);
@@ -511,6 +516,7 @@ public class WidgetPreviewLoader {
if (cellHSpan < 1) cellHSpan = 1;
if (cellVSpan < 1) cellVSpan = 1;
+ // This Drawable is not directly drawn, so there's no need to mutate it.
BitmapDrawable previewDrawable = (BitmapDrawable) mContext.getResources()
.getDrawable(R.drawable.widget_tile);
final int previewDrawableWidth = previewDrawable
@@ -548,7 +554,7 @@ public class WidgetPreviewLoader {
int yoffset =
(int) ((previewDrawableHeight - mAppIconSize * iconScale) / 2);
if (iconId > 0)
- icon = mIconCache.getFullResIcon(packageName, iconId);
+ icon = mutateOnMainThread(mIconCache.getFullResIcon(packageName, iconId));
if (icon != null) {
renderDrawableToBitmap(icon, defaultPreview, hoffset,
yoffset, (int) (mAppIconSize * iconScale),
@@ -617,7 +623,7 @@ public class WidgetPreviewLoader {
c.setBitmap(null);
}
// Render the icon
- Drawable icon = mIconCache.getFullResIcon(info);
+ Drawable icon = mutateOnMainThread(mIconCache.getFullResIcon(info));
int paddingTop = mContext.
getResources().getDimensionPixelOffset(R.dimen.shortcut_preview_padding_top);
@@ -677,4 +683,19 @@ public class WidgetPreviewLoader {
}
}
+ private Drawable mutateOnMainThread(final Drawable drawable) {
+ try {
+ return mMainThreadExecutor.submit(new Callable<Drawable>() {
+ @Override
+ public Drawable call() throws Exception {
+ return drawable.mutate();
+ }
+ }).get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ }
}