diff --git a/quickstep/res/drawable/ic_sysbar_accessibility_button.xml b/quickstep/res/drawable/ic_sysbar_accessibility_button.xml
new file mode 100644
index 0000000000..e0d5406810
--- /dev/null
+++ b/quickstep/res/drawable/ic_sysbar_accessibility_button.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonUIController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonUIController.java
index 1281b2e38f..dc292a1816 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonUIController.java
@@ -15,10 +15,16 @@
*/
package com.android.launcher3.taskbar;
+import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y;
+import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y_LONG_CLICK;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_IME_SWITCH;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RECENTS;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
import android.animation.ObjectAnimator;
import android.annotation.DrawableRes;
@@ -58,14 +64,18 @@ public class NavbarButtonUIController {
private static final int FLAG_SWITCHER_SUPPORTED = 1 << 0;
private static final int FLAG_IME_VISIBLE = 1 << 1;
private static final int FLAG_ROTATION_BUTTON_VISIBLE = 1 << 2;
+ private static final int FLAG_A11Y_VISIBLE = 1 << 3;
private static final int MASK_IME_SWITCHER_VISIBLE = FLAG_SWITCHER_SUPPORTED | FLAG_IME_VISIBLE;
+ private View.OnLongClickListener mA11yLongClickListener;
private final ArrayList mPropertyHolders = new ArrayList<>();
private final ArrayList mAllButtons = new ArrayList<>();
private int mState;
private final TaskbarActivityContext mContext;
+ private View a11yButton;
+ private int mSysuiStateFlags;
public NavbarButtonUIController(TaskbarActivityContext context) {
mContext = context;
@@ -81,6 +91,11 @@ public class NavbarButtonUIController {
FrameLayout buttonController = dragLayer.findViewById(R.id.navbuttons_view);
buttonController.getLayoutParams().height = mContext.getDeviceProfile().taskbarSize;
+ mA11yLongClickListener = view -> {
+ navButtonController.onButtonClick(BUTTON_A11Y_LONG_CLICK);
+ return true;
+ };
+
if (mContext.canShowNavButtons()) {
ViewGroup startContainer = buttonController.findViewById(R.id.start_nav_buttons);
ViewGroup endContainer = buttonController.findViewById(R.id.end_nav_buttons);
@@ -132,18 +147,34 @@ public class NavbarButtonUIController {
endContainer, navButtonController);
mPropertyHolders.add(new StatePropertyHolder(imeSwitcherButton,
flags -> ((flags & MASK_IME_SWITCHER_VISIBLE) == MASK_IME_SWITCHER_VISIBLE)
- && ((flags & FLAG_ROTATION_BUTTON_VISIBLE) == 0)));
+ && ((flags & FLAG_ROTATION_BUTTON_VISIBLE) == 0)
+ && ((flags & FLAG_A11Y_VISIBLE) == 0)));
+
+ // A11y button
+ a11yButton = addButton(R.drawable.ic_sysbar_accessibility_button, BUTTON_A11Y,
+ endContainer, navButtonController);
+ mPropertyHolders.add(new StatePropertyHolder(a11yButton,
+ flags -> (flags & FLAG_A11Y_VISIBLE) != 0
+ && (flags & FLAG_ROTATION_BUTTON_VISIBLE) == 0));
+ a11yButton.setOnLongClickListener(mA11yLongClickListener);
}
- /**
- * Should be called when the IME visibility changes, so we can hide/show Taskbar accordingly.
- */
- public void setImeIsVisible(boolean isImeVisible) {
- if (isImeVisible) {
- mState |= FLAG_IME_VISIBLE;
- } else {
- mState &= ~FLAG_IME_VISIBLE;
+ public void updateStateForSysuiFlags(int systemUiStateFlags, boolean forceUpdate) {
+ boolean isImeVisible = (systemUiStateFlags & SYSUI_STATE_IME_SHOWING) != 0;
+ boolean isImeSwitcherShowing = (systemUiStateFlags & SYSUI_STATE_IME_SWITCHER_SHOWING) != 0;
+ boolean a11yVisible = (systemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
+ boolean a11yLongClickable =
+ (systemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
+
+ if (!forceUpdate && systemUiStateFlags == mSysuiStateFlags) {
+ return;
}
+ mSysuiStateFlags = systemUiStateFlags;
+
+ updateStateForFlag(FLAG_IME_VISIBLE, isImeVisible);
+ updateStateForFlag(FLAG_SWITCHER_SUPPORTED, isImeSwitcherShowing);
+ updateStateForFlag(FLAG_A11Y_VISIBLE, a11yVisible);
+ a11yButton.setLongClickable(a11yLongClickable);
applyState();
}
@@ -169,15 +200,14 @@ public class NavbarButtonUIController {
}
/**
- * Sets if ime switcher is visible or not when ime is visible
+ * Does not call {@link #applyState()}. Don't forget to!
*/
- public void setImeSwitcherVisible(boolean imeSwitcherVisible) {
- if (imeSwitcherVisible) {
- mState |= FLAG_SWITCHER_SUPPORTED;
+ private void updateStateForFlag(int flag, boolean enabled) {
+ if (enabled) {
+ mState |= flag;
} else {
- mState &= ~FLAG_SWITCHER_SUPPORTED;
+ mState &= ~flag;
}
- applyState();
}
private void applyState() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 5f7dce5fac..a25eb38d99 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -29,7 +29,6 @@ import android.content.Intent;
import android.content.pm.LauncherApps;
import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.inputmethodservice.InputMethodService;
import android.os.Process;
import android.os.SystemProperties;
import android.util.Log;
@@ -51,7 +50,6 @@ import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton;
import com.android.launcher3.taskbar.contextual.RotationButtonController;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.util.MultiValueAlpha;
@@ -231,30 +229,12 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
mWindowManager.removeViewImmediate(mDragLayer);
}
- void onNavigationButtonClick(@TaskbarButton int buttonType) {
- mNavButtonController.onButtonClick(buttonType);
- }
-
- /**
- * Should be called when the IME visibility changes, so we can hide/show Taskbar accordingly.
- */
- public void setImeIsVisible(boolean isImeVisible) {
- mIconController.setImeIsVisible(isImeVisible);
- mNavbarButtonUIController.setImeIsVisible(isImeVisible);
- }
-
- /**
- * When in 3 button nav, the above doesn't get called since we prevent sysui nav bar from
- * instantiating at all, which is what's responsible for sending sysui state flags over.
- *
- * @param vis IME visibility flag
- */
- public void updateImeStatus(int displayId, int vis, boolean showImeSwitcher) {
- if (displayId != getDisplayId() || !canShowNavButtons()) {
+ public void updateSysuiStateFlags(int systemUiStateFlags, boolean forceUpdate) {
+ if (!canShowNavButtons()) {
return;
}
- mNavbarButtonUIController.setImeSwitcherVisible(showImeSwitcher);
- setImeIsVisible((vis & InputMethodService.IME_VISIBLE) != 0);
+ mNavbarButtonUIController.updateStateForSysuiFlags(systemUiStateFlags, forceUpdate);
+ mIconController.setImeIsVisible(mNavbarButtonUIController.isImeVisible());
}
public void onRotationProposal(int rotation, boolean isValid) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 36bccee464..3563d09573 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -21,11 +21,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import android.content.Context;
import android.hardware.display.DisplayManager;
-import android.inputmethodservice.InputMethodService;
import android.view.Display;
import androidx.annotation.Nullable;
@@ -53,6 +51,11 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen
private TaskbarActivityContext mTaskbarActivityContext;
private BaseQuickstepLauncher mLauncher;
+ /**
+ * Cache a copy here so we can initialize state whenever taskbar is recreated, since
+ * this class does not get re-initialized w/ new taskbars.
+ */
+ private int mSysuiStateFlags;
private static final int CHANGE_FLAGS =
CHANGE_ACTIVE_SCREEN | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS;
@@ -130,6 +133,7 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen
mTaskbarActivityContext.setUIController(
new LauncherTaskbarUIController(mLauncher, mTaskbarActivityContext));
}
+ onSysuiFlagsChangedInternal(mSysuiStateFlags, true /* forceUpdate */);
}
/**
@@ -137,24 +141,13 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen
* @param systemUiStateFlags The latest SystemUiStateFlags
*/
public void onSystemUiFlagsChanged(int systemUiStateFlags) {
- boolean isImeVisible = (systemUiStateFlags & SYSUI_STATE_IME_SHOWING) != 0;
- if (mTaskbarActivityContext != null) {
- mTaskbarActivityContext.setImeIsVisible(isImeVisible);
- }
+ onSysuiFlagsChangedInternal(systemUiStateFlags, false /* forceUpdate */);
}
- /**
- * When in 3 button nav, the above doesn't get called since we prevent sysui nav bar from
- * instantiating at all, which is what's responsible for sending sysui state flags over.
- *
- * @param vis IME visibility flag
- * @param backDisposition Used to determine back button behavior for software keyboard
- * See BACK_DISPOSITION_* constants in {@link InputMethodService}
- */
- public void updateImeStatus(int displayId, int vis, int backDisposition,
- boolean showImeSwitcher) {
+ private void onSysuiFlagsChangedInternal(int systemUiStateFlags, boolean forceUpdate) {
+ mSysuiStateFlags = systemUiStateFlags;
if (mTaskbarActivityContext != null) {
- mTaskbarActivityContext.updateImeStatus(displayId, vis, showImeSwitcher);
+ mTaskbarActivityContext.updateSysuiStateFlags(systemUiStateFlags, forceUpdate);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
index 3b5afad691..002d42da3b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
@@ -44,7 +44,9 @@ public class TaskbarNavButtonController {
BUTTON_BACK,
BUTTON_HOME,
BUTTON_RECENTS,
- BUTTON_IME_SWITCH
+ BUTTON_IME_SWITCH,
+ BUTTON_A11Y,
+ BUTTON_A11Y_LONG_CLICK
})
public @interface TaskbarButton {}
@@ -53,6 +55,8 @@ public class TaskbarNavButtonController {
static final int BUTTON_HOME = BUTTON_BACK << 1;
static final int BUTTON_RECENTS = BUTTON_HOME << 1;
static final int BUTTON_IME_SWITCH = BUTTON_RECENTS << 1;
+ static final int BUTTON_A11Y = BUTTON_IME_SWITCH << 1;
+ static final int BUTTON_A11Y_LONG_CLICK = BUTTON_A11Y << 1;
private final TouchInteractionService mService;
@@ -74,6 +78,12 @@ public class TaskbarNavButtonController {
case BUTTON_IME_SWITCH:
showIMESwitcher();
break;
+ case BUTTON_A11Y:
+ notifyImeClick(false /* longClick */);
+ break;
+ case BUTTON_A11Y_LONG_CLICK:
+ notifyImeClick(true /* longClick */);
+ break;
}
}
@@ -97,4 +107,13 @@ public class TaskbarNavButtonController {
.showInputMethodPickerFromSystem(true /* showAuxiliarySubtypes */,
DEFAULT_DISPLAY);
}
+
+ private void notifyImeClick(boolean longClick) {
+ SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.getNoCreate();
+ if (longClick) {
+ systemUiProxy.notifyAccessibilityButtonLongClicked();
+ } else {
+ systemUiProxy.notifyAccessibilityButtonClicked(mService.getDisplayId());
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index afafce7382..a3136c7dd8 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -266,13 +266,6 @@ public class TouchInteractionService extends Service implements PluginListener SplitScreenBounds.INSTANCE.setSecondaryWindowBounds(wb));
}
- @Override
- public void onImeWindowStatusChanged(int displayId, IBinder token, int vis,
- int backDisposition, boolean showImeSwitcher) {
- executeForTaskbarManager(() -> mTaskbarManager
- .updateImeStatus(displayId, vis, backDisposition, showImeSwitcher));
- }
-
@Override
public void onRotationProposal(int rotation, boolean isValid) {
executeForTaskbarManager(() -> mTaskbarManager.onRotationProposal(rotation, isValid));