Merge "Creating a common class for loading drawables and handling various badging" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
15b48ff4de
@@ -79,6 +79,8 @@ import android.os.storage.StorageManager;
|
||||
import android.os.storage.VolumeInfo;
|
||||
import android.provider.Settings;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.LauncherIcons;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
|
||||
@@ -1245,16 +1247,9 @@ public class ApplicationPackageManager extends PackageManager {
|
||||
if (!isManagedProfile(user.getIdentifier())) {
|
||||
return icon;
|
||||
}
|
||||
Drawable badgeShadow = getDrawable("system",
|
||||
com.android.internal.R.drawable.ic_corp_icon_badge_shadow, null);
|
||||
Drawable badgeColor = getDrawable("system",
|
||||
com.android.internal.R.drawable.ic_corp_icon_badge_color, null);
|
||||
badgeColor.setTint(getUserBadgeColor(user));
|
||||
Drawable badgeForeground = getDrawable("system",
|
||||
com.android.internal.R.drawable.ic_corp_icon_badge_case, null);
|
||||
|
||||
Drawable badge = new LayerDrawable(
|
||||
new Drawable[] {badgeShadow, badgeColor, badgeForeground });
|
||||
Drawable badge = new LauncherIcons(mContext).getBadgeDrawable(
|
||||
com.android.internal.R.drawable.ic_corp_icon_badge_case,
|
||||
getUserBadgeColor(user));
|
||||
return getBadgedDrawable(icon, badge, null, true);
|
||||
}
|
||||
|
||||
@@ -1268,14 +1263,6 @@ public class ApplicationPackageManager extends PackageManager {
|
||||
return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
|
||||
}
|
||||
|
||||
// Should have enough colors to cope with UserManagerService.getMaxManagedProfiles()
|
||||
@VisibleForTesting
|
||||
public static final int[] CORP_BADGE_COLORS = new int[] {
|
||||
com.android.internal.R.color.profile_badge_1,
|
||||
com.android.internal.R.color.profile_badge_2,
|
||||
com.android.internal.R.color.profile_badge_3
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
public static final int[] CORP_BADGE_LABEL_RES_ID = new int[] {
|
||||
com.android.internal.R.string.managed_profile_label_badge,
|
||||
@@ -1284,12 +1271,7 @@ public class ApplicationPackageManager extends PackageManager {
|
||||
};
|
||||
|
||||
private int getUserBadgeColor(UserHandle user) {
|
||||
int badge = getUserManager().getManagedProfileBadge(user.getIdentifier());
|
||||
if (badge < 0) {
|
||||
badge = 0;
|
||||
}
|
||||
int resourceId = CORP_BADGE_COLORS[badge % CORP_BADGE_COLORS.length];
|
||||
return Resources.getSystem().getColor(resourceId, null);
|
||||
return IconDrawableFactory.getUserBadgeColor(getUserManager(), user.getIdentifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
112
core/java/android/util/IconDrawableFactory.java
Normal file
112
core/java/android/util/IconDrawableFactory.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package android.util;
|
||||
|
||||
import android.annotation.UserIdInt;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageItemInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* Utility class to load app drawables with appropriate badging.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class IconDrawableFactory {
|
||||
|
||||
protected final Context mContext;
|
||||
protected final PackageManager mPm;
|
||||
protected final UserManager mUm;
|
||||
protected final LauncherIcons mLauncherIcons;
|
||||
protected final boolean mEmbedShadow;
|
||||
|
||||
private IconDrawableFactory(Context context, boolean embedShadow) {
|
||||
mContext = context;
|
||||
mPm = context.getPackageManager();
|
||||
mUm = context.getSystemService(UserManager.class);
|
||||
mLauncherIcons = new LauncherIcons(context);
|
||||
mEmbedShadow = embedShadow;
|
||||
}
|
||||
|
||||
protected boolean needsBadging(ApplicationInfo appInfo, @UserIdInt int userId) {
|
||||
return appInfo.isInstantApp() || mUm.isManagedProfile(userId);
|
||||
}
|
||||
|
||||
public Drawable getBadgedIcon(ApplicationInfo appInfo) {
|
||||
return getBadgedIcon(appInfo, UserHandle.getUserId(appInfo.uid));
|
||||
}
|
||||
|
||||
public Drawable getBadgedIcon(ApplicationInfo appInfo, @UserIdInt int userId) {
|
||||
return getBadgedIcon(appInfo, appInfo, userId);
|
||||
}
|
||||
|
||||
public Drawable getBadgedIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo,
|
||||
@UserIdInt int userId) {
|
||||
Drawable icon = mPm.loadUnbadgedItemIcon(itemInfo, appInfo);
|
||||
if (!mEmbedShadow && !needsBadging(appInfo, userId)) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
// Before badging, add shadow to adaptive icon if needed.
|
||||
icon = mLauncherIcons.wrapIconDrawableWithShadow(icon);
|
||||
if (appInfo.isInstantApp()) {
|
||||
int badgeColor = Resources.getSystem().getColor(
|
||||
com.android.internal.R.color.instant_app_badge, null);
|
||||
icon = mLauncherIcons.getBadgedDrawable(icon,
|
||||
com.android.internal.R.drawable.ic_instant_icon_badge_bolt,
|
||||
badgeColor);
|
||||
}
|
||||
if (mUm.isManagedProfile(userId)) {
|
||||
icon = mLauncherIcons.getBadgedDrawable(icon,
|
||||
com.android.internal.R.drawable.ic_corp_icon_badge_case,
|
||||
getUserBadgeColor(mUm, userId));
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
// Should have enough colors to cope with UserManagerService.getMaxManagedProfiles()
|
||||
@VisibleForTesting
|
||||
public static final int[] CORP_BADGE_COLORS = new int[] {
|
||||
com.android.internal.R.color.profile_badge_1,
|
||||
com.android.internal.R.color.profile_badge_2,
|
||||
com.android.internal.R.color.profile_badge_3
|
||||
};
|
||||
|
||||
public static int getUserBadgeColor(UserManager um, @UserIdInt int userId) {
|
||||
int badge = um.getManagedProfileBadge(userId);
|
||||
if (badge < 0) {
|
||||
badge = 0;
|
||||
}
|
||||
int resourceId = CORP_BADGE_COLORS[badge % CORP_BADGE_COLORS.length];
|
||||
return Resources.getSystem().getColor(resourceId, null);
|
||||
}
|
||||
|
||||
public static IconDrawableFactory newInstance(Context context) {
|
||||
return new IconDrawableFactory(context, true);
|
||||
}
|
||||
|
||||
public static IconDrawableFactory newInstance(Context context, boolean embedShadow) {
|
||||
return new IconDrawableFactory(context, embedShadow);
|
||||
}
|
||||
}
|
||||
@@ -21,10 +21,11 @@ import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PaintFlagsDrawFilter;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.AdaptiveIconDrawable;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.DrawableWrapper;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
|
||||
/**
|
||||
* Utility class to handle icon treatments (e.g., shadow generation) for the Launcher icons.
|
||||
@@ -32,78 +33,152 @@ import android.graphics.drawable.Drawable;
|
||||
*/
|
||||
public final class LauncherIcons {
|
||||
|
||||
private final Paint mPaint = new Paint();
|
||||
private final Canvas mCanvas = new Canvas();
|
||||
// Percent of actual icon size
|
||||
private static final float ICON_SIZE_BLUR_FACTOR = 0.5f/48;
|
||||
// Percent of actual icon size
|
||||
private static final float ICON_SIZE_KEY_SHADOW_DELTA_FACTOR = 1f/48;
|
||||
|
||||
private static final int KEY_SHADOW_ALPHA = 61;
|
||||
private static final int AMBIENT_SHADOW_ALPHA = 30;
|
||||
private static final float BLUR_FACTOR = 0.5f / 48;
|
||||
private int mShadowInset;
|
||||
private Bitmap mShadowBitmap;
|
||||
private int mIconSize;
|
||||
private Resources mRes;
|
||||
|
||||
private final SparseArray<Bitmap> mShadowCache = new SparseArray<>();
|
||||
private final int mIconSize;
|
||||
private final Resources mRes;
|
||||
|
||||
public LauncherIcons(Context context) {
|
||||
mRes = context.getResources();
|
||||
DisplayMetrics metrics = mRes.getDisplayMetrics();
|
||||
mShadowInset = (int)(2 * metrics.density);
|
||||
mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
|
||||
Paint.FILTER_BITMAP_FLAG));
|
||||
mIconSize = (int) mRes.getDimensionPixelSize(android.R.dimen.app_icon_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the drawable into a bitmap.
|
||||
*/
|
||||
public Bitmap createIconBitmap(Drawable icon) {
|
||||
final Bitmap bitmap = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ARGB_8888);
|
||||
mPaint.setAlpha(255);
|
||||
mCanvas.setBitmap(bitmap);
|
||||
int iconInset = 0;
|
||||
if (mShadowBitmap != null) {
|
||||
mCanvas.drawBitmap(mShadowBitmap, 0, 0, mPaint);
|
||||
iconInset = mShadowInset;
|
||||
}
|
||||
|
||||
icon.setBounds(iconInset, iconInset, mIconSize - iconInset,
|
||||
mIconSize - iconInset);
|
||||
icon.draw(mCanvas);
|
||||
mCanvas.setBitmap(null);
|
||||
return bitmap;
|
||||
mIconSize = mRes.getDimensionPixelSize(android.R.dimen.app_icon_size);
|
||||
}
|
||||
|
||||
public Drawable wrapIconDrawableWithShadow(Drawable drawable) {
|
||||
if (!(drawable instanceof AdaptiveIconDrawable)) {
|
||||
return drawable;
|
||||
}
|
||||
AdaptiveIconDrawable d =
|
||||
(AdaptiveIconDrawable) drawable.getConstantState().newDrawable().mutate();
|
||||
getShadowBitmap(d);
|
||||
Bitmap iconbitmap = createIconBitmap(d);
|
||||
return new BitmapDrawable(mRes, iconbitmap);
|
||||
Bitmap shadow = getShadowBitmap((AdaptiveIconDrawable) drawable);
|
||||
return new ShadowDrawable(shadow, drawable);
|
||||
}
|
||||
|
||||
private Bitmap getShadowBitmap(AdaptiveIconDrawable d) {
|
||||
if (mShadowBitmap != null) {
|
||||
return mShadowBitmap;
|
||||
int shadowSize = Math.max(mIconSize, d.getIntrinsicHeight());
|
||||
synchronized (mShadowCache) {
|
||||
Bitmap shadow = mShadowCache.get(shadowSize);
|
||||
if (shadow != null) {
|
||||
return shadow;
|
||||
}
|
||||
}
|
||||
|
||||
mShadowBitmap = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ALPHA_8);
|
||||
mCanvas.setBitmap(mShadowBitmap);
|
||||
d.setBounds(0, 0, shadowSize, shadowSize);
|
||||
|
||||
// Draw key shadow
|
||||
mPaint.setColor(Color.TRANSPARENT);
|
||||
float blur = BLUR_FACTOR * mIconSize;
|
||||
mPaint.setShadowLayer(blur, 0, mShadowInset, KEY_SHADOW_ALPHA << 24);
|
||||
d.setBounds(mShadowInset, mShadowInset, mIconSize - mShadowInset, mIconSize - mShadowInset);
|
||||
mCanvas.drawPath(d.getIconMask(), mPaint);
|
||||
float blur = ICON_SIZE_BLUR_FACTOR * shadowSize;
|
||||
float keyShadowDistance = ICON_SIZE_KEY_SHADOW_DELTA_FACTOR * shadowSize;
|
||||
|
||||
int bitmapSize = (int) (shadowSize + 2 * blur + keyShadowDistance);
|
||||
Bitmap shadow = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
|
||||
|
||||
Canvas canvas = new Canvas(shadow);
|
||||
canvas.translate(blur + keyShadowDistance / 2, blur);
|
||||
|
||||
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
paint.setColor(Color.TRANSPARENT);
|
||||
|
||||
// Draw ambient shadow
|
||||
mPaint.setShadowLayer(blur, 0, 0, AMBIENT_SHADOW_ALPHA << 24);
|
||||
d.setBounds(mShadowInset, 2 * mShadowInset, mIconSize - mShadowInset, mIconSize);
|
||||
mCanvas.drawPath(d.getIconMask(), mPaint);
|
||||
mPaint.clearShadowLayer();
|
||||
paint.setShadowLayer(blur, 0, 0, AMBIENT_SHADOW_ALPHA << 24);
|
||||
canvas.drawPath(d.getIconMask(), paint);
|
||||
|
||||
return mShadowBitmap;
|
||||
// Draw key shadow
|
||||
canvas.translate(0, keyShadowDistance);
|
||||
paint.setShadowLayer(blur, 0, 0, KEY_SHADOW_ALPHA << 24);
|
||||
canvas.drawPath(d.getIconMask(), paint);
|
||||
|
||||
canvas.setBitmap(null);
|
||||
synchronized (mShadowCache) {
|
||||
mShadowCache.put(shadowSize, shadow);
|
||||
}
|
||||
return shadow;
|
||||
}
|
||||
|
||||
public Drawable getBadgeDrawable(int foregroundRes, int backgroundColor) {
|
||||
return getBadgedDrawable(null, foregroundRes, backgroundColor);
|
||||
}
|
||||
|
||||
public Drawable getBadgedDrawable(Drawable base, int foregroundRes, int backgroundColor) {
|
||||
Resources sysRes = Resources.getSystem();
|
||||
|
||||
Drawable badgeShadow = sysRes.getDrawable(
|
||||
com.android.internal.R.drawable.ic_corp_icon_badge_shadow);
|
||||
|
||||
Drawable badgeColor = sysRes.getDrawable(
|
||||
com.android.internal.R.drawable.ic_corp_icon_badge_color)
|
||||
.getConstantState().newDrawable().mutate();
|
||||
badgeColor.setTint(backgroundColor);
|
||||
|
||||
Drawable badgeForeground = sysRes.getDrawable(foregroundRes);
|
||||
|
||||
Drawable[] drawables = base == null
|
||||
? new Drawable[] {badgeShadow, badgeColor, badgeForeground }
|
||||
: new Drawable[] {base, badgeShadow, badgeColor, badgeForeground };
|
||||
return new LayerDrawable(drawables);
|
||||
}
|
||||
|
||||
/**
|
||||
* A drawable which draws a shadow bitmap behind a drawable
|
||||
*/
|
||||
private static class ShadowDrawable extends DrawableWrapper {
|
||||
|
||||
final MyConstantState mState;
|
||||
|
||||
public ShadowDrawable(Bitmap shadow, Drawable dr) {
|
||||
super(dr);
|
||||
mState = new MyConstantState(shadow, dr.getConstantState());
|
||||
}
|
||||
|
||||
ShadowDrawable(MyConstantState state) {
|
||||
super(state.mChildState.newDrawable());
|
||||
mState = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstantState getConstantState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
Rect bounds = getBounds();
|
||||
canvas.drawBitmap(mState.mShadow, null, bounds, mState.mPaint);
|
||||
canvas.save();
|
||||
// Ratio of child drawable size to shadow bitmap size
|
||||
float factor = 1 / (1 + 2 * ICON_SIZE_BLUR_FACTOR + ICON_SIZE_KEY_SHADOW_DELTA_FACTOR);
|
||||
|
||||
canvas.translate(
|
||||
bounds.width() * factor *
|
||||
(ICON_SIZE_BLUR_FACTOR + ICON_SIZE_KEY_SHADOW_DELTA_FACTOR / 2),
|
||||
bounds.height() * factor * ICON_SIZE_BLUR_FACTOR);
|
||||
canvas.scale(factor, factor);
|
||||
super.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
private static class MyConstantState extends ConstantState {
|
||||
|
||||
final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
|
||||
final Bitmap mShadow;
|
||||
final ConstantState mChildState;
|
||||
|
||||
MyConstantState(Bitmap shadow, ConstantState childState) {
|
||||
mShadow = shadow;
|
||||
mChildState = childState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable newDrawable() {
|
||||
return new ShadowDrawable(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChangingConfigurations() {
|
||||
return mChildState.getChangingConfigurations();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<!--
|
||||
Copyright (C) 2014 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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20.0dp"
|
||||
android:height="20.0dp"
|
||||
android:viewportWidth="20.0"
|
||||
android:viewportHeight="20.0">
|
||||
<path
|
||||
android:pathData="M10.0,10.0m-10.0,0.0a10.0,10.0 0.0,1.0 1.0,20.0 0.0a10.0,10.0 0.0,1.0 1.0,-20.0 0.0"
|
||||
android:fillColor="#FF5722"/>
|
||||
<path
|
||||
android:pathData="M15.2,6.2L4.8,6.2c-0.5,0.0 -0.9,0.4 -0.9,1.0L3.9,10.0c0.0,0.5 0.4,1.0 0.9,1.0l3.8,0.0l0.0,-1.0l2.9,0.0l0.0,1.0l3.8,0.0c0.5,0.0 1.0,-0.4 1.0,-1.0L16.3,7.1C16.2,6.6 15.8,6.2 15.2,6.2z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M8.6,12.9l0.0,-1.0L4.3,11.9l0.0,2.4c0.0,0.5 0.4,0.9 0.9,0.9l9.5,0.0c0.5,0.0 0.9,-0.4 0.9,-0.9l0.0,-2.4l-4.3,0.0l0.0,1.0L8.6,12.9z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M7.1,5.2l0.0,1.0 1.0,0.0 0.0,-1.0 3.799999,0.0 0.0,1.0 1.0,0.0 0.0,-1.0 -1.0,-0.9 -3.799999,0.0z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
</vector>
|
||||
29
core/res/res/drawable/ic_instant_icon_badge_bolt.xml
Normal file
29
core/res/res/drawable/ic_instant_icon_badge_bolt.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="64.0dp"
|
||||
android:height="64.0dp"
|
||||
android:viewportWidth="64.0"
|
||||
android:viewportHeight="64.0">
|
||||
|
||||
<!--
|
||||
The path is similar to ic_corp_icon_badge_case, such that it positions on top of
|
||||
ic_corp_icon_badge_shadow.
|
||||
-->
|
||||
<path
|
||||
android:pathData="M43.9 50.9h4v8l6-12h-4v-8l-6 12z"
|
||||
android:fillColor="#757575"/>
|
||||
</vector>
|
||||
@@ -171,6 +171,9 @@
|
||||
<color name="profile_badge_2">#ff000000</color><!-- Black -->
|
||||
<color name="profile_badge_3">#ff22f033</color><!-- Green -->
|
||||
|
||||
<!-- Default instant app badge color -->
|
||||
<color name="instant_app_badge">#FFFFFFFF</color><!-- White -->
|
||||
|
||||
<!-- Multi-sim sim colors -->
|
||||
<color name="Teal_700">#ff00796b</color>
|
||||
<color name="Teal_800">#ff00695c</color>
|
||||
|
||||
@@ -1322,6 +1322,7 @@
|
||||
<java-symbol type="drawable" name="ic_corp_user_badge" />
|
||||
<java-symbol type="drawable" name="ic_corp_badge_no_background" />
|
||||
<java-symbol type="drawable" name="ic_corp_statusbar_icon" />
|
||||
<java-symbol type="drawable" name="ic_instant_icon_badge_bolt" />
|
||||
<java-symbol type="drawable" name="emulator_circular_window_overlay" />
|
||||
|
||||
<java-symbol type="drawable" name="sim_light_blue" />
|
||||
@@ -1353,6 +1354,7 @@
|
||||
<java-symbol type="color" name="profile_badge_1" />
|
||||
<java-symbol type="color" name="profile_badge_2" />
|
||||
<java-symbol type="color" name="profile_badge_3" />
|
||||
<java-symbol type="color" name="instant_app_badge" />
|
||||
|
||||
<java-symbol type="layout" name="action_bar_home" />
|
||||
<java-symbol type="layout" name="action_bar_title_item" />
|
||||
|
||||
@@ -46,6 +46,7 @@ import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
@@ -95,6 +96,7 @@ public class ApplicationsState {
|
||||
|
||||
final Context mContext;
|
||||
final PackageManager mPm;
|
||||
final IconDrawableFactory mDrawableFactory;
|
||||
final IPackageManager mIpm;
|
||||
final UserManager mUm;
|
||||
final StorageStatsManager mStats;
|
||||
@@ -132,6 +134,7 @@ public class ApplicationsState {
|
||||
private ApplicationsState(Application app) {
|
||||
mContext = app;
|
||||
mPm = mContext.getPackageManager();
|
||||
mDrawableFactory = IconDrawableFactory.newInstance(mContext);
|
||||
mIpm = AppGlobals.getPackageManager();
|
||||
mUm = mContext.getSystemService(UserManager.class);
|
||||
mStats = mContext.getSystemService(StorageStatsManager.class);
|
||||
@@ -327,7 +330,7 @@ public class ApplicationsState {
|
||||
return;
|
||||
}
|
||||
synchronized (entry) {
|
||||
entry.ensureIconLocked(mContext, mPm);
|
||||
entry.ensureIconLocked(mContext, mDrawableFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -943,7 +946,7 @@ public class ApplicationsState {
|
||||
AppEntry entry = mAppEntries.get(i);
|
||||
if (entry.icon == null || !entry.mounted) {
|
||||
synchronized (entry) {
|
||||
if (entry.ensureIconLocked(mContext, mPm)) {
|
||||
if (entry.ensureIconLocked(mContext, mDrawableFactory)) {
|
||||
if (!mRunning) {
|
||||
mRunning = true;
|
||||
Message m = mMainHandler.obtainMessage(
|
||||
@@ -1266,10 +1269,10 @@ public class ApplicationsState {
|
||||
}
|
||||
}
|
||||
|
||||
boolean ensureIconLocked(Context context, PackageManager pm) {
|
||||
boolean ensureIconLocked(Context context, IconDrawableFactory drawableFactory) {
|
||||
if (this.icon == null) {
|
||||
if (this.apkFile.exists()) {
|
||||
this.icon = getBadgedIcon(pm);
|
||||
this.icon = drawableFactory.getBadgedIcon(info);
|
||||
return true;
|
||||
} else {
|
||||
this.mounted = false;
|
||||
@@ -1281,19 +1284,13 @@ public class ApplicationsState {
|
||||
// its icon.
|
||||
if (this.apkFile.exists()) {
|
||||
this.mounted = true;
|
||||
this.icon = getBadgedIcon(pm);
|
||||
this.icon = drawableFactory.getBadgedIcon(info);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Drawable getBadgedIcon(PackageManager pm) {
|
||||
// Do badging ourself so that it comes from the user of the app not the current user.
|
||||
return pm.getUserBadgedIcon(pm.loadUnbadgedItemIcon(info, info),
|
||||
new UserHandle(UserHandle.getUserId(info.uid)));
|
||||
}
|
||||
|
||||
public String getVersion(Context context) {
|
||||
try {
|
||||
return context.getPackageManager().getPackageInfo(info.packageName, 0).versionName;
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -48,10 +49,12 @@ public class RecentLocationApps {
|
||||
|
||||
private final PackageManager mPackageManager;
|
||||
private final Context mContext;
|
||||
private final IconDrawableFactory mDrawableFactory;
|
||||
|
||||
public RecentLocationApps(Context context) {
|
||||
mContext = context;
|
||||
mPackageManager = context.getPackageManager();
|
||||
mDrawableFactory = IconDrawableFactory.newInstance(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,8 +149,7 @@ public class RecentLocationApps {
|
||||
}
|
||||
|
||||
final UserHandle userHandle = new UserHandle(userId);
|
||||
Drawable appIcon = mPackageManager.getApplicationIcon(appInfo);
|
||||
Drawable icon = mPackageManager.getUserBadgedIcon(appIcon, userHandle);
|
||||
Drawable icon = mDrawableFactory.getBadgedIcon(appInfo, userId);
|
||||
CharSequence appLabel = mPackageManager.getApplicationLabel(appInfo);
|
||||
CharSequence badgedAppLabel = mPackageManager.getUserBadgedLabel(appLabel, userHandle);
|
||||
if (appLabel.toString().contentEquals(badgedAppLabel)) {
|
||||
|
||||
@@ -65,7 +65,7 @@ import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.util.ArraySet;
|
||||
import android.util.LauncherIcons;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.Log;
|
||||
import android.util.MutableBoolean;
|
||||
import android.view.Display;
|
||||
@@ -121,6 +121,7 @@ public class SystemServicesProxy {
|
||||
ActivityManager mAm;
|
||||
IActivityManager mIam;
|
||||
PackageManager mPm;
|
||||
IconDrawableFactory mDrawableFactory;
|
||||
IPackageManager mIpm;
|
||||
AssistUtils mAssistUtils;
|
||||
WindowManager mWm;
|
||||
@@ -139,7 +140,6 @@ public class SystemServicesProxy {
|
||||
int mDummyThumbnailHeight;
|
||||
Paint mBgProtectionPaint;
|
||||
Canvas mBgProtectionCanvas;
|
||||
LauncherIcons mLauncherIcons;
|
||||
|
||||
private final Handler mHandler = new H();
|
||||
|
||||
@@ -258,6 +258,7 @@ public class SystemServicesProxy {
|
||||
mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
mIam = ActivityManager.getService();
|
||||
mPm = context.getPackageManager();
|
||||
mDrawableFactory = IconDrawableFactory.newInstance(context);
|
||||
mIpm = AppGlobals.getPackageManager();
|
||||
mAssistUtils = new AssistUtils(context);
|
||||
mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
@@ -296,8 +297,6 @@ public class SystemServicesProxy {
|
||||
|
||||
Collections.addAll(sRecentsBlacklist,
|
||||
res.getStringArray(R.array.recents_blacklist_array));
|
||||
|
||||
mLauncherIcons = new LauncherIcons(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -840,8 +839,7 @@ public class SystemServicesProxy {
|
||||
return new ColorDrawable(0xFF666666);
|
||||
}
|
||||
|
||||
Drawable icon = mLauncherIcons.wrapIconDrawableWithShadow(info.loadIcon(mPm));
|
||||
return getBadgedIcon(icon, userId);
|
||||
return mDrawableFactory.getBadgedIcon(info, info.applicationInfo, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -856,8 +854,7 @@ public class SystemServicesProxy {
|
||||
return new ColorDrawable(0xFF666666);
|
||||
}
|
||||
|
||||
Drawable icon = mLauncherIcons.wrapIconDrawableWithShadow(appInfo.loadIcon(mPm));
|
||||
return getBadgedIcon(icon, userId);
|
||||
return mDrawableFactory.getBadgedIcon(appInfo, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.os.UserManagerInternal;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.MediumTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.util.IconDrawableFactory;
|
||||
|
||||
import com.android.server.LocalServices;
|
||||
|
||||
@@ -155,9 +156,9 @@ public class UserManagerServiceCreateProfileTest {
|
||||
public void testNumberOfBadges() {
|
||||
assertTrue("Max profiles greater than number of badges",
|
||||
UserManagerService.MAX_MANAGED_PROFILES
|
||||
<= ApplicationPackageManager.CORP_BADGE_COLORS.length);
|
||||
<= IconDrawableFactory.CORP_BADGE_COLORS.length);
|
||||
assertEquals("Num colors doesn't match number of badge labels",
|
||||
ApplicationPackageManager.CORP_BADGE_COLORS.length,
|
||||
IconDrawableFactory.CORP_BADGE_COLORS.length,
|
||||
ApplicationPackageManager.CORP_BADGE_LABEL_RES_ID.length);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user