IconCompat.java revision 801ca190c6df56bdf67ebd0a320ab5912640db10
1801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal/* 2801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Copyright (C) 2017 The Android Open Source Project 3801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * 4801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Licensed under the Apache License, Version 2.0 (the "License"); 5801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * you may not use this file except in compliance with the License. 6801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * You may obtain a copy of the License at 7801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * 8801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * http://www.apache.org/licenses/LICENSE-2.0 9801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * 10801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Unless required by applicable law or agreed to in writing, software 11801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * distributed under the License is distributed on an "AS IS" BASIS, 12801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * See the License for the specific language governing permissions and 14801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * limitations under the License. 15801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 16801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 17801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalpackage android.support.v4.graphics.drawable; 18801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 19801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; 20801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 21801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.annotation.TargetApi; 22801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.content.Context; 23801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.content.Intent; 24801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Bitmap; 25801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.BitmapShader; 26801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Canvas; 27801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Color; 28801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Matrix; 29801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Paint; 30801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Shader; 31801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.drawable.Icon; 32801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.net.Uri; 33801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.os.Build; 34801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.support.annotation.DrawableRes; 35801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.support.annotation.RestrictTo; 36801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.support.annotation.VisibleForTesting; 37801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.support.v4.os.BuildCompat; 38801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 39801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal/** 40801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Helper for accessing features in {@link android.graphics.drawable.Icon} 41801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * introduced after API level 4 in a backwards compatible fashion. 42801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 43801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalpublic class IconCompat { 44801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 45801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // Ratio of expected size to actual icon size 46801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final float ADAPTIVE_ICON_INSET_FACTOR = 1 / 4f; 47801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final float DEFAULT_VIEW_PORT_SCALE = 1 / (1 + 2 * ADAPTIVE_ICON_INSET_FACTOR); 48801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final float ICON_DIAMETER_FACTOR = 176f / 192; 49801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final float BLUR_FACTOR = 0.5f / 48; 50801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final float KEY_SHADOW_OFFSET_FACTOR = 1f / 48; 51801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 52801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int KEY_SHADOW_ALPHA = 61; 53801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int AMBIENT_SHADOW_ALPHA = 30; 54801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 55801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int TYPE_BITMAP = 1; 56801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int TYPE_RESOURCE = 2; 57801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int TYPE_DATA = 3; 58801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int TYPE_URI = 4; 59801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int TYPE_ADAPTIVE_BITMAP = 5; 60801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 61801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private final int mType; 62801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 63801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // To avoid adding unnecessary overhead, we have a few basic objects that get repurposed 64801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // based on the value of mType. 65801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 66801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_BITMAP: Bitmap 67801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_ADAPTIVE_BITMAP: Bitmap 68801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_RESOURCE: Context 69801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_URI: String 70801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_DATA: DataBytes 71801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private Object mObj1; 72801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 73801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_RESOURCE: resId 74801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_DATA: data offset 75801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private int mInt1; 76801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 77801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_DATA: data length 78801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private int mInt2; 79801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 80801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 81801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to a drawable resource. 82801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param context The context for the application whose resources should be used to resolve the 83801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * given resource ID. 84801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param resId ID of the drawable resource 85801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithResource(Context, int) 86801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 87801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithResource(Context context, @DrawableRes int resId) { 88801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (context == null) { 89801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Context must not be null."); 90801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 91801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal final IconCompat rep = new IconCompat(TYPE_RESOURCE); 92801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mInt1 = resId; 93801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mObj1 = context; 94801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return rep; 95801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 96801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 97801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 98801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to a bitmap in memory. 99801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param bits A valid {@link android.graphics.Bitmap} object 100801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithBitmap(Bitmap) 101801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 102801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithBitmap(Bitmap bits) { 103801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (bits == null) { 104801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Bitmap must not be null."); 105801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 106801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal final IconCompat rep = new IconCompat(TYPE_BITMAP); 107801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mObj1 = bits; 108801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return rep; 109801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 110801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 111801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 112801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to a bitmap in memory that follows the icon design guideline defined 113801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * by {@link android.graphics.drawable.AdaptiveIconDrawable}. 114801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param bits A valid {@link android.graphics.Bitmap} object 115801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithAdaptiveBitmap(Bitmap) 116801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 117801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithAdaptiveBitmap(Bitmap bits) { 118801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (bits == null) { 119801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Bitmap must not be null."); 120801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 121801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal final IconCompat rep = new IconCompat(TYPE_ADAPTIVE_BITMAP); 122801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mObj1 = bits; 123801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return rep; 124801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 125801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 126801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 127801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to a compressed bitmap stored in a byte array. 128801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param data Byte array storing compressed bitmap data of a type that 129801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * {@link android.graphics.BitmapFactory} 130801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * can decode (see {@link android.graphics.Bitmap.CompressFormat}). 131801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param offset Offset into <code>data</code> at which the bitmap data starts 132801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param length Length of the bitmap data 133801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithData(byte[], int, int) 134801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 135801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithData(byte[] data, int offset, int length) { 136801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (data == null) { 137801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Data must not be null."); 138801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 139801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal final IconCompat rep = new IconCompat(TYPE_DATA); 140801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mObj1 = data; 141801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mInt1 = offset; 142801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mInt2 = length; 143801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return rep; 144801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 145801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 146801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 147801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to an image file specified by URI. 148801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * 149801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param uri A uri referring to local content:// or file:// image data. 150801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithContentUri(String) 151801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 152801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithContentUri(String uri) { 153801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (uri == null) { 154801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Uri must not be null."); 155801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 156801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal final IconCompat rep = new IconCompat(TYPE_URI); 157801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mObj1 = uri; 158801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return rep; 159801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 160801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 161801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 162801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to an image file specified by URI. 163801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * 164801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param uri A uri referring to local content:// or file:// image data. 165801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithContentUri(String) 166801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 167801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithContentUri(Uri uri) { 168801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (uri == null) { 169801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Uri must not be null."); 170801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 171801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return createWithContentUri(uri.toString()); 172801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 173801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 174801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private IconCompat(int mType) { 175801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal this.mType = mType; 176801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 177801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 178801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 179801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @hide 180801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 181801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal @VisibleForTesting 182801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal @RestrictTo(LIBRARY_GROUP) 183801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal @TargetApi(Build.VERSION_CODES.O) 184801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public Icon toIcon() { 185801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal switch (mType) { 186801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_BITMAP: 187801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithBitmap((Bitmap) mObj1); 188801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_ADAPTIVE_BITMAP: 189801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (BuildCompat.isAtLeastO()) { 190801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithAdaptiveBitmap((Bitmap) mObj1); 191801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } else { 192801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithBitmap(createLegacyIconFromAdaptiveIcon((Bitmap) mObj1)); 193801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 194801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_RESOURCE: 195801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithResource((Context) mObj1, mInt1); 196801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_DATA: 197801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithData((byte[]) mObj1, mInt1, mInt2); 198801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_URI: 199801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithContentUri((String) mObj1); 200801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal default: 201801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Unknown type"); 202801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 203801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 204801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 205801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 206801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @hide 207801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 208801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal @RestrictTo(LIBRARY_GROUP) 209801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public void addToShortcutIntent(Intent outIntent) { 210801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal switch (mType) { 211801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_BITMAP: 212801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal outIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, (Bitmap) mObj1); 213801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal break; 214801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_ADAPTIVE_BITMAP: 215801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal outIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, 216801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal createLegacyIconFromAdaptiveIcon((Bitmap) mObj1)); 217801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal break; 218801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_RESOURCE: 219801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal outIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, 220801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Intent.ShortcutIconResource.fromContext((Context) mObj1, mInt1)); 221801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal break; 222801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal default: 223801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Icon type not supported for intent shortcuts"); 224801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 225801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 226801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 227801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 228801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Converts a bitmap following the adaptive icon guide lines, into a bitmap following the 229801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * shortcut icon guide lines. 230801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * The returned bitmap will always have same width and height and clipped to a circle. 231801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 232801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal @VisibleForTesting 233801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal static Bitmap createLegacyIconFromAdaptiveIcon(Bitmap adaptiveIconBitmap) { 234801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal int size = (int) (DEFAULT_VIEW_PORT_SCALE * Math.min(adaptiveIconBitmap.getWidth(), 235801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal adaptiveIconBitmap.getHeight())); 236801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 237801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Bitmap icon = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); 238801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Canvas canvas = new Canvas(icon); 239801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); 240801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 241801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal float center = size * 0.5f; 242801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal float radius = center * ICON_DIAMETER_FACTOR; 243801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 244801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // Draw key shadow 245801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal float blur = BLUR_FACTOR * size; 246801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.setColor(Color.TRANSPARENT); 247801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.setShadowLayer(blur, 0, KEY_SHADOW_OFFSET_FACTOR * size, KEY_SHADOW_ALPHA << 24); 248801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal canvas.drawCircle(center, center, radius, paint); 249801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 250801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // Draw ambient shadow 251801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.setShadowLayer(blur, 0, 0, AMBIENT_SHADOW_ALPHA << 24); 252801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal canvas.drawCircle(center, center, radius, paint); 253801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.clearShadowLayer(); 254801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 255801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // Draw the clipped icon 256801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.setColor(Color.BLACK); 257801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal BitmapShader shader = new BitmapShader(adaptiveIconBitmap, Shader.TileMode.CLAMP, 258801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Shader.TileMode.CLAMP); 259801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Matrix shift = new Matrix(); 260801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal shift.setTranslate(-(adaptiveIconBitmap.getWidth() - size) / 2, 261801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal -(adaptiveIconBitmap.getHeight() - size) / 2); 262801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal shader.setLocalMatrix(shift); 263801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.setShader(shader); 264801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal canvas.drawCircle(center, center, radius, paint); 265801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 266801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal canvas.setBitmap(null); 267801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return icon; 268801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 269801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal} 270