From e54c1462a38a7bc7d1767c08e6dcdb358f4733f2 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Thu, 6 Jun 2024 18:26:16 -0400 Subject: [PATCH] Test TaskbarAllAppsController non-search behavior. Flag: TEST_ONLY Bug: 230027385, 346394798 Test: TaskbarAllAppsControllerTest Change-Id: Id97e1b82cb8fba48687b5e23222e3bba6695ac4c --- .../allapps/TaskbarAllAppsControllerTest.kt | 185 ++++++++++++++++++ .../notification/NotificationKeyData.java | 6 + 2 files changed, 191 insertions(+) create mode 100644 quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsControllerTest.kt diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsControllerTest.kt new file mode 100644 index 0000000000..c09dcf27de --- /dev/null +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsControllerTest.kt @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.taskbar.allapps + +import android.content.ComponentName +import android.content.Intent +import android.os.Process +import androidx.test.annotation.UiThreadTest +import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation +import com.android.launcher3.BubbleTextView +import com.android.launcher3.appprediction.PredictionRowView +import com.android.launcher3.model.data.AppInfo +import com.android.launcher3.model.data.WorkspaceItemInfo +import com.android.launcher3.notification.NotificationKeyData +import com.android.launcher3.taskbar.TaskbarUnitTestRule +import com.android.launcher3.taskbar.TaskbarUnitTestRule.InjectController +import com.android.launcher3.taskbar.overlay.TaskbarOverlayController +import com.android.launcher3.util.LauncherMultivalentJUnit +import com.android.launcher3.util.LauncherMultivalentJUnit.EmulatedDevices +import com.android.launcher3.util.PackageUserKey +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(LauncherMultivalentJUnit::class) +@EmulatedDevices(["pixelFoldable2023", "pixelTablet2023"]) +class TaskbarAllAppsControllerTest { + + @get:Rule val taskbarUnitTestRule = TaskbarUnitTestRule() + + @InjectController lateinit var allAppsController: TaskbarAllAppsController + @InjectController lateinit var overlayController: TaskbarOverlayController + + @Test + @UiThreadTest + fun testToggle_once_showsAllApps() { + allAppsController.toggle() + assertThat(allAppsController.isOpen).isTrue() + } + + @Test + @UiThreadTest + fun testToggle_twice_closesAllApps() { + allAppsController.toggle() + allAppsController.toggle() + assertThat(allAppsController.isOpen).isFalse() + } + + @Test + @UiThreadTest + fun testToggle_taskbarRecreated_allAppsReopened() { + allAppsController.toggle() + taskbarUnitTestRule.recreateTaskbar() + assertThat(allAppsController.isOpen).isTrue() + } + + @Test + @UiThreadTest + fun testSetApps_beforeOpened_cachesInfo() { + allAppsController.setApps(TEST_APPS, 0, emptyMap()) + allAppsController.toggle() + + val overlayContext = overlayController.requestWindow() + assertThat(overlayContext.appsView.appsStore.apps).isEqualTo(TEST_APPS) + } + + @Test + @UiThreadTest + fun testSetApps_afterOpened_updatesStore() { + allAppsController.toggle() + allAppsController.setApps(TEST_APPS, 0, emptyMap()) + + val overlayContext = overlayController.requestWindow() + assertThat(overlayContext.appsView.appsStore.apps).isEqualTo(TEST_APPS) + } + + @Test + @UiThreadTest + fun testSetPredictedApps_beforeOpened_cachesInfo() { + allAppsController.setPredictedApps(TEST_PREDICTED_APPS) + allAppsController.toggle() + + val predictedApps = + overlayController + .requestWindow() + .appsView + .floatingHeaderView + .findFixedRowByType(PredictionRowView::class.java) + .predictedApps + assertThat(predictedApps).isEqualTo(TEST_PREDICTED_APPS) + } + + @Test + @UiThreadTest + fun testSetPredictedApps_afterOpened_cachesInfo() { + allAppsController.toggle() + allAppsController.setPredictedApps(TEST_PREDICTED_APPS) + + val predictedApps = + overlayController + .requestWindow() + .appsView + .floatingHeaderView + .findFixedRowByType(PredictionRowView::class.java) + .predictedApps + assertThat(predictedApps).isEqualTo(TEST_PREDICTED_APPS) + } + + @Test + fun testUpdateNotificationDots_appInfo_hasDot() { + getInstrumentation().runOnMainSync { + allAppsController.setApps(TEST_APPS, 0, emptyMap()) + allAppsController.toggle() + taskbarUnitTestRule.activityContext.popupDataProvider.onNotificationPosted( + PackageUserKey.fromItemInfo(TEST_APPS[0]), + NotificationKeyData("key"), + ) + } + + // Ensure the recycler view fully inflates before trying to grab an icon. + getInstrumentation().runOnMainSync { + val btv = + overlayController + .requestWindow() + .appsView + .activeRecyclerView + .findViewHolderForAdapterPosition(0) + ?.itemView as? BubbleTextView + assertThat(btv?.hasDot()).isTrue() + } + } + + @Test + @UiThreadTest + fun testUpdateNotificationDots_predictedApp_hasDot() { + allAppsController.setPredictedApps(TEST_PREDICTED_APPS) + allAppsController.toggle() + + taskbarUnitTestRule.activityContext.popupDataProvider.onNotificationPosted( + PackageUserKey.fromItemInfo(TEST_PREDICTED_APPS[0]), + NotificationKeyData("key"), + ) + + val predictionRowView = + overlayController + .requestWindow() + .appsView + .floatingHeaderView + .findFixedRowByType(PredictionRowView::class.java) + val btv = predictionRowView.getChildAt(0) as BubbleTextView + assertThat(btv.hasDot()).isTrue() + } + + private companion object { + private val TEST_APPS = + Array(16) { + AppInfo( + ComponentName( + getInstrumentation().context, + "com.android.launcher3.tests.Activity$it", + ), + "Test App $it", + Process.myUserHandle(), + Intent(), + ) + } + + private val TEST_PREDICTED_APPS = TEST_APPS.take(4).map { WorkspaceItemInfo(it) } + } +} diff --git a/src/com/android/launcher3/notification/NotificationKeyData.java b/src/com/android/launcher3/notification/NotificationKeyData.java index 4115b3da5c..e38824cb4b 100644 --- a/src/com/android/launcher3/notification/NotificationKeyData.java +++ b/src/com/android/launcher3/notification/NotificationKeyData.java @@ -22,6 +22,7 @@ import android.service.notification.StatusBarNotification; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import com.android.launcher3.Utilities; @@ -38,6 +39,11 @@ public class NotificationKeyData { public final String[] personKeysFromNotification; public int count; + @VisibleForTesting + public NotificationKeyData(String notificationKey) { + this(notificationKey, null, 1, new String[]{}); + } + private NotificationKeyData(String notificationKey, String shortcutId, int count, String[] personKeysFromNotification) { this.notificationKey = notificationKey;