diff --git a/res/layout/keyguard_appwidget_item.xml b/res/layout/keyguard_appwidget_item.xml
index 7280098f1b1..ed17bcf4aa2 100755
--- a/res/layout/keyguard_appwidget_item.xml
+++ b/res/layout/keyguard_appwidget_item.xml
@@ -15,21 +15,33 @@
-->
+
-
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:background="@drawable/appwidget_item_bg"
+ android:layout_marginTop="2dip"
+ android:layout_marginBottom="2dip"
+ android:layout_marginLeft="8dip"
+ android:layout_marginRight="8dip"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:paddingTop="16dip"
+ android:paddingBottom="16dip" >
+
+
+
diff --git a/res/layout/keyguard_appwidget_pick_layout.xml b/res/layout/keyguard_appwidget_pick_layout.xml
index feb85a56a45..85667f675d2 100644
--- a/res/layout/keyguard_appwidget_pick_layout.xml
+++ b/res/layout/keyguard_appwidget_pick_layout.xml
@@ -18,6 +18,8 @@
android:id="@+id/layout_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:paddingTop="2dip"
+ android:paddingBottom="2dip"
android:orientation="vertical" >
0dp
+
+ 140dip
+ 80dip
diff --git a/src/com/android/settings/KeyguardAppWidgetPickActivity.java b/src/com/android/settings/KeyguardAppWidgetPickActivity.java
index c82906e7183..b3c612dd7a9 100644
--- a/src/com/android/settings/KeyguardAppWidgetPickActivity.java
+++ b/src/com/android/settings/KeyguardAppWidgetPickActivity.java
@@ -17,26 +17,24 @@
package com.android.settings;
import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.LauncherActivity.IconResizer;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
-import android.graphics.ColorFilter;
import android.graphics.Paint;
-import android.graphics.PaintFlagsDrawFilter;
-import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.PaintDrawable;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
@@ -50,11 +48,13 @@ import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
+import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.internal.widget.LockPatternUtils;
+import java.lang.ref.WeakReference;
import java.util.List;
/**
@@ -77,6 +77,7 @@ public class KeyguardAppWidgetPickActivity extends Activity
private AppWidgetLoader- mAppWidgetLoader;
private List
- mItems;
private GridView mGridView;
+ private AppWidgetAdapter mAppWidgetAdapter;
private AppWidgetManager mAppWidgetManager;
private int mAppWidgetId;
// Might make it possible to make this be false in future
@@ -108,8 +109,8 @@ public class KeyguardAppWidgetPickActivity extends Activity
mAppWidgetManager = AppWidgetManager.getInstance(this);
mAppWidgetLoader = new AppWidgetLoader
- (this, mAppWidgetManager, this);
mItems = mAppWidgetLoader.getItems(getIntent());
- AppWidgetAdapter adapter = new AppWidgetAdapter(this, mItems);
- mGridView.setAdapter(adapter);
+ mAppWidgetAdapter = new AppWidgetAdapter(this, mItems);
+ mGridView.setAdapter(mAppWidgetAdapter);
mGridView.setOnItemClickListener(this);
mLockPatternUtils = new LockPatternUtils(this); // TEMP-- we want to delete this
@@ -127,207 +128,40 @@ public class KeyguardAppWidgetPickActivity extends Activity
setResult(code, result);
}
- private static class EmptyDrawable extends Drawable {
- private final int mWidth;
- private final int mHeight;
-
- EmptyDrawable(int width, int height) {
- mWidth = width;
- mHeight = height;
- }
-
- @Override
- public int getIntrinsicWidth() {
- return mWidth;
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mHeight;
- }
-
- @Override
- public int getMinimumWidth() {
- return mWidth;
- }
-
- @Override
- public int getMinimumHeight() {
- return mHeight;
- }
-
- @Override
- public void draw(Canvas canvas) {
- }
-
- @Override
- public void setAlpha(int alpha) {
- }
-
- @Override
- public void setColorFilter(ColorFilter cf) {
- }
-
- @Override
- public int getOpacity() {
- return PixelFormat.TRANSLUCENT;
- }
- }
-
- /**
- * Utility class to resize icons to match default icon size. Code is mostly
- * borrowed from Launcher.
- */
- private static class IconResizer {
- private final int mIconWidth;
- private final int mIconHeight;
-
- private final DisplayMetrics mMetrics;
- private final Rect mOldBounds = new Rect();
- private final Canvas mCanvas = new Canvas();
-
- public IconResizer(int width, int height, DisplayMetrics metrics) {
- mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
- Paint.FILTER_BITMAP_FLAG));
-
- mMetrics = metrics;
- mIconWidth = width;
- mIconHeight = height;
- }
-
- /**
- * Returns a Drawable representing the thumbnail of the specified Drawable.
- * The size of the thumbnail is defined by the dimension
- * android.R.dimen.launcher_application_icon_size.
- *
- * This method is not thread-safe and should be invoked on the UI thread only.
- *
- * @param icon The icon to get a thumbnail of.
- *
- * @return A thumbnail for the specified icon or the icon itself if the
- * thumbnail could not be created.
- */
- public Drawable createIconThumbnail(Drawable icon) {
- int width = mIconWidth;
- int height = mIconHeight;
-
- if (icon == null) {
- return new EmptyDrawable(width, height);
- }
-
- try {
- if (icon instanceof PaintDrawable) {
- PaintDrawable painter = (PaintDrawable) icon;
- painter.setIntrinsicWidth(width);
- painter.setIntrinsicHeight(height);
- } else if (icon instanceof BitmapDrawable) {
- // Ensure the bitmap has a density.
- BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
- Bitmap bitmap = bitmapDrawable.getBitmap();
- if (bitmap.getDensity() == Bitmap.DENSITY_NONE) {
- bitmapDrawable.setTargetDensity(mMetrics);
- }
- }
- int iconWidth = icon.getIntrinsicWidth();
- int iconHeight = icon.getIntrinsicHeight();
-
- if (iconWidth > 0 && iconHeight > 0) {
- if (width < iconWidth || height < iconHeight) {
- final float ratio = (float) iconWidth / iconHeight;
-
- if (iconWidth > iconHeight) {
- height = (int) (width / ratio);
- } else if (iconHeight > iconWidth) {
- width = (int) (height * ratio);
- }
-
- final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ?
- Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
- final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
- final Canvas canvas = mCanvas;
- canvas.setBitmap(thumb);
- // Copy the old bounds to restore them later
- // If we were to do oldBounds = icon.getBounds(),
- // the call to setBounds() that follows would
- // change the same instance and we would lose the
- // old bounds
- mOldBounds.set(icon.getBounds());
- final int x = (mIconWidth - width) / 2;
- final int y = (mIconHeight - height) / 2;
- icon.setBounds(x, y, x + width, y + height);
- icon.draw(canvas);
- icon.setBounds(mOldBounds);
- //noinspection deprecation
- icon = new BitmapDrawable(thumb);
- ((BitmapDrawable) icon).setTargetDensity(mMetrics);
- canvas.setBitmap(null);
- } else if (iconWidth < width && iconHeight < height) {
- final Bitmap.Config c = Bitmap.Config.ARGB_8888;
- final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
- final Canvas canvas = mCanvas;
- canvas.setBitmap(thumb);
- mOldBounds.set(icon.getBounds());
- final int x = (width - iconWidth) / 2;
- final int y = (height - iconHeight) / 2;
- icon.setBounds(x, y, x + iconWidth, y + iconHeight);
- icon.draw(canvas);
- icon.setBounds(mOldBounds);
- //noinspection deprecation
- icon = new BitmapDrawable(thumb);
- ((BitmapDrawable) icon).setTargetDensity(mMetrics);
- canvas.setBitmap(null);
- }
- }
-
- } catch (Throwable t) {
- icon = new EmptyDrawable(width, height);
- }
-
- return icon;
- }
- }
-
/**
* Item that appears in the AppWidget picker grid.
*/
public static class Item implements AppWidgetLoader.LabelledItem {
protected static IconResizer sResizer;
- protected IconResizer getResizer(Context context) {
- if (sResizer == null) {
- final Resources resources = context.getResources();
- int size = (int) resources.getDimension(android.R.dimen.app_icon_size);
- sResizer = new IconResizer(size, size, resources.getDisplayMetrics());
- }
- return sResizer;
- }
+
CharSequence label;
- Drawable icon;
+ int appWidgetPreviewId;
+ int iconId;
String packageName;
String className;
Bundle extras;
+ private WidgetPreviewLoader mWidgetPreviewLoader;
+ private Context mContext;
/**
* Create a list item from given label and icon.
*/
- Item(Context context, CharSequence label, Drawable icon) {
+ Item(Context context, CharSequence label) {
this.label = label;
- this.icon = getResizer(context).createIconThumbnail(icon);
+ mContext = context;
}
- /**
- * Create a list item and fill it with details from the given
- * {@link ResolveInfo} object.
- */
- Item(Context context, PackageManager pm, ResolveInfo resolveInfo) {
- label = resolveInfo.loadLabel(pm);
- if (label == null && resolveInfo.activityInfo != null) {
- label = resolveInfo.activityInfo.name;
- }
+ void loadWidgetPreview(ImageView v) {
+ mWidgetPreviewLoader = new WidgetPreviewLoader(mContext, v);
+ mWidgetPreviewLoader.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
+ }
- icon = getResizer(context).createIconThumbnail(resolveInfo.loadIcon(pm));
- packageName = resolveInfo.activityInfo.applicationInfo.packageName;
- className = resolveInfo.activityInfo.name;
+ void cancelLoadingWidgetPreview() {
+ if (mWidgetPreviewLoader != null) {
+ mWidgetPreviewLoader.cancel(false);
+ mWidgetPreviewLoader = null;
+ }
}
/**
@@ -354,48 +188,264 @@ public class KeyguardAppWidgetPickActivity extends Activity
public CharSequence getLabel() {
return label;
}
+
+ class WidgetPreviewLoader extends AsyncTask {
+ private Resources mResources;
+ private PackageManager mPackageManager;
+ private int mIconDpi;
+ private ImageView mView;
+ private float mDensityScale;
+ public WidgetPreviewLoader(Context context, ImageView v) {
+ super();
+ mResources = context.getResources();
+ DisplayMetrics metrics = new DisplayMetrics();
+ ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metrics);
+ mDensityScale = metrics.density;
+ mPackageManager = context.getPackageManager();
+ ActivityManager activityManager =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ mIconDpi = activityManager.getLauncherLargeIconDensity();
+ mView = v;
+ }
+ public Void doInBackground(Void... params) {
+ if (!isCancelled()) {
+ int appWidgetPreviewWidth =
+ mResources.getDimensionPixelSize(R.dimen.appwidget_preview_width);
+ int appWidgetPreviewHeight =
+ mResources.getDimensionPixelSize(R.dimen.appwidget_preview_height);
+ // TODO: fix the hspan, vspan of the default preview
+ Bitmap b = getWidgetPreview(new ComponentName(packageName, className),
+ appWidgetPreviewId, iconId,
+ appWidgetPreviewWidth, appWidgetPreviewHeight);
+ publishProgress(b);
+ }
+ return null;
+ }
+ public void onProgressUpdate(Bitmap... values) {
+ if (!isCancelled()) {
+ Bitmap b = values[0];
+ mView.setImageBitmap(b);
+ }
+ }
+ abstract class WeakReferenceThreadLocal {
+ private ThreadLocal> mThreadLocal;
+ public WeakReferenceThreadLocal() {
+ mThreadLocal = new ThreadLocal>();
+ }
+
+ abstract T initialValue();
+
+ public void set(T t) {
+ mThreadLocal.set(new WeakReference(t));
+ }
+
+ public T get() {
+ WeakReference reference = mThreadLocal.get();
+ T obj;
+ if (reference == null) {
+ obj = initialValue();
+ mThreadLocal.set(new WeakReference(obj));
+ return obj;
+ } else {
+ obj = reference.get();
+ if (obj == null) {
+ obj = initialValue();
+ mThreadLocal.set(new WeakReference(obj));
+ }
+ return obj;
+ }
+ }
+ }
+
+ class CanvasCache extends WeakReferenceThreadLocal