From a6203c3f6a172e72351276bcda75e8b8a5cd8aa9 Mon Sep 17 00:00:00 2001 From: Antony Sargent Date: Fri, 19 Jan 2018 11:04:22 -0800 Subject: [PATCH] Include instant apps in Recently opened apps list We were accidentally excluding instant apps from the recently opened apps list in Settings->Apps and notifications. Test: make RunSettingsRoboTests Change-Id: I9cac956ceacbfba74a79b38cb01afa2de74ee6fe Fixes: 71591298 --- .../RecentAppsPreferenceController.java | 11 +++- .../RecentAppsPreferenceControllerTest.java | 58 +++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java index ee954acf250..20c5581ae8e 100644 --- a/src/com/android/settings/applications/RecentAppsPreferenceController.java +++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java @@ -44,6 +44,7 @@ import com.android.settings.applications.appinfo.AppInfoDashboardFragment; import com.android.settings.core.FeatureFlags; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.widget.AppPreference; +import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.wrapper.PackageManagerWrapper; @@ -321,9 +322,13 @@ public class RecentAppsPreferenceController extends AbstractPreferenceController .setPackage(pkgName); if (mPm.resolveActivity(launchIntent, 0) == null) { - // Not visible on launcher -> likely not a user visible app, skip - Log.d(TAG, "Not a user visible app, skipping " + pkgName); - return false; + // Not visible on launcher -> likely not a user visible app, skip if non-instant. + final ApplicationsState.AppEntry appEntry = + mApplicationsState.getEntry(pkgName, mUserId); + if (!AppUtils.isInstant(appEntry.info)) { + Log.d(TAG, "Not a user visible or instant app, skipping " + pkgName); + return false; + } } return true; } diff --git a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java index 84a121f0ead..bd57211a231 100644 --- a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java @@ -50,16 +50,21 @@ import android.text.TextUtils; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; +import com.android.settingslib.applications.instantapps.InstantAppDataProvider; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; @@ -193,6 +198,55 @@ public class RecentAppsPreferenceControllerTest { verify(mDivider).setVisible(true); } + @Test + public void display_showRecentsWithInstantApp() { + // Regular app. + final List stats = new ArrayList<>(); + final UsageStats stat1 = new UsageStats(); + stat1.mLastTimeUsed = System.currentTimeMillis(); + stat1.mPackageName = "com.foo.bar"; + stats.add(stat1); + + // Instant app. + final UsageStats stat2 = new UsageStats(); + stat2.mLastTimeUsed = System.currentTimeMillis() + 200; + stat2.mPackageName = "com.foo.barinstant"; + stats.add(stat2); + + ApplicationsState.AppEntry stat1Entry = mock(ApplicationsState.AppEntry.class); + ApplicationsState.AppEntry stat2Entry = mock(ApplicationsState.AppEntry.class); + stat1Entry.info = mApplicationInfo; + stat2Entry.info = mApplicationInfo; + + when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId())).thenReturn(stat1Entry); + when(mAppState.getEntry(stat2.mPackageName, UserHandle.myUserId())).thenReturn(stat2Entry); + + // Only the regular app stat1 should have its intent resolve. + when(mPackageManager.resolveActivity(argThat(intentMatcher(stat1.mPackageName)), + anyInt())).thenReturn(new ResolveInfo()); + + when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong())) + .thenReturn(stats); + + // Make sure stat2 is considered an instant app. + ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", + (InstantAppDataProvider) (ApplicationInfo info) -> { + if (info == stat2Entry.info) { + return true; + } else { + return false; + } + }); + + mController.displayPreference(mScreen); + + ArgumentCaptor prefCaptor = ArgumentCaptor.forClass(Preference.class); + verify(mCategory, times(2)).addPreference(prefCaptor.capture()); + List prefs = prefCaptor.getAllValues(); + assertThat(prefs.get(1).getKey()).isEqualTo(stat1.mPackageName); + assertThat(prefs.get(0).getKey()).isEqualTo(stat2.mPackageName); + } + @Test public void display_hasRecentButNoneDisplayable_showAppInfo() { final List stats = new ArrayList<>(); @@ -249,4 +303,8 @@ public class RecentAppsPreferenceControllerTest { return preference -> TextUtils.equals(expected, preference.getSummary()); } + // Used for matching an intent with a specific package name. + private static ArgumentMatcher intentMatcher(String packageName) { + return intent -> packageName.equals(intent.getPackage()); + } }