From b3cd9802e87eefcba754d42128d47ace3c6b7307 Mon Sep 17 00:00:00 2001 From: Himanshu Gupta Date: Sun, 25 Feb 2024 14:49:06 +0000 Subject: [PATCH] Clearing All Apps Search For ALL_APPS Intent Currently, if ALL_APPS intent is executed while All Apps QSB is highlighted, user is left on the search sub-view of the All Apps view. To fix this, we add a runner to check the search view and exit from it after State Transition has happened. Before: https://photos.app.goo.gl/c5WeUnAzowxRWW1m7 After: https://photos.app.goo.gl/dxvb23wzwPfKqi3o6 Bug: 324516950 Flag: NA Test: Manual flash and running intent via cmd Change-Id: Icc291f792545b0c515535857f578bc2e01fef7f7 --- src/com/android/launcher3/Launcher.java | 19 +++- .../search/AllAppsSearchBarController.java | 1 + .../android/launcher3/LauncherIntentTest.java | 106 ++++++++++++++++++ 3 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 tests/src/com/android/launcher3/LauncherIntentTest.java diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index c1ebbe58a2..e4914aabf5 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1629,7 +1629,8 @@ public class Launcher extends StatefulActivity } else if (INTENT_ACTION_ALL_APPS_TOGGLE.equals(intent.getAction())) { toggleAllAppsFromIntent(alreadyOnHome); } else if (Intent.ACTION_SHOW_WORK_APPS.equals(intent.getAction())) { - showAllAppsWorkTabFromIntent(alreadyOnHome); + showAllAppsWithSelectedTabFromIntent(alreadyOnHome, + ActivityAllAppsContainerView.AdapterHolder.WORK); } TraceHelper.INSTANCE.endSection(); @@ -1661,13 +1662,19 @@ public class Launcher extends StatefulActivity } protected void showAllAppsFromIntent(boolean alreadyOnHome) { - AbstractFloatingView.closeAllOpenViews(this); - getStateManager().goToState(ALL_APPS, alreadyOnHome); + showAllAppsWithSelectedTabFromIntent(alreadyOnHome, + ActivityAllAppsContainerView.AdapterHolder.MAIN); } - private void showAllAppsWorkTabFromIntent(boolean alreadyOnHome) { - showAllAppsFromIntent(alreadyOnHome); - mAppsView.switchToTab(ActivityAllAppsContainerView.AdapterHolder.WORK); + private void showAllAppsWithSelectedTabFromIntent(boolean alreadyOnHome, int tab) { + AbstractFloatingView.closeAllOpenViews(this); + getStateManager().goToState(ALL_APPS, alreadyOnHome); + if (mAppsView.isSearching()) { + mAppsView.reset(alreadyOnHome); + } + if (mAppsView.getCurrentPage() != tab) { + mAppsView.switchToTab(tab); + } } /** diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java index f9d047b980..ec45415afa 100644 --- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java +++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java @@ -155,6 +155,7 @@ public class AllAppsSearchBarController public void reset() { mCallback.clearSearchResult(); mInput.reset(); + mInput.clearFocus(); mQuery = null; mInput.removeOnFocusChangeListener(this); } diff --git a/tests/src/com/android/launcher3/LauncherIntentTest.java b/tests/src/com/android/launcher3/LauncherIntentTest.java new file mode 100644 index 0000000000..e2971e8731 --- /dev/null +++ b/tests/src/com/android/launcher3/LauncherIntentTest.java @@ -0,0 +1,106 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.content.Intent; +import android.platform.test.annotations.LargeTest; +import android.view.KeyEvent; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.launcher3.allapps.ActivityAllAppsContainerView; +import com.android.launcher3.allapps.SearchRecyclerView; +import com.android.launcher3.ui.AbstractLauncherUiTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@LargeTest +@RunWith(AndroidJUnit4.class) +public class LauncherIntentTest extends AbstractLauncherUiTest { + + public final Intent allAppsIntent = new Intent(Intent.ACTION_ALL_APPS); + + @Test + public void testAllAppsIntent() { + // setup by moving to home + mLauncher.goHome(); + assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL)); + + // Try executing ALL_APPS intent + executeOnLauncher(launcher -> launcher.onNewIntent(allAppsIntent)); + // A-Z view with Main adapter should be loaded + assertOnMainAdapterAToZView(); + + + // Try Moving to search view now + moveToSearchView(); + // Try executing ALL_APPS intent + executeOnLauncher(launcher -> launcher.onNewIntent(allAppsIntent)); + // A-Z view with Main adapter should be loaded + assertOnMainAdapterAToZView(); + + // finish + mLauncher.goHome(); + assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL)); + } + + // Highlights the search bar, then fills text to display the SearchView. + private void moveToSearchView() { + mLauncher.goHome().switchToAllApps(); + + // All Apps view should be loaded + assertTrue("Launcher internal state is not All Apps", + isInState(() -> LauncherState.ALL_APPS)); + executeOnLauncher(launcher -> launcher.getAppsView().getSearchView().requestFocus()); + // Search view should be in focus + waitForLauncherCondition("Search view is not in focus.", + launcher -> launcher.getAppsView().getSearchView().hasFocus()); + mLauncher.pressAndHoldKeyCode(KeyEvent.KEYCODE_C, 0); + // Upon key press, search recycler view should be loaded + waitForLauncherCondition("Search view not active.", + launcher -> launcher.getAppsView().getActiveRecyclerView() + instanceof SearchRecyclerView); + mLauncher.unpressKeyCode(KeyEvent.KEYCODE_C, 0); + } + + // Checks if main adapter view is selected, search bar is out of focus and scroller is at start. + private void assertOnMainAdapterAToZView() { + // All Apps State should be loaded + assertTrue("Launcher internal state is not All Apps", + isInState(() -> LauncherState.ALL_APPS)); + + // A-Z recycler view should be active. + waitForLauncherCondition("A-Z view not active.", + launcher -> !(launcher.getAppsView().getActiveRecyclerView() + instanceof SearchRecyclerView)); + // Personal Adapter should be selected. + waitForLauncherCondition("Not on Main Adapter View", + launcher -> launcher.getAppsView().getCurrentPage() + == ActivityAllAppsContainerView.AdapterHolder.MAIN); + // Search view should not be in focus + waitForLauncherCondition("Search view has focus.", + launcher -> !launcher.getAppsView().getSearchView().hasFocus()); + // Scroller should be at top + executeOnLauncher(launcher -> assertEquals( + "All Apps started in already scrolled state", 0, + getAllAppsScroll(launcher))); + } +}