Merge "Improve launch time for Apps & notifications page"
diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java
index fe52a8b..838d758 100644
--- a/src/com/android/settings/applications/RecentAppsPreferenceController.java
+++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java
@@ -82,6 +82,8 @@
Preference mAllAppPref;
@VisibleForTesting
Preference mDivider;
+ @VisibleForTesting
+ boolean mIsFirstLaunch;
private final PackageManager mPm;
private final UsageStatsManager mUsageStatsManager;
@@ -93,6 +95,7 @@
private Fragment mHost;
private Calendar mCal;
private List<UsageStats> mStats;
+ private List<UsageStats> mRecentApps;
private boolean mHasRecentApps;
static {
@@ -115,6 +118,9 @@
mIconDrawableFactory = IconDrawableFactory.newInstance(mContext);
mPowerManager = mContext.getSystemService(PowerManager.class);
mUsageStatsManager = mContext.getSystemService(UsageStatsManager.class);
+ mRecentApps = new ArrayList<>();
+ mIsFirstLaunch = true;
+ reloadData();
}
public void setFragment(Fragment fragment) {
@@ -123,8 +129,7 @@
@Override
public int getAvailabilityStatus() {
- reloadData();
- return getDisplayableRecentAppList().isEmpty() ? AVAILABLE_UNSEARCHABLE : AVAILABLE;
+ return mRecentApps.isEmpty() ? AVAILABLE_UNSEARCHABLE : AVAILABLE;
}
@Override
@@ -152,7 +157,11 @@
@Override
public void updateState(Preference preference) {
super.updateState(preference);
- refreshUi();
+ // In order to improve launch time, we don't load data again at first launch.
+ if (!mIsFirstLaunch) {
+ reloadData();
+ refreshUi();
+ }
// Show total number of installed apps as See all's summary.
new InstalledAppCounter(mContext, InstalledAppCounter.IGNORE_INSTALL_REASON,
mContext.getPackageManager()) {
@@ -167,6 +176,7 @@
}
}
}.execute();
+ mIsFirstLaunch = false;
}
@Override
@@ -177,11 +187,9 @@
@VisibleForTesting
void refreshUi() {
- reloadData();
- final List<UsageStats> recentApps = getDisplayableRecentAppList();
- if (recentApps != null && !recentApps.isEmpty()) {
+ if (mRecentApps != null && !mRecentApps.isEmpty()) {
mHasRecentApps = true;
- displayRecentApps(recentApps);
+ displayRecentApps();
} else {
mHasRecentApps = false;
displayOnlyAppInfo();
@@ -197,6 +205,8 @@
: mUsageStatsManager.queryUsageStats(
UsageStatsManager.INTERVAL_BEST, mCal.getTimeInMillis(),
System.currentTimeMillis());
+
+ updateDisplayableRecentAppList();
}
private void displayOnlyAppInfo() {
@@ -206,10 +216,10 @@
mRecentAppsPreference.setVisible(false);
}
- private void displayRecentApps(List<UsageStats> recentApps) {
+ private void displayRecentApps() {
int showAppsCount = 0;
- for (UsageStats stat : recentApps) {
+ for (UsageStats stat : mRecentApps) {
final AppEntityInfo appEntityInfoInfo = createAppEntity(stat);
if (appEntityInfoInfo != null) {
mAppEntitiesController.setAppEntity(showAppsCount++, appEntityInfoInfo);
@@ -246,8 +256,8 @@
.build();
}
- private List<UsageStats> getDisplayableRecentAppList() {
- final List<UsageStats> recentApps = new ArrayList<>();
+ private void updateDisplayableRecentAppList() {
+ mRecentApps.clear();
final Map<String, UsageStats> map = new ArrayMap<>();
final int statCount = mStats.size();
for (int i = 0; i < statCount; i++) {
@@ -273,13 +283,12 @@
if (appEntry == null) {
continue;
}
- recentApps.add(stat);
+ mRecentApps.add(stat);
count++;
if (count >= AppEntitiesHeaderController.MAXIMUM_APPS) {
break;
}
}
- return recentApps;
}
diff --git a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
index 1411bc0..e2a1657 100644
--- a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
@@ -25,9 +25,9 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -146,6 +146,7 @@
when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
.thenReturn(stats);
mAppEntry.info = mApplicationInfo;
+ mController.reloadData();
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@@ -157,13 +158,17 @@
}
@Test
- public void displayPreferenceAndUpdateState_shouldRefreshUi() {
- doNothing().when(mController).refreshUi();
-
+ public void displayPreference_shouldNotReloadData() {
mController.displayPreference(mScreen);
- mController.updateState(mScreen);
- verify(mController, times(2)).refreshUi();
+ verify(mController, never()).reloadData();
+ }
+
+ @Test
+ public void displayPreference_shouldRefreshUi() {
+ mController.displayPreference(mScreen);
+
+ verify(mController).refreshUi();
}
@Test
@@ -174,6 +179,25 @@
}
@Test
+ public void updateState_firstLaunch_shouldNotReloadData() {
+ mController.mIsFirstLaunch = true;
+
+ mController.updateState(mRecentAppsPreference);
+
+ verify(mController, never()).reloadData();
+ }
+
+ @Test
+ public void updateState_afterFirstLaunch_shouldReloadDataAndRefreshUi() {
+ mController.mIsFirstLaunch = false;
+
+ mController.updateState(mRecentAppsPreference);
+
+ verify(mController).reloadData();
+ verify(mController).refreshUi();
+ }
+
+ @Test
public void updateState_threeValidRecentOpenAppsSet_setAppEntityThreeTime() {
final List<UsageStats> stats = new ArrayList<>();
final UsageStats stat1 = new UsageStats();
@@ -203,6 +227,7 @@
when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
.thenReturn(stats);
mAppEntry.info = mApplicationInfo;
+ mController.mIsFirstLaunch = false;
mController.updateState(mRecentAppsPreference);
@@ -243,6 +268,7 @@
when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
.thenReturn(stats);
mAppEntry.info = mApplicationInfo;
+ mController.mIsFirstLaunch = false;
mController.updateState(mRecentAppsPreference);
@@ -274,6 +300,7 @@
when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
.thenReturn(stats);
mAppEntry.info = mApplicationInfo;
+ mController.mIsFirstLaunch = false;
mController.updateState(mRecentAppsPreference);
@@ -314,6 +341,7 @@
// Make sure stat2 is considered an instant app.
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
(InstantAppDataProvider) (ApplicationInfo info) -> info == stat2Entry.info);
+ mController.mIsFirstLaunch = false;
mController.updateState(mRecentAppsPreference);
@@ -389,6 +417,7 @@
.thenReturn(new ResolveInfo());
when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
.thenReturn(stats);
+ mController.mIsFirstLaunch = false;
mController.updateState(mRecentAppsPreference);