Merge "Extract assistant logic from NavigationBar to share with Taskbar" into sc-v2-dev am: 325d89dd12
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16231766 Change-Id: I34417abf752722ac3f96883cfb484e7a4f382751
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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),
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user