diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 853ac7415c..33313218a6 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -401,6 +401,9 @@ 300dp 16dp + + 60dp + 30dp diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index b69f657183..5de1e8b222 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -72,6 +72,8 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import androidx.core.graphics.Insets; +import androidx.core.view.WindowInsetsCompat; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BubbleTextView; @@ -417,6 +419,28 @@ public class TaskbarActivityContext extends BaseTaskbarContext { return isPhoneMode() && !isThreeButtonNav(); } + /** + * Returns if software keyboard is docked or input toolbar is placed at the taskbar area + */ + public boolean isImeDocked() { + View dragLayer = getDragLayer(); + WindowInsets insets = dragLayer.getRootWindowInsets(); + if (insets == null) { + return false; + } + + WindowInsetsCompat insetsCompat = + WindowInsetsCompat.toWindowInsetsCompat(insets, dragLayer.getRootView()); + + if (insetsCompat.isVisible(WindowInsetsCompat.Type.ime())) { + Insets imeInsets = insetsCompat.getInsets(WindowInsetsCompat.Type.ime()); + return imeInsets.bottom >= getResources().getDimensionPixelSize( + R.dimen.floating_ime_inset_height); + } else { + return false; + } + } + /** * Show Taskbar upon receiving broadcast */ diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java index 491938d2b5..a3c8550334 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java @@ -30,9 +30,12 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewTreeObserver; +import android.view.WindowInsets; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.graphics.Insets; +import androidx.core.view.WindowInsetsCompat; import com.android.app.viewcapture.SettingsAwareViewCapture; import com.android.launcher3.AbstractFloatingView; @@ -110,6 +113,18 @@ public class TaskbarDragLayer extends BaseDragLayer { recreateControllers(); } + @Override + public WindowInsets onApplyWindowInsets(WindowInsets insets) { + if (insets != null) { + WindowInsetsCompat insetsCompat = WindowInsetsCompat.toWindowInsetsCompat(insets, this); + Insets imeInsets = insetsCompat.getInsets(WindowInsetsCompat.Type.ime()); + if (imeInsets != null) { + mControllerCallbacks.onImeInsetChanged(); + } + } + return insets; + } + @Override public void recreateControllers() { mControllers = mControllerCallbacks.getTouchControllers(); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java index 74eda24e6e..e48c20dd61 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java @@ -275,6 +275,13 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa mControllers.taskbarInsetsController.updateInsetsTouchability(insetsInfo); } + /** + * Called when an IME inset is changed. + */ + public void onImeInsetChanged() { + mControllers.taskbarStashController.onImeInsetChanged(); + } + /** * Called when a child is removed from TaskbarDragLayer. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 8db343fa3f..cf463d2cce 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -891,6 +891,10 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba } // Only update the following flags when system gesture is not in progress. + setStashedImeState(); + } + + private void setStashedImeState() { boolean shouldStashForIme = shouldStashForIme(); updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false); if (hasAnyFlag(FLAG_STASHED_IN_APP_IME) != shouldStashForIme) { @@ -901,6 +905,13 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba } } + /** + * Should be called when Ime inset is changed to determine if taskbar should be stashed + */ + public void onImeInsetChanged() { + setStashedImeState(); + } + /** * When hiding the IME, delay the unstash animation to align with the end of the transition. */ @@ -950,7 +961,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * *

Do not stash if in small screen, with 3 button nav, and in landscape (or seascape). *

Do not stash if taskbar is transient. - *

Do not stash if hardware keyboard is attached and taskbar is pinned. + *

Do not stash if hardware keyboard is attached and taskbar is pinned and IME is docked */ private boolean shouldStashForIme() { if (DisplayController.isTransientTaskbar(mActivity)) { @@ -961,8 +972,10 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba && mActivity.getDeviceProfile().isLandscape) { return false; } - // Do not stash if pinned taskbar and hardware keyboard is attached. - if (mActivity.isHardwareKeyboard() && DisplayController.isPinnedTaskbar(mActivity)) { + + // Do not stash if pinned taskbar, hardware keyboard is attached and no IME is docked + if (mActivity.isHardwareKeyboard() && DisplayController.isPinnedTaskbar(mActivity) + && !mActivity.isImeDocked()) { return false; } diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 8535a33b06..c3a4351d7b 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -187,7 +187,10 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { // Allow null-pointer to catch illegal states. runOnTISBinder(tisBinder -> tisBinder.getTaskbarManager().recreateTaskbar()); return response; - + case TestProtocol.REQUEST_TASKBAR_IME_DOCKED: + return getTISBinderUIProperty(Bundle::putBoolean, tisBinder -> + tisBinder.getTaskbarManager() + .getCurrentActivityContext().isImeDocked()); case TestProtocol.REQUEST_UNSTASH_BUBBLE_BAR_IF_STASHED: runOnTISBinder(tisBinder -> { // Allow null-pointer to catch illegal states. diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java index cbb48949d1..6014ad4fcc 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java @@ -347,7 +347,7 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest { boolean isTransientTaskbar = mLauncher.isTransientTaskbar(); // Expect task bar invisible when the launched app was the IME activity. LaunchedAppState launchedAppState = getAndAssertLaunchedApp(); - if (!isTransientTaskbar && isHardwareKeyboard()) { + if (!isTransientTaskbar && isHardwareKeyboard() && !mLauncher.isImeDocked()) { launchedAppState.assertTaskbarVisible(); } else { launchedAppState.assertTaskbarHidden(); diff --git a/res/values/dimens.xml b/res/values/dimens.xml index c7190b67b6..6c7c3d8c5a 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -401,6 +401,9 @@ 0dp 0dp + + 0dp + 0dp diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java index 230a651698..31f5d6541a 100644 --- a/src/com/android/launcher3/views/ActivityContext.java +++ b/src/com/android/launcher3/views/ActivityContext.java @@ -322,8 +322,8 @@ public interface ActivityContext { } /** - * Returns if the software keyboard is hidden. Hardware keyboards do not display on screen by - * default. + * Returns if the software keyboard (including input toolbar) is hidden. Hardware + * keyboards do not display on screen by default. */ default boolean isSoftwareKeyboardHidden() { if (isHardwareKeyboard()) { diff --git a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java index 4e1e9c826c..05e23a3b16 100644 --- a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java +++ b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java @@ -101,6 +101,7 @@ public final class TestProtocol { public static final String REQUEST_TASKBAR_FROM_NAV_THRESHOLD = "taskbar-from-nav-threshold"; public static final String REQUEST_STASHED_TASKBAR_SCALE = "taskbar-stash-handle-scale"; public static final String REQUEST_RECREATE_TASKBAR = "recreate-taskbar"; + public static final String REQUEST_TASKBAR_IME_DOCKED = "taskbar-ime-docked"; public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags"; public static final String REQUEST_APPS_LIST_SCROLL_Y = "apps-list-scroll-y"; public static final String REQUEST_TASKBAR_APPS_LIST_SCROLL_Y = "taskbar-apps-list-scroll-y"; diff --git a/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 326802f540..246a7d093c 100644 --- a/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -2241,6 +2241,11 @@ public final class LauncherInstrumentation { .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD); } + public boolean isImeDocked() { + return getTestInfo(TestProtocol.REQUEST_TASKBAR_IME_DOCKED).getBoolean( + TestProtocol.TEST_INFO_RESPONSE_FIELD); + } + /** Enables transient taskbar for testing purposes only. */ public void enableTransientTaskbar(boolean enable) { getTestInfo(enable