diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java index 8ec5c18393..8ff030eb48 100644 --- a/src/com/android/launcher3/ExtendedEditText.java +++ b/src/com/android/launcher3/ExtendedEditText.java @@ -101,8 +101,14 @@ public class ExtendedEditText extends EditText { } public void hideKeyboard() { + hideKeyboard(/* clearFocus= */ true); + } + + public void hideKeyboard(boolean clearFocus) { ActivityContext.lookupContext(getContext()).hideKeyboard(); - clearFocus(); + if (clearFocus) { + clearFocus(); + } } protected void onKeyboardShown() { diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index 84d3805536..2315111b3b 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -49,6 +49,7 @@ import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM; import android.animation.ValueAnimator; import android.util.FloatProperty; import android.view.View; +import android.view.ViewGroup; import android.view.animation.Interpolator; import com.android.launcher3.LauncherState.PageAlphaProvider; @@ -164,6 +165,8 @@ public class WorkspaceStateTransitionAnimation { state.hasFlag(FLAG_HOTSEAT_INACCESSIBLE) ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); + hotseat.setDescendantFocusability(state.hasFlag(FLAG_HOTSEAT_INACCESSIBLE) + ? ViewGroup.FOCUS_BLOCK_DESCENDANTS : ViewGroup.FOCUS_BEFORE_DESCENDANTS); Interpolator translationInterpolator = config.getInterpolator(ANIM_WORKSPACE_TRANSLATE, ZOOM_OUT); diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java index 005e6dfe87..7baf7d3325 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java @@ -27,7 +27,6 @@ import android.widget.TextView; import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.BubbleTextView; -import com.android.launcher3.Flags; import com.android.launcher3.R; import com.android.launcher3.allapps.search.SearchAdapterProvider; import com.android.launcher3.config.FeatureFlags; @@ -213,6 +212,7 @@ public abstract class BaseAllAppsAdapter ex BubbleTextView icon = (BubbleTextView) holder.itemView; icon.reset(); icon.applyFromApplicationInfo(adapterItem.itemInfo); + icon.setOnFocusChangeListener(mIconFocusListener); break; } case VIEW_TYPE_EMPTY_SEARCH: { diff --git a/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java b/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java new file mode 100644 index 0000000000..80f73cb159 --- /dev/null +++ b/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023 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.allapps; + +import static com.android.launcher3.ui.TaplTestsLauncher3.initialize; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import android.view.KeyEvent; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import com.android.launcher3.LauncherState; +import com.android.launcher3.tapl.HomeAllApps; +import com.android.launcher3.ui.AbstractLauncherUiTest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class TaplKeyboardFocusTest extends AbstractLauncherUiTest { + + @Before + public void setUp() throws Exception { + super.setUp(); + initialize(this); + } + + @Test + public void testAllAppsFocusApp() { + final HomeAllApps allApps = mLauncher.goHome().switchToAllApps(); + assertTrue("Launcher internal state is not All Apps", + isInState(() -> LauncherState.ALL_APPS)); + allApps.freeze(); + try { + mLauncher.pressAndHoldKeyCode(KeyEvent.KEYCODE_DPAD_DOWN, 0); + executeOnLauncher(launcher -> assertNotNull("No focused child.", + launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild())); + } finally { + allApps.unfreeze(); + } + } + + @Test + public void testAllAppsExitSearchAndFocusApp() { + final HomeAllApps allApps = mLauncher.goHome().switchToAllApps(); + assertTrue("Launcher internal state is not All Apps", + isInState(() -> LauncherState.ALL_APPS)); + allApps.freeze(); + try { + executeOnLauncher(launcher -> launcher.getAppsView().getSearchView().requestFocus()); + waitForLauncherCondition("Search view does not have focus.", + launcher -> launcher.getAppsView().getSearchView().hasFocus()); + + mLauncher.pressAndHoldKeyCode(KeyEvent.KEYCODE_DPAD_DOWN, 0); + executeOnLauncher(launcher -> assertNotNull("No focused child.", + launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild())); + } finally { + allApps.unfreeze(); + } + } +}