1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.launcher3.icons;
17 
18 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
19 
20 import static com.android.launcher3.icons.IconCache.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE;
21 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
22 
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertTrue;
25 
26 import android.content.ComponentName;
27 import android.content.Context;
28 import android.content.ContextWrapper;
29 import android.content.Intent;
30 import android.content.pm.ShortcutInfo;
31 import android.content.pm.ShortcutInfo.Builder;
32 import android.os.PersistableBundle;
33 import android.text.TextUtils;
34 
35 import androidx.annotation.Nullable;
36 import androidx.test.ext.junit.runners.AndroidJUnit4;
37 import androidx.test.filters.SmallTest;
38 
39 import com.android.launcher3.InvariantDeviceProfile;
40 import com.android.launcher3.model.data.AppInfo;
41 import com.android.launcher3.model.data.ItemInfoWithIcon;
42 import com.android.launcher3.model.data.PackageItemInfo;
43 import com.android.launcher3.settings.SettingsActivity;
44 
45 import org.junit.Before;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 
49 @SmallTest
50 @RunWith(AndroidJUnit4.class)
51 public class IconCacheTest {
52 
53     private Context mContext;
54     private IconCache mIconCache;
55 
56     private ComponentName mMyComponent;
57 
58     @Before
setup()59     public void setup() {
60         mContext = getInstrumentation().getTargetContext();
61         mMyComponent = new ComponentName(mContext, SettingsActivity.class);
62 
63         // In memory icon cache
64         mIconCache = new IconCache(mContext,
65                 InvariantDeviceProfile.INSTANCE.get(mContext), null,
66                 new LauncherIconProvider(mContext));
67     }
68 
69     @Test
getShortcutInfoBadge_nullComponent_overrideAllowed()70     public void getShortcutInfoBadge_nullComponent_overrideAllowed() throws Exception {
71         String overridePackage = "com.android.settings";
72         ItemInfoWithIcon item = getBadgingInfo(mContext, null, overridePackage);
73         assertTrue(item instanceof PackageItemInfo);
74         assertEquals(((PackageItemInfo) item).packageName, overridePackage);
75     }
76 
77     @Test
getShortcutInfoBadge_withComponent_overrideAllowed()78     public void getShortcutInfoBadge_withComponent_overrideAllowed() throws Exception {
79         String overridePackage = "com.android.settings";
80         ItemInfoWithIcon item = getBadgingInfo(mContext, mMyComponent, overridePackage);
81         assertTrue(item instanceof PackageItemInfo);
82         assertEquals(((PackageItemInfo) item).packageName, overridePackage);
83     }
84 
85     @Test
getShortcutInfoBadge_nullComponent()86     public void getShortcutInfoBadge_nullComponent() throws Exception {
87         ItemInfoWithIcon item = getBadgingInfo(mContext, null, null);
88         assertTrue(item instanceof PackageItemInfo);
89         assertEquals(((PackageItemInfo) item).packageName, mContext.getPackageName());
90     }
91 
92     @Test
getShortcutInfoBadge_withComponent()93     public void getShortcutInfoBadge_withComponent() throws Exception {
94         ItemInfoWithIcon item = getBadgingInfo(mContext, mMyComponent, null);
95         assertTrue(item instanceof AppInfo);
96         assertEquals(((AppInfo) item).componentName, mMyComponent);
97     }
98 
99     @Test
getShortcutInfoBadge_overrideNotAllowed()100     public void getShortcutInfoBadge_overrideNotAllowed() throws Exception {
101         String overridePackage = "com.android.settings";
102         String otherPackage = mContext.getPackageName() + ".does.not.exist";
103         Context otherContext = new ContextWrapper(mContext) {
104             @Override
105             public String getPackageName() {
106                 return otherPackage;
107             }
108         };
109         ItemInfoWithIcon item = getBadgingInfo(otherContext, null, overridePackage);
110         assertTrue(item instanceof PackageItemInfo);
111         // Badge is set to the original package, and not the override package
112         assertEquals(((PackageItemInfo) item).packageName, otherPackage);
113     }
114 
getBadgingInfo(Context context, @Nullable ComponentName cn, @Nullable String badgeOverride)115     private ItemInfoWithIcon getBadgingInfo(Context context,
116             @Nullable ComponentName cn, @Nullable String badgeOverride) throws Exception {
117         Builder builder = new Builder(context, "test-shortcut")
118                 .setIntent(new Intent(Intent.ACTION_VIEW))
119                 .setShortLabel("Test");
120         if (cn != null) {
121             builder.setActivity(cn);
122         }
123         if (!TextUtils.isEmpty(badgeOverride)) {
124             PersistableBundle extras = new PersistableBundle();
125             extras.putString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE, badgeOverride);
126             builder.setExtras(extras);
127         }
128         ShortcutInfo info = builder.build();
129         return MODEL_EXECUTOR.submit(() -> mIconCache.getShortcutInfoBadgeItem(info)).get();
130     }
131 }
132