Fix adaptive shortcut icons am: 02c3dee53a
Change-Id: I1d878c123665f0a560b2ece45098b4082df1896b
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()));
+ }
}