Loading src/com/android/contacts/DynamicShortcuts.java +42 −10 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.graphics.BitmapFactory; 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; Loading @@ -45,6 +46,7 @@ import android.provider.ContactsContract; 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; Loading Loading @@ -329,9 +331,12 @@ public class DynamicShortcuts { 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); } Loading Loading @@ -364,7 +369,7 @@ public class DynamicShortcuts { 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( Loading Loading @@ -393,25 +398,52 @@ public class DynamicShortcuts { prescaledXOffset, prescaledYOffset, sourceWidth - prescaledXOffset, sourceHeight - prescaledYOffset ), opts); bitmapDecoder.recycle(); 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; } Loading src/com/android/contacts/ShortcutIntentBuilder.java +14 −6 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.graphics.Canvas; 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; Loading Loading @@ -329,10 +330,8 @@ public class ShortcutIntentBuilder { 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); } Loading Loading @@ -421,14 +420,23 @@ public class ShortcutIntentBuilder { } // 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; } // 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; } } Loading
src/com/android/contacts/DynamicShortcuts.java +42 −10 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.graphics.BitmapFactory; 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; Loading @@ -45,6 +46,7 @@ import android.provider.ContactsContract; 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; Loading Loading @@ -329,9 +331,12 @@ public class DynamicShortcuts { 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); } Loading Loading @@ -364,7 +369,7 @@ public class DynamicShortcuts { 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( Loading Loading @@ -393,25 +398,52 @@ public class DynamicShortcuts { prescaledXOffset, prescaledYOffset, sourceWidth - prescaledXOffset, sourceHeight - prescaledYOffset ), opts); bitmapDecoder.recycle(); 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; } Loading
src/com/android/contacts/ShortcutIntentBuilder.java +14 −6 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.graphics.Canvas; 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; Loading Loading @@ -329,10 +330,8 @@ public class ShortcutIntentBuilder { 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); } Loading Loading @@ -421,14 +420,23 @@ public class ShortcutIntentBuilder { } // 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; } // 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; } }