Loading src/com/android/launcher3/ShortcutInfo.java +22 −6 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import android.text.TextUtils; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.compat.LauncherActivityInfoCompat; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.folder.FolderIcon; Loading Loading @@ -295,16 +294,33 @@ public class ShortcutInfo extends ItemInfo { contentDescription = UserManagerCompat.getInstance(context) .getBadgedLabelForUser(label, user); // TODO: Use cache for this LauncherAppState launcherAppState = LauncherAppState.getInstance(); Drawable unbadgedIcon = launcherAppState.getShortcutManager() Drawable unbadgedDrawable = launcherAppState.getShortcutManager() .getShortcutIconDrawable(shortcutInfo, launcherAppState.getInvariantDeviceProfile().fillResIconDpi); Bitmap icon = unbadgedIcon == null ? null : getBadgedIcon(unbadgedIcon, context); setIcon(icon != null ? icon : launcherAppState.getIconCache().getDefaultIcon(user)); IconCache cache = launcherAppState.getIconCache(); Bitmap unbadgedBitmap = unbadgedDrawable == null ? cache.getDefaultIcon(UserHandleCompat.myUserHandle()) : Utilities.createScaledBitmapWithoutShadow(unbadgedDrawable, context); setIcon(getBadgedIcon(unbadgedBitmap, shortcutInfo, cache, context)); } protected Bitmap getBadgedIcon(Drawable unbadgedIcon, Context context) { return Utilities.createBadgedIconBitmapWithShadow(unbadgedIcon, user, context); protected Bitmap getBadgedIcon(Bitmap unbadgedBitmap, ShortcutInfoCompat shortcutInfo, IconCache cache, Context context) { unbadgedBitmap = Utilities.addShadowToIcon(unbadgedBitmap); // Get the app info for the source activity. AppInfo appInfo = new AppInfo(); appInfo.user = user; appInfo.componentName = shortcutInfo.getActivity(); try { cache.getTitleAndIcon(appInfo, shortcutInfo.getActivityInfo(context), false); } catch (NullPointerException e) { // This may happen when we fail to load the activity info. Worst case ignore badging. return Utilities.badgeIconForUser(unbadgedBitmap, user, context); } return Utilities.badgeWithBitmap(unbadgedBitmap, appInfo.iconBitmap, context); } /** Returns the ShortcutInfo id associated with the deep shortcut. */ Loading src/com/android/launcher3/Utilities.java +28 −19 Original line number Diff line number Diff line Loading @@ -248,9 +248,16 @@ public final class Utilities { float scale = FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ? 1 : IconNormalizer.getInstance().getScale(icon, null); Bitmap bitmap = createIconBitmap(icon, context, scale); return badgeIconForUser(bitmap, user, context); } /** * Badges the provided icon with the user badge if required. */ public static Bitmap badgeIconForUser(Bitmap icon, UserHandleCompat user, Context context) { if (Utilities.ATLEAST_LOLLIPOP && user != null && !UserHandleCompat.myUserHandle().equals(user)) { BitmapDrawable drawable = new FixedSizeBitmapDrawable(bitmap); BitmapDrawable drawable = new FixedSizeBitmapDrawable(icon); Drawable badged = context.getPackageManager().getUserBadgedIcon( drawable, user.getUser()); if (badged instanceof BitmapDrawable) { Loading @@ -259,7 +266,7 @@ public final class Utilities { return createIconBitmap(badged, context); } } else { return bitmap; return icon; } } Loading @@ -276,26 +283,28 @@ public final class Utilities { } /** * Same as {@link #createBadgedIconBitmap} but adds a shadow before badging the icon * Adds a shadow to the provided icon. It assumes that the icon has already been scaled using * {@link #createScaledBitmapWithoutShadow(Drawable, Context)} */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public static Bitmap createBadgedIconBitmapWithShadow( Drawable icon, UserHandleCompat user, Context context) { Bitmap bitmap = ShadowGenerator.getInstance().recreateIcon( createScaledBitmapWithoutShadow(icon, context)); if (Utilities.ATLEAST_LOLLIPOP && user != null && !UserHandleCompat.myUserHandle().equals(user)) { BitmapDrawable drawable = new FixedSizeBitmapDrawable(bitmap); Drawable badged = context.getPackageManager().getUserBadgedIcon( drawable, user.getUser()); if (badged instanceof BitmapDrawable) { return ((BitmapDrawable) badged).getBitmap(); } else { return createIconBitmap(badged, context); } } else { return bitmap; public static Bitmap addShadowToIcon(Bitmap icon) { return ShadowGenerator.getInstance().recreateIcon(icon); } /** * Adds the {@param badge} on top of {@param srcTgt} using the badge dimensions. */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public static Bitmap badgeWithBitmap(Bitmap srcTgt, Bitmap badge, Context context) { int badgeSize = context.getResources().getDimensionPixelSize(R.dimen.profile_badge_size); synchronized (sCanvas) { sCanvas.setBitmap(srcTgt); sCanvas.drawBitmap(badge, new Rect(0, 0, badge.getWidth(), badge.getHeight()), new Rect(srcTgt.getWidth() - badgeSize, srcTgt.getHeight() - badgeSize, srcTgt.getWidth(), srcTgt.getHeight()), new Paint(Paint.FILTER_BITMAP_FLAG)); sCanvas.setBitmap(null); } return srcTgt; } /** Loading src/com/android/launcher3/compat/DeferredLauncherActivityInfo.java 0 → 100644 +83 −0 Original line number Diff line number Diff line /* * 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. */ package com.android.launcher3.compat; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.graphics.drawable.Drawable; import android.util.Log; /** * {@link LauncherActivityInfoCompat} which loads its data only when needed. */ public class DeferredLauncherActivityInfo extends LauncherActivityInfoCompat { private final ComponentName mComponent; private final UserHandleCompat mUser; private final Context mContext; private LauncherActivityInfoCompat mActualInfo; public DeferredLauncherActivityInfo( ComponentName component, UserHandleCompat user, Context context) { mComponent = component; mUser = user; mContext = context; } @Override public ComponentName getComponentName() { return mComponent; } @Override public UserHandleCompat getUser() { return mUser; } private synchronized LauncherActivityInfoCompat getActualInfo() { if (mActualInfo == null) { Intent intent = new Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_LAUNCHER) .setComponent(mComponent); mActualInfo = LauncherAppsCompat.getInstance(mContext).resolveActivity(intent, mUser); } return mActualInfo; } @Override public CharSequence getLabel() { return getActualInfo().getLabel(); } @Override public Drawable getIcon(int density) { return getActualInfo().getIcon(density); } @Override public ApplicationInfo getApplicationInfo() { return getActualInfo().getApplicationInfo(); } @Override public long getFirstInstallTime() { return getActualInfo().getFirstInstallTime(); } } src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java +4 −2 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import android.widget.LinearLayout; import com.android.launcher3.BubbleTextView; import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget; import com.android.launcher3.IconCache; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; Loading Loading @@ -761,8 +762,9 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC } @Override protected Bitmap getBadgedIcon(Drawable unbadgedIcon, Context context) { return Utilities.createScaledBitmapWithoutShadow(unbadgedIcon, context); protected Bitmap getBadgedIcon(Bitmap unbadgedBitmap, ShortcutInfoCompat shortcutInfo, IconCache cache, Context context) { return unbadgedBitmap; } } } src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java +6 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.content.pm.ShortcutInfo; import android.os.Build; import com.android.launcher3.ItemInfo; import com.android.launcher3.compat.DeferredLauncherActivityInfo; import com.android.launcher3.compat.LauncherActivityInfoCompat; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.util.ComponentKey; Loading Loading @@ -109,4 +111,8 @@ public class ShortcutInfoCompat { public String toString() { return mShortcutInfo.toString(); } public LauncherActivityInfoCompat getActivityInfo(Context context) { return new DeferredLauncherActivityInfo(getActivity(), getUserHandle(), context); } } Loading
src/com/android/launcher3/ShortcutInfo.java +22 −6 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import android.text.TextUtils; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.compat.LauncherActivityInfoCompat; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.folder.FolderIcon; Loading Loading @@ -295,16 +294,33 @@ public class ShortcutInfo extends ItemInfo { contentDescription = UserManagerCompat.getInstance(context) .getBadgedLabelForUser(label, user); // TODO: Use cache for this LauncherAppState launcherAppState = LauncherAppState.getInstance(); Drawable unbadgedIcon = launcherAppState.getShortcutManager() Drawable unbadgedDrawable = launcherAppState.getShortcutManager() .getShortcutIconDrawable(shortcutInfo, launcherAppState.getInvariantDeviceProfile().fillResIconDpi); Bitmap icon = unbadgedIcon == null ? null : getBadgedIcon(unbadgedIcon, context); setIcon(icon != null ? icon : launcherAppState.getIconCache().getDefaultIcon(user)); IconCache cache = launcherAppState.getIconCache(); Bitmap unbadgedBitmap = unbadgedDrawable == null ? cache.getDefaultIcon(UserHandleCompat.myUserHandle()) : Utilities.createScaledBitmapWithoutShadow(unbadgedDrawable, context); setIcon(getBadgedIcon(unbadgedBitmap, shortcutInfo, cache, context)); } protected Bitmap getBadgedIcon(Drawable unbadgedIcon, Context context) { return Utilities.createBadgedIconBitmapWithShadow(unbadgedIcon, user, context); protected Bitmap getBadgedIcon(Bitmap unbadgedBitmap, ShortcutInfoCompat shortcutInfo, IconCache cache, Context context) { unbadgedBitmap = Utilities.addShadowToIcon(unbadgedBitmap); // Get the app info for the source activity. AppInfo appInfo = new AppInfo(); appInfo.user = user; appInfo.componentName = shortcutInfo.getActivity(); try { cache.getTitleAndIcon(appInfo, shortcutInfo.getActivityInfo(context), false); } catch (NullPointerException e) { // This may happen when we fail to load the activity info. Worst case ignore badging. return Utilities.badgeIconForUser(unbadgedBitmap, user, context); } return Utilities.badgeWithBitmap(unbadgedBitmap, appInfo.iconBitmap, context); } /** Returns the ShortcutInfo id associated with the deep shortcut. */ Loading
src/com/android/launcher3/Utilities.java +28 −19 Original line number Diff line number Diff line Loading @@ -248,9 +248,16 @@ public final class Utilities { float scale = FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ? 1 : IconNormalizer.getInstance().getScale(icon, null); Bitmap bitmap = createIconBitmap(icon, context, scale); return badgeIconForUser(bitmap, user, context); } /** * Badges the provided icon with the user badge if required. */ public static Bitmap badgeIconForUser(Bitmap icon, UserHandleCompat user, Context context) { if (Utilities.ATLEAST_LOLLIPOP && user != null && !UserHandleCompat.myUserHandle().equals(user)) { BitmapDrawable drawable = new FixedSizeBitmapDrawable(bitmap); BitmapDrawable drawable = new FixedSizeBitmapDrawable(icon); Drawable badged = context.getPackageManager().getUserBadgedIcon( drawable, user.getUser()); if (badged instanceof BitmapDrawable) { Loading @@ -259,7 +266,7 @@ public final class Utilities { return createIconBitmap(badged, context); } } else { return bitmap; return icon; } } Loading @@ -276,26 +283,28 @@ public final class Utilities { } /** * Same as {@link #createBadgedIconBitmap} but adds a shadow before badging the icon * Adds a shadow to the provided icon. It assumes that the icon has already been scaled using * {@link #createScaledBitmapWithoutShadow(Drawable, Context)} */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public static Bitmap createBadgedIconBitmapWithShadow( Drawable icon, UserHandleCompat user, Context context) { Bitmap bitmap = ShadowGenerator.getInstance().recreateIcon( createScaledBitmapWithoutShadow(icon, context)); if (Utilities.ATLEAST_LOLLIPOP && user != null && !UserHandleCompat.myUserHandle().equals(user)) { BitmapDrawable drawable = new FixedSizeBitmapDrawable(bitmap); Drawable badged = context.getPackageManager().getUserBadgedIcon( drawable, user.getUser()); if (badged instanceof BitmapDrawable) { return ((BitmapDrawable) badged).getBitmap(); } else { return createIconBitmap(badged, context); } } else { return bitmap; public static Bitmap addShadowToIcon(Bitmap icon) { return ShadowGenerator.getInstance().recreateIcon(icon); } /** * Adds the {@param badge} on top of {@param srcTgt} using the badge dimensions. */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public static Bitmap badgeWithBitmap(Bitmap srcTgt, Bitmap badge, Context context) { int badgeSize = context.getResources().getDimensionPixelSize(R.dimen.profile_badge_size); synchronized (sCanvas) { sCanvas.setBitmap(srcTgt); sCanvas.drawBitmap(badge, new Rect(0, 0, badge.getWidth(), badge.getHeight()), new Rect(srcTgt.getWidth() - badgeSize, srcTgt.getHeight() - badgeSize, srcTgt.getWidth(), srcTgt.getHeight()), new Paint(Paint.FILTER_BITMAP_FLAG)); sCanvas.setBitmap(null); } return srcTgt; } /** Loading
src/com/android/launcher3/compat/DeferredLauncherActivityInfo.java 0 → 100644 +83 −0 Original line number Diff line number Diff line /* * 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. */ package com.android.launcher3.compat; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.graphics.drawable.Drawable; import android.util.Log; /** * {@link LauncherActivityInfoCompat} which loads its data only when needed. */ public class DeferredLauncherActivityInfo extends LauncherActivityInfoCompat { private final ComponentName mComponent; private final UserHandleCompat mUser; private final Context mContext; private LauncherActivityInfoCompat mActualInfo; public DeferredLauncherActivityInfo( ComponentName component, UserHandleCompat user, Context context) { mComponent = component; mUser = user; mContext = context; } @Override public ComponentName getComponentName() { return mComponent; } @Override public UserHandleCompat getUser() { return mUser; } private synchronized LauncherActivityInfoCompat getActualInfo() { if (mActualInfo == null) { Intent intent = new Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_LAUNCHER) .setComponent(mComponent); mActualInfo = LauncherAppsCompat.getInstance(mContext).resolveActivity(intent, mUser); } return mActualInfo; } @Override public CharSequence getLabel() { return getActualInfo().getLabel(); } @Override public Drawable getIcon(int density) { return getActualInfo().getIcon(density); } @Override public ApplicationInfo getApplicationInfo() { return getActualInfo().getApplicationInfo(); } @Override public long getFirstInstallTime() { return getActualInfo().getFirstInstallTime(); } }
src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java +4 −2 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import android.widget.LinearLayout; import com.android.launcher3.BubbleTextView; import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget; import com.android.launcher3.IconCache; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; Loading Loading @@ -761,8 +762,9 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC } @Override protected Bitmap getBadgedIcon(Drawable unbadgedIcon, Context context) { return Utilities.createScaledBitmapWithoutShadow(unbadgedIcon, context); protected Bitmap getBadgedIcon(Bitmap unbadgedBitmap, ShortcutInfoCompat shortcutInfo, IconCache cache, Context context) { return unbadgedBitmap; } } }
src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java +6 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.content.pm.ShortcutInfo; import android.os.Build; import com.android.launcher3.ItemInfo; import com.android.launcher3.compat.DeferredLauncherActivityInfo; import com.android.launcher3.compat.LauncherActivityInfoCompat; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.util.ComponentKey; Loading Loading @@ -109,4 +111,8 @@ public class ShortcutInfoCompat { public String toString() { return mShortcutInfo.toString(); } public LauncherActivityInfoCompat getActivityInfo(Context context) { return new DeferredLauncherActivityInfo(getActivity(), getUserHandle(), context); } }