1 /*
2  * Copyright (C) 2019 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 
17 package com.android.settings.applications;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyInt;
23 import static org.mockito.ArgumentMatchers.anyLong;
24 import static org.mockito.ArgumentMatchers.anyString;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.spy;
28 import static org.mockito.Mockito.when;
29 
30 import android.app.usage.UsageStats;
31 import android.app.usage.UsageStatsManager;
32 import android.content.Context;
33 import android.content.Intent;
34 import android.content.pm.ApplicationInfo;
35 import android.content.pm.ModuleInfo;
36 import android.content.pm.PackageManager;
37 import android.content.pm.ResolveInfo;
38 import android.os.PowerManager;
39 import android.os.UserHandle;
40 import android.os.UserManager;
41 
42 import com.android.settingslib.applications.AppUtils;
43 import com.android.settingslib.applications.ApplicationsState;
44 import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
45 
46 import org.junit.Before;
47 import org.junit.Test;
48 import org.junit.runner.RunWith;
49 import org.mockito.Mock;
50 import org.mockito.MockitoAnnotations;
51 import org.robolectric.RobolectricTestRunner;
52 import org.robolectric.RuntimeEnvironment;
53 import org.robolectric.util.ReflectionHelpers;
54 
55 import java.util.ArrayList;
56 import java.util.Arrays;
57 import java.util.List;
58 
59 @RunWith(RobolectricTestRunner.class)
60 public class RecentAppStatsMixinTest {
61 
62     private static final UserHandle NORMAL_USER = UserHandle.SYSTEM;
63     private static final UserHandle CLONE_USER = new UserHandle(2222);
64     private static final UserHandle WORK_USER = new UserHandle(3333);
65 
66     @Mock
67     private UsageStatsManager mUsageStatsManager;
68     @Mock
69     private UsageStatsManager mWorkUsageStatsManager;
70     @Mock
71     private UserManager mUserManager;
72     @Mock
73     private ApplicationsState mAppState;
74     @Mock
75     private PackageManager mPackageManager;
76     @Mock
77     private ApplicationsState.AppEntry mAppEntry;
78     @Mock
79     private ApplicationInfo mApplicationInfo;
80     @Mock
81     private PowerManager mPowerManager;
82     @Mock
83     private UsageStatsManager mCloneUsageStatsManager;
84     @Mock
85     Context mMockContext;
86 
87     private Context mContext;
88 
89     private RecentAppStatsMixin mRecentAppStatsMixin;
90 
91     @Before
setUp()92     public void setUp() throws PackageManager.NameNotFoundException {
93         MockitoAnnotations.initMocks(this);
94         mContext = spy(RuntimeEnvironment.application);
95         when(mContext.getApplicationContext()).thenReturn(mContext);
96         ReflectionHelpers.setStaticField(ApplicationsState.class, "sInstance", mAppState);
97         doReturn(mUsageStatsManager).when(mContext).getSystemService(UsageStatsManager.class);
98         doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
99         doReturn(mPackageManager).when(mContext).getPackageManager();
100         doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
101         when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
102 
103         doReturn(mMockContext).when(mContext).createContextAsUser(any(), anyInt());
104         doReturn(mMockContext).when(mContext).createPackageContextAsUser(any(), anyInt(), any());
105         when(mUserManager.getUserProfiles())
106                 .thenReturn(new ArrayList<>(Arrays.asList(NORMAL_USER)));
107 
108         mRecentAppStatsMixin = new RecentAppStatsMixin(mContext, 3 /* maximumApps */);
109     }
110 
111     @Test
loadDisplayableRecentApps_oneValidRecentAppSet_shouldHaveOneRecentApp()112     public void loadDisplayableRecentApps_oneValidRecentAppSet_shouldHaveOneRecentApp() {
113         final List<UsageStats> stats = new ArrayList<>();
114         final UsageStats stat1 = new UsageStats();
115         stat1.mLastTimeUsed = System.currentTimeMillis();
116         stat1.mPackageName = "pkg.class";
117         stats.add(stat1);
118         // stat1 is valid app.
119         when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId()))
120                 .thenReturn(mAppEntry);
121         when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
122                 .thenReturn(new ResolveInfo());
123         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
124                 .thenReturn(stats);
125         mAppEntry.info = mApplicationInfo;
126 
127         mRecentAppStatsMixin.loadDisplayableRecentApps(3);
128 
129         assertThat(mRecentAppStatsMixin.mRecentApps.size()).isEqualTo(1);
130     }
131 
132     @Test
loadDisplayableRecentApps_threeValidRecentAppsSet_shouldHaveThreeRecentApps()133     public void loadDisplayableRecentApps_threeValidRecentAppsSet_shouldHaveThreeRecentApps() {
134         final List<UsageStats> stats = new ArrayList<>();
135         final UsageStats stat1 = new UsageStats();
136         final UsageStats stat2 = new UsageStats();
137         final UsageStats stat3 = new UsageStats();
138         stat1.mLastTimeUsed = System.currentTimeMillis();
139         stat1.mPackageName = "pkg.class";
140         stats.add(stat1);
141 
142         stat2.mLastTimeUsed = System.currentTimeMillis();
143         stat2.mPackageName = "pkg.class2";
144         stats.add(stat2);
145 
146         stat3.mLastTimeUsed = System.currentTimeMillis();
147         stat3.mPackageName = "pkg.class3";
148         stats.add(stat3);
149 
150         when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId()))
151                 .thenReturn(mAppEntry);
152         when(mAppState.getEntry(stat2.mPackageName, UserHandle.myUserId()))
153                 .thenReturn(mAppEntry);
154         when(mAppState.getEntry(stat3.mPackageName, UserHandle.myUserId()))
155                 .thenReturn(mAppEntry);
156         when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
157                 .thenReturn(new ResolveInfo());
158         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
159                 .thenReturn(stats);
160         mAppEntry.info = mApplicationInfo;
161 
162         mRecentAppStatsMixin.loadDisplayableRecentApps(3);
163 
164         assertThat(mRecentAppStatsMixin.mRecentApps.size()).isEqualTo(3);
165     }
166 
167     @Test
loadDisplayableRecentApps_oneValidAndTwoInvalidSet_shouldHaveOneRecentApp()168     public void loadDisplayableRecentApps_oneValidAndTwoInvalidSet_shouldHaveOneRecentApp() {
169         final List<UsageStats> stats = new ArrayList<>();
170         final UsageStats stat1 = new UsageStats();
171         final UsageStats stat2 = new UsageStats();
172         final UsageStats stat3 = new UsageStats();
173         stat1.mLastTimeUsed = System.currentTimeMillis();
174         stat1.mPackageName = "pkg.class";
175         stats.add(stat1);
176 
177         stat2.mLastTimeUsed = System.currentTimeMillis();
178         stat2.mPackageName = "com.android.settings";
179         stats.add(stat2);
180 
181         stat3.mLastTimeUsed = System.currentTimeMillis();
182         stat3.mPackageName = "pkg.class3";
183         stats.add(stat3);
184 
185         // stat1, stat2 are valid apps. stat3 is invalid.
186         when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId()))
187                 .thenReturn(mAppEntry);
188         when(mAppState.getEntry(stat2.mPackageName, UserHandle.myUserId()))
189                 .thenReturn(mAppEntry);
190         when(mAppState.getEntry(stat3.mPackageName, UserHandle.myUserId()))
191                 .thenReturn(null);
192         when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
193                 .thenReturn(new ResolveInfo());
194         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
195                 .thenReturn(stats);
196         mAppEntry.info = mApplicationInfo;
197 
198         mRecentAppStatsMixin.loadDisplayableRecentApps(3);
199 
200         // Only stat1. stat2 is skipped because of the package name, stat3 skipped because
201         // it's invalid app.
202         assertThat(mRecentAppStatsMixin.mRecentApps.size()).isEqualTo(1);
203     }
204 
205     @Test
loadDisplayableRecentApps_oneInstantAppSet_shouldHaveOneRecentApp()206     public void loadDisplayableRecentApps_oneInstantAppSet_shouldHaveOneRecentApp() {
207         final List<UsageStats> stats = new ArrayList<>();
208         // Instant app.
209         final UsageStats stat = new UsageStats();
210         stat.mLastTimeUsed = System.currentTimeMillis() + 200;
211         stat.mPackageName = "com.foo.barinstant";
212         stats.add(stat);
213 
214         ApplicationsState.AppEntry statEntry = mock(ApplicationsState.AppEntry.class);
215         statEntry.info = mApplicationInfo;
216 
217         when(mAppState.getEntry(stat.mPackageName, UserHandle.myUserId())).thenReturn(statEntry);
218         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
219                 .thenReturn(stats);
220 
221         // Make sure stat is considered an instant app.
222         ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
223                 (InstantAppDataProvider) (ApplicationInfo info) -> info == statEntry.info);
224 
225         mRecentAppStatsMixin.loadDisplayableRecentApps(3);
226 
227         assertThat(mRecentAppStatsMixin.mRecentApps.size()).isEqualTo(1);
228     }
229 
230     @Test
loadDisplayableRecentApps_withNullAppEntryOrInfo_shouldNotCrash()231     public void loadDisplayableRecentApps_withNullAppEntryOrInfo_shouldNotCrash() {
232         final List<UsageStats> stats = new ArrayList<>();
233         final UsageStats stat1 = new UsageStats();
234         final UsageStats stat2 = new UsageStats();
235         stat1.mLastTimeUsed = System.currentTimeMillis();
236         stat1.mPackageName = "pkg.class";
237         stats.add(stat1);
238 
239         stat2.mLastTimeUsed = System.currentTimeMillis();
240         stat2.mPackageName = "pkg.class2";
241         stats.add(stat2);
242 
243         // app1 has AppEntry with null info, app2 has null AppEntry.
244         mAppEntry.info = null;
245         when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId()))
246                 .thenReturn(mAppEntry);
247         when(mAppState.getEntry(stat2.mPackageName, UserHandle.myUserId()))
248                 .thenReturn(null);
249 
250         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
251                 .thenReturn(stats);
252 
253         // We should not crash here.
254         mRecentAppStatsMixin.loadDisplayableRecentApps(3);
255     }
256 
257     @Test
loadDisplayableRecentApps_hiddenSystemModuleSet_shouldNotHaveHiddenSystemModule()258     public void loadDisplayableRecentApps_hiddenSystemModuleSet_shouldNotHaveHiddenSystemModule() {
259         final List<UsageStats> stats = new ArrayList<>();
260         // Regular app.
261         final UsageStats stat1 = new UsageStats();
262         stat1.mLastTimeUsed = System.currentTimeMillis();
263         stat1.mPackageName = "com.foo.bar";
264         stats.add(stat1);
265 
266         // Hidden system module.
267         final UsageStats stat2 = new UsageStats();
268         stat2.mLastTimeUsed = System.currentTimeMillis() + 200;
269         stat2.mPackageName = "com.foo.hidden";
270         stats.add(stat2);
271 
272         ApplicationsState.AppEntry stat1Entry = mock(ApplicationsState.AppEntry.class);
273         ApplicationsState.AppEntry stat2Entry = mock(ApplicationsState.AppEntry.class);
274         stat1Entry.info = mApplicationInfo;
275         stat2Entry.info = mApplicationInfo;
276 
277         when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId())).thenReturn(stat1Entry);
278         when(mAppState.getEntry(stat2.mPackageName, UserHandle.myUserId())).thenReturn(stat2Entry);
279 
280         final ModuleInfo moduleInfo1 = new ModuleInfo();
281         moduleInfo1.setPackageName(stat1.mPackageName);
282         moduleInfo1.setHidden(false);
283 
284         final ModuleInfo moduleInfo2 = new ModuleInfo();
285         moduleInfo2.setPackageName(stat2.mPackageName);
286         moduleInfo2.setHidden(true);
287 
288         ReflectionHelpers.setStaticField(ApplicationsState.class, "sInstance", null);
289         final List<ModuleInfo> modules = new ArrayList<>();
290         modules.add(moduleInfo2);
291         when(mPackageManager.getInstalledModules(anyInt() /* flags */))
292                 .thenReturn(modules);
293 
294         when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
295                 .thenReturn(new ResolveInfo());
296         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
297                 .thenReturn(stats);
298 
299         mRecentAppStatsMixin.loadDisplayableRecentApps(3);
300 
301         assertThat(mRecentAppStatsMixin.mRecentApps.size()).isEqualTo(1);
302     }
303 
304     @Test
loadDisplayableRecentApps_powerSaverModeOn_shouldHaveEmptyList()305     public void loadDisplayableRecentApps_powerSaverModeOn_shouldHaveEmptyList() {
306         when(mPowerManager.isPowerSaveMode()).thenReturn(true);
307 
308         final List<UsageStats> stats = new ArrayList<>();
309         final UsageStats stat1 = new UsageStats();
310 
311         stat1.mLastTimeUsed = System.currentTimeMillis();
312         stat1.mPackageName = "pkg.class";
313         stats.add(stat1);
314 
315         // stat1, stat2 are valid apps. stat3 is invalid.
316         when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId()))
317                 .thenReturn(mAppEntry);
318         when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
319                 .thenReturn(new ResolveInfo());
320         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
321                 .thenReturn(stats);
322         mAppEntry.info = mApplicationInfo;
323 
324         mRecentAppStatsMixin.loadDisplayableRecentApps(3);
325 
326         assertThat(mRecentAppStatsMixin.mRecentApps).isEmpty();
327     }
328 
329     @Test
loadDisplayableRecentApps_usePersonalAndWorkApps_shouldBeSortedByLastTimeUse()330     public void loadDisplayableRecentApps_usePersonalAndWorkApps_shouldBeSortedByLastTimeUse() {
331         final List<UsageStats> personalStats = new ArrayList<>();
332         final UsageStats stats1 = new UsageStats();
333         final UsageStats stats2 = new UsageStats();
334         stats1.mLastTimeUsed = System.currentTimeMillis();
335         stats1.mPackageName = "personal.pkg.class";
336         personalStats.add(stats1);
337 
338         stats2.mLastTimeUsed = System.currentTimeMillis() - 5000;
339         stats2.mPackageName = "personal.pkg.class2";
340         personalStats.add(stats2);
341 
342         final List<UsageStats> workStats = new ArrayList<>();
343         final UsageStats stat3 = new UsageStats();
344         stat3.mLastTimeUsed = System.currentTimeMillis() - 2000;
345         stat3.mPackageName = "work.pkg.class3";
346         workStats.add(stat3);
347 
348         when(mAppState.getEntry(anyString(), anyInt()))
349                 .thenReturn(mAppEntry);
350         when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
351                 .thenReturn(new ResolveInfo());
352         when(mUserManager.getUserProfiles())
353                 .thenReturn(new ArrayList<>(Arrays.asList(NORMAL_USER, WORK_USER)));
354         when(mMockContext.getSystemService(UsageStatsManager.class))
355                 .thenReturn(mWorkUsageStatsManager);
356         // personal app stats
357         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
358                 .thenReturn(personalStats);
359         // work app stats
360         when(mWorkUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
361                 .thenReturn(workStats);
362         mAppEntry.info = mApplicationInfo;
363 
364         mRecentAppStatsMixin.loadDisplayableRecentApps(3);
365 
366         assertThat(mRecentAppStatsMixin.mRecentApps.size()).isEqualTo(3);
367         assertThat(mRecentAppStatsMixin.mRecentApps.get(0).mUsageStats.mPackageName).isEqualTo(
368                 "personal.pkg.class");
369         assertThat(mRecentAppStatsMixin.mRecentApps.get(1).mUsageStats.mPackageName).isEqualTo(
370                 "work.pkg.class3");
371         assertThat(mRecentAppStatsMixin.mRecentApps.get(2).mUsageStats.mPackageName).isEqualTo(
372                 "personal.pkg.class2");
373     }
374 
375     @Test
loadDisplayableRecentApps_usePersonalAndWorkApps_shouldBeUniquePerProfile()376     public void loadDisplayableRecentApps_usePersonalAndWorkApps_shouldBeUniquePerProfile()
377             throws PackageManager.NameNotFoundException {
378         final String firstAppPackageName = "app1.pkg.class";
379         final String secondAppPackageName = "app2.pkg.class";
380         final List<UsageStats> personalStats = new ArrayList<>();
381         final UsageStats personalStatsFirstApp = new UsageStats();
382         final UsageStats personalStatsFirstAppOlderUse = new UsageStats();
383         final UsageStats personalStatsSecondApp = new UsageStats();
384         personalStatsFirstApp.mLastTimeUsed = System.currentTimeMillis();
385         personalStatsFirstApp.mPackageName = firstAppPackageName;
386         personalStats.add(personalStatsFirstApp);
387 
388         personalStatsFirstAppOlderUse.mLastTimeUsed = System.currentTimeMillis() - 5000;
389         personalStatsFirstAppOlderUse.mPackageName = firstAppPackageName;
390         personalStats.add(personalStatsFirstAppOlderUse);
391 
392         personalStatsSecondApp.mLastTimeUsed = System.currentTimeMillis() - 2000;
393         personalStatsSecondApp.mPackageName = secondAppPackageName;
394         personalStats.add(personalStatsSecondApp);
395 
396         final List<UsageStats> workStats = new ArrayList<>();
397         final UsageStats workStatsSecondApp = new UsageStats();
398         workStatsSecondApp.mLastTimeUsed = System.currentTimeMillis() - 1000;
399         workStatsSecondApp.mPackageName = secondAppPackageName;
400         workStats.add(workStatsSecondApp);
401 
402         when(mAppState.getEntry(anyString(), anyInt()))
403                 .thenReturn(mAppEntry);
404         when(mUserManager.getUserProfiles())
405                 .thenReturn(new ArrayList<>(Arrays.asList(NORMAL_USER, WORK_USER)));
406         when(mMockContext.getSystemService(UsageStatsManager.class))
407                 .thenReturn(mWorkUsageStatsManager);
408         when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
409                 .thenReturn(new ResolveInfo());
410         // personal app stats
411         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
412                 .thenReturn(personalStats);
413         // work app stats
414         when(mWorkUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
415                 .thenReturn(workStats);
416         mAppEntry.info = mApplicationInfo;
417 
418         mRecentAppStatsMixin.loadDisplayableRecentApps(3);
419 
420         // The output should have the first app once since the duplicate use in the personal profile
421         // is filtered out, and the second app twice - once for each profile.
422         assertThat(mRecentAppStatsMixin.mRecentApps.size()).isEqualTo(3);
423         assertThat(mRecentAppStatsMixin.mRecentApps.get(0).mUsageStats.mPackageName).isEqualTo(
424                 firstAppPackageName);
425         assertThat(mRecentAppStatsMixin.mRecentApps.get(1).mUsageStats.mPackageName).isEqualTo(
426                 secondAppPackageName);
427         assertThat(mRecentAppStatsMixin.mRecentApps.get(2).mUsageStats.mPackageName).isEqualTo(
428                 secondAppPackageName);
429     }
430 
431     @Test
loadDisplayableRecentApps_multipleProfileApps_shouldBeSortedByLastTimeUse()432     public void loadDisplayableRecentApps_multipleProfileApps_shouldBeSortedByLastTimeUse()
433             throws PackageManager.NameNotFoundException {
434         final List<UsageStats> personalStats = new ArrayList<>();
435         final UsageStats stats1 = new UsageStats();
436         final UsageStats stats2 = new UsageStats();
437         stats1.mLastTimeUsed = System.currentTimeMillis();
438         stats1.mPackageName = "personal.pkg.class";
439         personalStats.add(stats1);
440 
441         stats2.mLastTimeUsed = System.currentTimeMillis() - 5000;
442         stats2.mPackageName = "personal.pkg.class2";
443         personalStats.add(stats2);
444 
445         final List<UsageStats> workStats = new ArrayList<>();
446         final UsageStats stat3 = new UsageStats();
447         stat3.mLastTimeUsed = System.currentTimeMillis() - 2000;
448         stat3.mPackageName = "work.pkg.class3";
449         workStats.add(stat3);
450 
451         final List<UsageStats> cloneStats = new ArrayList<>();
452         final UsageStats stat4 = new UsageStats();
453         stat4.mLastTimeUsed = System.currentTimeMillis() - 1000;
454         stat4.mPackageName = "clone.pkg.class4";
455         cloneStats.add(stat4);
456 
457         when(mAppState.getEntry(anyString(), anyInt()))
458                 .thenReturn(mAppEntry);
459         when(mUserManager.getUserProfiles())
460                 .thenReturn(new ArrayList<>(Arrays.asList(NORMAL_USER, CLONE_USER, WORK_USER)));
461         when(mMockContext.getSystemService(UsageStatsManager.class))
462                 .thenReturn(mCloneUsageStatsManager, mWorkUsageStatsManager);
463         when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
464                 .thenReturn(new ResolveInfo());
465         // personal app stats
466         when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
467                 .thenReturn(personalStats);
468         // work app stats
469         when(mWorkUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
470                 .thenReturn(workStats);
471         // clone app stats
472         when(mCloneUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
473                 .thenReturn(cloneStats);
474 
475         mAppEntry.info = mApplicationInfo;
476 
477         mRecentAppStatsMixin.loadDisplayableRecentApps(4);
478 
479         assertThat(mRecentAppStatsMixin.mRecentApps.size()).isEqualTo(4);
480         assertThat(mRecentAppStatsMixin.mRecentApps.get(0).mUsageStats.mPackageName).isEqualTo(
481                 "personal.pkg.class");
482         assertThat(mRecentAppStatsMixin.mRecentApps.get(1).mUsageStats.mPackageName).isEqualTo(
483                 "clone.pkg.class4");
484         assertThat(mRecentAppStatsMixin.mRecentApps.get(2).mUsageStats.mPackageName).isEqualTo(
485                 "work.pkg.class3");
486         assertThat(mRecentAppStatsMixin.mRecentApps.get(3).mUsageStats.mPackageName).isEqualTo(
487                 "personal.pkg.class2");
488     }
489 }
490