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;
}
}