OSDN Git Service

Extract method to filter real pinned apps in TaskbarController
authorutzcoz <utzcoz@outlook.com>
Mon, 8 Jun 2020 05:10:14 +0000 (13:10 +0800)
committerutzcoz <utzcoz@outlook.com>
Mon, 8 Jun 2020 07:01:37 +0000 (15:01 +0800)
Robolectric doesn't support LauncherApps.isPackageEnabled in this shadow
implementation, so we should add a new implementation to support it. And
we should ignore custom shadows from powermock to avoid the problem
that the classloader of custom shadow isn't equals to classloader
used by robolectric. For example, if we don't ignore custom shadow from
powermock, the following casting can't be executed:

TaskbarShadowLauncherApps shadowLauncherApps =
Shadows.shadowOf(launcherApps);

Test: ./gradlew test

Signed-off-by: utzcoz <utzcoz@outlook.com>
app/src/main/java/com/farmerbb/taskbar/ui/TaskbarController.java
app/src/test/java/com/farmerbb/taskbar/shadow/TaskbarShadowLauncherApps.java [new file with mode: 0644]
app/src/test/java/com/farmerbb/taskbar/shadow/TaskbarShadowScrollView.java [moved from app/src/test/java/com/farmerbb/taskbar/ui/TaskbarShadowScrollView.java with 91% similarity]
app/src/test/java/com/farmerbb/taskbar/ui/TaskbarControllerTest.java

index 3664e00..1f50eb1 100644 (file)
@@ -771,7 +771,6 @@ public class TaskbarController extends UIController {
         final List<AppEntry> entries = new ArrayList<>();
         List<LauncherActivityInfo> launcherAppCache = new ArrayList<>();
         int maxNumOfEntries = firstRefresh ? 0 : U.getMaxNumOfEntries(context);
-        int realNumOfPinnedApps = 0;
         boolean fullLength = pref.getBoolean(PREF_FULL_LENGTH, true);
 
         PinnedBlockedApps pba = PinnedBlockedApps.getInstance(context);
@@ -780,24 +779,8 @@ public class TaskbarController extends UIController {
         List<String> applicationIdsToRemove = new ArrayList<>();
 
         // Filter out anything on the pinned/blocked apps lists
-        if(pinnedApps.size() > 0) {
-            UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-            LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
-
-            for(AppEntry entry : pinnedApps) {
-                boolean packageEnabled = launcherApps.isPackageEnabled(entry.getPackageName(),
-                        userManager.getUserForSerialNumber(entry.getUserId(context)));
-
-                if(packageEnabled)
-                    entries.add(entry);
-                else
-                    realNumOfPinnedApps--;
-
-                applicationIdsToRemove.add(entry.getPackageName());
-            }
-
-            realNumOfPinnedApps = realNumOfPinnedApps + pinnedApps.size();
-        }
+        int realNumOfPinnedApps =
+                filterRealPinnedApps(context, pinnedApps, entries, applicationIdsToRemove);
 
         if(blockedApps.size() > 0) {
             for(AppEntry entry : blockedApps) {
@@ -1182,6 +1165,33 @@ public class TaskbarController extends UIController {
         }
     }
 
+    @VisibleForTesting
+    public int filterRealPinnedApps(Context context,
+                                    List<AppEntry> pinnedApps,
+                                    List<AppEntry> entries,
+                                    List<String> applicationIdsToRemove) {
+        int realNumOfPinnedApps = 0;
+        if(pinnedApps.size() > 0) {
+            UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+            LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
+
+            for(AppEntry entry : pinnedApps) {
+                boolean packageEnabled = launcherApps.isPackageEnabled(entry.getPackageName(),
+                        userManager.getUserForSerialNumber(entry.getUserId(context)));
+
+                if(packageEnabled)
+                    entries.add(entry);
+                else
+                    realNumOfPinnedApps--;
+
+                applicationIdsToRemove.add(entry.getPackageName());
+            }
+
+            realNumOfPinnedApps = realNumOfPinnedApps + pinnedApps.size();
+        }
+        return realNumOfPinnedApps;
+    }
+
     private void updateRunningAppIndicators(List<AppEntry> pinnedApps, List<AppEntry> usageStatsList, List<AppEntry> entries) {
         if(taskbar.getChildCount() != entries.size())
             return;
diff --git a/app/src/test/java/com/farmerbb/taskbar/shadow/TaskbarShadowLauncherApps.java b/app/src/test/java/com/farmerbb/taskbar/shadow/TaskbarShadowLauncherApps.java
new file mode 100644 (file)
index 0000000..7fee78d
--- /dev/null
@@ -0,0 +1,37 @@
+package com.farmerbb.taskbar.shadow;
+
+import android.content.pm.LauncherApps;
+import android.os.UserHandle;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowLauncherApps;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.os.Build.VERSION_CODES.LOLLIPOP;
+
+@Implements(value = LauncherApps.class, minSdk = LOLLIPOP)
+public class TaskbarShadowLauncherApps extends ShadowLauncherApps {
+    private static final List<String> enabledPackages = new ArrayList<>();
+
+    public static void addEnabledPackages(String packageName) {
+        if (!enabledPackages.contains(packageName)) {
+            enabledPackages.add(packageName);
+        }
+    }
+
+    public static void removeEnabledPackage(String packageName) {
+        enabledPackages.remove(packageName);
+    }
+
+    public static void reset() {
+        enabledPackages.clear();
+    }
+
+    @Implementation
+    protected boolean isPackageEnabled(String packageName, UserHandle user) {
+        return enabledPackages.contains(packageName);
+    }
+}
index aafd803..5c61e56 100644 (file)
@@ -27,6 +27,9 @@ import com.farmerbb.taskbar.activity.MainActivity;
 import com.farmerbb.taskbar.activity.SecondaryHomeActivity;
 import com.farmerbb.taskbar.mockito.BooleanAnswer;
 import com.farmerbb.taskbar.mockito.StringAnswer;
+import com.farmerbb.taskbar.shadow.TaskbarShadowLauncherApps;
+import com.farmerbb.taskbar.shadow.TaskbarShadowScrollView;
+import com.farmerbb.taskbar.util.AppEntry;
 import com.farmerbb.taskbar.util.DisplayInfo;
 import com.farmerbb.taskbar.util.TaskbarPosition;
 import com.farmerbb.taskbar.util.U;
@@ -77,7 +80,8 @@ import static org.powermock.api.mockito.PowerMockito.when;
 import static org.robolectric.Shadows.shadowOf;
 
 @RunWith(RobolectricTestRunner.class)
-@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*", "androidx.*"})
+@PowerMockIgnore({"org.mockito.*", "org.robolectric.*",
+        "android.*", "androidx.*", "com.farmerbb.taskbar.shadow.*"})
 @PrepareForTest(value = {U.class, TaskbarPosition.class})
 public class TaskbarControllerTest {
     @Rule
@@ -101,6 +105,7 @@ public class TaskbarControllerTest {
     @After
     public void tearDown() {
         prefs.edit().remove(PREF_START_BUTTON_IMAGE).apply();
+        TaskbarShadowLauncherApps.reset();
 
         uiController.onDestroyHost(host);
     }
@@ -588,6 +593,53 @@ public class TaskbarControllerTest {
         }
     }
 
+    @Test
+    @Config(shadows = TaskbarShadowLauncherApps.class)
+    public void testFilterRealPinnedApps() {
+        List<AppEntry> pinnedApps = new ArrayList<>();
+        List<AppEntry> entries = new ArrayList<>();
+        List<String> applicationIdsToRemove = new ArrayList<>();
+
+        int realNumOfPinnedApps = uiController.filterRealPinnedApps(
+                context, pinnedApps, entries, applicationIdsToRemove
+        );
+        assertEquals(0, realNumOfPinnedApps);
+
+        AppEntry appEntry = generateTestAppEntry(1);
+        pinnedApps.add(appEntry);
+        TaskbarShadowLauncherApps.addEnabledPackages(appEntry.getPackageName());
+        realNumOfPinnedApps = uiController.filterRealPinnedApps(
+                context, pinnedApps, entries, applicationIdsToRemove
+        );
+        assertEquals(1, realNumOfPinnedApps);
+        assertEquals(appEntry.getPackageName(), applicationIdsToRemove.get(0));
+        assertEquals(appEntry, entries.get(0));
+        applicationIdsToRemove.clear();
+        entries.clear();
+
+        appEntry = generateTestAppEntry(2);
+        pinnedApps.add(appEntry);
+        realNumOfPinnedApps = uiController.filterRealPinnedApps(
+                context, pinnedApps, entries, applicationIdsToRemove
+        );
+        assertEquals(1, realNumOfPinnedApps);
+        assertEquals(2, applicationIdsToRemove.size());
+        assertEquals(1, entries.size());
+    }
+
+    private AppEntry generateTestAppEntry(int index) {
+        AppEntry appEntry =
+                new AppEntry(
+                        "test-package-" + index,
+                        "test-component" + index,
+                        "test-label-" + index,
+                        null,
+                        false
+                );
+        appEntry.setUserId(0);
+        return appEntry;
+    }
+
     private UsageEvents.Event buildTaskbarForegroundAppEvent(String className, long timestamp) {
         return EventBuilder
                 .buildEvent()