Allow LetterTileProvider to use a defined fontsize

Also refactors the bitmap cropping into a circle from MessageHeaderView into
BitmapUtil and makes NotificationUtils use that method as well.

Bug: 16875798 SetupAddressesActivity: Show letter avatar if none
Bug: 16378212 Draw letter tile for non-Gmail avatars in Account switcher

Change-Id: I375990e3df331ff9952652d5f06a4f4f8d133e48
diff --git a/res/values/dimen.xml b/res/values/dimen.xml
index 8f7909a..791a8ab 100644
--- a/res/values/dimen.xml
+++ b/res/values/dimen.xml
@@ -114,8 +114,9 @@
     <dimen name="widget_margin_bottom">0dip</dimen>
     <dimen name="wait_padding">16dp</dimen>
     <integer name="chips_max_lines">2</integer>
-    <dimen name="tile_letter_font_size">24dp</dimen>
-    <dimen name="tile_letter_font_size_small">16dp</dimen>
+    <dimen name="tile_letter_font_size_tiny">16dp</dimen>
+    <dimen name="tile_letter_font_size_small">24dp</dimen>
+    <dimen name="tile_letter_font_size_medium">40dp</dimen>
     <dimen name="tile_divider_width">1dp</dimen>
     <dimen name="checked_text_padding">16dip</dimen>
     <dimen name="send_mail_as_padding">8dip</dimen>
diff --git a/src/com/android/mail/bitmap/ContactDrawable.java b/src/com/android/mail/bitmap/ContactDrawable.java
index 34983bf..7acb2c9 100644
--- a/src/com/android/mail/bitmap/ContactDrawable.java
+++ b/src/com/android/mail/bitmap/ContactDrawable.java
@@ -96,7 +96,7 @@
         mMatrix = new Matrix();
 
         if (sTileLetterFontSize == 0) {
-            sTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size);
+            sTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size_small);
             sTileFontColor = res.getColor(R.color.letter_tile_font_color);
             DEFAULT_AVATAR = BitmapFactory.decodeResource(res, R.drawable.ic_generic_man);
 
diff --git a/src/com/android/mail/browse/MessageHeaderView.java b/src/com/android/mail/browse/MessageHeaderView.java
index 9c5e486..6570cd2 100644
--- a/src/com/android/mail/browse/MessageHeaderView.java
+++ b/src/com/android/mail/browse/MessageHeaderView.java
@@ -23,11 +23,6 @@
 import android.content.res.Resources;
 import android.database.DataSetObserver;
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
 import android.support.v4.text.BidiFormatter;
 import android.text.Html;
 import android.text.Spannable;
@@ -66,6 +61,7 @@
 import com.android.mail.text.EmailAddressSpan;
 import com.android.mail.ui.AbstractConversationViewFragment;
 import com.android.mail.ui.ImageCanvas;
+import com.android.mail.utils.BitmapUtil;
 import com.android.mail.utils.LogTag;
 import com.android.mail.utils.LogUtils;
 import com.android.mail.utils.StyleUtils;
@@ -861,7 +857,7 @@
             }
 
             if (info.photo != null) {
-                mPhotoView.setImageBitmap(frameBitmapInCircle(info.photo));
+                mPhotoView.setImageBitmap(BitmapUtil.frameBitmapInCircle(info.photo));
                 photoSet = true;
             }
         } else {
@@ -870,14 +866,14 @@
 
         if (!photoSet) {
             mPhotoView.setImageBitmap(
-                    frameBitmapInCircle(makeLetterTile(mSender.getPersonal(), email)));
+                    BitmapUtil.frameBitmapInCircle(makeLetterTile(mSender.getPersonal(), email)));
         }
     }
 
     private Bitmap makeLetterTile(
             String displayName, String senderAddress) {
         if (mLetterTileProvider == null) {
-            mLetterTileProvider = new LetterTileProvider(getContext());
+            mLetterTileProvider = new LetterTileProvider(getContext().getResources());
         }
 
         final ImageCanvas.Dimensions dimensions = new ImageCanvas.Dimensions(
@@ -885,46 +881,6 @@
         return mLetterTileProvider.getLetterTile(dimensions, displayName, senderAddress);
     }
 
-    /**
-     * Frames the input bitmap in a circle.
-     */
-    private static Bitmap frameBitmapInCircle(Bitmap input) {
-        if (input == null) {
-            return null;
-        }
-
-        // Crop the image if not squared.
-        int inputWidth = input.getWidth();
-        int inputHeight = input.getHeight();
-        int targetX, targetY, targetSize;
-        if (inputWidth >= inputHeight) {
-            targetX = inputWidth / 2 - inputHeight / 2;
-            targetY = 0;
-            targetSize = inputHeight;
-        } else {
-            targetX = 0;
-            targetY = inputHeight / 2 - inputWidth / 2;
-            targetSize = inputWidth;
-        }
-
-        // Create an output bitmap and a canvas to draw on it.
-        Bitmap output = Bitmap.createBitmap(targetSize, targetSize, Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(output);
-
-        // Create a black paint to draw the mask.
-        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        paint.setColor(Color.BLACK);
-
-        // Draw a circle.
-        canvas.drawCircle(targetSize / 2, targetSize / 2, targetSize / 2, paint);
-
-        // Replace the black parts of the mask with the input image.
-        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
-        canvas.drawBitmap(input, targetX /* left */, targetY /* top */, paint);
-
-        return output;
-    }
-
     @Override
     public boolean onMenuItemClick(MenuItem item) {
         mPopup.dismiss();
diff --git a/src/com/android/mail/photomanager/LetterTileProvider.java b/src/com/android/mail/photomanager/LetterTileProvider.java
index ca70e72..3aaf7b1 100644
--- a/src/com/android/mail/photomanager/LetterTileProvider.java
+++ b/src/com/android/mail/photomanager/LetterTileProvider.java
@@ -16,9 +16,7 @@
 
 package com.android.mail.photomanager;
 
-import android.content.Context;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
@@ -59,13 +57,15 @@
     private final char[] mFirstChar = new char[1];
 
     private static final int POSSIBLE_BITMAP_SIZES = 3;
-    private ColorPicker sTileColorPicker;
+    private final ColorPicker mTileColorPicker;
 
-    public LetterTileProvider(Context context) {
-        final Resources res = context.getResources();
-        mTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size);
-        mTileLetterFontSizeSmall = res
-                .getDimensionPixelSize(R.dimen.tile_letter_font_size_small);
+    public LetterTileProvider(Resources res) {
+        this(res, new ColorPicker.PaletteColorPicker(res));
+    }
+
+    public LetterTileProvider(Resources res, ColorPicker colorPicker) {
+        mTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size_small);
+        mTileLetterFontSizeSmall = res.getDimensionPixelSize(R.dimen.tile_letter_font_size_tiny);
         mTileFontColor = res.getColor(R.color.letter_tile_font_color);
         mSansSerifLight = Typeface.create("sans-serif-light", Typeface.NORMAL);
         mBounds = new Rect();
@@ -78,9 +78,7 @@
         mDefaultBitmap = BitmapFactory.decodeResource(res, R.drawable.ic_generic_man);
         mDefaultBitmapCache = new Bitmap[POSSIBLE_BITMAP_SIZES];
 
-        if (sTileColorPicker == null) {
-            sTileColorPicker = new ColorPicker.PaletteColorPicker(res);
-        }
+        mTileColorPicker = colorPicker;
     }
 
     public Bitmap getLetterTile(final Dimensions dimensions, final String displayName,
@@ -98,13 +96,14 @@
 
         final Canvas c = mCanvas;
         c.setBitmap(bitmap);
-        c.drawColor(sTileColorPicker.pickColor(address));
+        c.drawColor(mTileColorPicker.pickColor(address));
 
         // If its a valid English alphabet letter,
         // draw the letter on top of the color
         if (isEnglishLetterOrDigit(firstChar)) {
             mFirstChar[0] = Character.toUpperCase(firstChar);
-            mPaint.setTextSize(getFontSize(dimensions.scale));
+            mPaint.setTextSize(
+                    dimensions.fontSize > 0 ? dimensions.fontSize : getFontSize(dimensions.scale));
             mPaint.getTextBounds(mFirstChar, 0, 1, mBounds);
             c.drawText(mFirstChar, 0, 1, 0 + dimensions.width / 2,
                     0 + dimensions.height / 2 + (mBounds.bottom - mBounds.top) / 2, mPaint);
diff --git a/src/com/android/mail/ui/ImageCanvas.java b/src/com/android/mail/ui/ImageCanvas.java
index 9fdf0ae..b19b3e8 100644
--- a/src/com/android/mail/ui/ImageCanvas.java
+++ b/src/com/android/mail/ui/ImageCanvas.java
@@ -31,6 +31,7 @@
         public int width;
         public int height;
         public float scale;
+        public float fontSize;
 
         public static final float SCALE_ONE = 1.0f;
         public static final float SCALE_HALF = 0.5f;
@@ -40,9 +41,14 @@
         }
 
         public Dimensions(int w, int h, float s) {
-            width = w;
-            height = h;
-            scale = s;
+            this(w, h, s, -1f);
+        }
+
+        public Dimensions(int width, int height, float scale, float fontSize) {
+            this.width = width;
+            this.height = height;
+            this.scale = scale;
+            this.fontSize = fontSize;
         }
 
         @Override
diff --git a/src/com/android/mail/utils/BitmapUtil.java b/src/com/android/mail/utils/BitmapUtil.java
index 6f61f56..7cde938 100644
--- a/src/com/android/mail/utils/BitmapUtil.java
+++ b/src/com/android/mail/utils/BitmapUtil.java
@@ -17,7 +17,12 @@
 package com.android.mail.utils;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 
 /**
  * Provides static functions to decode bitmaps at the optimal size
@@ -172,4 +177,43 @@
         return cropped;
     }
 
+    /**
+     * Frames the input bitmap in a circle.
+     */
+    public static Bitmap frameBitmapInCircle(Bitmap input) {
+        if (input == null) {
+            return null;
+        }
+
+        // Crop the image if not squared.
+        int inputWidth = input.getWidth();
+        int inputHeight = input.getHeight();
+        int targetX, targetY, targetSize;
+        if (inputWidth >= inputHeight) {
+            targetX = inputWidth / 2 - inputHeight / 2;
+            targetY = 0;
+            targetSize = inputHeight;
+        } else {
+            targetX = 0;
+            targetY = inputHeight / 2 - inputWidth / 2;
+            targetSize = inputWidth;
+        }
+
+        // Create an output bitmap and a canvas to draw on it.
+        Bitmap output = Bitmap.createBitmap(targetSize, targetSize, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(output);
+
+        // Create a black paint to draw the mask.
+        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        paint.setColor(Color.BLACK);
+
+        // Draw a circle.
+        canvas.drawCircle(targetSize / 2, targetSize / 2, targetSize / 2, paint);
+
+        // Replace the black parts of the mask with the input image.
+        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+        canvas.drawBitmap(input, targetX /* left */, targetY /* top */, paint);
+
+        return output;
+    }
 }
diff --git a/src/com/android/mail/utils/NotificationUtils.java b/src/com/android/mail/utils/NotificationUtils.java
index 58bf0ac..0b19005 100644
--- a/src/com/android/mail/utils/NotificationUtils.java
+++ b/src/com/android/mail/utils/NotificationUtils.java
@@ -26,11 +26,6 @@
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Looper;
 import android.provider.ContactsContract;
@@ -1693,13 +1688,13 @@
                 final Dimensions dimensions = new Dimensions(idealIconWidth, idealIconHeight,
                         Dimensions.SCALE_ONE);
 
-                contactIconInfo.icon = new LetterTileProvider(context).getLetterTile(dimensions,
-                        displayName, senderAddress);
+                contactIconInfo.icon = new LetterTileProvider(context.getResources())
+                        .getLetterTile(dimensions, displayName, senderAddress);
             }
 
             // Only turn the square photo/letter tile into a circle for L and later
             if (Utils.isRunningLOrLater()) {
-                contactIconInfo.icon = cropSquareIconToCircle(contactIconInfo.icon);
+                contactIconInfo.icon = BitmapUtil.frameBitmapInCircle(contactIconInfo.icon);
             }
         }
 
@@ -1787,28 +1782,6 @@
         return contactIconInfo;
     }
 
-    /**
-     * Crop a square bitmap into a circular one. Used for both contact photos and letter tiles.
-     * @param icon Square bitmap to crop
-     * @return Circular bitmap
-     */
-    private static Bitmap cropSquareIconToCircle(Bitmap icon) {
-        final int iconWidth = icon.getWidth();
-        final Bitmap newIcon = Bitmap.createBitmap(iconWidth, iconWidth, Bitmap.Config.ARGB_8888);
-        final Canvas canvas = new Canvas(newIcon);
-        final Paint paint = new Paint();
-        final Rect rect = new Rect(0, 0, icon.getWidth(),
-                icon.getHeight());
-
-        paint.setAntiAlias(true);
-        canvas.drawARGB(0, 0, 0, 0);
-        canvas.drawCircle(iconWidth/2, iconWidth/2, iconWidth/2, paint);
-        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
-        canvas.drawBitmap(icon, rect, rect, paint);
-
-        return newIcon;
-    }
-
     private static String getMessageBodyWithoutElidedText(final Message message) {
         return getMessageBodyWithoutElidedText(message.getBodyAsHtml());
     }