Merge "Support A11y contextual button" into sc-v2-dev

This commit is contained in:
Vinit Nayak
2021-06-08 22:07:53 +00:00
committed by Android (Google) Code Review
6 changed files with 105 additions and 64 deletions

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="21dp"
android:height="21dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M20.5,6c-2.61,0.7 -5.67,1 -8.5,1S6.11,6.7 3.5,6L3,8c1.86,0.5 4,0.83 6,1v13h2v-6h2v6h2V9c2,-0.17 4.14,-0.5 6,-1L20.5,6zM12,6c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2s-2,0.9 -2,2S10.9,6 12,6z"
android:fillColor="@android:color/white"
/>
</vector>

View File

@@ -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<StatePropertyHolder> mPropertyHolders = new ArrayList<>();
private final ArrayList<View> 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() {

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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());
}
}
}

View File

@@ -266,13 +266,6 @@ public class TouchInteractionService extends Service implements PluginListener<O
MAIN_EXECUTOR.execute(() -> 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));