Merge "Remove SYSTEM_UI_FLAG_LIGHT_NAV_BAR flag bit from systemUiVisibility call" into ub-launcher3-calgary
diff --git a/src/com/android/launcher3/BaseRecyclerViewFastScrollPopup.java b/src/com/android/launcher3/BaseRecyclerViewFastScrollPopup.java
index baf96fe..da7fa41 100644
--- a/src/com/android/launcher3/BaseRecyclerViewFastScrollPopup.java
+++ b/src/com/android/launcher3/BaseRecyclerViewFastScrollPopup.java
@@ -18,6 +18,7 @@
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
 import android.content.res.Resources;
+import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
@@ -31,9 +32,16 @@
 
     private static final float FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR = 1.5f;
 
+    private static final int SHADOW_INSET = 6;
+    private static final int SHADOW_SHIFT_Y = 4;
+    private static final float SHADOW_ALPHA_MULTIPLIER = 0.6f;
+
     private Resources mRes;
     private BaseRecyclerView mRv;
 
+    private Bitmap mShadow;
+    private Paint mShadowPaint;
+
     private Drawable mBg;
     // The absolute bounds of the fast scroller bg
     private Rect mBgBounds = new Rect();
@@ -52,13 +60,20 @@
     public BaseRecyclerViewFastScrollPopup(BaseRecyclerView rv, Resources res) {
         mRes = res;
         mRv = rv;
+
         mBgOriginalSize = res.getDimensionPixelSize(R.dimen.container_fastscroll_popup_size);
         mBg = rv.getContext().getDrawable(R.drawable.container_fastscroll_popup_bg);
         mBg.setBounds(0, 0, mBgOriginalSize, mBgOriginalSize);
+
         mTextPaint = new Paint();
         mTextPaint.setColor(Color.WHITE);
         mTextPaint.setAntiAlias(true);
         mTextPaint.setTextSize(res.getDimensionPixelSize(R.dimen.container_fastscroll_popup_text_size));
+
+        mShadowPaint = new Paint();
+        mShadowPaint.setAntiAlias(true);
+        mShadowPaint.setFilterBitmap(true);
+        mShadowPaint.setDither(true);
     }
 
     /**
@@ -75,6 +90,7 @@
 
     /**
      * Updates the bounds for the fast scroller.
+     *
      * @return the invalidation rect for this update.
      */
     public Rect updateFastScrollerBounds(int lastTouchY) {
@@ -98,7 +114,12 @@
             mBgBounds.top = Math.max(edgePadding,
                     Math.min(mBgBounds.top, mRv.getHeight() - edgePadding - bgHeight));
             mBgBounds.bottom = mBgBounds.top + bgHeight;
+
+            // Generate a bitmap for a shadow matching these bounds
+            mShadow = HolographicOutlineHelper.obtain(
+                    mRv.getContext()).createMediumDropShadow(mBg, false /* shouldCache */);
         } else {
+            mShadow = null;
             mBgBounds.setEmpty();
         }
 
@@ -138,17 +159,32 @@
 
     public void draw(Canvas c) {
         if (isVisible()) {
-            // Draw the fast scroller popup
+            // Determine the alpha and prepare the canvas
+            final int alpha = (int) (mAlpha * 255);
             int restoreCount = c.save(Canvas.MATRIX_SAVE_FLAG);
             c.translate(mBgBounds.left, mBgBounds.top);
             mTmpRect.set(mBgBounds);
             mTmpRect.offsetTo(0, 0);
+
+            // Expand the rect (with a negative inset), translate it, and draw the shadow
+            if (mShadow != null) {
+                mTmpRect.inset(-SHADOW_INSET * 2, -SHADOW_INSET * 2);
+                mTmpRect.offset(0, SHADOW_SHIFT_Y);
+                mShadowPaint.setAlpha((int) (alpha * SHADOW_ALPHA_MULTIPLIER));
+                c.drawBitmap(mShadow, null, mTmpRect, mShadowPaint);
+                mTmpRect.inset(SHADOW_INSET * 2, SHADOW_INSET * 2);
+                mTmpRect.offset(0, -SHADOW_SHIFT_Y);
+            }
+
+            // Draw the background
             mBg.setBounds(mTmpRect);
-            mBg.setAlpha((int) (mAlpha * 255));
+            mBg.setAlpha(alpha);
             mBg.draw(c);
-            mTextPaint.setAlpha((int) (mAlpha * 255));
+
+            // Draw the text
+            mTextPaint.setAlpha(alpha);
             c.drawText(mSectionName, (mBgBounds.width() - mTextBounds.width()) / 2,
-                    mBgBounds.height() - (mBgBounds.height() - mTextBounds.height()) / 2,
+                    mBgBounds.height() - (mBgBounds.height() / 2) - mTextBounds.exactCenterY(),
                     mTextPaint);
             c.restoreToCount(restoreCount);
         }
diff --git a/src/com/android/launcher3/HolographicOutlineHelper.java b/src/com/android/launcher3/HolographicOutlineHelper.java
index 6ea06e9..1cff8ef 100644
--- a/src/com/android/launcher3/HolographicOutlineHelper.java
+++ b/src/com/android/launcher3/HolographicOutlineHelper.java
@@ -83,6 +83,7 @@
             int outlineColor) {
         applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, true);
     }
+
     void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
             int outlineColor, boolean clipAlpha) {
 
@@ -151,33 +152,44 @@
     }
 
     Bitmap createMediumDropShadow(BubbleTextView view) {
-        Drawable icon = view.getIcon();
-        if (icon == null) {
+        return createMediumDropShadow(view.getIcon(), view.getScaleX(), view.getScaleY(), true);
+    }
+
+    Bitmap createMediumDropShadow(Drawable drawable, boolean shouldCache) {
+        return createMediumDropShadow(drawable, 1f, 1f, shouldCache);
+    }
+
+    Bitmap createMediumDropShadow(Drawable drawable, float scaleX, float scaleY,
+                boolean shouldCache) {
+        if (drawable == null) {
             return null;
         }
-        Rect rect = icon.getBounds();
+        Rect rect = drawable.getBounds();
 
-        int bitmapWidth = (int) (rect.width() * view.getScaleX());
-        int bitmapHeight = (int) (rect.height() * view.getScaleY());
+        int bitmapWidth = (int) (rect.width() * scaleX);
+        int bitmapHeight = (int) (rect.height() * scaleY);
         if (bitmapHeight <= 0 || bitmapWidth <= 0) {
             return null;
         }
 
         int key = (bitmapWidth << 16) | bitmapHeight;
-        Bitmap cache = mBitmapCache.get(key);
+        Bitmap cache = shouldCache ? mBitmapCache.get(key) : null;
         if (cache == null) {
             cache = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ALPHA_8);
             mCanvas.setBitmap(cache);
-            mBitmapCache.put(key, cache);
+
+            if (shouldCache) {
+                mBitmapCache.put(key, cache);
+            }
         } else {
             mCanvas.setBitmap(cache);
             mCanvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR);
         }
 
         int saveCount = mCanvas.save();
-        mCanvas.scale(view.getScaleX(), view.getScaleY());
+        mCanvas.scale(scaleX, scaleY);
         mCanvas.translate(-rect.left, -rect.top);
-        icon.draw(mCanvas);
+        drawable.draw(mCanvas);
         mCanvas.restoreToCount(saveCount);
         mCanvas.setBitmap(null);
 
@@ -188,7 +200,7 @@
         int resultWidth = bitmapWidth + extraSize;
         int resultHeight = bitmapHeight + extraSize;
         key = (resultWidth << 16) | resultHeight;
-        Bitmap result = mBitmapCache.get(key);
+        Bitmap result = shouldCache ? mBitmapCache.get(key) : null;
         if (result == null) {
             result = Bitmap.createBitmap(resultWidth, resultHeight, Bitmap.Config.ALPHA_8);
             mCanvas.setBitmap(result);