1 package com.android.launcher3.model;
2 
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertNotSame;
6 import static org.junit.Assert.assertTrue;
7 
8 import android.content.ComponentName;
9 import android.content.Context;
10 import android.content.pm.PackageInfo;
11 import android.graphics.Bitmap;
12 import android.graphics.Bitmap.Config;
13 import android.graphics.Color;
14 import android.os.Process;
15 import android.os.UserHandle;
16 import android.os.UserManager;
17 
18 import androidx.annotation.NonNull;
19 import androidx.test.ext.junit.runners.AndroidJUnit4;
20 import androidx.test.filters.SmallTest;
21 
22 import com.android.launcher3.LauncherAppState;
23 import com.android.launcher3.icons.BitmapInfo;
24 import com.android.launcher3.icons.IconCache;
25 import com.android.launcher3.icons.cache.CachingLogic;
26 import com.android.launcher3.model.data.AppInfo;
27 import com.android.launcher3.model.data.ItemInfo;
28 import com.android.launcher3.model.data.WorkspaceItemInfo;
29 import com.android.launcher3.util.LauncherModelHelper;
30 
31 import org.junit.After;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 
36 import java.util.Arrays;
37 import java.util.HashSet;
38 
39 /**
40  * Tests for {@link CacheDataUpdatedTask}
41  */
42 @SmallTest
43 @RunWith(AndroidJUnit4.class)
44 public class CacheDataUpdatedTaskTest {
45 
46     private static final String NEW_LABEL_PREFIX = "new-label-";
47 
48     private LauncherModelHelper mModelHelper;
49 
50     @Before
setup()51     public void setup() throws Exception {
52         mModelHelper = new LauncherModelHelper();
53         mModelHelper.initializeData("cache_data_updated_task_data");
54 
55         // Add placeholder entries in the cache to simulate update
56         Context context = mModelHelper.sandboxContext;
57         IconCache iconCache = LauncherAppState.getInstance(context).getIconCache();
58         CachingLogic<ItemInfo> placeholderLogic = new CachingLogic<ItemInfo>() {
59             @Override
60             public ComponentName getComponent(ItemInfo info) {
61                 return info.getTargetComponent();
62             }
63 
64             @Override
65             public UserHandle getUser(ItemInfo info) {
66                 return info.user;
67             }
68 
69             @Override
70             public CharSequence getLabel(ItemInfo info) {
71                 return NEW_LABEL_PREFIX + info.id;
72             }
73 
74             @NonNull
75             @Override
76             public BitmapInfo loadIcon(Context context, ItemInfo info) {
77                 return BitmapInfo.of(Bitmap.createBitmap(1, 1, Config.ARGB_8888), Color.RED);
78             }
79         };
80 
81         UserManager um = context.getSystemService(UserManager.class);
82         for (ItemInfo info : mModelHelper.getBgDataModel().itemsIdMap) {
83             iconCache.addIconToDBAndMemCache(info, placeholderLogic, new PackageInfo(),
84                     um.getSerialNumberForUser(info.user), true);
85         }
86     }
87 
88     @After
tearDown()89     public void tearDown() {
90         mModelHelper.destroy();
91     }
92 
newTask(int op, String... pkg)93     private CacheDataUpdatedTask newTask(int op, String... pkg) {
94         return new CacheDataUpdatedTask(op, Process.myUserHandle(),
95                 new HashSet<>(Arrays.asList(pkg)));
96     }
97 
98     @Test
testCacheUpdate_update_apps()99     public void testCacheUpdate_update_apps() throws Exception {
100         // Clear all icons from apps list so that its easy to check what was updated
101         for (AppInfo info : mModelHelper.getAllAppsList().data) {
102             info.bitmap = BitmapInfo.LOW_RES_INFO;
103         }
104 
105         mModelHelper.executeTaskForTest(newTask(CacheDataUpdatedTask.OP_CACHE_UPDATE, "app1"));
106 
107         // Verify that only the app icons of app1 (id 1 & 2) are updated. Custom shortcut (id 7)
108         // is not updated
109         verifyUpdate(1, 2);
110 
111         // Verify that only app1 var updated in allAppsList
112         assertFalse(mModelHelper.getAllAppsList().data.isEmpty());
113         for (AppInfo info : mModelHelper.getAllAppsList().data) {
114             if (info.componentName.getPackageName().equals("app1")) {
115                 assertFalse(info.bitmap.isNullOrLowRes());
116             } else {
117                 assertTrue(info.bitmap.isNullOrLowRes());
118             }
119         }
120     }
121 
122     @Test
testSessionUpdate_ignores_normal_apps()123     public void testSessionUpdate_ignores_normal_apps() throws Exception {
124         mModelHelper.executeTaskForTest(newTask(CacheDataUpdatedTask.OP_SESSION_UPDATE, "app1"));
125 
126         // app1 has no restored shortcuts. Verify that nothing was updated.
127         verifyUpdate();
128     }
129 
130     @Test
testSessionUpdate_updates_pending_apps()131     public void testSessionUpdate_updates_pending_apps() throws Exception {
132         mModelHelper.executeTaskForTest(newTask(CacheDataUpdatedTask.OP_SESSION_UPDATE, "app3"));
133 
134         // app3 has only restored apps (id 5, 6) and shortcuts (id 9). Verify that only apps were
135         // were updated
136         verifyUpdate(5, 6);
137     }
138 
verifyUpdate(Integer... idsUpdated)139     private void verifyUpdate(Integer... idsUpdated) {
140         HashSet<Integer> updates = new HashSet<>(Arrays.asList(idsUpdated));
141         for (ItemInfo info : mModelHelper.getBgDataModel().itemsIdMap) {
142             if (updates.contains(info.id)) {
143                 assertEquals(NEW_LABEL_PREFIX + info.id, info.title);
144                 assertFalse(((WorkspaceItemInfo) info).bitmap.isNullOrLowRes());
145             } else {
146                 assertNotSame(NEW_LABEL_PREFIX + info.id, info.title);
147                 assertTrue(((WorkspaceItemInfo) info).bitmap.isNullOrLowRes());
148             }
149         }
150     }
151 }
152