Use Icon.createWithAdaptiveBitmap on >= O

Add padding around the bitmaps so the icons still look right.

Test: Manually verified shortcuts created on:
L, M, N, and O all look correct
O was tested on a Pixel.

Bug: 36405262
Change-Id: Ie14209357b91a866225a315d1c3355bc228c8dff
diff --git a/src/com/android/contacts/DynamicShortcuts.java b/src/com/android/contacts/DynamicShortcuts.java
index 63df713..98e725f 100644
--- a/src/com/android/contacts/DynamicShortcuts.java
+++ b/src/com/android/contacts/DynamicShortcuts.java
@@ -35,6 +35,7 @@
 import android.graphics.BitmapRegionDecoder;
 import android.graphics.Canvas;
 import android.graphics.Rect;
+import android.graphics.drawable.AdaptiveIconDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
@@ -45,6 +46,7 @@
 import android.provider.ContactsContract.Contacts;
 import android.support.annotation.VisibleForTesting;
 import android.support.v4.content.LocalBroadcastManager;
+import android.support.v4.os.BuildCompat;
 import android.util.Log;
 
 import com.android.contacts.activities.RequestPermissionsActivity;
@@ -329,9 +331,12 @@
         if (bitmap == null) {
             bitmap = getFallbackAvatar(displayName, lookupKey);
         }
-        // TODO: Use createWithAdaptiveBitmap if >= O. Since we create these, we'll also need to
-        // return AdaptiveIconDrawables when >= O as well.
-        final Icon icon = Icon.createWithBitmap(bitmap);
+        final Icon icon;
+        if (BuildCompat.isAtLeastO()) {
+            icon = Icon.createWithAdaptiveBitmap(bitmap);
+        } else {
+            icon = Icon.createWithBitmap(bitmap);
+        }
 
         builder.setIcon(icon);
     }
@@ -364,7 +369,7 @@
         final int sourceWidth = bitmapDecoder.getWidth();
         final int sourceHeight = bitmapDecoder.getHeight();
 
-        final int iconMaxWidth = mShortcutManager.getIconMaxWidth();;
+        final int iconMaxWidth = mShortcutManager.getIconMaxWidth();
         final int iconMaxHeight = mShortcutManager.getIconMaxHeight();
 
         final int sampleSize = Math.min(
@@ -393,25 +398,52 @@
                 prescaledXOffset, prescaledYOffset,
                 sourceWidth - prescaledXOffset, sourceHeight - prescaledYOffset
         ), opts);
-
         bitmapDecoder.recycle();
 
-        return BitmapUtil.getRoundedBitmap(bitmap, targetSize, targetSize);
+        if (!BuildCompat.isAtLeastO()) {
+            return BitmapUtil.getRoundedBitmap(bitmap, targetSize, targetSize);
+        }
+
+        // If on O or higher, add padding around the bitmap.
+        final int paddingW = (int) (bitmap.getWidth() *
+                AdaptiveIconDrawable.getExtraInsetPercentage());
+        final int paddingH = (int) (bitmap.getHeight() *
+                AdaptiveIconDrawable.getExtraInsetPercentage());
+
+        final Bitmap scaledBitmap = Bitmap.createBitmap(bitmap.getWidth() + paddingW,
+                bitmap.getHeight() + paddingH, bitmap.getConfig());
+
+        final Canvas scaledCanvas = new Canvas(scaledBitmap);
+        scaledCanvas.drawBitmap(bitmap, paddingW / 2, paddingH / 2, null);
+
+        return scaledBitmap;
     }
 
     private Bitmap getFallbackAvatar(String displayName, String lookupKey) {
-        final int w = RECOMMENDED_ICON_PIXEL_LENGTH;
-        final int h = RECOMMENDED_ICON_PIXEL_LENGTH;
+        final int width;
+        final int height;
+        final int padding;
+        if (BuildCompat.isAtLeastO()) {
+            // Add padding on >= O
+            padding = (int) (RECOMMENDED_ICON_PIXEL_LENGTH *
+                    AdaptiveIconDrawable.getExtraInsetPercentage());
+            width = RECOMMENDED_ICON_PIXEL_LENGTH + padding;
+            height = RECOMMENDED_ICON_PIXEL_LENGTH + padding;
+        } else {
+            padding = 0;
+            width = RECOMMENDED_ICON_PIXEL_LENGTH;
+            height = RECOMMENDED_ICON_PIXEL_LENGTH;
+        }
 
         final ContactPhotoManager.DefaultImageRequest request =
                 new ContactPhotoManager.DefaultImageRequest(displayName, lookupKey, true);
         final Drawable avatar = ContactPhotoManager.getDefaultAvatarDrawableForContact(
                 mContext.getResources(), true, request);
-        final Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+        final Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
         // The avatar won't draw unless it thinks it is visible
         avatar.setVisible(true, true);
         final Canvas canvas = new Canvas(result);
-        avatar.setBounds(0, 0, w, h);
+        avatar.setBounds(padding, padding, width - padding, height - padding);
         avatar.draw(canvas);
         return result;
     }
diff --git a/src/com/android/contacts/ShortcutIntentBuilder.java b/src/com/android/contacts/ShortcutIntentBuilder.java
index 03e9a93..76ef08f 100644
--- a/src/com/android/contacts/ShortcutIntentBuilder.java
+++ b/src/com/android/contacts/ShortcutIntentBuilder.java
@@ -30,6 +30,7 @@
 import android.graphics.Paint;
 import android.graphics.Paint.FontMetricsInt;
 import android.graphics.Rect;
+import android.graphics.drawable.AdaptiveIconDrawable;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
@@ -329,10 +330,8 @@
                     mContext.getSystemService(Context.SHORTCUT_SERVICE);
             final String id = shortcutAction + lookupKey;
             final DynamicShortcuts dynamicShortcuts = new DynamicShortcuts(mContext);
-            // TODO: Use createWithAdaptiveBitmap if >= O. Since we create these, we'll also need to
-            // return AdaptiveIconDrawables when >= O as well.
             final ShortcutInfo shortcutInfo = dynamicShortcuts.getActionShortcutInfo(
-                    id, displayName, shortcutIntent, Icon.createWithBitmap(icon));
+                    id, displayName, shortcutIntent, Icon.createWithAdaptiveBitmap(icon));
             intent = sm.createShortcutResultIntent(shortcutInfo);
         }
 
@@ -421,14 +420,23 @@
         }
 
         // Draw the phone action icon as an overlay
-        Rect src = new Rect(0, 0, phoneIcon.getWidth(), phoneIcon.getHeight());
         int iconWidth = icon.getWidth();
         dst.set(iconWidth - ((int) (20 * density)), -1,
                 iconWidth, ((int) (19 * density)));
-        canvas.drawBitmap(phoneIcon, src, dst, photoPaint);
+        canvas.drawBitmap(phoneIcon, null, dst, photoPaint);
 
         canvas.setBitmap(null);
+        if (!BuildCompat.isAtLeastO()) {
+            return icon;
+        }
 
-        return icon;
+        // On >= O scale image up by AdaptiveIconDrawable.DEFAULT_VIEW_PORT_SCALE.
+        final int scale = (int) (icon.getHeight() *
+                (1f / (1 + 2 * AdaptiveIconDrawable.getExtraInsetPercentage())));
+        final Bitmap scaledBitmap = Bitmap.createBitmap(icon.getWidth() + scale,
+                icon.getHeight() + scale, icon.getConfig());
+        Canvas scaledCanvas = new Canvas(scaledBitmap);
+        scaledCanvas.drawBitmap(icon, scale / 2, scale / 2, null);
+        return scaledBitmap;
     }
 }