Fix adaptive shortcut icons am: 02c3dee53a am: edfce60617

Change-Id: I9b873311091199215971dd83bf58b1a9b9a9ef7a
diff --git a/res/drawable-anydpi-v26/ic_add_contact_shortcut.xml b/res/drawable-anydpi-v26/ic_add_contact_shortcut.xml
new file mode 100644
index 0000000..fbd7a09
--- /dev/null
+++ b/res/drawable-anydpi-v26/ic_add_contact_shortcut.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@color/ic_add_contact_shortcut_background"/>
+    <foreground android:drawable="@drawable/ic_add_circle_24dp"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/res/drawable/ic_add_circle_24dp.xml b/res/drawable/ic_add_circle_24dp.xml
index ae37470..ebaab34 100644
--- a/res/drawable/ic_add_circle_24dp.xml
+++ b/res/drawable/ic_add_circle_24dp.xml
@@ -20,7 +20,7 @@
         android:width="24dp"
         android:viewportHeight="192.0"
         android:viewportWidth="192.0">
-  <path android:fillColor="#F5F5F5"
+  <path android:fillColor="@color/ic_add_contact_shortcut_background"
         android:pathData="M96,8C47.38,8 8,47.38 8,96s39.38,88 88,88s88,-39.38 88,-88S144.62,8 96,8z"/>
   <path android:fillColor="#039BE5"
         android:pathData="M124,100h-24v24h-8v-24H68v-8h24V68h8v24h24V100z"/>
diff --git a/res/drawable/ic_add_contact_shortcut.xml b/res/drawable/ic_add_contact_shortcut.xml
new file mode 100644
index 0000000..85a7e61
--- /dev/null
+++ b/res/drawable/ic_add_contact_shortcut.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<!-- A copy of ic_add_circle_24dp for use in pre O devices. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportHeight="192.0"
+    android:viewportWidth="192.0">
+    <path android:fillColor="@color/ic_add_contact_shortcut_background"
+        android:pathData="M96,8C47.38,8 8,47.38 8,96s39.38,88 88,88s88,-39.38 88,-88S144.62,8 96,8z"/>
+    <path android:fillColor="#039BE5"
+        android:pathData="M124,100h-24v24h-8v-24H68v-8h24V68h8v24h24V100z"/>
+</vector>
diff --git a/res/values-v26/dimens.xml b/res/values-v26/dimens.xml
new file mode 100644
index 0000000..b5737f2
--- /dev/null
+++ b/res/values-v26/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<resources>
+    <!-- On Android O, shortcut icons will be 108dp unmasked.
+         See go/o-icons-eng for more details. -->
+    <dimen name="shortcut_icon_size">108dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 1aa84c6..e311ff3 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -16,6 +16,7 @@
 <resources>
     <!-- Adaptive icon background layer color -->
     <color name="ic_contacts_launcher_background">#2458CA</color>
+    <color name="ic_add_contact_shortcut_background">#F5F5F5</color>
 
     <!-- 87% black -->
     <color name="quantum_black_text">#dd000000</color>
diff --git a/res/xml/shortcuts.xml b/res/xml/shortcuts.xml
index c33893a..7ce90e6 100644
--- a/res/xml/shortcuts.xml
+++ b/res/xml/shortcuts.xml
@@ -17,7 +17,7 @@
 <shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
     <shortcut
         android:enabled="true"
-        android:icon="@drawable/ic_add_circle_24dp"
+        android:icon="@drawable/ic_add_contact_shortcut"
         android:shortcutId="shortcut-add-contact"
         android:shortcutShortLabel="@string/shortcut_add_contact">
         <intent
diff --git a/src/com/android/contacts/DynamicShortcuts.java b/src/com/android/contacts/DynamicShortcuts.java
index e287e4a..fc0d05a 100644
--- a/src/com/android/contacts/DynamicShortcuts.java
+++ b/src/com/android/contacts/DynamicShortcuts.java
@@ -16,6 +16,7 @@
 package com.android.contacts;
 
 import android.annotation.TargetApi;
+import android.app.ActivityManager;
 import android.app.job.JobInfo;
 import android.app.job.JobParameters;
 import android.app.job.JobScheduler;
@@ -51,6 +52,7 @@
 
 import com.android.contacts.activities.RequestPermissionsActivity;
 import com.android.contacts.compat.CompatUtils;
+import com.android.contacts.lettertiles.LetterTileDrawable;
 import com.android.contacts.util.BitmapUtil;
 import com.android.contacts.util.ImplicitIntentsUtil;
 import com.android.contacts.util.PermissionsUtil;
@@ -95,21 +97,18 @@
     private static final int SHORTCUT_TYPE_CONTACT_URI = 1;
     private static final int SHORTCUT_TYPE_ACTION_URI = 2;
 
-    // The spec specifies that it should be 44dp @ xxxhdpi
-    // Note that ShortcutManager.getIconMaxWidth and ShortcutManager.getMaxHeight return different
-    // (larger) values.
-    private static final int RECOMMENDED_ICON_PIXEL_LENGTH = 176;
-
     @VisibleForTesting
     static final String[] PROJECTION = new String[] {
             Contacts._ID, Contacts.LOOKUP_KEY, Contacts.DISPLAY_NAME_PRIMARY
     };
 
     private final Context mContext;
+
     private final ContentResolver mContentResolver;
     private final ShortcutManager mShortcutManager;
     private int mShortLabelMaxLength = SHORT_LABEL_MAX_LENGTH;
     private int mLongLabelMaxLength = LONG_LABEL_MAX_LENGTH;
+    private int mIconSize;
     private final int mContentChangeMinUpdateDelay;
     private final int mContentChangeMaxUpdateDelay;
     private final JobScheduler mJobScheduler;
@@ -131,6 +130,12 @@
                 .getInteger(Experiments.DYNAMIC_MIN_CONTENT_CHANGE_UPDATE_DELAY_MILLIS);
         mContentChangeMaxUpdateDelay = Flags.getInstance()
                 .getInteger(Experiments.DYNAMIC_MAX_CONTENT_CHANGE_UPDATE_DELAY_MILLIS);
+        final ActivityManager am = (ActivityManager) context
+                .getSystemService(Context.ACTIVITY_SERVICE);
+        mIconSize = context.getResources().getDimensionPixelSize(R.dimen.shortcut_icon_size);
+        if (mIconSize == 0) {
+            mIconSize = am.getLauncherLargeIconSize();
+        }
     }
 
     @VisibleForTesting
@@ -373,10 +378,8 @@
         final int iconMaxHeight = mShortcutManager.getIconMaxHeight();
 
         final int sampleSize = Math.min(
-                BitmapUtil.findOptimalSampleSize(sourceWidth,
-                        RECOMMENDED_ICON_PIXEL_LENGTH),
-                BitmapUtil.findOptimalSampleSize(sourceHeight,
-                        RECOMMENDED_ICON_PIXEL_LENGTH));
+                BitmapUtil.findOptimalSampleSize(sourceWidth, mIconSize),
+                BitmapUtil.findOptimalSampleSize(sourceHeight, mIconSize));
         final BitmapFactory.Options opts = new BitmapFactory.Options();
         opts.inSampleSize = sampleSize;
 
@@ -404,46 +407,26 @@
             return BitmapUtil.getRoundedBitmap(bitmap, targetSize, targetSize);
         }
 
-        // If on O or higher, add padding around the bitmap.
-        final int paddingW = (int) (bitmap.getWidth() *
-                AdaptiveIconDrawable.getExtraInsetFraction());
-        final int paddingH = (int) (bitmap.getHeight() *
-                AdaptiveIconDrawable.getExtraInsetFraction());
-
-        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;
+        return bitmap;
     }
 
     private Bitmap getFallbackAvatar(String displayName, String lookupKey) {
-        final int width;
-        final int height;
-        final int padding;
-        if (BuildCompat.isAtLeastO()) {
-            // Add padding on >= O
-            padding = (int) (RECOMMENDED_ICON_PIXEL_LENGTH *
-                    AdaptiveIconDrawable.getExtraInsetFraction());
-            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;
-        }
+        // Use a circular icon if we're not on O or higher.
+        final boolean circularIcon = !BuildCompat.isAtLeastO();
 
         final ContactPhotoManager.DefaultImageRequest request =
-                new ContactPhotoManager.DefaultImageRequest(displayName, lookupKey, true);
+                new ContactPhotoManager.DefaultImageRequest(displayName, lookupKey, circularIcon);
+        if (BuildCompat.isAtLeastO()) {
+            // On O, scale the image down to add the padding needed by AdaptiveIcons.
+            request.scale = LetterTileDrawable.getAdaptiveIconScale();
+        }
         final Drawable avatar = ContactPhotoManager.getDefaultAvatarDrawableForContact(
                 mContext.getResources(), true, request);
-        final Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        final Bitmap result = Bitmap.createBitmap(mIconSize, mIconSize, 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(padding, padding, width - padding, height - padding);
+        avatar.setBounds(0, 0, mIconSize, mIconSize);
         avatar.draw(canvas);
         return result;
     }
diff --git a/src/com/android/contacts/ShortcutIntentBuilder.java b/src/com/android/contacts/ShortcutIntentBuilder.java
index 3a0b36b..0a4bb67 100644
--- a/src/com/android/contacts/ShortcutIntentBuilder.java
+++ b/src/com/android/contacts/ShortcutIntentBuilder.java
@@ -49,6 +49,7 @@
 import android.text.TextUtils.TruncateAt;
 
 import com.android.contacts.ContactPhotoManager.DefaultImageRequest;
+import com.android.contacts.lettertiles.LetterTileDrawable;
 import com.android.contacts.util.BitmapUtil;
 import com.android.contacts.util.ImplicitIntentsUtil;
 
@@ -260,8 +261,14 @@
             Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length, null);
             return new BitmapDrawable(mContext.getResources(), bitmap);
         } else {
+            final DefaultImageRequest request = new DefaultImageRequest(displayName, lookupKey,
+                    false);
+            if (BuildCompat.isAtLeastO()) {
+                // On O, scale the image down to add the padding needed by AdaptiveIcons.
+                request.scale = LetterTileDrawable.getAdaptiveIconScale();
+            }
             return ContactPhotoManager.getDefaultAvatarDrawableForContact(mContext.getResources(),
-                    false, new DefaultImageRequest(displayName, lookupKey, false));
+                    false, request);
         }
     }
 
@@ -344,7 +351,6 @@
     }
 
     private Bitmap generateQuickContactIcon(Drawable photo) {
-
         // Setup the drawing classes
         Bitmap bitmap = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ARGB_8888);
         Canvas canvas = new Canvas(bitmap);
@@ -354,6 +360,11 @@
         photo.setBounds(dst);
         photo.draw(canvas);
 
+        // Don't put a rounded border on an icon for O
+        if (BuildCompat.isAtLeastO()) {
+            return bitmap;
+        }
+
         // Draw the icon with a rounded border
         RoundedBitmapDrawable roundedDrawable =
                 RoundedBitmapDrawableFactory.create(mResources, bitmap);
@@ -421,22 +432,24 @@
 
         // Draw the phone action icon as an overlay
         int iconWidth = icon.getWidth();
-        dst.set(iconWidth - ((int) (20 * density)), -1,
-                iconWidth, ((int) (19 * density)));
-        canvas.drawBitmap(phoneIcon, null, dst, photoPaint);
-
-        canvas.setBitmap(null);
-        if (!BuildCompat.isAtLeastO()) {
-            return icon;
+        if (BuildCompat.isAtLeastO()) {
+            // On O we need to calculate where the phone icon goes slightly differently. The whole
+            // canvas area is 108dp, a centered circle with a diameter of 66dp is the "safe zone".
+            // So we start the drawing the phone icon at
+            // 108dp - 21 dp (distance from right edge of safe zone to the edge of the canvas)
+            // - 24 dp (size of the phone icon) on the x axis (left)
+            // The y axis is simply 21dp for the distance to the safe zone (top).
+            // See go/o-icons-eng for more details and a handy picture.
+            final int left = (int) (mIconSize - (45 * density));
+            final int top = (int) (21 * density);
+            canvas.drawBitmap(phoneIcon, left, top, photoPaint);
+        } else {
+            dst.set(iconWidth - ((int) (20 * density)), -1,
+                    iconWidth, ((int) (19 * density)));
+            canvas.drawBitmap(phoneIcon, null, dst, photoPaint);
         }
 
-        // On >= O scale image up by AdaptiveIconDrawable.DEFAULT_VIEW_PORT_SCALE.
-        final int scale = (int) (icon.getHeight() *
-                (1f / (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction())));
-        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;
+        canvas.setBitmap(null);
+        return icon;
     }
 }
diff --git a/src/com/android/contacts/lettertiles/LetterTileDrawable.java b/src/com/android/contacts/lettertiles/LetterTileDrawable.java
index 5652ac6..b80fd4f 100644
--- a/src/com/android/contacts/lettertiles/LetterTileDrawable.java
+++ b/src/com/android/contacts/lettertiles/LetterTileDrawable.java
@@ -26,6 +26,7 @@
 import android.graphics.Paint.Align;
 import android.graphics.Rect;
 import android.graphics.Typeface;
+import android.graphics.drawable.AdaptiveIconDrawable;
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 
@@ -284,4 +285,11 @@
         mIsCircle = isCircle;
         return this;
     }
+
+    /**
+     * Returns the scale percentage as a float for LetterTileDrawables used in AdaptiveIcons.
+     */
+    public static float getAdaptiveIconScale() {
+        return 1 / (1 + (2 * AdaptiveIconDrawable.getExtraInsetFraction()));
+    }
 }