diff options
author | 2024-08-06 13:46:56 -0700 | |
---|---|---|
committer | 2024-08-14 14:12:19 -0700 | |
commit | 2f6086166956949bc5ab732795f671b1800cb613 (patch) | |
tree | 886f3dcfeda08675aed66ed77791b08aaf43db1b /tests | |
parent | 6872117b988dbf42ab81f078c5c27f8182517d0a (diff) |
Add timeout for AppPredictor response.
Timeout AppPredictor callbacks and fallback to ShortcutManager.
Bug: 295956687
Bug: 343300158
Test: atest IntentResolver-tests-unit
Flag: com.android.intentresolver.fix_shortcuts_flashing
Change-Id: Ia6e5643451a840e10213f242c6c79364b0193e78
Diffstat (limited to 'tests')
-rw-r--r-- | tests/unit/src/com/android/intentresolver/shortcuts/ShortcutLoaderTest.kt | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/tests/unit/src/com/android/intentresolver/shortcuts/ShortcutLoaderTest.kt b/tests/unit/src/com/android/intentresolver/shortcuts/ShortcutLoaderTest.kt index 9c84cdcf..d11cb460 100644 --- a/tests/unit/src/com/android/intentresolver/shortcuts/ShortcutLoaderTest.kt +++ b/tests/unit/src/com/android/intentresolver/shortcuts/ShortcutLoaderTest.kt @@ -26,9 +26,11 @@ import android.content.pm.PackageManager.ApplicationInfoFlags import android.content.pm.ShortcutManager import android.os.UserHandle import android.os.UserManager +import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.SetFlagsRule import androidx.test.filters.SmallTest +import com.android.intentresolver.Flags.FLAG_FIX_SHORTCUTS_FLASHING import com.android.intentresolver.Flags.FLAG_FIX_SHORTCUT_LOADER_JOB_LEAK import com.android.intentresolver.chooser.DisplayResolveInfo import com.android.intentresolver.createAppTarget @@ -323,6 +325,143 @@ class ShortcutLoaderTest { } @Test + @DisableFlags(FLAG_FIX_SHORTCUTS_FLASHING) + fun test_appPredictorNotResponding_noCallbackFromShortcutLoader() { + scope.runTest { + val shortcutManagerResult = + listOf( + ShortcutManager.ShareShortcutInfo(matchingShortcutInfo, componentName), + // mismatching shortcut + createShareShortcutInfo("id-1", ComponentName("mismatching.pkg", "Class"), 1) + ) + val shortcutManager = + mock<ShortcutManager> { + on { getShareTargets(intentFilter) } doReturn shortcutManagerResult + } + whenever(context.getSystemService(Context.SHORTCUT_SERVICE)).thenReturn(shortcutManager) + val testSubject = + ShortcutLoader( + context, + backgroundScope, + appPredictor, + UserHandle.of(0), + true, + intentFilter, + dispatcher, + callback + ) + + testSubject.updateAppTargets(appTargets) + + verify(appPredictor, times(1)).requestPredictionUpdate() + + scheduler.advanceTimeBy(ShortcutLoader.APP_PREDICTOR_RESPONSE_TIMEOUT_MS * 2) + verify(callback, never()).accept(any()) + } + } + + @Test + @EnableFlags(FLAG_FIX_SHORTCUTS_FLASHING) + fun test_appPredictorNotResponding_timeoutAndFallbackToShortcutManager() { + scope.runTest { + val testSubject = + ShortcutLoader( + context, + backgroundScope, + appPredictor, + UserHandle.of(0), + true, + intentFilter, + dispatcher, + callback + ) + + testSubject.updateAppTargets(appTargets) + + val matchingAppTarget = createAppTarget(matchingShortcutInfo) + val shortcuts = + listOf( + matchingAppTarget, + // an AppTarget that does not belong to any resolved application; should be + // ignored + createAppTarget( + createShortcutInfo("id-1", ComponentName("mismatching.pkg", "Class"), 1) + ) + ) + val appPredictorCallbackCaptor = argumentCaptor<AppPredictor.Callback>() + verify(appPredictor, atLeastOnce()) + .registerPredictionUpdates(any(), appPredictorCallbackCaptor.capture()) + appPredictorCallbackCaptor.firstValue.onTargetsAvailable(shortcuts) + + scheduler.advanceTimeBy(ShortcutLoader.APP_PREDICTOR_RESPONSE_TIMEOUT_MS * 2) + verify(callback, times(1)).accept(any()) + } + } + + @Test + @EnableFlags(FLAG_FIX_SHORTCUTS_FLASHING) + fun test_appPredictorResponding_appPredictorTimeoutJobIsCancelled() { + scope.runTest { + val shortcutManagerResult = + listOf( + ShortcutManager.ShareShortcutInfo(matchingShortcutInfo, componentName), + // mismatching shortcut + createShareShortcutInfo("id-1", ComponentName("mismatching.pkg", "Class"), 1) + ) + val shortcutManager = + mock<ShortcutManager> { + on { getShareTargets(intentFilter) } doReturn shortcutManagerResult + } + whenever(context.getSystemService(Context.SHORTCUT_SERVICE)).thenReturn(shortcutManager) + val testSubject = + ShortcutLoader( + context, + backgroundScope, + appPredictor, + UserHandle.of(0), + true, + intentFilter, + dispatcher, + callback + ) + + testSubject.updateAppTargets(appTargets) + + verify(appPredictor, times(1)).requestPredictionUpdate() + + scheduler.advanceTimeBy(ShortcutLoader.APP_PREDICTOR_RESPONSE_TIMEOUT_MS / 2) + verify(callback, never()).accept(any()) + + val resultCaptor = argumentCaptor<ShortcutLoader.Result>() + scheduler.advanceTimeBy(ShortcutLoader.APP_PREDICTOR_RESPONSE_TIMEOUT_MS) + verify(callback, times(1)).accept(resultCaptor.capture()) + val result = resultCaptor.firstValue + assertWithMessage("An ShortcutManager result is expected") + .that(result.isFromAppPredictor) + .isFalse() + assertWithMessage("Wrong input app targets in the result") + .that(appTargets) + .asList() + .containsExactlyElementsIn(result.appTargets) + .inOrder() + assertWithMessage("Wrong shortcut count").that(result.shortcutsByApp).hasLength(1) + assertWithMessage("Wrong app target") + .that(appTarget) + .isEqualTo(result.shortcutsByApp[0].appTarget) + for (shortcut in result.shortcutsByApp[0].shortcuts) { + assertWithMessage( + "AppTargets are not expected the cache of a ShortcutManager result" + ) + .that(result.directShareAppTargetCache) + .isEmpty() + assertWithMessage("Wrong ShortcutInfo in the cache") + .that(matchingShortcutInfo) + .isEqualTo(result.directShareShortcutInfoCache[shortcut]) + } + } + } + + @Test fun test_ShortcutLoader_shortcutsRequestedIndependentlyFromAppTargets() = scope.runTest { ShortcutLoader( |