Merge "Ensuring that badge override is respected even if component name is set on the Shortcut" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0770b619ed
@@ -46,10 +46,10 @@ import android.util.SparseArray;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.util.Pair;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.LauncherFiles;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
|
||||
import com.android.launcher3.icons.cache.BaseIconCache;
|
||||
@@ -105,10 +105,6 @@ public class IconCache extends BaseIconCache {
|
||||
|
||||
private int mPendingIconRequestCount = 0;
|
||||
|
||||
public IconCache(Context context, InvariantDeviceProfile idp) {
|
||||
this(context, idp, LauncherFiles.APP_ICONS_DB, new IconProvider(context));
|
||||
}
|
||||
|
||||
public IconCache(Context context, InvariantDeviceProfile idp, String dbFileName,
|
||||
IconProvider iconProvider) {
|
||||
super(context, dbFileName, MODEL_EXECUTOR.getLooper(),
|
||||
@@ -254,30 +250,37 @@ public class IconCache extends BaseIconCache {
|
||||
* Returns the badging info for the shortcut
|
||||
*/
|
||||
public BitmapInfo getShortcutInfoBadge(ShortcutInfo shortcutInfo) {
|
||||
ComponentName cn = shortcutInfo.getActivity();
|
||||
if (cn != null) {
|
||||
// Get the app info for the source activity.
|
||||
AppInfo appInfo = new AppInfo();
|
||||
appInfo.user = shortcutInfo.getUserHandle();
|
||||
appInfo.componentName = cn;
|
||||
appInfo.intent = new Intent(Intent.ACTION_MAIN)
|
||||
.addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
.setComponent(cn);
|
||||
getTitleAndIcon(appInfo, false);
|
||||
return appInfo.bitmap;
|
||||
return getShortcutInfoBadgeItem(shortcutInfo).bitmap;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected ItemInfoWithIcon getShortcutInfoBadgeItem(ShortcutInfo shortcutInfo) {
|
||||
// Check for badge override first.
|
||||
String pkg = shortcutInfo.getPackage();
|
||||
String override = shortcutInfo.getExtras() == null ? null
|
||||
: shortcutInfo.getExtras().getString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE);
|
||||
if (!TextUtils.isEmpty(override)
|
||||
&& InstallSessionHelper.INSTANCE.get(mContext)
|
||||
.isTrustedPackage(pkg, shortcutInfo.getUserHandle())) {
|
||||
pkg = override;
|
||||
} else {
|
||||
String pkg = shortcutInfo.getPackage();
|
||||
String override = shortcutInfo.getExtras() == null ? null
|
||||
: shortcutInfo.getExtras().getString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE);
|
||||
if (!TextUtils.isEmpty(override)
|
||||
&& InstallSessionHelper.INSTANCE.get(mContext)
|
||||
.isTrustedPackage(pkg, shortcutInfo.getUserHandle())) {
|
||||
pkg = override;
|
||||
// Try component based badge before trying the normal package badge
|
||||
ComponentName cn = shortcutInfo.getActivity();
|
||||
if (cn != null) {
|
||||
// Get the app info for the source activity.
|
||||
AppInfo appInfo = new AppInfo();
|
||||
appInfo.user = shortcutInfo.getUserHandle();
|
||||
appInfo.componentName = cn;
|
||||
appInfo.intent = new Intent(Intent.ACTION_MAIN)
|
||||
.addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
.setComponent(cn);
|
||||
getTitleAndIcon(appInfo, false);
|
||||
return appInfo;
|
||||
}
|
||||
PackageItemInfo pkgInfo = new PackageItemInfo(pkg, shortcutInfo.getUserHandle());
|
||||
getTitleAndIconForApp(pkgInfo, false);
|
||||
return pkgInfo.bitmap;
|
||||
}
|
||||
PackageItemInfo pkgInfo = new PackageItemInfo(pkg, shortcutInfo.getUserHandle());
|
||||
getTitleAndIconForApp(pkgInfo, false);
|
||||
return pkgInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -181,9 +181,10 @@ public class InstallSessionHelper {
|
||||
public boolean isTrustedPackage(String pkg, UserHandle user) {
|
||||
synchronized (mSessionVerifiedMap) {
|
||||
if (!mSessionVerifiedMap.containsKey(pkg)) {
|
||||
boolean hasSystemFlag = new PackageManagerHelper(mAppContext).getApplicationInfo(
|
||||
pkg, user, ApplicationInfo.FLAG_SYSTEM) != null;
|
||||
mSessionVerifiedMap.put(pkg, DEBUG || hasSystemFlag);
|
||||
boolean hasSystemFlag = DEBUG || mAppContext.getPackageName().equals(pkg)
|
||||
|| new PackageManagerHelper(mAppContext)
|
||||
.getApplicationInfo(pkg, user, ApplicationInfo.FLAG_SYSTEM) != null;
|
||||
mSessionVerifiedMap.put(pkg, hasSystemFlag);
|
||||
}
|
||||
}
|
||||
return mSessionVerifiedMap.get(pkg);
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.icons;
|
||||
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
|
||||
import static com.android.launcher3.icons.IconCache.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutInfo.Builder;
|
||||
import android.os.PersistableBundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||
import com.android.launcher3.model.data.PackageItemInfo;
|
||||
import com.android.launcher3.settings.SettingsActivity;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class IconCacheTest {
|
||||
|
||||
private Context mContext;
|
||||
private IconCache mIconCache;
|
||||
|
||||
private ComponentName mMyComponent;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mContext = getInstrumentation().getTargetContext();
|
||||
mMyComponent = new ComponentName(mContext, SettingsActivity.class);
|
||||
|
||||
// In memory icon cache
|
||||
mIconCache = new IconCache(mContext,
|
||||
InvariantDeviceProfile.INSTANCE.get(mContext), null,
|
||||
new LauncherIconProvider(mContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getShortcutInfoBadge_nullComponent_overrideAllowed() throws Exception {
|
||||
String overridePackage = "com.android.settings";
|
||||
ItemInfoWithIcon item = getBadgingInfo(mContext, null, overridePackage);
|
||||
assertTrue(item instanceof PackageItemInfo);
|
||||
assertEquals(((PackageItemInfo) item).packageName, overridePackage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getShortcutInfoBadge_withComponent_overrideAllowed() throws Exception {
|
||||
String overridePackage = "com.android.settings";
|
||||
ItemInfoWithIcon item = getBadgingInfo(mContext, mMyComponent, overridePackage);
|
||||
assertTrue(item instanceof PackageItemInfo);
|
||||
assertEquals(((PackageItemInfo) item).packageName, overridePackage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getShortcutInfoBadge_nullComponent() throws Exception {
|
||||
ItemInfoWithIcon item = getBadgingInfo(mContext, null, null);
|
||||
assertTrue(item instanceof PackageItemInfo);
|
||||
assertEquals(((PackageItemInfo) item).packageName, mContext.getPackageName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getShortcutInfoBadge_withComponent() throws Exception {
|
||||
ItemInfoWithIcon item = getBadgingInfo(mContext, mMyComponent, null);
|
||||
assertTrue(item instanceof AppInfo);
|
||||
assertEquals(((AppInfo) item).componentName, mMyComponent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getShortcutInfoBadge_overrideNotAllowed() throws Exception {
|
||||
String overridePackage = "com.android.settings";
|
||||
String otherPackage = mContext.getPackageName() + ".does.not.exist";
|
||||
Context otherContext = new ContextWrapper(mContext) {
|
||||
@Override
|
||||
public String getPackageName() {
|
||||
return otherPackage;
|
||||
}
|
||||
};
|
||||
ItemInfoWithIcon item = getBadgingInfo(otherContext, null, overridePackage);
|
||||
assertTrue(item instanceof PackageItemInfo);
|
||||
// Badge is set to the original package, and not the override package
|
||||
assertEquals(((PackageItemInfo) item).packageName, otherPackage);
|
||||
}
|
||||
|
||||
private ItemInfoWithIcon getBadgingInfo(Context context,
|
||||
@Nullable ComponentName cn, @Nullable String badgeOverride) throws Exception {
|
||||
Builder builder = new Builder(context, "test-shortcut")
|
||||
.setIntent(new Intent(Intent.ACTION_VIEW))
|
||||
.setTitle("Test");
|
||||
if (cn != null) {
|
||||
builder.setActivity(cn);
|
||||
}
|
||||
if (!TextUtils.isEmpty(badgeOverride)) {
|
||||
PersistableBundle extras = new PersistableBundle();
|
||||
extras.putString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE, badgeOverride);
|
||||
builder.setExtras(extras);
|
||||
}
|
||||
ShortcutInfo info = builder.build();
|
||||
return MODEL_EXECUTOR.submit(() -> mIconCache.getShortcutInfoBadgeItem(info)).get();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user