1 package com.android.launcher3.model; 2 3 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; 4 import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY; 5 import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY2; 6 import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY3; 7 import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE; 8 import static com.android.launcher3.util.TestUtil.runOnExecutorSync; 9 10 import static org.junit.Assert.assertEquals; 11 12 import androidx.test.ext.junit.runners.AndroidJUnit4; 13 import androidx.test.filters.SmallTest; 14 15 import com.android.launcher3.model.data.ItemInfo; 16 import com.android.launcher3.model.data.LauncherAppWidgetInfo; 17 import com.android.launcher3.model.data.WorkspaceItemInfo; 18 import com.android.launcher3.pm.PackageInstallInfo; 19 import com.android.launcher3.util.IntSet; 20 import com.android.launcher3.util.LauncherLayoutBuilder; 21 import com.android.launcher3.util.LauncherModelHelper; 22 23 import org.junit.After; 24 import org.junit.Before; 25 import org.junit.Test; 26 import org.junit.runner.RunWith; 27 28 /** 29 * Tests for {@link PackageInstallStateChangedTask} 30 */ 31 @SmallTest 32 @RunWith(AndroidJUnit4.class) 33 public class PackageInstallStateChangedTaskTest { 34 35 private static final String PENDING_APP_1 = TEST_PACKAGE + ".pending1"; 36 private static final String PENDING_APP_2 = TEST_PACKAGE + ".pending2"; 37 38 private LauncherModelHelper mModelHelper; 39 private IntSet mDownloadingApps; 40 41 @Before setup()42 public void setup() throws Exception { 43 mModelHelper = new LauncherModelHelper(); 44 mModelHelper.createInstallerSession(PENDING_APP_1); 45 mModelHelper.createInstallerSession(PENDING_APP_2); 46 47 LauncherLayoutBuilder builder = new LauncherLayoutBuilder() 48 .atWorkspace(0, 0, 1).putApp(TEST_PACKAGE, TEST_ACTIVITY) // 1 49 .atWorkspace(0, 0, 2).putApp(TEST_PACKAGE, TEST_ACTIVITY2) // 2 50 .atWorkspace(0, 0, 3).putApp(TEST_PACKAGE, TEST_ACTIVITY3) // 3 51 52 .atWorkspace(0, 0, 4).putApp(PENDING_APP_1, TEST_ACTIVITY) // 4 53 .atWorkspace(0, 0, 5).putApp(PENDING_APP_1, TEST_ACTIVITY2) // 5 54 .atWorkspace(0, 0, 6).putApp(PENDING_APP_1, TEST_ACTIVITY3) // 6 55 .atWorkspace(0, 0, 7).putWidget(PENDING_APP_1, "pending.widget", 1, 1) // 7 56 57 .atWorkspace(0, 0, 8).putApp(PENDING_APP_2, TEST_ACTIVITY) // 8 58 .atWorkspace(0, 0, 9).putApp(PENDING_APP_2, TEST_ACTIVITY2) // 9 59 .atWorkspace(0, 0, 10).putApp(PENDING_APP_2, TEST_ACTIVITY3); // 10 60 61 mDownloadingApps = IntSet.wrap(4, 5, 6, 7, 8, 9, 10); 62 mModelHelper.setupDefaultLayoutProvider(builder); 63 mModelHelper.loadModelSync(); 64 assertEquals(10, mModelHelper.getBgDataModel().itemsIdMap.size()); 65 } 66 67 @After tearDown()68 public void tearDown() { 69 mModelHelper.destroy(); 70 } 71 newTask(String pkg, int progress)72 private PackageInstallStateChangedTask newTask(String pkg, int progress) { 73 int state = PackageInstallInfo.STATUS_INSTALLING; 74 PackageInstallInfo installInfo = new PackageInstallInfo(pkg, state, progress, 75 android.os.Process.myUserHandle()); 76 return new PackageInstallStateChangedTask(installInfo); 77 } 78 79 @Test testSessionUpdate_ignore_installed()80 public void testSessionUpdate_ignore_installed() { 81 // Run on model executor so that no other task runs in the middle. 82 runOnExecutorSync(MODEL_EXECUTOR, () -> { 83 mModelHelper.getModel().enqueueModelUpdateTask(newTask(TEST_PACKAGE, 30)); 84 85 // No shortcuts were updated 86 verifyProgressUpdate(0); 87 }); 88 } 89 90 @Test testSessionUpdate_shortcuts_updated()91 public void testSessionUpdate_shortcuts_updated() { 92 // Run on model executor so that no other task runs in the middle. 93 runOnExecutorSync(MODEL_EXECUTOR, () -> { 94 mModelHelper.getModel().enqueueModelUpdateTask(newTask(PENDING_APP_1, 30)); 95 96 verifyProgressUpdate(30, 4, 5, 6, 7); 97 }); 98 } 99 100 @Test testSessionUpdate_widgets_updated()101 public void testSessionUpdate_widgets_updated() { 102 // Run on model executor so that no other task runs in the middle. 103 runOnExecutorSync(MODEL_EXECUTOR, () -> { 104 mModelHelper.getModel().enqueueModelUpdateTask(newTask(PENDING_APP_2, 30)); 105 106 verifyProgressUpdate(30, 8, 9, 10); 107 }); 108 } 109 verifyProgressUpdate(int progress, int... idsUpdated)110 private void verifyProgressUpdate(int progress, int... idsUpdated) { 111 IntSet updates = IntSet.wrap(idsUpdated); 112 for (ItemInfo info : mModelHelper.getBgDataModel().itemsIdMap) { 113 int expectedProgress = updates.contains(info.id) ? progress 114 : (mDownloadingApps.contains(info.id) ? 0 : 100); 115 if (info instanceof WorkspaceItemInfo wi) { 116 assertEquals(expectedProgress, wi.getProgressLevel()); 117 } else { 118 assertEquals(expectedProgress, ((LauncherAppWidgetInfo) info).installProgress); 119 } 120 } 121 } 122 } 123