Merge "Import translations. DO NOT MERGE" into jb-mr1-dev
diff --git a/res/drawable-hdpi/appwidget_item_bg_normal.9.png b/res/drawable-hdpi/appwidget_item_bg_normal.9.png
index baff858..6fd0e6e 100644
--- a/res/drawable-hdpi/appwidget_item_bg_normal.9.png
+++ b/res/drawable-hdpi/appwidget_item_bg_normal.9.png
Binary files differ
diff --git a/res/drawable-hdpi/appwidget_item_bg_pressed.9.png b/res/drawable-hdpi/appwidget_item_bg_pressed.9.png
index 7ec33dd..0da4a1d 100644
--- a/res/drawable-hdpi/appwidget_item_bg_pressed.9.png
+++ b/res/drawable-hdpi/appwidget_item_bg_pressed.9.png
Binary files differ
diff --git a/res/drawable-mdpi/appwidget_item_bg_normal.9.png b/res/drawable-mdpi/appwidget_item_bg_normal.9.png
index 976083f..47009b4 100644
--- a/res/drawable-mdpi/appwidget_item_bg_normal.9.png
+++ b/res/drawable-mdpi/appwidget_item_bg_normal.9.png
Binary files differ
diff --git a/res/drawable-mdpi/appwidget_item_bg_pressed.9.png b/res/drawable-mdpi/appwidget_item_bg_pressed.9.png
index 8f340d3..9a5001b 100644
--- a/res/drawable-mdpi/appwidget_item_bg_pressed.9.png
+++ b/res/drawable-mdpi/appwidget_item_bg_pressed.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/appwidget_item_bg_normal.9.png b/res/drawable-xhdpi/appwidget_item_bg_normal.9.png
index b26f1d2..3cb534a 100644
--- a/res/drawable-xhdpi/appwidget_item_bg_normal.9.png
+++ b/res/drawable-xhdpi/appwidget_item_bg_normal.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/appwidget_item_bg_pressed.9.png b/res/drawable-xhdpi/appwidget_item_bg_pressed.9.png
index 3871689..3160e85 100644
--- a/res/drawable-xhdpi/appwidget_item_bg_pressed.9.png
+++ b/res/drawable-xhdpi/appwidget_item_bg_pressed.9.png
Binary files differ
diff --git a/res/layout/keyguard_appwidget_item.xml b/res/layout/keyguard_appwidget_item.xml
index 7280098..de0c855 100755
--- a/res/layout/keyguard_appwidget_item.xml
+++ b/res/layout/keyguard_appwidget_item.xml
@@ -15,21 +15,33 @@
 -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+  android:layout_width="match_parent"
+  android:layout_height="wrap_content" >
+  <LinearLayout
     android:layout_width="match_parent"
-    android:layout_height="wrap_content" >
-  <TextView
-     android:id="@+id/icon_and_label"
-     android:layout_width="match_parent"
-     android:layout_height="wrap_content"
-     android:layout_marginLeft="8dip"
-     android:layout_marginRight="8dip"
-     android:layout_marginTop="4dip"
-     android:layout_marginBottom="4dip"
-     android:background="@drawable/appwidget_item_bg"
-     android:minHeight="?android:attr/listPreferredItemHeightSmall"
-     android:textAppearance="?android:attr/textAppearanceMedium"
-     android:gravity="center_vertical"
-     android:drawablePadding="8dip"
-     android:paddingStart="11dip"
-     android:paddingEnd="11dip" />
+    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="2dip"
+    android:layout_marginRight="2dip"
+    android:paddingLeft="16dip"
+    android:paddingRight="16dip"
+    android:paddingTop="16dip"
+    android:paddingBottom="16dip" >
+      <ImageView
+       android:id="@+id/icon"
+       android:layout_width="@dimen/appwidget_preview_width"
+       android:layout_height="@dimen/appwidget_preview_height"
+       android:scaleType="center" />
+      <TextView
+       android:id="@+id/label"
+       style="@style/KeyguardAppWidgetItem"
+       android:layout_width="match_parent"
+       android:layout_height="match_parent"
+       android:paddingLeft="24dip"
+       android:paddingBottom="8dip"
+       android:gravity="left|bottom" />
+  </LinearLayout>
 </FrameLayout>
diff --git a/res/layout/keyguard_appwidget_pick_layout.xml b/res/layout/keyguard_appwidget_picker_layout.xml
similarity index 76%
rename from res/layout/keyguard_appwidget_pick_layout.xml
rename to res/layout/keyguard_appwidget_picker_layout.xml
index feb85a5..b678925 100644
--- a/res/layout/keyguard_appwidget_pick_layout.xml
+++ b/res/layout/keyguard_appwidget_picker_layout.xml
@@ -18,10 +18,16 @@
         android:id="@+id/layout_root"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
+        android:layout_marginLeft="@dimen/keyguard_appwidget_picker_margin_left"
+        android:layout_marginRight="@dimen/keyguard_appwidget_picker_margin_right"
+        android:paddingTop="2dip"
+        android:paddingBottom="2dip"
         android:orientation="vertical" >
   <GridView android:layout_width="match_parent"
             android:layout_height="0dp"
             android:layout_weight="1"
+            android:numColumns="@integer/keyguard_appwidget_picker_cols"
+            android:layout_gravity="center_horizontal"
             android:listSelector="@android:color/transparent"
             android:id="@+id/widget_list" />
 </LinearLayout>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 2ced533..498aa4d 100755
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -17,4 +17,9 @@
 <resources>
     <dimen name="appwidget_width">421dip</dimen>
     <dimen name="appwidget_height">68dip</dimen>
+    <dimen name="appwidget_preview_width">120dip</dimen>
+    <dimen name="appwidget_preview_height">70dip</dimen>
+    <dimen name="keyguard_appwidget_picker_margin_left">2dip</dimen>
+    <dimen name="keyguard_appwidget_picker_margin_right">2dip</dimen>
+    <integer name="keyguard_appwidget_picker_cols">2</integer>
 </resources>
diff --git a/res/values-land/styles.xml b/res/values-land/styles.xml
new file mode 100644
index 0000000..0903167
--- /dev/null
+++ b/res/values-land/styles.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <style name="KeyguardAppWidgetItem">
+        <item name="android:textSize">16sp</item>
+    </style>
+</resources>
diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml
index 994d4bb..c0a79ad 100755
--- a/res/values-sw600dp-land/dimens.xml
+++ b/res/values-sw600dp-land/dimens.xml
@@ -18,4 +18,6 @@
     <dimen name="screen_margin_sides">128dip</dimen>
     <dimen name="screen_margin_top">72dip</dimen>
     <dimen name="screen_margin_bottom">48dip</dimen>
+    <dimen name="appwidget_preview_height">80dip</dimen>
+    <dimen name="keyguard_appwidget_picker_width">720dip</dimen>
 </resources>
diff --git a/res/values-sw600dp-land/styles.xml b/res/values-sw600dp-land/styles.xml
new file mode 100644
index 0000000..645d1fe
--- /dev/null
+++ b/res/values-sw600dp-land/styles.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <style name="KeyguardAppWidgetItem">
+        <item name="android:textSize">18sp</item>
+    </style>
+</resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index cf7ac6b..1374efd 100755
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -32,4 +32,10 @@
     <dimen name="setup_item_margin">32dip</dimen>
     <dimen name="appwidget_min_width">325dip</dimen>
     <dimen name="appwidget_min_height">50dip</dimen>
+
+    <dimen name="appwidget_preview_width">120dip</dimen>
+    <dimen name="appwidget_preview_height">70dip</dimen>
+    <dimen name="keyguard_appwidget_picker_margin_left">2dip</dimen>
+    <dimen name="keyguard_appwidget_picker_margin_right">2dip</dimen>
+    <integer name="keyguard_appwidget_picker_cols">2</integer>
 </resources>
diff --git a/res/values-sw600dp/styles.xml b/res/values-sw600dp/styles.xml
index f780f53..9f02164 100644
--- a/res/values-sw600dp/styles.xml
+++ b/res/values-sw600dp/styles.xml
@@ -57,4 +57,8 @@
         <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
         <item name="android:textSize">20sp</item>
     </style>
+
+    <style name="KeyguardAppWidgetItem">
+        <item name="android:textSize">16sp</item>
+    </style>
 </resources>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 5a58609..d6d9184 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -16,4 +16,7 @@
 
 <resources>
     <dimen name="pager_tabs_padding">@*android:dimen/preference_fragment_padding_side</dimen>
+    <dimen name="appwidget_preview_height">80dip</dimen>
+    <integer name="keyguard_appwidget_picker_cols">2</integer>
+    <dimen name="keyguard_appwidget_picker_width">720dip</dimen>
 </resources>
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
new file mode 100644
index 0000000..645d1fe
--- /dev/null
+++ b/res/values-sw720dp/styles.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <style name="KeyguardAppWidgetItem">
+        <item name="android:textSize">18sp</item>
+    </style>
+</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 34b2d86..91f293c 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -54,4 +54,11 @@
 
     <dimen name="pager_tabs_padding">0dp</dimen>
 
+    <!-- Size of AppWidget previews in KeyguardAppWidgetPickActivity -->
+    <dimen name="appwidget_preview_width">140dip</dimen>
+    <dimen name="appwidget_preview_height">80dip</dimen>
+    <dimen name="keyguard_appwidget_picker_max_width">800dip</dimen>
+    <dimen name="keyguard_appwidget_picker_margin_left">6dip</dimen>
+    <dimen name="keyguard_appwidget_picker_margin_right">6dip</dimen>
+    <integer name="keyguard_appwidget_picker_cols">1</integer>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 9b9cb83..dda22d9 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -191,4 +191,8 @@
         <item name="android:textAllCaps">true</item>
         <item name="android:textStyle">bold</item>
     </style>
+
+    <style name="KeyguardAppWidgetItem">
+        <item name="android:textSize">18sp</item>
+    </style>
 </resources>
diff --git a/src/com/android/settings/KeyguardAppWidgetPickActivity.java b/src/com/android/settings/KeyguardAppWidgetPickActivity.java
index 0afc5b2..db5f115 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.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,17 +77,18 @@
     private AppWidgetLoader<Item> mAppWidgetLoader;
     private List<Item> mItems;
     private GridView mGridView;
+    private AppWidgetAdapter mAppWidgetAdapter;
     private AppWidgetManager mAppWidgetManager;
     private int mAppWidgetId;
     // Might make it possible to make this be false in future
     private boolean mAddingToKeyguard = true;
     private Intent mResultData;
     private LockPatternUtils mLockPatternUtils;
-    private boolean mSuccess;
+    private Bundle mExtraConfigureOptions;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
-        setContentView(R.layout.keyguard_appwidget_pick_layout);
+        setContentView(R.layout.keyguard_appwidget_picker_layout);
         super.onCreate(savedInstanceState);
 
         // Set default return data
@@ -101,13 +102,22 @@
         } else {
             finish();
         }
+        mExtraConfigureOptions = intent.getBundleExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);
 
         mGridView = (GridView) findViewById(R.id.widget_list);
+        DisplayMetrics dm = new DisplayMetrics();
+        getWindowManager().getDefaultDisplay().getMetrics(dm);
+        int maxGridWidth = getResources().getDimensionPixelSize(
+                R.dimen.keyguard_appwidget_picker_max_width);
+
+        if (maxGridWidth < dm.widthPixels) {
+            mGridView.getLayoutParams().width = maxGridWidth;
+        }
         mAppWidgetManager = AppWidgetManager.getInstance(this);
         mAppWidgetLoader = new AppWidgetLoader<Item>(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
@@ -125,207 +135,40 @@
         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;
+            }
         }
 
         /**
@@ -352,48 +195,259 @@
         public CharSequence getLabel() {
             return label;
         }
+
+        class WidgetPreviewLoader extends AsyncTask<Void, Bitmap, Void> {
+            private Resources mResources;
+            private PackageManager mPackageManager;
+            private int mIconDpi;
+            private ImageView mView;
+            public WidgetPreviewLoader(Context context, ImageView v) {
+                super();
+                mResources = context.getResources();
+                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<T> {
+                private ThreadLocal<WeakReference<T>> mThreadLocal;
+                public WeakReferenceThreadLocal() {
+                    mThreadLocal = new ThreadLocal<WeakReference<T>>();
+                }
+
+                abstract T initialValue();
+
+                public void set(T t) {
+                    mThreadLocal.set(new WeakReference<T>(t));
+                }
+
+                public T get() {
+                    WeakReference<T> reference = mThreadLocal.get();
+                    T obj;
+                    if (reference == null) {
+                        obj = initialValue();
+                        mThreadLocal.set(new WeakReference<T>(obj));
+                        return obj;
+                    } else {
+                        obj = reference.get();
+                        if (obj == null) {
+                            obj = initialValue();
+                            mThreadLocal.set(new WeakReference<T>(obj));
+                        }
+                        return obj;
+                    }
+                }
+            }
+
+            class CanvasCache extends WeakReferenceThreadLocal<Canvas> {
+                @Override
+                protected Canvas initialValue() {
+                    return new Canvas();
+                }
+            }
+
+            class PaintCache extends WeakReferenceThreadLocal<Paint> {
+                @Override
+                protected Paint initialValue() {
+                    return null;
+                }
+            }
+
+            class BitmapCache extends WeakReferenceThreadLocal<Bitmap> {
+                @Override
+                protected Bitmap initialValue() {
+                    return null;
+                }
+            }
+
+            class RectCache extends WeakReferenceThreadLocal<Rect> {
+                @Override
+                protected Rect initialValue() {
+                    return new Rect();
+                }
+            }
+
+            // Used for drawing widget previews
+            CanvasCache sCachedAppWidgetPreviewCanvas = new CanvasCache();
+            RectCache sCachedAppWidgetPreviewSrcRect = new RectCache();
+            RectCache sCachedAppWidgetPreviewDestRect = new RectCache();
+            PaintCache sCachedAppWidgetPreviewPaint = new PaintCache();
+
+            private Bitmap getWidgetPreview(ComponentName provider, int previewImage,
+                    int iconId, int maxWidth, int maxHeight) {
+                // Load the preview image if possible
+                String packageName = provider.getPackageName();
+                if (maxWidth < 0) maxWidth = Integer.MAX_VALUE;
+                if (maxHeight < 0) maxHeight = Integer.MAX_VALUE;
+
+
+                int appIconSize = mResources.getDimensionPixelSize(R.dimen.app_icon_size);
+
+                Drawable drawable = null;
+                if (previewImage != 0) {
+                    drawable = mPackageManager.getDrawable(packageName, previewImage, null);
+                    if (drawable == null) {
+                        Log.w(TAG, "Can't load widget preview drawable 0x" +
+                                Integer.toHexString(previewImage) + " for provider: " + provider);
+                    }
+                }
+
+                int bitmapWidth;
+                int bitmapHeight;
+                Bitmap defaultPreview = null;
+                boolean widgetPreviewExists = (drawable != null);
+                if (widgetPreviewExists) {
+                    bitmapWidth = drawable.getIntrinsicWidth();
+                    bitmapHeight = drawable.getIntrinsicHeight();
+                } else {
+                    // Generate a preview image if we couldn't load one
+                    bitmapWidth = maxWidth;
+                    bitmapHeight = maxHeight;
+                    defaultPreview = Bitmap.createBitmap(bitmapWidth, bitmapHeight,
+                            Config.ARGB_8888);
+                    final Canvas c = sCachedAppWidgetPreviewCanvas.get();
+                    c.setBitmap(defaultPreview);
+                    c.drawColor(0xFF2D2D2D);
+                    c.setBitmap(null);
+
+                    // Draw the icon in the top left corner
+                    final float marginPercentage = 0.125f;
+                    final float finalIconSize = (bitmapHeight / 2);
+                    float iconScale = finalIconSize / appIconSize;
+
+                    try {
+                        Drawable icon = null;
+                        int hoffset =
+                                (int) (finalIconSize * marginPercentage);
+                        int yoffset =
+                                (int) (finalIconSize * marginPercentage);
+                        if (iconId > 0)
+                            icon = getFullResIcon(packageName, iconId);
+                        if (icon != null) {
+                            renderDrawableToBitmap(icon, defaultPreview, hoffset,
+                                    yoffset, (int) (appIconSize * iconScale),
+                                    (int) (appIconSize * iconScale));
+                        }
+                    } catch (Resources.NotFoundException e) {
+                    }
+                }
+
+                // Scale to fit width only - let the widget preview be clipped in the
+                // vertical dimension
+                float scale = 1f;
+                if (bitmapWidth > maxWidth) {
+                    scale = maxWidth / (float) bitmapWidth;
+                }
+                int finalPreviewWidth = (int) (scale * bitmapWidth);
+                int finalPreviewHeight = (int) (scale * bitmapHeight);
+
+                bitmapWidth = finalPreviewWidth;
+                bitmapHeight = Math.min(finalPreviewHeight, maxHeight);
+
+                Bitmap preview = Bitmap.createBitmap(bitmapWidth, bitmapHeight,
+                        Config.ARGB_8888);
+
+                // Draw the scaled preview into the final bitmap
+                if (widgetPreviewExists) {
+                    renderDrawableToBitmap(drawable, preview, 0, 0, finalPreviewWidth,
+                            finalPreviewHeight);
+                } else {
+                    final Canvas c = sCachedAppWidgetPreviewCanvas.get();
+                    final Rect src = sCachedAppWidgetPreviewSrcRect.get();
+                    final Rect dest = sCachedAppWidgetPreviewDestRect.get();
+                    c.setBitmap(preview);
+                    src.set(0, 0, defaultPreview.getWidth(), defaultPreview.getHeight());
+                    dest.set(0, 0, finalPreviewWidth, finalPreviewHeight);
+
+                    Paint p = sCachedAppWidgetPreviewPaint.get();
+                    if (p == null) {
+                        p = new Paint();
+                        p.setFilterBitmap(true);
+                        sCachedAppWidgetPreviewPaint.set(p);
+                    }
+                    c.drawBitmap(defaultPreview, src, dest, p);
+                    c.setBitmap(null);
+                }
+                return preview;
+            }
+            public Drawable getFullResDefaultActivityIcon() {
+                return getFullResIcon(Resources.getSystem(),
+                        android.R.mipmap.sym_def_app_icon);
+            }
+
+            public Drawable getFullResIcon(Resources resources, int iconId) {
+                Drawable d;
+                try {
+                    d = resources.getDrawableForDensity(iconId, mIconDpi);
+                } catch (Resources.NotFoundException e) {
+                    d = null;
+                }
+
+                return (d != null) ? d : getFullResDefaultActivityIcon();
+            }
+
+            public Drawable getFullResIcon(String packageName, int iconId) {
+                Resources resources;
+                try {
+                    resources = mPackageManager.getResourcesForApplication(packageName);
+                } catch (PackageManager.NameNotFoundException e) {
+                    resources = null;
+                }
+                if (resources != null) {
+                    if (iconId != 0) {
+                        return getFullResIcon(resources, iconId);
+                    }
+                }
+                return getFullResDefaultActivityIcon();
+            }
+
+            private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h) {
+                renderDrawableToBitmap(d, bitmap, x, y, w, h, 1f);
+            }
+
+            private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h,
+                    float scale) {
+                if (bitmap != null) {
+                    Canvas c = new Canvas(bitmap);
+                    c.scale(scale, scale);
+                    Rect oldBounds = d.copyBounds();
+                    d.setBounds(x, y, x + w, y + h);
+                    d.draw(c);
+                    d.setBounds(oldBounds); // Restore the bounds
+                    c.setBitmap(null);
+                }
+            }
+        }
     }
 
     @Override
     public Item createItem(Context context, AppWidgetProviderInfo info, Bundle extras) {
         CharSequence label = info.label;
-        Drawable icon = null;
 
-        if (info.icon != 0) {
-            try {
-                final Resources res = context.getResources();
-                final int density = res.getDisplayMetrics().densityDpi;
-                int iconDensity;
-                switch (density) {
-                    case DisplayMetrics.DENSITY_MEDIUM:
-                        iconDensity = DisplayMetrics.DENSITY_LOW;
-                    case DisplayMetrics.DENSITY_TV:
-                        iconDensity = DisplayMetrics.DENSITY_MEDIUM;
-                    case DisplayMetrics.DENSITY_HIGH:
-                        iconDensity = DisplayMetrics.DENSITY_MEDIUM;
-                    case DisplayMetrics.DENSITY_XHIGH:
-                        iconDensity = DisplayMetrics.DENSITY_HIGH;
-                    case DisplayMetrics.DENSITY_XXHIGH:
-                        iconDensity = DisplayMetrics.DENSITY_XHIGH;
-                    default:
-                        // The density is some abnormal value.  Return some other
-                        // abnormal value that is a reasonable scaling of it.
-                        iconDensity = (int)((density*0.75f)+.5f);
-                }
-                Resources packageResources = getPackageManager().
-                        getResourcesForApplication(info.provider.getPackageName());
-                icon = packageResources.getDrawableForDensity(info.icon, iconDensity);
-            } catch (NameNotFoundException e) {
-                Log.w(TAG, "Can't load icon drawable 0x" + Integer.toHexString(info.icon)
-                        + " for provider: " + info.provider);
-            }
-            if (icon == null) {
-                Log.w(TAG, "Can't load icon drawable 0x" + Integer.toHexString(info.icon)
-                        + " for provider: " + info.provider);
-            }
-        }
-
-        Item item = new Item(context, label, icon);
+        Item item = new Item(context, label);
+        item.appWidgetPreviewId = info.previewImage;
+        item.iconId = info.icon;
         item.packageName = info.provider.getPackageName();
         item.className = info.provider.getClassName();
         item.extras = extras;
@@ -442,12 +496,19 @@
             }
 
             Item item = (Item) getItem(position);
-            TextView textView = (TextView) convertView.findViewById(R.id.icon_and_label);
+            TextView textView = (TextView) convertView.findViewById(R.id.label);
             textView.setText(item.label);
-            textView.setCompoundDrawablesWithIntrinsicBounds(item.icon, null, null, null);
-
+            ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
+            iconView.setImageDrawable(null);
+            item.loadWidgetPreview(iconView);
             return convertView;
         }
+
+        public void cancelAllWidgetPreviewLoaders() {
+            for (int i = 0; i < mItems.size(); i++) {
+                mItems.get(i).cancelLoadingWidgetPreview();
+            }
+        }
     }
 
     /**
@@ -466,12 +527,13 @@
             setResultData(result, intent);
         } else {
             try {
-                Bundle options = null;
-                if (intent.getExtras() != null) {
-                    options = intent.getExtras().getBundle(
-                            AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);
+                if (mAddingToKeyguard && mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+                    // Found in KeyguardHostView.java
+                    final int KEYGUARD_HOST_ID = 0x4B455947;
+                    mAppWidgetId = AppWidgetHost.allocateAppWidgetIdForSystem(KEYGUARD_HOST_ID);
                 }
-                mAppWidgetManager.bindAppWidgetId(mAppWidgetId, intent.getComponent(), options);
+                mAppWidgetManager.bindAppWidgetId(
+                        mAppWidgetId, intent.getComponent(), mExtraConfigureOptions);
                 result = RESULT_OK;
             } catch (IllegalArgumentException e) {
                 // This is thrown if they're already bound, or otherwise somehow
@@ -491,9 +553,8 @@
     }
 
     protected void onDestroy() {
-        if (!mSuccess && mAddingToKeyguard &&
-                mAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
-            AppWidgetHost.deleteAppWidgetIdForSystem(mAppWidgetId);
+        if (mAppWidgetAdapter != null) {
+            mAppWidgetAdapter.cancelAllWidgetPreviewLoaders();
         }
         super.onDestroy();
     }
@@ -502,20 +563,20 @@
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
         if (requestCode == REQUEST_PICK_APPWIDGET || requestCode == REQUEST_CREATE_APPWIDGET) {
-            int appWidgetId = (data == null) ? -1 : data.getIntExtra(
-                    AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
-            if ((requestCode == REQUEST_PICK_APPWIDGET) &&
-                resultCode == Activity.RESULT_OK) {
+            int appWidgetId;
+            if  (data == null) {
+                appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID ;
+            } else {
+                appWidgetId = data.getIntExtra(
+                        AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+            }
+            if (requestCode == REQUEST_PICK_APPWIDGET && resultCode == Activity.RESULT_OK) {
                 AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
-                boolean defaultWidget =
-                        data.getBooleanExtra(LockPatternUtils.EXTRA_DEFAULT_WIDGET, false);
 
                 AppWidgetProviderInfo appWidget = null;
-                if (!defaultWidget) {
-                    appWidget = appWidgetManager.getAppWidgetInfo(appWidgetId);
-                }
+                appWidget = appWidgetManager.getAppWidgetInfo(appWidgetId);
 
-                if (!defaultWidget && appWidget.configure != null) {
+                if (appWidget.configure != null) {
                     // Launch over to configure widget, if needed
                     Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
                     intent.setComponent(appWidget.configure);
@@ -525,29 +586,31 @@
                     startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET);
                 } else {
                     // Otherwise just add it
-                    if (defaultWidget) {
-                        // If we selected "none", delete the allocated id
-                        AppWidgetHost.deleteAppWidgetIdForSystem(appWidgetId);
-                        data.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
-                                LockPatternUtils.ID_DEFAULT_STATUS_WIDGET);
-                    }
                     onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data);
                 }
             } else if (requestCode == REQUEST_CREATE_APPWIDGET && resultCode == Activity.RESULT_OK) {
-                mSuccess = true;
                 mLockPatternUtils.addAppWidget(appWidgetId, 0);
-                finishDelayedAndShowLockScreen();
+                finishDelayedAndShowLockScreen(appWidgetId);
             } else {
-                finishDelayedAndShowLockScreen();
+                if (mAddingToKeyguard &&
+                        mAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+                    AppWidgetHost.deleteAppWidgetIdForSystem(mAppWidgetId);
+                }
+                finishDelayedAndShowLockScreen(AppWidgetManager.INVALID_APPWIDGET_ID);
             }
         }
     }
 
-    private void finishDelayedAndShowLockScreen() {
+    private void finishDelayedAndShowLockScreen(int appWidgetId) {
         IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
         IWindowManager iWm = IWindowManager.Stub.asInterface(b);
+        Bundle opts = null;
+        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+            opts = new Bundle();
+            opts.putInt(LockPatternUtils.KEYGUARD_SHOW_APPWIDGET, appWidgetId);
+        }
         try {
-            iWm.lockNow(null);
+            iWm.lockNow(opts);
         } catch (RemoteException e) {
         }