Merge "Ensuring that badge override is respected even if component name is set on the Shortcut" into udc-dev

This commit is contained in:
TreeHugger Robot
2023-04-04 00:40:14 +00:00
committed by Android (Google) Code Review
3 changed files with 164 additions and 29 deletions
+29 -26
View File
@@ -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();
}
}