merge in honeycomb-mr2-release history after reset to honeycomb-mr2
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java
index 36ff8e1..b4c4f3e 100644
--- a/src/com/android/launcher2/AllAppsPagedView.java
+++ b/src/com/android/launcher2/AllAppsPagedView.java
@@ -70,6 +70,7 @@
     private int mLastMeasureWidth = -1;
     private int mLastMeasureHeight = -1;
     private boolean mWaitingToInitPages = true;
+    private boolean mWaitingToDetermineRowsAndColumns = true;
 
     private int mMaxCellCountY;
 
@@ -129,8 +130,8 @@
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        if (mWaitingToInitPages) {
-            mWaitingToInitPages = false;
+        if (mWaitingToDetermineRowsAndColumns) {
+            mWaitingToDetermineRowsAndColumns = false;
             postInvalidatePageData(false);
         }
         super.onLayout(changed, left, top, right, bottom);
@@ -451,6 +452,7 @@
         Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR);
         mFilteredApps = rebuildFilteredApps(mApps);
         mPageViewIconCache.retainAllApps(list);
+        mWaitingToInitPages = false;
         invalidatePageData();
     }
 
@@ -549,7 +551,8 @@
 
     @Override
     protected void invalidatePageData() {
-        if (mWaitingToInitPages || mCellCountX <= 0 || mCellCountY <= 0) {
+        if (mWaitingToDetermineRowsAndColumns ||
+            mWaitingToInitPages || mCellCountX <= 0 || mCellCountY <= 0) {
             // We don't know our size yet, which means we haven't calculated cell count x/y;
             // onMeasure will call us once we figure out our size
             return;
diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java
index d3779c4..6aa4c72 100644
--- a/src/com/android/launcher2/CustomizePagedView.java
+++ b/src/com/android/launcher2/CustomizePagedView.java
@@ -43,6 +43,7 @@
 import android.graphics.RectF;
 import android.graphics.Bitmap.Config;
 import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
@@ -99,6 +100,10 @@
     // The max dimensions for the ImageView we use for displaying a widget
     private int mMaxWidgetWidth;
 
+    // The min and max dimensions for the bitmap that is used for a widget preview
+    private int mMinWidgetPreviewDim;
+    private int mMaxWidgetPreviewDim;
+
     // The max number of widget cells to take a "page" of widgets
     private int mMaxWidgetsCellHSpan;
 
@@ -152,6 +157,7 @@
     private AllAppsPagedView mAllAppsPagedView;
 
     private boolean mWaitingToInitPages = true;
+    private boolean mWaitingToDetermineRowsAndColumns = true;
 
     public CustomizePagedView(Context context) {
         this(context, null, 0);
@@ -223,8 +229,8 @@
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        if (mWaitingToInitPages) {
-            mWaitingToInitPages = false;
+        if (mWaitingToDetermineRowsAndColumns) {
+            mWaitingToDetermineRowsAndColumns = false;
             postInvalidatePageData(false);
         }
         super.onLayout(changed, left, top, right, bottom);
@@ -250,6 +256,7 @@
 
         // Update the widgets/shortcuts to reflect changes in the set of available apps
         mPageViewIconCache.retainAllApps(list);
+        mWaitingToInitPages = false;
         invalidatePageData();
     }
 
@@ -861,13 +868,14 @@
     /**
      * This method will extract the preview image specified by the widget developer (if it exists),
      * otherwise, it will try to generate a default image preview with the widget's package icon.
-     * @return the drawable that will be used and sized in the ImageView to represent the widget
+     * This method must be safe to call from a background thread
+     * @return the Bitmap that will be wrapped in a FastBitmapDrawable and used and sized in the
+     * ImageView to represent the widget
      */
-    private FastBitmapDrawable getWidgetPreview(AppWidgetProviderInfo info) {
+    private Bitmap getWidgetPreview(AppWidgetProviderInfo info) {
         final PackageManager packageManager = mPackageManager;
         String packageName = info.provider.getPackageName();
         Drawable drawable = null;
-        FastBitmapDrawable newDrawable = null;
         if (info.previewImage != 0) {
             drawable = packageManager.getDrawable(packageName, info.previewImage, null);
             if (drawable == null) {
@@ -877,14 +885,14 @@
         }
 
         // If we don't have a preview image, create a default one
-        final int minDim = mWorkspaceWidgetLayout.estimateCellWidth(1);
-        final int maxDim = mWorkspaceWidgetLayout.estimateCellWidth(3);
         if (drawable == null) {
             Resources resources = mLauncher.getResources();
 
             // Create a new bitmap to hold the widget preview
-            int width = (int) (Math.max(minDim, Math.min(maxDim, info.minWidth)) * sScaleFactor);
-            int height = (int) (Math.max(minDim, Math.min(maxDim, info.minHeight)) * sScaleFactor);
+            int width = (int) (Math.max(mMinWidgetPreviewDim,
+                Math.min(mMaxWidgetPreviewDim, info.minWidth)) * sScaleFactor);
+            int height = (int) (Math.max(mMinWidgetPreviewDim,
+                Math.min(mMaxWidgetPreviewDim, info.minHeight)) * sScaleFactor);
             final Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
             final Drawable background = resources.getDrawable(R.drawable.default_widget_preview);
             renderDrawableToBitmap(background, bitmap, 0, 0, width, height, 1.0f, 1.0f);
@@ -899,23 +907,23 @@
                     icon = resources.getDrawable(R.drawable.ic_launcher_application);
                 }
 
-                final int iconSize = minDim / 2;
+                final int iconSize = mMinWidgetPreviewDim / 2;
                 final int offset = iconSize / 4;
                 renderDrawableToBitmap(icon, null, offset, offset, iconSize, iconSize, 1.0f, 1.0f);
             } catch (Resources.NotFoundException e) {
                 // if we can't find the icon, then just don't draw it
             }
 
-            newDrawable = new FastBitmapDrawable(bitmap);
+            return bitmap;
         } else {
             // Scale down the preview if necessary
             final float imageWidth = drawable.getIntrinsicWidth();
             final float imageHeight = drawable.getIntrinsicHeight();
             final float aspect = (float) imageWidth / imageHeight;
-            final int scaledWidth =
-                (int) (Math.max(minDim, Math.min(maxDim, imageWidth)) * sScaleFactor);
-            final int scaledHeight =
-                (int) (Math.max(minDim, Math.min(maxDim, imageHeight)) * sScaleFactor);
+            final int scaledWidth = (int) (Math.max(mMinWidgetPreviewDim,
+                Math.min(mMaxWidgetPreviewDim, imageWidth)) * sScaleFactor);
+            final int scaledHeight = (int) (Math.max(mMinWidgetPreviewDim,
+                Math.min(mMaxWidgetPreviewDim, imageHeight)) * sScaleFactor);
             int width;
             int height;
             if (aspect >= 1.0f) {
@@ -929,11 +937,8 @@
             final Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
             renderDrawableToBitmap(drawable, bitmap, 0, 0, width, height, 1.0f, 1.0f);
 
-            newDrawable = new FastBitmapDrawable(bitmap);
+            return bitmap;
         }
-        newDrawable.setBounds(0, 0, newDrawable.getIntrinsicWidth(),
-                newDrawable.getIntrinsicHeight());
-        return newDrawable;
     }
 
     private void setupPage(PagedViewCellLayout layout) {
@@ -948,6 +953,8 @@
         mWorkspaceWidgetLayout.setPadding(20, 10, 20, 0);
 
         mMaxWidgetWidth = mWorkspaceWidgetLayout.estimateCellWidth(sMaxWidgetCellHSpan);
+        mMinWidgetPreviewDim = mWorkspaceWidgetLayout.estimateCellWidth(1);
+        mMaxWidgetPreviewDim = mWorkspaceWidgetLayout.estimateCellWidth(3);
     }
 
     private void syncWidgetPages() {
@@ -957,42 +964,90 @@
         removeAllViews();
         int numPages = relayoutWidgets();
         for (int i = 0; i < numPages; ++i) {
-            LinearLayout layout = new PagedViewExtendedLayout(getContext());
+            PagedViewExtendedLayout layout = new PagedViewExtendedLayout(getContext());
             layout.setGravity(Gravity.CENTER_HORIZONTAL);
             layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
                     mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
-
+            if (i < (numPages - 1)) {
+                layout.setHasFixedWidth(true);
+                layout.setMinimumWidth(mMinPageWidth);
+            }
             addView(layout, new LinearLayout.LayoutParams(
                     LinearLayout.LayoutParams.WRAP_CONTENT,
                     LinearLayout.LayoutParams.MATCH_PARENT));
         }
     }
 
-    private void syncWidgetPageItems(int page) {
-        // ensure that we have the right number of items on the pages
-        LinearLayout layout = (LinearLayout) getChildAt(page);
-        final ArrayList<AppWidgetProviderInfo> list = mWidgetPages.get(page);
-        final int count = list.size();
-        final int numPages = getPageCount();
-        layout.removeAllViews();
-        for (int i = 0; i < count; ++i) {
-            final AppWidgetProviderInfo info = (AppWidgetProviderInfo) list.get(i);
-            final PendingAddWidgetInfo createItemInfo = new PendingAddWidgetInfo(info, null, null);
-            final int[] cellSpans = CellLayout.rectToCell(getResources(), info.minWidth,
-                    info.minHeight, null);
-            final FastBitmapDrawable icon = getWidgetPreview(info);
+    private static class AppWidgetsPageToSync {
+        public AppWidgetsPageToSync(
+            LinearLayout layout, ArrayList<AppWidgetProviderInfo> appWidgets) {
+            mLayout = layout;
+            mAppWidgets = (ArrayList<AppWidgetProviderInfo>) appWidgets.clone();
+            mAppWidgetBitmaps = new ArrayList<Bitmap>(appWidgets.size());
+        }
+        public int mPage;
+        public LinearLayout mLayout;
+        public ArrayList<AppWidgetProviderInfo> mAppWidgets;
+        public ArrayList<Bitmap> mAppWidgetBitmaps;
+    }
 
-            PagedViewWidget l = (PagedViewWidget) mInflater.inflate(
+    private void syncWidgetPageItems(int page) {
+        LinearLayout layout = (LinearLayout) getChildAt(page);
+        layout.removeAllViews();
+        AppWidgetsPageToSync pageToSync =
+            new AppWidgetsPageToSync(layout, mWidgetPages.get(page));
+
+        // Load the widget previews in the bcakground
+        new SyncWidgetPageItemsTask().execute(pageToSync);
+    }
+
+    private class SyncWidgetPageItemsTask extends
+        AsyncTask<AppWidgetsPageToSync, Void, AppWidgetsPageToSync> {
+        protected AppWidgetsPageToSync doInBackground(AppWidgetsPageToSync... args) {
+            if (args.length != 1) {
+                throw new RuntimeException("Wrong number of args to SyncWidgetPageItemsTask");
+            }
+            AppWidgetsPageToSync pageToSync = args[0];
+
+            // generating widgetPreviews on more than one thread at a time causes a crash
+            synchronized(CustomizePagedView.this) {
+                // Load whatever was not in the cache
+                int numWidgets = pageToSync.mAppWidgets.size();
+                for (int i = 0; i < numWidgets; i++) {
+                    AppWidgetProviderInfo info = pageToSync.mAppWidgets.get(i);
+                    pageToSync.mAppWidgetBitmaps.add(getWidgetPreview(info));
+                }
+            }
+            return pageToSync;
+        }
+
+        protected void onPostExecute(AppWidgetsPageToSync pageToSync) {
+            LinearLayout layout = (LinearLayout) pageToSync.mLayout;
+            final int numPages = getPageCount();
+            final int numWidgets = pageToSync.mAppWidgets.size();
+            for (int i = 0; i < numWidgets; ++i) {
+                final AppWidgetProviderInfo info = pageToSync.mAppWidgets.get(i);
+                final PendingAddWidgetInfo createItemInfo =
+                    new PendingAddWidgetInfo(info, null, null);
+                final int[] cellSpans = CellLayout.rectToCell(getResources(), info.minWidth,
+                                                              info.minHeight, null);
+
+                FastBitmapDrawable icon
+                    = new FastBitmapDrawable(pageToSync.mAppWidgetBitmaps.get(i));
+                icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
+
+                PagedViewWidget l = (PagedViewWidget) mInflater.inflate(
                     R.layout.customize_paged_view_widget, layout, false);
 
-            l.applyFromAppWidgetProviderInfo(info, icon, mMaxWidgetWidth, cellSpans,
+                l.applyFromAppWidgetProviderInfo(info, icon, mMaxWidgetWidth, cellSpans,
                     mPageViewIconCache, (numPages > 1));
-            l.setTag(createItemInfo);
-            l.setOnClickListener(this);
-            l.setOnTouchListener(this);
-            l.setOnLongClickListener(this);
+                l.setTag(createItemInfo);
+                l.setOnClickListener(CustomizePagedView.this);
+                l.setOnTouchListener(CustomizePagedView.this);
+                l.setOnLongClickListener(CustomizePagedView.this);
 
-            layout.addView(l);
+                layout.addView(l);
+            }
         }
     }
 
@@ -1004,11 +1059,14 @@
         int numPages = (int) Math.ceil((float) (mWallpaperList.size() * mWallpaperCellHSpan) /
                 mMaxWallpaperCellHSpan);
         for (int i = 0; i < numPages; ++i) {
-            LinearLayout layout = new PagedViewExtendedLayout(getContext());
+            PagedViewExtendedLayout layout = new PagedViewExtendedLayout(getContext());
             layout.setGravity(Gravity.CENTER_HORIZONTAL);
             layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
                     mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
-
+            if (i < (numPages - 1)) {
+                layout.setHasFixedWidth(true);
+                layout.setMinimumWidth(mMinPageWidth);
+            }
             addView(layout, new LinearLayout.LayoutParams(
                     LinearLayout.LayoutParams.WRAP_CONTENT,
                     LinearLayout.LayoutParams.MATCH_PARENT));
@@ -1140,7 +1198,7 @@
 
     @Override
     protected void invalidatePageData() {
-        if (mWaitingToInitPages || mCellCountX <= 0 || mCellCountY <= 0) {
+        if (mWaitingToDetermineRowsAndColumns || mWaitingToInitPages || mCellCountX <= 0 || mCellCountY <= 0) {
             // We don't know our size yet, which means we haven't calculated cell count x/y;
             // onMeasure will call us once we figure out our size
             return;
@@ -1229,11 +1287,11 @@
 
     @Override
     protected int getAssociatedLowerPageBound(int page) {
-        return 0;
+        return Math.max(0, page - 2);
     }
     @Override
     protected int getAssociatedUpperPageBound(int page) {
-        return getChildCount();
+        return Math.min(page + 2, getChildCount() - 1);
     }
 
     @Override
diff --git a/src/com/android/launcher2/PagedViewExtendedLayout.java b/src/com/android/launcher2/PagedViewExtendedLayout.java
index e54d261..4ceb44d 100644
--- a/src/com/android/launcher2/PagedViewExtendedLayout.java
+++ b/src/com/android/launcher2/PagedViewExtendedLayout.java
@@ -20,6 +20,7 @@
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
 /**
@@ -27,6 +28,8 @@
  */
 public class PagedViewExtendedLayout extends LinearLayout implements Page {
     static final String TAG = "PagedViewWidgetLayout";
+    float mChildrenAlpha = 1f;
+    private boolean mHasFixedWidth;
 
     public PagedViewExtendedLayout(Context context) {
         this(context, null);
@@ -40,6 +43,24 @@
         super(context, attrs, defStyle);
     }
 
+    public void setHasFixedWidth(boolean hasFixedWidth) {
+        mHasFixedWidth = hasFixedWidth;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (mHasFixedWidth) {
+            // PagedView currently has issues with different-sized pages since it calculates the
+            // offset of each page to scroll to before it updates the actual size of each page
+            // (which canchange depending on the content if the contains aren't a fixed size).
+            // We work around this by having a fixed size on each widget page).
+            int widthSpecSize = getSuggestedMinimumWidth();
+            int widthSpecMode = MeasureSpec.EXACTLY;
+            widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSpecSize, widthSpecMode);
+        }
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         // We eat up the touch events here, since the PagedView (which uses the same swiping
@@ -59,6 +80,7 @@
 
     @Override
     public void setAlpha(float alpha) {
+        mChildrenAlpha = alpha;
         setChildrenAlpha(alpha);
         super.setAlpha(alpha);
     }
@@ -71,6 +93,37 @@
     }
 
     @Override
+    public void addView(View child, int index, ViewGroup.LayoutParams params) {
+        super.addView(child, index, params);
+        child.setAlpha(mChildrenAlpha);
+    }
+
+
+    @Override
+    public void addView(View child, ViewGroup.LayoutParams params) {
+        super.addView(child, params);
+        child.setAlpha(mChildrenAlpha);
+    }
+
+    @Override
+    public void addView(View child, int index) {
+        super.addView(child, index);
+        child.setAlpha(mChildrenAlpha);
+    }
+
+    @Override
+    public void addView(View child) {
+        super.addView(child);
+        child.setAlpha(mChildrenAlpha);
+    }
+
+    @Override
+    public void addView(View child, int width, int height) {
+        super.addView(child, width, height);
+        child.setAlpha(mChildrenAlpha);
+    }
+
+    @Override
     public void removeAllViewsOnPage() {
         removeAllViews();
     }
diff --git a/src/com/android/launcher2/PagedViewIconCache.java b/src/com/android/launcher2/PagedViewIconCache.java
index de05ff1..d65f68b 100644
--- a/src/com/android/launcher2/PagedViewIconCache.java
+++ b/src/com/android/launcher2/PagedViewIconCache.java
@@ -48,11 +48,11 @@
             final ComponentInfo ci = info.activityInfo != null ? info.activityInfo :
                 info.serviceInfo;
             mComponentName = new ComponentName(ci.packageName, ci.name);
-            mType = Type.AppWidgetProviderInfoKey;
+            mType = Type.ResolveInfoKey;
         }
         public Key(AppWidgetProviderInfo info) {
             mComponentName = info.provider;
-            mType = Type.ResolveInfoKey;
+            mType = Type.AppWidgetProviderInfoKey;
         }
 
         private ComponentName getComponentName() {
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 72f928b..5791fb8 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -61,9 +61,6 @@
     private final Rect mEraseStrokeRect = new Rect();
     private final Paint mEraseStrokeRectPaint = new Paint();
 
-    private PagedViewIconCache.Key mIconCacheKey;
-    private PagedViewIconCache mIconCache;
-
     private int mAlpha = 255;
     private int mHolographicAlpha;
 
@@ -118,7 +115,6 @@
             mHandler.post(new Runnable() {
                 public void run() {
                     widget.mHolographicOutline = outline;
-                    widget.mIconCache.addOutline(widget.mIconCacheKey, outline);
                     widget.invalidate();
                 }
             });
@@ -189,9 +185,6 @@
         dims.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
 
         if (createHolographicOutline) {
-            mIconCache = cache;
-            mIconCacheKey = new PagedViewIconCache.Key(info);
-            mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
             mPreview = preview;
         }
     }
@@ -208,9 +201,6 @@
         name.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
 
         if (createHolographicOutline) {
-            mIconCache = cache;
-            mIconCacheKey = new PagedViewIconCache.Key(info);
-            mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
             mPreview = preview;
         }
     }
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index d570b8b..05b3573 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -730,8 +730,9 @@
 
     protected void setWallpaperDimension() {
         Display display = mLauncher.getWindowManager().getDefaultDisplay();
-        final int maxDim = Math.max(display.getWidth(), display.getHeight());
-        final int minDim = Math.min(display.getWidth(), display.getHeight());
+        int height = display.getHeight() + (int) getResources().getDimension(R.dimen.status_bar_height);
+        final int maxDim = Math.max(display.getWidth(), height);
+        final int minDim = Math.min(display.getWidth(), height);
 
         // We need to ensure that there is enough extra space in the wallpaper for the intended
         // parallax effects