Merge "Extract assistant logic from NavigationBar to share with Taskbar" into sc-v2-dev

This commit is contained in:
Vinit Nayak
2021-11-21 02:10:49 +00:00
committed by Android (Google) Code Review
8 changed files with 519 additions and 186 deletions

View File

@@ -0,0 +1,246 @@
/*
* Copyright (C) 2021 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.systemui.navigationbar;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
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 android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.provider.Settings;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.NonNull;
import com.android.systemui.Dumpable;
import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import dagger.Lazy;
/**
* Extracts shared elements between navbar and taskbar delegate to de-dupe logic and help them
* experience the joys of friendship.
* The events are then passed through
*
* Currently consolidates
* * A11y
* * Assistant
*/
@SysUISingleton
public final class NavBarHelper implements
AccessibilityButtonModeObserver.ModeChangedListener,
OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener,
Dumpable {
private final AccessibilityManager mAccessibilityManager;
private final Lazy<AssistManager> mAssistManagerLazy;
private final UserTracker mUserTracker;
private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
private final List<NavbarTaskbarStateUpdater> mA11yEventListeners = new ArrayList<>();
private Context mContext;
private ContentResolver mContentResolver;
private boolean mAssistantAvailable;
private boolean mLongPressHomeEnabled;
private boolean mAssistantTouchGestureEnabled;
private int mNavBarMode;
private final ContentObserver mAssistContentObserver = new ContentObserver(
new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange, Uri uri) {
updateAssitantAvailability();
}
};
@Inject
public NavBarHelper(AccessibilityManager accessibilityManager,
AccessibilityManagerWrapper accessibilityManagerWrapper,
AccessibilityButtonModeObserver accessibilityButtonModeObserver,
OverviewProxyService overviewProxyService,
Lazy<AssistManager> assistManagerLazy,
NavigationModeController navigationModeController,
UserTracker userTracker,
DumpManager dumpManager) {
mAccessibilityManager = accessibilityManager;
mAssistManagerLazy = assistManagerLazy;
mUserTracker = userTracker;
accessibilityManagerWrapper.addCallback(
accessibilityManager1 -> NavBarHelper.this.dispatchA11yEventUpdate());
mAccessibilityButtonModeObserver = accessibilityButtonModeObserver;
mAccessibilityButtonModeObserver.addListener(this);
mNavBarMode = navigationModeController.addListener(this);
overviewProxyService.addCallback(this);
dumpManager.registerDumpable(this);
}
public void init(Context context) {
mContext = context;
mContentResolver = mContext.getContentResolver();
mContentResolver.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.ASSISTANT),
false /* notifyForDescendants */, mAssistContentObserver, UserHandle.USER_ALL);
mContentResolver.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED),
false, mAssistContentObserver, UserHandle.USER_ALL);
mContentResolver.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED),
false, mAssistContentObserver, UserHandle.USER_ALL);
updateAssitantAvailability();
}
public void destroy() {
mContentResolver.unregisterContentObserver(mAssistContentObserver);
}
/**
* @param listener Will immediately get callbacks based on current state
*/
public void registerNavTaskStateUpdater(NavbarTaskbarStateUpdater listener) {
mA11yEventListeners.add(listener);
listener.updateAccessibilityServicesState();
listener.updateAssistantAvailable(mAssistantAvailable);
}
public void removeNavTaskStateUpdater(NavbarTaskbarStateUpdater listener) {
mA11yEventListeners.remove(listener);
}
private void dispatchA11yEventUpdate() {
for (NavbarTaskbarStateUpdater listener : mA11yEventListeners) {
listener.updateAccessibilityServicesState();
}
}
private void dispatchAssistantEventUpdate(boolean assistantAvailable) {
for (NavbarTaskbarStateUpdater listener : mA11yEventListeners) {
listener.updateAssistantAvailable(assistantAvailable);
}
}
@Override
public void onAccessibilityButtonModeChanged(int mode) {
dispatchA11yEventUpdate();
}
/**
* See {@link QuickStepContract#SYSUI_STATE_A11Y_BUTTON_CLICKABLE} and
* {@link QuickStepContract#SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE}
*
* @return the a11y button clickable and long_clickable states, or 0 if there is no
* a11y button in the navbar
*/
public int getA11yButtonState() {
// AccessibilityManagerService resolves services for the current user since the local
// AccessibilityManager is created from a Context with the INTERACT_ACROSS_USERS permission
final List<String> a11yButtonTargets =
mAccessibilityManager.getAccessibilityShortcutTargets(
AccessibilityManager.ACCESSIBILITY_BUTTON);
final int requestingServices = a11yButtonTargets.size();
// If accessibility button is floating menu mode, click and long click state should be
// disabled.
if (mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode()
== ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU) {
return 0;
}
return (requestingServices >= 1 ? SYSUI_STATE_A11Y_BUTTON_CLICKABLE : 0)
| (requestingServices >= 2 ? SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE : 0);
}
@Override
public void onConnectionChanged(boolean isConnected) {
if (isConnected) {
updateAssitantAvailability();
}
}
private void updateAssitantAvailability() {
boolean assistantAvailableForUser = mAssistManagerLazy.get()
.getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
boolean longPressDefault = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_assistLongPressHomeEnabledDefault);
mLongPressHomeEnabled = Settings.Secure.getIntForUser(mContentResolver,
Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, longPressDefault ? 1 : 0,
mUserTracker.getUserId()) != 0;
boolean gestureDefault = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_assistTouchGestureEnabledDefault);
mAssistantTouchGestureEnabled = Settings.Secure.getIntForUser(mContentResolver,
Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED, gestureDefault ? 1 : 0,
mUserTracker.getUserId()) != 0;
mAssistantAvailable = assistantAvailableForUser
&& mAssistantTouchGestureEnabled
&& QuickStepContract.isGesturalMode(mNavBarMode);
dispatchAssistantEventUpdate(mAssistantAvailable);
}
public boolean getLongPressHomeEnabled() {
return mLongPressHomeEnabled;
}
@Override
public void startAssistant(Bundle bundle) {
mAssistManagerLazy.get().startAssist(bundle);
}
@Override
public void onNavigationModeChanged(int mode) {
mNavBarMode = mode;
updateAssitantAvailability();
}
/**
* Callbacks will get fired once immediately after registering via
* {@link #registerNavTaskStateUpdater(NavbarTaskbarStateUpdater)}
*/
public interface NavbarTaskbarStateUpdater {
void updateAccessibilityServicesState();
void updateAssistantAvailable(boolean available);
}
@Override
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("NavbarTaskbarFriendster");
pw.println(" longPressHomeEnabled=" + mLongPressHomeEnabled);
pw.println(" mAssistantTouchGestureEnabled=" + mAssistantTouchGestureEnabled);
pw.println(" mAssistantAvailable=" + mAssistantAvailable);
pw.println(" mNavBarMode=" + mNavBarMode);
}
}

View File

@@ -68,22 +68,18 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.database.ContentObserver;
import android.graphics.Insets; import android.graphics.Insets;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.RectF; import android.graphics.RectF;
import android.inputmethodservice.InputMethodService; import android.inputmethodservice.InputMethodService;
import android.net.Uri;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
import android.provider.Settings;
import android.telecom.TelecomManager; import android.telecom.TelecomManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@@ -200,8 +196,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
private final Handler mHandler; private final Handler mHandler;
private final NavigationBarOverlayController mNavbarOverlayController; private final NavigationBarOverlayController mNavbarOverlayController;
private final UiEventLogger mUiEventLogger; private final UiEventLogger mUiEventLogger;
private final NavigationBarA11yHelper mNavigationBarA11yHelper; private final NavBarHelper mNavBarHelper;
private final UserTracker mUserTracker;
private final NotificationShadeDepthController mNotificationShadeDepthController; private final NotificationShadeDepthController mNotificationShadeDepthController;
private Bundle mSavedState; private Bundle mSavedState;
@@ -213,9 +208,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
private int mNavigationIconHints = 0; private int mNavigationIconHints = 0;
private @TransitionMode int mNavigationBarMode; private @TransitionMode int mNavigationBarMode;
private ContentResolver mContentResolver; private ContentResolver mContentResolver;
private boolean mAssistantAvailable;
private boolean mLongPressHomeEnabled; private boolean mLongPressHomeEnabled;
private boolean mAssistantTouchGestureEnabled;
private int mDisabledFlags1; private int mDisabledFlags1;
private int mDisabledFlags2; private int mDisabledFlags2;
@@ -309,16 +302,31 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
} }
}; };
private final NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater =
new NavBarHelper.NavbarTaskbarStateUpdater() {
@Override
public void updateAccessibilityServicesState() {
updateAcessibilityStateFlags();
}
@Override
public void updateAssistantAvailable(boolean available) {
// TODO(b/198002034): Content observers currently can still be called back after
// being unregistered, and in this case we can ignore the change if the nav bar
// has been destroyed already
if (mNavigationBarView == null) {
return;
}
mLongPressHomeEnabled = mNavBarHelper.getLongPressHomeEnabled();
updateAssistantEntrypoints(available);
}
};
private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() { private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() {
@Override @Override
public void onConnectionChanged(boolean isConnected) { public void onConnectionChanged(boolean isConnected) {
mNavigationBarView.updateStates(); mNavigationBarView.updateStates();
updateScreenPinningGestures(); updateScreenPinningGestures();
// Send the assistant availability upon connection
if (isConnected) {
updateAssistantEntrypoints();
}
} }
@Override @Override
@@ -421,20 +429,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
} }
}; };
private final ContentObserver mAssistContentObserver = new ContentObserver(
new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange, Uri uri) {
// TODO(b/198002034): Content observers currently can still be called back after being
// unregistered, and in this case we can ignore the change if the nav bar has been
// destroyed already
if (mNavigationBarView == null) {
return;
}
updateAssistantEntrypoints();
}
};
private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener = private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
new DeviceConfig.OnPropertiesChangedListener() { new DeviceConfig.OnPropertiesChangedListener() {
@Override @Override
@@ -504,7 +498,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
@Main Handler mainHandler, @Main Handler mainHandler,
NavigationBarOverlayController navbarOverlayController, NavigationBarOverlayController navbarOverlayController,
UiEventLogger uiEventLogger, UiEventLogger uiEventLogger,
NavigationBarA11yHelper navigationBarA11yHelper, NavBarHelper navBarHelper,
UserTracker userTracker, UserTracker userTracker,
LightBarController mainLightBarController, LightBarController mainLightBarController,
LightBarController.Factory lightBarControllerFactory, LightBarController.Factory lightBarControllerFactory,
@@ -535,8 +529,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mHandler = mainHandler; mHandler = mainHandler;
mNavbarOverlayController = navbarOverlayController; mNavbarOverlayController = navbarOverlayController;
mUiEventLogger = uiEventLogger; mUiEventLogger = uiEventLogger;
mNavigationBarA11yHelper = navigationBarA11yHelper; mNavBarHelper = navBarHelper;
mUserTracker = userTracker;
mNotificationShadeDepthController = notificationShadeDepthController; mNotificationShadeDepthController = notificationShadeDepthController;
mMainLightBarController = mainLightBarController; mMainLightBarController = mainLightBarController;
mLightBarControllerFactory = lightBarControllerFactory; mLightBarControllerFactory = lightBarControllerFactory;
@@ -568,18 +561,9 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mIsOnDefaultDisplay = mDisplayId == DEFAULT_DISPLAY; mIsOnDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
mCommandQueue.addCallback(this); mCommandQueue.addCallback(this);
mAssistantAvailable = mAssistManagerLazy.get() mLongPressHomeEnabled = mNavBarHelper.getLongPressHomeEnabled();
.getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
mContentResolver = mContext.getContentResolver(); mContentResolver = mContext.getContentResolver();
mContentResolver.registerContentObserver( mNavBarHelper.init(mContext);
Settings.Secure.getUriFor(Settings.Secure.ASSISTANT),
false /* notifyForDescendants */, mAssistContentObserver, UserHandle.USER_ALL);
mContentResolver.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED),
false, mAssistContentObserver, UserHandle.USER_ALL);
mContentResolver.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED),
false, mAssistContentObserver, UserHandle.USER_ALL);
mAllowForceNavBarHandleOpaque = mContext.getResources().getBoolean( mAllowForceNavBarHandleOpaque = mContext.getResources().getBoolean(
R.bool.allow_force_nav_bar_handle_opaque); R.bool.allow_force_nav_bar_handle_opaque);
mForceNavBarHandleOpaque = DeviceConfig.getBoolean( mForceNavBarHandleOpaque = DeviceConfig.getBoolean(
@@ -593,7 +577,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
)).filter(duration -> duration != 0); )).filter(duration -> duration != 0);
DeviceConfig.addOnPropertiesChangedListener( DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_SYSTEMUI, mHandler::post, mOnPropertiesChangedListener); DeviceConfig.NAMESPACE_SYSTEMUI, mHandler::post, mOnPropertiesChangedListener);
updateAssistantEntrypoints();
if (savedState != null) { if (savedState != null) {
mDisabledFlags1 = savedState.getInt(EXTRA_DISABLE_STATE, 0); mDisabledFlags1 = savedState.getInt(EXTRA_DISABLE_STATE, 0);
@@ -620,8 +603,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mWindowManager.removeViewImmediate(mNavigationBarView.getRootView()); mWindowManager.removeViewImmediate(mNavigationBarView.getRootView());
mNavigationModeController.removeListener(this); mNavigationModeController.removeListener(this);
mNavigationBarA11yHelper.removeA11yEventListener(mAccessibilityListener); mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mContentResolver.unregisterContentObserver(mAssistContentObserver); mNavBarHelper.destroy();
mDeviceProvisionedController.removeCallback(mUserSetupListener); mDeviceProvisionedController.removeCallback(mUserSetupListener);
mNotificationShadeDepthController.removeListener(mDepthListener); mNotificationShadeDepthController.removeListener(mDepthListener);
@@ -643,7 +626,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mNavigationBarView.setWindowVisible(isNavBarWindowVisible()); mNavigationBarView.setWindowVisible(isNavBarWindowVisible());
mNavigationBarView.setBehavior(mBehavior); mNavigationBarView.setBehavior(mBehavior);
mNavigationBarA11yHelper.registerA11yEventListener(mAccessibilityListener); mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mSplitScreenOptional.ifPresent(mNavigationBarView::registerDockedListener); mSplitScreenOptional.ifPresent(mNavigationBarView::registerDockedListener);
mPipOptional.ifPresent(mNavigationBarView::registerPipExclusionBoundsChangeListener); mPipOptional.ifPresent(mNavigationBarView::registerPipExclusionBoundsChangeListener);
@@ -716,7 +699,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mHandler.removeCallbacks(mAutoDim); mHandler.removeCallbacks(mAutoDim);
mHandler.removeCallbacks(mOnVariableDurationHomeLongClick); mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
mHandler.removeCallbacks(mEnableLayoutTransitions); mHandler.removeCallbacks(mEnableLayoutTransitions);
mNavigationBarA11yHelper.removeA11yEventListener(mAccessibilityListener); mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mFrame = null; mFrame = null;
mNavigationBarView = null; mNavigationBarView = null;
mOrientationHandle = null; mOrientationHandle = null;
@@ -885,7 +868,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
pw.println(" mCurrentRotation=" + mCurrentRotation); pw.println(" mCurrentRotation=" + mCurrentRotation);
pw.println(" mHomeButtonLongPressDurationMs=" + mHomeButtonLongPressDurationMs); pw.println(" mHomeButtonLongPressDurationMs=" + mHomeButtonLongPressDurationMs);
pw.println(" mLongPressHomeEnabled=" + mLongPressHomeEnabled); pw.println(" mLongPressHomeEnabled=" + mLongPressHomeEnabled);
pw.println(" mAssistantTouchGestureEnabled=" + mAssistantTouchGestureEnabled);
pw.println(" mNavigationBarWindowState=" pw.println(" mNavigationBarWindowState="
+ windowStateToString(mNavigationBarWindowState)); + windowStateToString(mNavigationBarWindowState));
pw.println(" mNavigationBarMode=" pw.println(" mNavigationBarMode="
@@ -1165,7 +1147,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton(); ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
accessibilityButton.setOnClickListener(this::onAccessibilityClick); accessibilityButton.setOnClickListener(this::onAccessibilityClick);
accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick); accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
updateAccessibilityServicesState(); updateAcessibilityStateFlags();
ButtonDispatcher imeSwitcherButton = mNavigationBarView.getImeSwitchButton(); ButtonDispatcher imeSwitcherButton = mNavigationBarView.getImeSwitchButton();
imeSwitcherButton.setOnClickListener(this::onImeSwitcherClick); imeSwitcherButton.setOnClickListener(this::onImeSwitcherClick);
@@ -1390,8 +1372,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
return true; return true;
} }
void updateAccessibilityServicesState() { void updateAcessibilityStateFlags() {
int a11yFlags = mNavigationBarA11yHelper.getA11yButtonState(); int a11yFlags = mNavBarHelper.getA11yButtonState();
if (mNavigationBarView != null) { if (mNavigationBarView != null) {
boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0; boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
@@ -1403,7 +1385,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
public void updateSystemUiStateFlags(int a11yFlags) { public void updateSystemUiStateFlags(int a11yFlags) {
if (a11yFlags < 0) { if (a11yFlags < 0) {
a11yFlags = mNavigationBarA11yHelper.getA11yButtonState(); a11yFlags = mNavBarHelper.getA11yButtonState();
} }
boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0; boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0; boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
@@ -1430,24 +1412,10 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
} }
} }
private void updateAssistantEntrypoints() { private void updateAssistantEntrypoints(boolean assistantAvailable) {
mAssistantAvailable = mAssistManagerLazy.get()
.getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
boolean longPressDefault = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_assistLongPressHomeEnabledDefault);
mLongPressHomeEnabled = Settings.Secure.getIntForUser(mContentResolver,
Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, longPressDefault ? 1 : 0,
mUserTracker.getUserId()) != 0;
boolean gestureDefault = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_assistTouchGestureEnabledDefault);
mAssistantTouchGestureEnabled = Settings.Secure.getIntForUser(mContentResolver,
Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED, gestureDefault ? 1 : 0,
mUserTracker.getUserId()) != 0;
if (mOverviewProxyService.getProxy() != null) { if (mOverviewProxyService.getProxy() != null) {
try { try {
mOverviewProxyService.getProxy().onAssistantAvailable(mAssistantAvailable mOverviewProxyService.getProxy().onAssistantAvailable(assistantAvailable);
&& mAssistantTouchGestureEnabled
&& QuickStepContract.isGesturalMode(mNavBarMode));
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "Unable to send assistant availability data to launcher"); Log.w(TAG, "Unable to send assistant availability data to launcher");
} }
@@ -1518,8 +1486,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
@Override @Override
public void onNavigationModeChanged(int mode) { public void onNavigationModeChanged(int mode) {
mNavBarMode = mode; mNavBarMode = mode;
// update assistant entry points on system navigation radio button click
updateAssistantEntrypoints();
if (!QuickStepContract.isGesturalMode(mode)) { if (!QuickStepContract.isGesturalMode(mode)) {
// Reset the override alpha // Reset the override alpha
@@ -1558,9 +1524,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mNavigationBarView.getBarTransitions().finishAnimations(); mNavigationBarView.getBarTransitions().finishAnimations();
} }
private final NavigationBarA11yHelper.NavA11yEventListener mAccessibilityListener =
this::updateAccessibilityServicesState;
private WindowManager.LayoutParams getBarLayoutParams(int rotation) { private WindowManager.LayoutParams getBarLayoutParams(int rotation) {
WindowManager.LayoutParams lp = getBarLayoutParamsForRotation(rotation); WindowManager.LayoutParams lp = getBarLayoutParamsForRotation(rotation);
lp.paramsForRotation = new WindowManager.LayoutParams[4]; lp.paramsForRotation = new WindowManager.LayoutParams[4];
@@ -1668,7 +1631,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
} }
if (Intent.ACTION_USER_SWITCHED.equals(action)) { if (Intent.ACTION_USER_SWITCHED.equals(action)) {
// The accessibility settings may be different for the new user // The accessibility settings may be different for the new user
updateAccessibilityServicesState(); updateAcessibilityStateFlags();
} }
} }
}; };
@@ -1704,7 +1667,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
private final Handler mMainHandler; private final Handler mMainHandler;
private final NavigationBarOverlayController mNavbarOverlayController; private final NavigationBarOverlayController mNavbarOverlayController;
private final UiEventLogger mUiEventLogger; private final UiEventLogger mUiEventLogger;
private final NavigationBarA11yHelper mNavigationBarA11yHelper; private final NavBarHelper mNavBarHelper;
private final UserTracker mUserTracker; private final UserTracker mUserTracker;
private final LightBarController mMainLightBarController; private final LightBarController mMainLightBarController;
private final LightBarController.Factory mLightBarControllerFactory; private final LightBarController.Factory mLightBarControllerFactory;
@@ -1737,7 +1700,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
@Main Handler mainHandler, @Main Handler mainHandler,
NavigationBarOverlayController navbarOverlayController, NavigationBarOverlayController navbarOverlayController,
UiEventLogger uiEventLogger, UiEventLogger uiEventLogger,
NavigationBarA11yHelper navigationBarA11yHelper, NavBarHelper navBarHelper,
UserTracker userTracker, UserTracker userTracker,
LightBarController mainLightBarController, LightBarController mainLightBarController,
LightBarController.Factory lightBarControllerFactory, LightBarController.Factory lightBarControllerFactory,
@@ -1767,7 +1730,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mMainHandler = mainHandler; mMainHandler = mainHandler;
mNavbarOverlayController = navbarOverlayController; mNavbarOverlayController = navbarOverlayController;
mUiEventLogger = uiEventLogger; mUiEventLogger = uiEventLogger;
mNavigationBarA11yHelper = navigationBarA11yHelper; mNavBarHelper = navBarHelper;
mUserTracker = userTracker; mUserTracker = userTracker;
mMainLightBarController = mainLightBarController; mMainLightBarController = mainLightBarController;
mLightBarControllerFactory = lightBarControllerFactory; mLightBarControllerFactory = lightBarControllerFactory;
@@ -1788,7 +1751,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mSplitScreenOptional, mRecentsOptional, mStatusBarOptionalLazy, mSplitScreenOptional, mRecentsOptional, mStatusBarOptionalLazy,
mShadeController, mNotificationRemoteInputManager, mShadeController, mNotificationRemoteInputManager,
mNotificationShadeDepthController, mSystemActions, mMainHandler, mNotificationShadeDepthController, mSystemActions, mMainHandler,
mNavbarOverlayController, mUiEventLogger, mNavigationBarA11yHelper, mNavbarOverlayController, mUiEventLogger, mNavBarHelper,
mUserTracker, mMainLightBarController, mLightBarControllerFactory, mUserTracker, mMainLightBarController, mLightBarControllerFactory,
mMainAutoHideController, mAutoHideControllerFactory, mTelecomManagerOptional, mMainAutoHideController, mAutoHideControllerFactory, mTelecomManagerOptional,
mInputMethodManager); mInputMethodManager);

View File

@@ -1,90 +0,0 @@
package com.android.systemui.navigationbar;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
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 android.view.accessibility.AccessibilityManager;
import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
/**
* Extracts shared elements of a11y necessary between navbar and taskbar delegate
*/
@SysUISingleton
public final class NavigationBarA11yHelper implements
AccessibilityButtonModeObserver.ModeChangedListener {
private final AccessibilityManager mAccessibilityManager;
private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
private final List<NavA11yEventListener> mA11yEventListeners = new ArrayList<>();
@Inject
public NavigationBarA11yHelper(AccessibilityManager accessibilityManager,
AccessibilityManagerWrapper accessibilityManagerWrapper,
AccessibilityButtonModeObserver accessibilityButtonModeObserver) {
mAccessibilityManager = accessibilityManager;
accessibilityManagerWrapper.addCallback(
accessibilityManager1 -> NavigationBarA11yHelper.this.dispatchEventUpdate());
mAccessibilityButtonModeObserver = accessibilityButtonModeObserver;
mAccessibilityButtonModeObserver.addListener(this);
}
public void registerA11yEventListener(NavA11yEventListener listener) {
mA11yEventListeners.add(listener);
}
public void removeA11yEventListener(NavA11yEventListener listener) {
mA11yEventListeners.remove(listener);
}
private void dispatchEventUpdate() {
for (NavA11yEventListener listener : mA11yEventListeners) {
listener.updateAccessibilityServicesState();
}
}
@Override
public void onAccessibilityButtonModeChanged(int mode) {
dispatchEventUpdate();
}
/**
* See {@link QuickStepContract#SYSUI_STATE_A11Y_BUTTON_CLICKABLE} and
* {@link QuickStepContract#SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE}
*
* @return the a11y button clickable and long_clickable states, or 0 if there is no
* a11y button in the navbar
*/
public int getA11yButtonState() {
// AccessibilityManagerService resolves services for the current user since the local
// AccessibilityManager is created from a Context with the INTERACT_ACROSS_USERS permission
final List<String> a11yButtonTargets =
mAccessibilityManager.getAccessibilityShortcutTargets(
AccessibilityManager.ACCESSIBILITY_BUTTON);
final int requestingServices = a11yButtonTargets.size();
// If accessibility button is floating menu mode, click and long click state should be
// disabled.
if (mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode()
== ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU) {
return 0;
}
return (requestingServices >= 1 ? SYSUI_STATE_A11Y_BUTTON_CLICKABLE : 0)
| (requestingServices >= 2 ? SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE : 0);
}
public interface NavA11yEventListener {
void updateAccessibilityServicesState();
}
}

View File

@@ -100,7 +100,7 @@ public class NavigationBarController implements
CommandQueue commandQueue, CommandQueue commandQueue,
@Main Handler mainHandler, @Main Handler mainHandler,
ConfigurationController configurationController, ConfigurationController configurationController,
NavigationBarA11yHelper navigationBarA11yHelper, NavBarHelper navBarHelper,
TaskbarDelegate taskbarDelegate, TaskbarDelegate taskbarDelegate,
NavigationBar.Factory navigationBarFactory, NavigationBar.Factory navigationBarFactory,
DumpManager dumpManager, DumpManager dumpManager,
@@ -115,7 +115,7 @@ public class NavigationBarController implements
mNavMode = navigationModeController.addListener(this); mNavMode = navigationModeController.addListener(this);
mTaskbarDelegate = taskbarDelegate; mTaskbarDelegate = taskbarDelegate;
mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService, mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService,
navigationBarA11yHelper, navigationModeController, sysUiFlagsContainer, navBarHelper, navigationModeController, sysUiFlagsContainer,
dumpManager, autoHideController); dumpManager, autoHideController);
mIsTablet = isTablet(mContext); mIsTablet = isTablet(mContext);
dumpManager.registerDumpable(this); dumpManager.registerDumpable(this);

View File

@@ -43,6 +43,8 @@ import android.content.res.Configuration;
import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager;
import android.inputmethodservice.InputMethodService; import android.inputmethodservice.InputMethodService;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.Display; import android.view.Display;
import android.view.InsetsVisibilities; import android.view.InsetsVisibilities;
import android.view.View; import android.view.View;
@@ -73,19 +75,30 @@ import javax.inject.Singleton;
public class TaskbarDelegate implements CommandQueue.Callbacks, public class TaskbarDelegate implements CommandQueue.Callbacks,
OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener, OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener,
ComponentCallbacks, Dumpable { ComponentCallbacks, Dumpable {
private static final String TAG = TaskbarDelegate.class.getSimpleName();
private final EdgeBackGestureHandler mEdgeBackGestureHandler; private final EdgeBackGestureHandler mEdgeBackGestureHandler;
private boolean mInitialized;
private CommandQueue mCommandQueue; private CommandQueue mCommandQueue;
private OverviewProxyService mOverviewProxyService; private OverviewProxyService mOverviewProxyService;
private NavigationBarA11yHelper mNavigationBarA11yHelper; private NavBarHelper mNavBarHelper;
private NavigationModeController mNavigationModeController; private NavigationModeController mNavigationModeController;
private SysUiState mSysUiState; private SysUiState mSysUiState;
private AutoHideController mAutoHideController; private AutoHideController mAutoHideController;
private int mDisplayId; private int mDisplayId;
private int mNavigationIconHints; private int mNavigationIconHints;
private final NavigationBarA11yHelper.NavA11yEventListener mNavA11yEventListener = private final NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater =
this::updateSysuiFlags; new NavBarHelper.NavbarTaskbarStateUpdater() {
@Override
public void updateAccessibilityServicesState() {
updateSysuiFlags();
}
@Override
public void updateAssistantAvailable(boolean available) {
updateAssistantAvailability(available);
}
};
private int mDisabledFlags; private int mDisabledFlags;
private @WindowVisibleState int mTaskBarWindowState = WINDOW_STATE_SHOWING; private @WindowVisibleState int mTaskBarWindowState = WINDOW_STATE_SHOWING;
private @Behavior int mBehavior; private @Behavior int mBehavior;
@@ -125,14 +138,14 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
public void setDependencies(CommandQueue commandQueue, public void setDependencies(CommandQueue commandQueue,
OverviewProxyService overviewProxyService, OverviewProxyService overviewProxyService,
NavigationBarA11yHelper navigationBarA11yHelper, NavBarHelper navBarHelper,
NavigationModeController navigationModeController, NavigationModeController navigationModeController,
SysUiState sysUiState, DumpManager dumpManager, SysUiState sysUiState, DumpManager dumpManager,
AutoHideController autoHideController) { AutoHideController autoHideController) {
// TODO: adding this in the ctor results in a dagger dependency cycle :( // TODO: adding this in the ctor results in a dagger dependency cycle :(
mCommandQueue = commandQueue; mCommandQueue = commandQueue;
mOverviewProxyService = overviewProxyService; mOverviewProxyService = overviewProxyService;
mNavigationBarA11yHelper = navigationBarA11yHelper; mNavBarHelper = navBarHelper;
mNavigationModeController = navigationModeController; mNavigationModeController = navigationModeController;
mSysUiState = sysUiState; mSysUiState = sysUiState;
dumpManager.registerDumpable(this); dumpManager.registerDumpable(this);
@@ -140,12 +153,16 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
} }
public void init(int displayId) { public void init(int displayId) {
if (mInitialized) {
return;
}
mDisplayId = displayId; mDisplayId = displayId;
mCommandQueue.addCallback(this); mCommandQueue.addCallback(this);
mOverviewProxyService.addCallback(this); mOverviewProxyService.addCallback(this);
mEdgeBackGestureHandler.onNavigationModeChanged( mEdgeBackGestureHandler.onNavigationModeChanged(
mNavigationModeController.addListener(this)); mNavigationModeController.addListener(this));
mNavigationBarA11yHelper.registerA11yEventListener(mNavA11yEventListener); mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mNavBarHelper.init(mContext);
mEdgeBackGestureHandler.onNavBarAttached(); mEdgeBackGestureHandler.onNavBarAttached();
// Initialize component callback // Initialize component callback
Display display = mDisplayManager.getDisplay(displayId); Display display = mDisplayManager.getDisplay(displayId);
@@ -154,23 +171,29 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
// Set initial state for any listeners // Set initial state for any listeners
updateSysuiFlags(); updateSysuiFlags();
mAutoHideController.setNavigationBar(mAutoHideUiElement); mAutoHideController.setNavigationBar(mAutoHideUiElement);
mInitialized = true;
} }
public void destroy() { public void destroy() {
if (!mInitialized) {
return;
}
mCommandQueue.removeCallback(this); mCommandQueue.removeCallback(this);
mOverviewProxyService.removeCallback(this); mOverviewProxyService.removeCallback(this);
mNavigationModeController.removeListener(this); mNavigationModeController.removeListener(this);
mNavigationBarA11yHelper.removeA11yEventListener(mNavA11yEventListener); mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mNavBarHelper.destroy();
mEdgeBackGestureHandler.onNavBarDetached(); mEdgeBackGestureHandler.onNavBarDetached();
if (mWindowContext != null) { if (mWindowContext != null) {
mWindowContext.unregisterComponentCallbacks(this); mWindowContext.unregisterComponentCallbacks(this);
mWindowContext = null; mWindowContext = null;
} }
mAutoHideController.setNavigationBar(null); mAutoHideController.setNavigationBar(null);
mInitialized = false;
} }
private void updateSysuiFlags() { private void updateSysuiFlags() {
int a11yFlags = mNavigationBarA11yHelper.getA11yButtonState(); int a11yFlags = mNavBarHelper.getA11yButtonState();
boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0; boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0; boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
@@ -194,6 +217,18 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
.commitUpdate(mDisplayId); .commitUpdate(mDisplayId);
} }
private void updateAssistantAvailability(boolean assistantAvailable) {
if (mOverviewProxyService.getProxy() == null) {
return;
}
try {
mOverviewProxyService.getProxy().onAssistantAvailable(assistantAvailable);
} catch (RemoteException e) {
Log.e(TAG, "onAssistantAvailable() failed, available: " + assistantAvailable, e);
}
}
@Override @Override
public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
boolean showImeSwitcher) { boolean showImeSwitcher) {

View File

@@ -0,0 +1,178 @@
/*
* Copyright (C) 2021 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.systemui.navigationbar;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.view.accessibility.AccessibilityManager;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import dagger.Lazy;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class NavBarHelperTest extends SysuiTestCase {
@Mock
AccessibilityManager mAccessibilityManager;
@Mock
AccessibilityManagerWrapper mAccessibilityManagerWrapper;
@Mock
AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
@Mock
OverviewProxyService mOverviewProxyService;
@Mock
Lazy<AssistManager> mAssistManagerLazy;
@Mock
AssistManager mAssistManager;
@Mock
NavigationModeController mNavigationModeController;
@Mock
UserTracker mUserTracker;
@Mock
ComponentName mAssistantComponent;
@Mock
DumpManager mDumpManager;
@Mock
NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater;
private NavBarHelper mNavBarHelper;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(mAssistManagerLazy.get()).thenReturn(mAssistManager);
when(mAssistManager.getAssistInfoForUser(anyInt())).thenReturn(mAssistantComponent);
when(mUserTracker.getUserId()).thenReturn(1);
mNavBarHelper = new NavBarHelper(mAccessibilityManager,
mAccessibilityManagerWrapper, mAccessibilityButtonModeObserver,
mOverviewProxyService, mAssistManagerLazy, mNavigationModeController,
mUserTracker, mDumpManager);
}
@Test
public void registerListenersInCtor() {
verify(mAccessibilityButtonModeObserver, times(1)).addListener(mNavBarHelper);
verify(mNavigationModeController, times(1)).addListener(mNavBarHelper);
verify(mOverviewProxyService, times(1)).addCallback(mNavBarHelper);
}
@Test
public void registerAssistantContentObserver() {
mNavBarHelper.init(mContext);
verify(mAssistManager, times(1)).getAssistInfoForUser(anyInt());
}
@Test
public void callbacksFiredWhenRegistering() {
mNavBarHelper.init(mContext);
mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
verify(mNavbarTaskbarStateUpdater, times(1))
.updateAccessibilityServicesState();
verify(mNavbarTaskbarStateUpdater, times(1))
.updateAssistantAvailable(anyBoolean());
}
@Test
public void assistantCallbacksFiredAfterConnecting() {
mNavBarHelper.init(mContext);
// 1st set of callbacks get called when registering
mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mNavBarHelper.onConnectionChanged(false);
// assert no more callbacks fired
verify(mNavbarTaskbarStateUpdater, times(1))
.updateAccessibilityServicesState();
verify(mNavbarTaskbarStateUpdater, times(1))
.updateAssistantAvailable(anyBoolean());
mNavBarHelper.onConnectionChanged(true);
// assert no more callbacks fired
verify(mNavbarTaskbarStateUpdater, times(1))
.updateAccessibilityServicesState();
verify(mNavbarTaskbarStateUpdater, times(2))
.updateAssistantAvailable(anyBoolean());
}
@Test
public void a11yCallbacksFiredAfterModeChange() {
mNavBarHelper.init(mContext);
// 1st set of callbacks get called when registering
mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mNavBarHelper.onAccessibilityButtonModeChanged(0);
verify(mNavbarTaskbarStateUpdater, times(2))
.updateAccessibilityServicesState();
verify(mNavbarTaskbarStateUpdater, times(1))
.updateAssistantAvailable(anyBoolean());
}
@Test
public void assistantCallbacksFiredAfterNavModeChange() {
mNavBarHelper.init(mContext);
// 1st set of callbacks get called when registering
mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mNavBarHelper.onNavigationModeChanged(0);
verify(mNavbarTaskbarStateUpdater, times(1))
.updateAccessibilityServicesState();
verify(mNavbarTaskbarStateUpdater, times(2))
.updateAssistantAvailable(anyBoolean());
}
@Test
public void removeListenerNoCallbacksFired() {
mNavBarHelper.init(mContext);
// 1st set of callbacks get called when registering
mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
// Remove listener
mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
// Would have fired 2nd callback if not removed
mNavBarHelper.onAccessibilityButtonModeChanged(0);
// assert no more callbacks fired
verify(mNavbarTaskbarStateUpdater, times(1))
.updateAccessibilityServicesState();
verify(mNavbarTaskbarStateUpdater, times(1))
.updateAssistantAvailable(anyBoolean());
}
}

View File

@@ -82,7 +82,7 @@ public class NavigationBarControllerTest extends SysuiTestCase {
mCommandQueue, mCommandQueue,
Dependency.get(Dependency.MAIN_HANDLER), Dependency.get(Dependency.MAIN_HANDLER),
mock(ConfigurationController.class), mock(ConfigurationController.class),
mock(NavigationBarA11yHelper.class), mock(NavBarHelper.class),
mock(TaskbarDelegate.class), mock(TaskbarDelegate.class),
mNavigationBarFactory, mNavigationBarFactory,
mock(DumpManager.class), mock(DumpManager.class),

View File

@@ -131,7 +131,7 @@ public class NavigationBarTest extends SysuiTestCase {
@Mock @Mock
EdgeBackGestureHandler mEdgeBackGestureHandler; EdgeBackGestureHandler mEdgeBackGestureHandler;
@Mock @Mock
NavigationBarA11yHelper mNavigationBarA11yHelper; NavBarHelper mNavBarHelper;
@Mock @Mock
private LightBarController mLightBarController; private LightBarController mLightBarController;
@Mock @Mock
@@ -220,6 +220,7 @@ public class NavigationBarTest extends SysuiTestCase {
new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_SYSTEMUI) new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_SYSTEMUI)
.setLong(HOME_BUTTON_LONG_PRESS_DURATION_MS, 100) .setLong(HOME_BUTTON_LONG_PRESS_DURATION_MS, 100)
.build()); .build());
when(mNavBarHelper.getLongPressHomeEnabled()).thenReturn(true);
mNavigationBar.onViewAttachedToWindow(mNavigationBar.createView(null)); mNavigationBar.onViewAttachedToWindow(mNavigationBar.createView(null));
mNavigationBar.onHomeTouch(mNavigationBar.getView(), MotionEvent.obtain( mNavigationBar.onHomeTouch(mNavigationBar.getView(), MotionEvent.obtain(
@@ -284,14 +285,14 @@ public class NavigationBarTest extends SysuiTestCase {
public void testA11yEventAfterDetach() { public void testA11yEventAfterDetach() {
View v = mNavigationBar.createView(null); View v = mNavigationBar.createView(null);
mNavigationBar.onViewAttachedToWindow(v); mNavigationBar.onViewAttachedToWindow(v);
verify(mNavigationBarA11yHelper).registerA11yEventListener(any( verify(mNavBarHelper).registerNavTaskStateUpdater(any(
NavigationBarA11yHelper.NavA11yEventListener.class)); NavBarHelper.NavbarTaskbarStateUpdater.class));
mNavigationBar.onViewDetachedFromWindow(v); mNavigationBar.onViewDetachedFromWindow(v);
verify(mNavigationBarA11yHelper).removeA11yEventListener(any( verify(mNavBarHelper).removeNavTaskStateUpdater(any(
NavigationBarA11yHelper.NavA11yEventListener.class)); NavBarHelper.NavbarTaskbarStateUpdater.class));
// Should be safe even though the internal view is now null. // Should be safe even though the internal view is now null.
mNavigationBar.updateAccessibilityServicesState(); mNavigationBar.updateAcessibilityStateFlags();
} }
private NavigationBar createNavBar(Context context) { private NavigationBar createNavBar(Context context) {
@@ -321,7 +322,7 @@ public class NavigationBarTest extends SysuiTestCase {
mHandler, mHandler,
mock(NavigationBarOverlayController.class), mock(NavigationBarOverlayController.class),
mUiEventLogger, mUiEventLogger,
mNavigationBarA11yHelper, mNavBarHelper,
mock(UserTracker.class), mock(UserTracker.class),
mLightBarController, mLightBarController,
mLightBarcontrollerFactory, mLightBarcontrollerFactory,