Merge branch 'master' into honeycomb-release
diff --git a/src/com/android/launcher2/BubbleTextView.java b/src/com/android/launcher2/BubbleTextView.java
index 113f35d..855f261 100644
--- a/src/com/android/launcher2/BubbleTextView.java
+++ b/src/com/android/launcher2/BubbleTextView.java
@@ -147,16 +147,18 @@
 
         // Draw the hotdog bubble
         final Layout layout = getLayout();
-        final int offset = getExtendedPaddingTop();
-        final int paddingLeft = getPaddingLeft();
-        final int paddingRight = getPaddingRight();
-        final float left = layout.getLineLeft(0) + paddingLeft;
-        final float right = Math.min(layout.getLineRight(0) + paddingRight,
-                left + getWidth() - paddingLeft - paddingRight);
-        mRect.set(left - mPaddingH, offset + (int) layout.getLineTop(0) - mPaddingV,
-                right + mPaddingH, offset + (int) layout.getLineBottom(0) + mPaddingV);
+        if (layout != null) {
+            final int offset = getExtendedPaddingTop();
+            final int paddingLeft = getPaddingLeft();
+            final int paddingRight = getPaddingRight();
+            final float left = layout.getLineLeft(0) + paddingLeft;
+            final float right = Math.min(layout.getLineRight(0) + paddingRight,
+                    left + getWidth() - paddingLeft - paddingRight);
+            mRect.set(left - mPaddingH, offset + (int) layout.getLineTop(0) - mPaddingV,
+                    right + mPaddingH, offset + (int) layout.getLineBottom(0) + mPaddingV);
 
-        canvas.drawRoundRect(mRect, mCornerRadius, mCornerRadius, mPaint);
+            canvas.drawRoundRect(mRect, mCornerRadius, mCornerRadius, mPaint);
+        }
 
         super.draw(canvas);
     }
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 023e9f4..8fe489d 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -796,7 +796,8 @@
 
                     final int[] cellXY = mTmpCellXY;
                     getLocationOnScreen(cellXY);
-                    mWallpaperManager.sendWallpaperCommand(getWindowToken(), "android.home.drop",
+                    mWallpaperManager.sendWallpaperCommand(getWindowToken(),
+                            WallpaperManager.COMMAND_DROP,
                             cellXY[0] + childLeft + lp.width / 2,
                             cellXY[1] + childTop + lp.height / 2, 0, null);
 
diff --git a/src/com/android/launcher2/DimmableAppWidgetHostView.java b/src/com/android/launcher2/DimmableAppWidgetHostView.java
deleted file mode 100644
index 1f512a3..0000000
--- a/src/com/android/launcher2/DimmableAppWidgetHostView.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-package com.android.launcher2;
-
-import com.android.launcher.R;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.view.View;
-
-public class DimmableAppWidgetHostView extends LauncherAppWidgetHostView implements Dimmable {
-    public DimmableAppWidgetHostView(Context context) {
-        super(context);
-        mPaint.setFilterBitmap(true);
-    }
-
-    private final Paint mPaint = new Paint();
-    private Bitmap mDimmedView;
-    private Canvas mDimmedViewCanvas;
-    private boolean isDimmedViewUpdatePass;
-    private float mDimmableProgress;
-
-    private void setChildAlpha(float alpha) {
-        if (getChildCount() > 0) {
-            final View child = getChildAt(0);
-            if (child.getAlpha() != alpha) {
-                getChildAt(0).setAlpha(alpha);
-            }
-        }
-    }
-
-    private void updateChildAlpha() {
-        // hacky, but sometimes widgets get their alpha set back to 1.0f, so we call
-        // this to force them back
-        setChildAlpha(getAlpha());
-    }
-
-    //@Override
-    public boolean onSetAlpha(int alpha) {
-        super.onSetAlpha(alpha);
-        return true;
-    }
-
-    public void setDimmableProgress(float progress) {
-        mDimmableProgress = progress;
-    }
-
-    public float getDimmableProgress() {
-        return mDimmableProgress;
-    }
-
-    private void updateDimmedView() {
-        if (mDimmedView == null) {
-            mDimmedView = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
-                    Bitmap.Config.ARGB_8888);
-            mDimmedViewCanvas = new Canvas(mDimmedView);
-        }
-        mDimmedViewCanvas.drawColor(0x00000000);
-        mDimmedViewCanvas.concat(getMatrix());
-        isDimmedViewUpdatePass = true;
-        draw(mDimmedViewCanvas);
-        // make the bitmap look "dimmed"
-        int dimmedColor = getContext().getResources().getColor(R.color.dimmed_view_color);
-        mDimmedViewCanvas.drawColor(dimmedColor, PorterDuff.Mode.SRC_IN);
-        isDimmedViewUpdatePass = false;
-        invalidate();
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-
-        if (mDimmedView == null && mDimmableProgress > 0.0f) {
-            updateDimmedView();
-        }
-    }
-
-    @Override
-    public void dispatchDraw(Canvas canvas) {
-        if (isDimmedViewUpdatePass) {
-            final float alpha = getAlpha();
-            canvas.save();
-            setAlpha(1.0f);
-            super.dispatchDraw(canvas);
-            canvas.restore();
-            setAlpha(alpha);
-        } else {
-            if (mDimmedView != null && mDimmableProgress > 0) {
-                // draw the dimmed version of this widget
-                mPaint.setAlpha((int) (mDimmableProgress * 255));
-                canvas.drawBitmap(mDimmedView, 0, 0, mPaint);
-            }
-
-            updateChildAlpha();
-            super.dispatchDraw(canvas);
-        }
-    }
-}
diff --git a/src/com/android/launcher2/DimmableBubbleTextView.java b/src/com/android/launcher2/DimmableBubbleTextView.java
deleted file mode 100644
index cb3b8ef..0000000
--- a/src/com/android/launcher2/DimmableBubbleTextView.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-package com.android.launcher2;
-
-import com.android.launcher.R;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.util.AttributeSet;
-
-public class DimmableBubbleTextView extends BubbleTextView implements Dimmable {
-    private  Paint mDimmedPaint = new Paint();
-    private int mAlpha;
-    private Bitmap mDimmedView;
-    private Canvas mDimmedViewCanvas;
-    private boolean isDimmedViewUpdatePass;
-    private float mDimmableProgress;
-
-    public DimmableBubbleTextView(Context context) {
-        super(context);
-        mDimmedPaint.setFilterBitmap(true);
-    }
-
-    public DimmableBubbleTextView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mDimmedPaint.setFilterBitmap(true);
-    }
-
-    public DimmableBubbleTextView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        mDimmedPaint.setFilterBitmap(true);
-    }
-
-    public void setDimmableProgress(float progress) {
-        mDimmableProgress = progress;
-    }
-
-    public float getDimmableProgress() {
-        return mDimmableProgress;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-
-        if (mDimmedView == null) {
-            isDimmedViewUpdatePass = true;
-            mDimmedView = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
-                    Bitmap.Config.ARGB_8888);
-            mDimmedViewCanvas = new Canvas(mDimmedView);
-            mDimmedViewCanvas.concat(getMatrix());
-
-            draw(mDimmedViewCanvas);
-
-            // MAKE THE DIMMED VERSION
-            int dimmedColor = getContext().getResources().getColor(R.color.dimmed_view_color);
-            mDimmedViewCanvas.drawColor(dimmedColor, PorterDuff.Mode.SRC_IN);
-
-            isDimmedViewUpdatePass = false;
-        }
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        if (isDimmedViewUpdatePass) {
-            canvas.save();
-            final float alpha = getAlpha();
-            super.setAlpha(1.0f);
-            super.onDraw(canvas);
-            super.setAlpha(alpha);
-            canvas.restore();
-        } else {
-            super.onDraw(canvas);
-        }
-
-        if (mDimmedView != null && mDimmableProgress > 0) {
-            mDimmedPaint.setAlpha((int) (mDimmableProgress * 255));
-            canvas.drawBitmap(mDimmedView, mScrollX, mScrollY, mDimmedPaint);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index dae84aa..86c099e 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -29,7 +29,7 @@
 /**
  * An icon that can appear on in the workspace representing an {@link UserFolder}.
  */
-public class FolderIcon extends DimmableBubbleTextView implements DropTarget {
+public class FolderIcon extends BubbleTextView implements DropTarget {
     private UserFolderInfo mInfo;
     private Launcher mLauncher;
     private Drawable mCloseIcon;
diff --git a/src/com/android/launcher2/HolographicOutlineHelper.java b/src/com/android/launcher2/HolographicOutlineHelper.java
index 658490a..bf4c05a 100644
--- a/src/com/android/launcher2/HolographicOutlineHelper.java
+++ b/src/com/android/launcher2/HolographicOutlineHelper.java
@@ -29,6 +29,7 @@
     private final Paint mHolographicPaint = new Paint();
     private final Paint mBlurPaint = new Paint();
     private final Paint mErasePaint = new Paint();
+    private final Paint mAlphaClipPaint = new Paint();
 
     public static final int OUTER_BLUR_RADIUS;
 
@@ -36,6 +37,10 @@
     private static final BlurMaskFilter sMediumOuterBlurMaskFilter;
     private static final BlurMaskFilter sThinOuterBlurMaskFilter;
     private static final BlurMaskFilter sThickInnerBlurMaskFilter;
+    private static final BlurMaskFilter sMediumInnerBlurMaskFilter;
+
+    private static final int THICK = 0;
+    private static final int MEDIUM = 1;
 
     static {
         final float scale = LauncherApplication.getScreenDensity();
@@ -47,6 +52,7 @@
         sMediumOuterBlurMaskFilter = new BlurMaskFilter(scale * 2.0f, BlurMaskFilter.Blur.OUTER);
         sThinOuterBlurMaskFilter = new BlurMaskFilter(scale * 1.0f, BlurMaskFilter.Blur.OUTER);
         sThickInnerBlurMaskFilter = new BlurMaskFilter(scale * 4.0f, BlurMaskFilter.Blur.NORMAL);
+        sMediumInnerBlurMaskFilter = new BlurMaskFilter(scale * 2.0f, BlurMaskFilter.Blur.NORMAL);
     }
 
     private static final MaskFilter sFineClipTable = TableMaskFilter.CreateClipTable(0, 20);
@@ -62,6 +68,8 @@
         mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
         mErasePaint.setFilterBitmap(true);
         mErasePaint.setAntiAlias(true);
+        MaskFilter alphaClipTable = TableMaskFilter.CreateClipTable(180, 255);
+        mAlphaClipPaint.setMaskFilter(alphaClipTable);
     }
 
     /**
@@ -98,66 +106,42 @@
         mHolographicPaint.setMaskFilter(sCoarseClipTable);
         mHolographicPaint.setAlpha(150);
         mHolographicPaint.setColor(color);
+
         canvas.drawBitmap(glow, mTempOffset[0], mTempOffset[1], mHolographicPaint);
         glow.recycle();
     }
 
     /**
-     * Draws a solid outline around a bitmap, erasing the original pixels.
-     *
-     * @param bitmap The bitmap to modify
-     * @param canvas A canvas on the bitmap
-     * @param color The color to draw the outline and glow in
-     * @param removeOrig If true, punch out the original pixels to just leave the outline
-     */
-    void applyExpensiveOuterOutline(Bitmap bitmap, Canvas canvas, int color, boolean removeOrig) {
-        Bitmap originalImage = null;
-        if (removeOrig) {
-            originalImage = bitmap.extractAlpha();
-        }
-
-        // Compute an outer blur on the original bitmap
-        mBlurPaint.setMaskFilter(sMediumOuterBlurMaskFilter);
-        Bitmap outline = bitmap.extractAlpha(mBlurPaint, mTempOffset);
-
-        // Paint the blurred bitmap back into the canvas. Using the clip table causes any alpha
-        // pixels above a certain threshold to be rounded up to be fully opaque. This gives the
-        // effect of a thick outline, with a slight blur on the edge
-        mHolographicPaint.setColor(color);
-        mHolographicPaint.setMaskFilter(sFineClipTable);
-        canvas.drawBitmap(outline, mTempOffset[0], mTempOffset[1], mHolographicPaint);
-        outline.recycle();
-
-        if (removeOrig) {
-            // Finally, punch out the original pixels, leaving just the outline
-            canvas.drawBitmap(originalImage, 0, 0, mErasePaint);
-            originalImage.recycle();
-        }
-    }
-
-    /**
      * Applies a more expensive and accurate outline to whatever is currently drawn in a specified
      * bitmap.
      */
     void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
-            int outlineColor) {
+            int outlineColor, int thickness) {
+
+        // We start by removing most of the alpha channel so as to ignore shadows, and
+        // other types of partial transparency when defining the shape of the object
+        Bitmap glowShape = srcDst.extractAlpha(mAlphaClipPaint, mTempOffset);
+
         // calculate the outer blur first
-        mBlurPaint.setMaskFilter(sThickOuterBlurMaskFilter);
+        mBlurPaint.setMaskFilter(thickness == THICK ? sThickOuterBlurMaskFilter :
+                                                      sMediumOuterBlurMaskFilter);
         int[] outerBlurOffset = new int[2];
-        Bitmap thickOuterBlur = srcDst.extractAlpha(mBlurPaint, outerBlurOffset);
+        Bitmap thickOuterBlur = glowShape.extractAlpha(mBlurPaint, outerBlurOffset);
         mBlurPaint.setMaskFilter(sThinOuterBlurMaskFilter);
         int[] thinOuterBlurOffset = new int[2];
-        Bitmap thinOuterBlur = srcDst.extractAlpha(mBlurPaint, thinOuterBlurOffset);
+        Bitmap thinOuterBlur = glowShape.extractAlpha(mBlurPaint, thinOuterBlurOffset);
 
         // calculate the inner blur
+        srcDstCanvas.setBitmap(glowShape);
         srcDstCanvas.drawColor(0xFF000000, PorterDuff.Mode.SRC_OUT);
-        mBlurPaint.setMaskFilter(sThickInnerBlurMaskFilter);
+        mBlurPaint.setMaskFilter(thickness == THICK ? sThickInnerBlurMaskFilter :
+                                                      sMediumInnerBlurMaskFilter);
         int[] thickInnerBlurOffset = new int[2];
-        Bitmap thickInnerBlur = srcDst.extractAlpha(mBlurPaint, thickInnerBlurOffset);
+        Bitmap thickInnerBlur = glowShape.extractAlpha(mBlurPaint, thickInnerBlurOffset);
 
         // mask out the inner blur
         srcDstCanvas.setBitmap(thickInnerBlur);
-        srcDstCanvas.drawBitmap(srcDst, -thickInnerBlurOffset[0],
+        srcDstCanvas.drawBitmap(glowShape, -thickInnerBlurOffset[0],
                 -thickInnerBlurOffset[1], mErasePaint);
         srcDstCanvas.drawRect(0, 0, -thickInnerBlurOffset[0], thickInnerBlur.getHeight(),
                 mErasePaint);
@@ -182,5 +166,17 @@
         thinOuterBlur.recycle();
         thickOuterBlur.recycle();
         thickInnerBlur.recycle();
+        glowShape.recycle();
     }
+
+    void applyThickExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
+            int outlineColor) {
+        applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, THICK);
+    }
+
+    void applyMediumExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
+            int outlineColor) {
+        applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, MEDIUM);
+    }
+
 }
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 31cfb5b..257531e 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -757,8 +757,9 @@
                 break;
             }
 
-            case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
+                onWallpaperTap(ev);
+            case MotionEvent.ACTION_CANCEL:
                 mTouchState = TOUCH_STATE_REST;
                 mAllowLongPress = false;
                 mActivePointerId = INVALID_POINTER;
@@ -958,6 +959,8 @@
                 } else {
                     snapToDestination();
                 }
+            } else {
+                onWallpaperTap(ev);
             }
             mTouchState = TOUCH_STATE_REST;
             mActivePointerId = INVALID_POINTER;
@@ -1011,6 +1014,12 @@
                 mVelocityTracker.clear();
             }
         }
+        if (mTouchState == TOUCH_STATE_REST) {
+            onWallpaperTap(ev);
+        }
+    }
+
+    protected void onWallpaperTap(MotionEvent ev) {
     }
 
     @Override
diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java
index 0e72598..300bab5 100644
--- a/src/com/android/launcher2/PagedViewIcon.java
+++ b/src/com/android/launcher2/PagedViewIcon.java
@@ -81,7 +81,7 @@
             Canvas holographicOutlineCanvas = new Canvas(holographicOutline);
             holographicOutlineCanvas.drawBitmap(icon.mIcon, 0, 0, mPaint);
 
-            sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(holographicOutline,
+            sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(holographicOutline,
                     holographicOutlineCanvas, icon.mHoloBlurColor, icon.mHoloOutlineColor);
 
             mHandler.post(new Runnable() {
@@ -235,7 +235,7 @@
                 mPaint.setAlpha(255);
                 checkedOutlineCanvas.drawBitmap(mIcon, 0, 0, mPaint);
 
-                sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(mCheckedOutline,
+                sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(mCheckedOutline,
                         checkedOutlineCanvas, mCheckedBlurColor, mCheckedOutlineColor);
             } else {
                 invalidateCheckedImage();
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 40e507b..4d4ccc2 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -80,7 +80,7 @@
             widget.mPreview.setAlpha(prevAlpha);
             widget.mHolographicOutlineCanvas.restore();
 
-            sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(outline,
+            sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(outline,
                     widget.mHolographicOutlineCanvas, widget.mHoloBlurColor,
                     widget.mHoloOutlineColor);
 
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index b12d357..42dbc9a 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -542,10 +542,6 @@
         Launcher.setScreen(mCurrentPage);
     };
 
-    private void updateWallpaperOffset() {
-        updateWallpaperOffset(getChildAt(getChildCount() - 1).getRight() - (mRight - mLeft));
-    }
-
     private void updateWallpaperOffset(int scrollRange) {
         final boolean isStaticWallpaper = (mWallpaperManager != null) &&
                 (mWallpaperManager.getWallpaperInfo() == null);
@@ -892,6 +888,21 @@
         return super.onTouchEvent(ev);
     }
 
+    @Override
+    protected void onWallpaperTap(MotionEvent ev) {
+        final int[] position = mTempCell;
+        getLocationOnScreen(position);
+
+        int pointerIndex = ev.getActionIndex();
+        position[0] += (int) ev.getX(pointerIndex);
+        position[1] += (int) ev.getY(pointerIndex);
+
+        mWallpaperManager.sendWallpaperCommand(getWindowToken(),
+                ev.getAction() == MotionEvent.ACTION_UP
+                        ? WallpaperManager.COMMAND_TAP : WallpaperManager.COMMAND_SECONDARY_TAP,
+                position[0], position[1], 0, null);
+    }
+
     public boolean isSmall() {
         return mIsSmall;
     }
@@ -1313,8 +1324,7 @@
 
         canvas.setBitmap(b);
         drawDragView(v, canvas, padding);
-        mOutlineHelper.applyExpensiveOuterOutline(b, canvas, outlineColor, true);
-
+        mOutlineHelper.applyMediumExpensiveOutlineWithBlur(b, canvas, outlineColor, outlineColor);
         return b;
     }
 
@@ -1336,8 +1346,7 @@
         canvas.setBitmap(b);
         canvas.drawRoundRect(new RectF(inset, inset, iconWidth - inset, iconHeight - inset),
                 rectRadius, rectRadius, mExternalDragOutlinePaint);
-        mOutlineHelper.applyExpensiveOuterOutline(b, canvas, outlineColor, true);
-
+        mOutlineHelper.applyMediumExpensiveOutlineWithBlur(b, canvas, outlineColor, outlineColor);
         return b;
     }