From 4cad7538c9615303d291f5b52e960aaf0985828f Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 18 Mar 2015 15:56:30 -0700 Subject: Cleaning up widget preview loader > Removing unnecessary canvas cache > Removing unnecessary new bitmap creation Change-Id: Ic9f45c5a204ea4d32dbf93c21a6a7fd6baea4b51 --- .../android/launcher3/AppsCustomizePagedView.java | 17 +- .../android/launcher3/LauncherBackupHelper.java | 6 +- src/com/android/launcher3/PagedViewCellLayout.java | 16 -- src/com/android/launcher3/WidgetPreviewLoader.java | 320 ++++++--------------- 4 files changed, 101 insertions(+), 258 deletions(-) (limited to 'src') diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java index bf368125f..3f2aa7036 100644 --- a/src/com/android/launcher3/AppsCustomizePagedView.java +++ b/src/com/android/launcher3/AppsCustomizePagedView.java @@ -38,7 +38,6 @@ import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.widget.GridLayout; import android.widget.ImageView; import android.widget.Toast; @@ -48,9 +47,7 @@ import com.android.launcher3.FocusHelper.PagedViewKeyListener; import com.android.launcher3.compat.AppWidgetManagerCompat; import java.util.ArrayList; -import java.util.Collections; import java.util.Iterator; -import java.util.List; /** * A simple callback interface which also provides the results of the task. @@ -171,7 +168,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // Dimens private int mContentWidth, mContentHeight; private int mWidgetCountX, mWidgetCountY; - private PagedViewCellLayout mWidgetSpacingLayout; private int mNumWidgetPages; // Previews & outlines @@ -219,7 +215,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen mWidgetCountX = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountX, 2); mWidgetCountY = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountY, 2); a.recycle(); - mWidgetSpacingLayout = new PagedViewCellLayout(getContext()); // The padding on the non-matched dimension for the default widget preview icons // (top + bottom) @@ -316,9 +311,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // Force a measure to update recalculate the gaps mContentWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight(); mContentHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); - int widthSpec = MeasureSpec.makeMeasureSpec(mContentWidth, MeasureSpec.AT_MOST); - int heightSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.AT_MOST); - mWidgetSpacingLayout.measure(widthSpec, heightSpec); final boolean hostIsTransitioning = getTabHost().isInTransition(); int page = getPageForComponent(mSaveInstanceStateItemIndex); @@ -596,13 +588,11 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen FastBitmapDrawable previewDrawable = (FastBitmapDrawable) image.getDrawable(); float minScale = 1.25f; - int maxWidth, maxHeight; - maxWidth = Math.min((int) (previewDrawable.getIntrinsicWidth() * minScale), size[0]); - maxHeight = Math.min((int) (previewDrawable.getIntrinsicHeight() * minScale), size[1]); + int maxWidth = Math.min((int) (previewDrawable.getIntrinsicWidth() * minScale), size[0]); int[] previewSizeBeforeScale = new int[1]; preview = getWidgetPreviewLoader().generateWidgetPreview(createWidgetInfo.info, - spanX, spanY, maxWidth, maxHeight, null, previewSizeBeforeScale); + maxWidth, null, previewSizeBeforeScale); // Compare the size of the drag preview to the preview in the AppsCustomize tray int previewWidthInAppsCustomize = Math.min(previewSizeBeforeScale[0], @@ -1075,8 +1065,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen maxPreviewHeight = maxSize[1]; } - getWidgetPreviewLoader().setPreviewSize( - maxPreviewWidth, maxPreviewHeight, mWidgetSpacingLayout); + getWidgetPreviewLoader().setPreviewSize(maxPreviewWidth, maxPreviewHeight); if (immediate) { AsyncTaskPageData data = new AsyncTaskPageData(page, items, maxPreviewWidth, maxPreviewHeight, null, null, getWidgetPreviewLoader()); diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java index 97ff32790..7849e5335 100644 --- a/src/com/android/launcher3/LauncherBackupHelper.java +++ b/src/com/android/launcher3/LauncherBackupHelper.java @@ -631,7 +631,6 @@ public class LauncherBackupHelper implements BackupHelper { } final ContentResolver cr = mContext.getContentResolver(); final WidgetPreviewLoader previewLoader = new WidgetPreviewLoader(mContext); - final PagedViewCellLayout widgetSpacingLayout = new PagedViewCellLayout(mContext); final int dpi = mContext.getResources().getDisplayMetrics().densityDpi; final DeviceProfile profile = appState.getDynamicGrid().getDeviceProfile(); if (DEBUG) Log.d(TAG, "cellWidthPx: " + profile.cellWidthPx); @@ -666,8 +665,9 @@ public class LauncherBackupHelper implements BackupHelper { if (DEBUG) Log.d(TAG, "I can count this high: " + backupWidgetCount); if (backupWidgetCount < MAX_WIDGETS_PER_PASS) { if (DEBUG) Log.d(TAG, "saving widget " + backupKey); - previewLoader.setPreviewSize(spanX * profile.cellWidthPx, - spanY * profile.cellHeightPx, widgetSpacingLayout); + previewLoader.setPreviewSize( + spanX * profile.cellWidthPx, + spanY * profile.cellHeightPx); writeRowToBackup(key, packWidget(dpi, previewLoader, mIconCache, provider), data); mKeys.add(key); backupWidgetCount ++; diff --git a/src/com/android/launcher3/PagedViewCellLayout.java b/src/com/android/launcher3/PagedViewCellLayout.java index 2d9e10b9d..e3ad9dad1 100644 --- a/src/com/android/launcher3/PagedViewCellLayout.java +++ b/src/com/android/launcher3/PagedViewCellLayout.java @@ -348,22 +348,6 @@ public class PagedViewCellLayout extends ViewGroup implements Page { requestLayout(); } - /** - * Estimates the width that the number of hSpan cells will take up. - */ - public int estimateCellWidth(int hSpan) { - // TODO: we need to take widthGap into effect - return hSpan * mCellWidth; - } - - /** - * Estimates the height that the number of vSpan cells will take up. - */ - public int estimateCellHeight(int vSpan) { - // TODO: we need to take heightGap into effect - return vSpan * mCellHeight; - } - @Override public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { return new PagedViewCellLayout.LayoutParams(getContext(), attrs); diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java index 312814039..3d57acca4 100644 --- a/src/com/android/launcher3/WidgetPreviewLoader.java +++ b/src/com/android/launcher3/WidgetPreviewLoader.java @@ -16,19 +16,19 @@ import android.database.sqlite.SQLiteReadOnlyDatabaseException; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; -import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.Rect; -import android.graphics.Shader; +import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Build; import android.util.Log; + import com.android.launcher3.compat.AppWidgetManagerCompat; import java.io.ByteArrayOutputStream; @@ -46,107 +46,27 @@ import java.util.concurrent.ExecutionException; public class WidgetPreviewLoader { - private static abstract class SoftReferenceThreadLocal { - private ThreadLocal> mThreadLocal; - public SoftReferenceThreadLocal() { - mThreadLocal = new ThreadLocal>(); - } - - abstract T initialValue(); - - public void set(T t) { - mThreadLocal.set(new SoftReference(t)); - } - - public T get() { - SoftReference reference = mThreadLocal.get(); - T obj; - if (reference == null) { - obj = initialValue(); - mThreadLocal.set(new SoftReference(obj)); - return obj; - } else { - obj = reference.get(); - if (obj == null) { - obj = initialValue(); - mThreadLocal.set(new SoftReference(obj)); - } - return obj; - } - } - } - - private static class CanvasCache extends SoftReferenceThreadLocal { - @Override - protected Canvas initialValue() { - return new Canvas(); - } - } - - private static class PaintCache extends SoftReferenceThreadLocal { - @Override - protected Paint initialValue() { - return null; - } - } - - private static class BitmapCache extends SoftReferenceThreadLocal { - @Override - protected Bitmap initialValue() { - return null; - } - } - - private static class RectCache extends SoftReferenceThreadLocal { - @Override - protected Rect initialValue() { - return new Rect(); - } - } - - private static class BitmapFactoryOptionsCache extends - SoftReferenceThreadLocal { - @Override - protected BitmapFactory.Options initialValue() { - return new BitmapFactory.Options(); - } - } - private static final String TAG = "WidgetPreviewLoader"; private static final String ANDROID_INCREMENTAL_VERSION_NAME_KEY = "android.incremental.version"; private static final float WIDGET_PREVIEW_ICON_PADDING_PERCENTAGE = 0.25f; private static final HashSet sInvalidPackages = new HashSet(); - // Used for drawing shortcut previews - private final BitmapCache mCachedShortcutPreviewBitmap = new BitmapCache(); - private final PaintCache mCachedShortcutPreviewPaint = new PaintCache(); - private final CanvasCache mCachedShortcutPreviewCanvas = new CanvasCache(); - - // Used for drawing widget previews - private final CanvasCache mCachedAppWidgetPreviewCanvas = new CanvasCache(); - private final RectCache mCachedAppWidgetPreviewSrcRect = new RectCache(); - private final RectCache mCachedAppWidgetPreviewDestRect = new RectCache(); - private final PaintCache mCachedAppWidgetPreviewPaint = new PaintCache(); - private final PaintCache mDefaultAppWidgetPreviewPaint = new PaintCache(); - private final BitmapFactoryOptionsCache mCachedBitmapFactoryOptions = new BitmapFactoryOptionsCache(); - private final HashMap> mLoadedPreviews = new HashMap<>(); private final ArrayList> mUnusedBitmaps = new ArrayList<>(); - private final Context mContext; private final int mAppIconSize; + private final int mCellWidth; + + private final Context mContext; private final IconCache mIconCache; private final AppWidgetManagerCompat mManager; private int mPreviewBitmapWidth; private int mPreviewBitmapHeight; private String mSize; - private PagedViewCellLayout mWidgetSpacingLayout; private String mCachedSelectQuery; - - private CacheDb mDb; private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor(); @@ -157,9 +77,10 @@ public class WidgetPreviewLoader { mContext = context; mAppIconSize = grid.iconSizePx; + mCellWidth = grid.cellWidthPx; + mIconCache = app.getIconCache(); mManager = AppWidgetManagerCompat.getInstance(context); - mDb = app.getWidgetPreviewCacheDb(); SharedPreferences sp = context.getSharedPreferences( @@ -193,12 +114,10 @@ public class WidgetPreviewLoader { mDb = app.getWidgetPreviewCacheDb(); } - public void setPreviewSize(int previewWidth, int previewHeight, - PagedViewCellLayout widgetSpacingLayout) { + public void setPreviewSize(int previewWidth, int previewHeight) { mPreviewBitmapWidth = previewWidth; mPreviewBitmapHeight = previewHeight; mSize = previewWidth + "x" + previewHeight; - mWidgetSpacingLayout = widgetSpacingLayout; } public Bitmap getPreview(final Object o) { @@ -233,12 +152,6 @@ public class WidgetPreviewLoader { unusedBitmap = candidate; } } - if (unusedBitmap != null) { - final Canvas c = mCachedAppWidgetPreviewCanvas.get(); - c.setBitmap(unusedBitmap); - c.drawColor(0, PorterDuff.Mode.CLEAR); - c.setBitmap(null); - } } if (unusedBitmap == null) { @@ -468,7 +381,7 @@ public class WidgetPreviewLoader { result.moveToFirst(); byte[] blob = result.getBlob(0); result.close(); - final BitmapFactory.Options opts = mCachedBitmapFactoryOptions.get(); + final BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inBitmap = b; opts.inSampleSize = 1; try { @@ -499,26 +412,17 @@ public class WidgetPreviewLoader { public Bitmap generateWidgetPreview(LauncherAppWidgetProviderInfo info, Bitmap preview) { int maxWidth = maxWidthForWidgetPreview(info.spanX); - int maxHeight = maxHeightForWidgetPreview(info.spanY); - return generateWidgetPreview(info, info.spanX, info.spanY, maxWidth, - maxHeight, preview, null); + return generateWidgetPreview(info, maxWidth, preview, null); } public int maxWidthForWidgetPreview(int spanX) { - return Math.min(mPreviewBitmapWidth, - mWidgetSpacingLayout.estimateCellWidth(spanX)); - } - - public int maxHeightForWidgetPreview(int spanY) { - return Math.min(mPreviewBitmapHeight, - mWidgetSpacingLayout.estimateCellHeight(spanY)); + return Math.min(mPreviewBitmapWidth, spanX * mCellWidth); } - public Bitmap generateWidgetPreview(LauncherAppWidgetProviderInfo info, int cellHSpan, int cellVSpan, - int maxPreviewWidth, int maxPreviewHeight, Bitmap preview, int[] preScaledWidthOut) { + public Bitmap generateWidgetPreview(LauncherAppWidgetProviderInfo info, + int maxPreviewWidth, Bitmap preview, int[] preScaledWidthOut) { // Load the preview image if possible if (maxPreviewWidth < 0) maxPreviewWidth = Integer.MAX_VALUE; - if (maxPreviewHeight < 0) maxPreviewHeight = Integer.MAX_VALUE; Drawable drawable = null; if (info.previewImage != 0) { @@ -531,61 +435,23 @@ public class WidgetPreviewLoader { } } + final boolean widgetPreviewExists = (drawable != null); + final int spanX = info.spanX < 1 ? 1 : info.spanX; + final int spanY = info.spanY < 1 ? 1 : info.spanY; + int previewWidth; int previewHeight; - Bitmap defaultPreview = null; - boolean widgetPreviewExists = (drawable != null); + Bitmap tileBitmap = null; + if (widgetPreviewExists) { previewWidth = drawable.getIntrinsicWidth(); previewHeight = drawable.getIntrinsicHeight(); } else { // Generate a preview image if we couldn't load one - 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 - .getIntrinsicWidth(); - final int previewDrawableHeight = previewDrawable - .getIntrinsicHeight(); - previewWidth = previewDrawableWidth * cellHSpan; - previewHeight = previewDrawableHeight * cellVSpan; - - defaultPreview = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888); - final Canvas c = mCachedAppWidgetPreviewCanvas.get(); - c.setBitmap(defaultPreview); - Paint p = mDefaultAppWidgetPreviewPaint.get(); - if (p == null) { - p = new Paint(); - p.setShader(new BitmapShader(previewDrawable.getBitmap(), - Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)); - mDefaultAppWidgetPreviewPaint.set(p); - } - final Rect dest = mCachedAppWidgetPreviewDestRect.get(); - dest.set(0, 0, previewWidth, previewHeight); - c.drawRect(dest, p); - c.setBitmap(null); - - // Draw the icon in the top left corner - int minOffset = (int) (mAppIconSize * WIDGET_PREVIEW_ICON_PADDING_PERCENTAGE); - int smallestSide = Math.min(previewWidth, previewHeight); - float iconScale = Math.min((float) smallestSide - / (mAppIconSize + 2 * minOffset), 1f); - - try { - Drawable icon = mManager.loadIcon(info, mIconCache); - if (icon != null) { - int hoffset = (int) ((previewDrawableWidth - mAppIconSize * iconScale) / 2); - int yoffset = (int) ((previewDrawableHeight - mAppIconSize * iconScale) / 2); - icon = mutateOnMainThread(icon); - renderDrawableToBitmap(icon, defaultPreview, hoffset, - yoffset, (int) (mAppIconSize * iconScale), - (int) (mAppIconSize * iconScale)); - } - } catch (Resources.NotFoundException e) { - } + tileBitmap = ((BitmapDrawable) mContext.getResources().getDrawable( + R.drawable.widget_tile)).getBitmap(); + previewWidth = tileBitmap.getWidth() * spanX; + previewHeight = tileBitmap.getHeight() * spanY; } // Scale to fit width only - let the widget preview be clipped in the @@ -603,30 +469,58 @@ public class WidgetPreviewLoader { } // If a bitmap is passed in, we use it; otherwise, we create a bitmap of the right size + final Canvas c = new Canvas(); if (preview == null) { preview = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888); + c.setBitmap(preview); + } else { + // Reusing bitmap. Clear it. + c.setBitmap(preview); + c.drawColor(0, PorterDuff.Mode.CLEAR); } // Draw the scaled preview into the final bitmap int x = (preview.getWidth() - previewWidth) / 2; if (widgetPreviewExists) { - renderDrawableToBitmap(drawable, preview, x, 0, previewWidth, - previewHeight); + drawable.setBounds(x, 0, x + previewWidth, previewHeight); + drawable.draw(c); } else { - final Canvas c = mCachedAppWidgetPreviewCanvas.get(); - final Rect src = mCachedAppWidgetPreviewSrcRect.get(); - final Rect dest = mCachedAppWidgetPreviewDestRect.get(); - c.setBitmap(preview); - src.set(0, 0, defaultPreview.getWidth(), defaultPreview.getHeight()); - dest.set(x, 0, x + previewWidth, previewHeight); - - Paint p = mCachedAppWidgetPreviewPaint.get(); - if (p == null) { - p = new Paint(); - p.setFilterBitmap(true); - mCachedAppWidgetPreviewPaint.set(p); + final Paint p = new Paint(); + p.setFilterBitmap(true); + + // draw the spanX x spanY tiles + final Rect src = new Rect(0, 0, tileBitmap.getWidth(), tileBitmap.getHeight()); + + float tileW = scale * tileBitmap.getWidth(); + float tileH = scale * tileBitmap.getHeight(); + final RectF dst = new RectF(0, 0, tileW, tileH); + + float tx = x; + for (int i = 0; i < spanX; i++, tx += tileW) { + float ty = 0; + for (int j = 0; j < spanY; j++, ty += tileH) { + dst.offsetTo(tx, ty); + c.drawBitmap(tileBitmap, src, dst, p); + } } - c.drawBitmap(defaultPreview, src, dest, p); + + // Draw the icon in the top left corner + // TODO: use top right for RTL + int minOffset = (int) (mAppIconSize * WIDGET_PREVIEW_ICON_PADDING_PERCENTAGE); + int smallestSide = Math.min(previewWidth, previewHeight); + float iconScale = Math.min((float) smallestSide / (mAppIconSize + 2 * minOffset), scale); + + try { + Drawable icon = mutateOnMainThread(mManager.loadIcon(info, mIconCache)); + if (icon != null) { + int hoffset = (int) ((tileW - mAppIconSize * iconScale) / 2) + x; + int yoffset = (int) ((tileH - mAppIconSize * iconScale) / 2); + icon.setBounds(hoffset, yoffset, + hoffset + (int) (mAppIconSize * iconScale), + yoffset + (int) (mAppIconSize * iconScale)); + icon.draw(c); + } + } catch (Resources.NotFoundException e) { } c.setBitmap(null); } return mManager.getBadgeBitmap(info, preview); @@ -634,71 +528,47 @@ public class WidgetPreviewLoader { private Bitmap generateShortcutPreview( ResolveInfo info, int maxWidth, int maxHeight, Bitmap preview) { - Bitmap tempBitmap = mCachedShortcutPreviewBitmap.get(); - final Canvas c = mCachedShortcutPreviewCanvas.get(); - if (tempBitmap == null || - tempBitmap.getWidth() != maxWidth || - tempBitmap.getHeight() != maxHeight) { - tempBitmap = Bitmap.createBitmap(maxWidth, maxHeight, Config.ARGB_8888); - mCachedShortcutPreviewBitmap.set(tempBitmap); + final Canvas c = new Canvas(); + if (preview == null) { + preview = Bitmap.createBitmap(maxWidth, maxHeight, Config.ARGB_8888); + c.setBitmap(preview); + } else if (preview.getWidth() != maxWidth || preview.getHeight() != maxHeight) { + throw new RuntimeException("Improperly sized bitmap passed as argument"); } else { - c.setBitmap(tempBitmap); + // Reusing bitmap. Clear it. + c.setBitmap(preview); c.drawColor(0, PorterDuff.Mode.CLEAR); - c.setBitmap(null); } - // Render the icon - Drawable icon = mutateOnMainThread(mIconCache.getFullResIcon(info.activityInfo)); - int paddingTop = mContext. - getResources().getDimensionPixelOffset(R.dimen.shortcut_preview_padding_top); - int paddingLeft = mContext. - getResources().getDimensionPixelOffset(R.dimen.shortcut_preview_padding_left); - int paddingRight = mContext. - getResources().getDimensionPixelOffset(R.dimen.shortcut_preview_padding_right); + Drawable icon = mutateOnMainThread(mIconCache.getFullResIcon(info.activityInfo)); + icon.setFilterBitmap(true); + // Draw a desaturated/scaled version of the icon in the background as a watermark + ColorMatrix colorMatrix = new ColorMatrix(); + colorMatrix.setSaturation(0); + icon.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); + icon.setAlpha((int) (255 * 0.06f)); + + Resources res = mContext.getResources(); + int paddingTop = res.getDimensionPixelOffset(R.dimen.shortcut_preview_padding_top); + int paddingLeft = res.getDimensionPixelOffset(R.dimen.shortcut_preview_padding_left); + int paddingRight = res.getDimensionPixelOffset(R.dimen.shortcut_preview_padding_right); int scaledIconWidth = (maxWidth - paddingLeft - paddingRight); + icon.setBounds(paddingLeft, paddingTop, + paddingLeft + scaledIconWidth, paddingTop + scaledIconWidth); + icon.draw(c); - renderDrawableToBitmap( - icon, tempBitmap, paddingLeft, paddingTop, scaledIconWidth, scaledIconWidth); + // Draw the final icon at top left corner. + // TODO: use top right for RTL + icon.setAlpha(255); + icon.setColorFilter(null); + icon.setBounds(0, 0, mAppIconSize, mAppIconSize); + icon.draw(c); - if (preview != null && - (preview.getWidth() != maxWidth || preview.getHeight() != maxHeight)) { - throw new RuntimeException("Improperly sized bitmap passed as argument"); - } else if (preview == null) { - preview = Bitmap.createBitmap(maxWidth, maxHeight, Config.ARGB_8888); - } - - c.setBitmap(preview); - // Draw a desaturated/scaled version of the icon in the background as a watermark - Paint p = mCachedShortcutPreviewPaint.get(); - if (p == null) { - p = new Paint(); - ColorMatrix colorMatrix = new ColorMatrix(); - colorMatrix.setSaturation(0); - p.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); - p.setAlpha((int) (255 * 0.06f)); - mCachedShortcutPreviewPaint.set(p); - } - c.drawBitmap(tempBitmap, 0, 0, p); c.setBitmap(null); - - renderDrawableToBitmap(icon, preview, 0, 0, mAppIconSize, mAppIconSize); - return preview; } - private static void renderDrawableToBitmap( - Drawable d, Bitmap bitmap, int x, int y, int w, int h) { - if (bitmap != null) { - Canvas c = new Canvas(bitmap); - Rect oldBounds = d.copyBounds(); - d.setBounds(x, y, x + w, y + h); - d.draw(c); - d.setBounds(oldBounds); // Restore the bounds - c.setBitmap(null); - } - } - private Drawable mutateOnMainThread(final Drawable drawable) { try { return mMainThreadExecutor.submit(new Callable() { -- cgit v1.2.3