1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.navigationbar; 18 19 import static android.app.StatusBarManager.WINDOW_NAVIGATION_BAR; 20 import static android.app.StatusBarManager.WindowVisibleState; 21 import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; 22 import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS; 23 import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS; 24 import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS; 25 26 import static com.android.systemui.accessibility.SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON; 27 import static com.android.systemui.accessibility.SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER; 28 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE; 29 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE; 30 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT; 31 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT; 32 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE; 33 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT; 34 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; 35 36 import android.content.ContentResolver; 37 import android.content.Context; 38 import android.database.ContentObserver; 39 import android.inputmethodservice.InputMethodService; 40 import android.net.Uri; 41 import android.os.Bundle; 42 import android.os.Handler; 43 import android.os.Looper; 44 import android.os.RemoteException; 45 import android.os.UserHandle; 46 import android.provider.Settings; 47 import android.provider.Settings.Secure; 48 import android.util.Log; 49 import android.view.IRotationWatcher; 50 import android.view.IWallpaperVisibilityListener; 51 import android.view.IWindowManager; 52 import android.view.View; 53 import android.view.WindowInsets; 54 import android.view.accessibility.AccessibilityManager; 55 56 import androidx.annotation.NonNull; 57 58 import com.android.systemui.Dumpable; 59 import com.android.systemui.accessibility.AccessibilityButtonModeObserver; 60 import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver; 61 import com.android.systemui.accessibility.SystemActions; 62 import com.android.systemui.assist.AssistManager; 63 import com.android.systemui.dagger.SysUISingleton; 64 import com.android.systemui.dump.DumpManager; 65 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; 66 import com.android.systemui.recents.OverviewProxyService; 67 import com.android.systemui.settings.DisplayTracker; 68 import com.android.systemui.settings.UserTracker; 69 import com.android.systemui.shared.system.QuickStepContract; 70 import com.android.systemui.statusbar.CommandQueue; 71 import com.android.systemui.statusbar.NotificationShadeWindowController; 72 import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; 73 import com.android.systemui.statusbar.phone.CentralSurfaces; 74 import com.android.systemui.statusbar.policy.KeyguardStateController; 75 76 import dagger.Lazy; 77 78 import java.io.PrintWriter; 79 import java.util.ArrayList; 80 import java.util.List; 81 import java.util.Optional; 82 83 import javax.inject.Inject; 84 85 /** 86 * Extracts shared elements between navbar and taskbar delegate to de-dupe logic and help them 87 * experience the joys of friendship. 88 * The events are then passed through 89 * 90 * Currently consolidates 91 * * A11y 92 * * Assistant 93 */ 94 @SysUISingleton 95 public final class NavBarHelper implements 96 AccessibilityManager.AccessibilityServicesStateChangeListener, 97 AccessibilityButtonModeObserver.ModeChangedListener, 98 AccessibilityButtonTargetsObserver.TargetsChangedListener, 99 OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener, 100 Dumpable, CommandQueue.Callbacks { 101 private static final String TAG = NavBarHelper.class.getSimpleName(); 102 103 private final Handler mHandler = new Handler(Looper.getMainLooper()); 104 private final AccessibilityManager mAccessibilityManager; 105 private final Lazy<AssistManager> mAssistManagerLazy; 106 private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy; 107 private final KeyguardStateController mKeyguardStateController; 108 private final UserTracker mUserTracker; 109 private final SystemActions mSystemActions; 110 private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver; 111 private final AccessibilityButtonTargetsObserver mAccessibilityButtonTargetsObserver; 112 private final List<NavbarTaskbarStateUpdater> mStateListeners = new ArrayList<>(); 113 private final Context mContext; 114 private final NotificationShadeWindowController mNotificationShadeWindowController; 115 private final CommandQueue mCommandQueue; 116 private final ContentResolver mContentResolver; 117 private final EdgeBackGestureHandler mEdgeBackGestureHandler; 118 private final IWindowManager mWm; 119 private final int mDefaultDisplayId; 120 private boolean mAssistantAvailable; 121 private boolean mLongPressHomeEnabled; 122 private boolean mAssistantTouchGestureEnabled; 123 private int mNavBarMode; 124 private int mA11yButtonState; 125 private int mRotationWatcherRotation; 126 private boolean mTogglingNavbarTaskbar; 127 private boolean mWallpaperVisible; 128 129 // Attributes used in NavBarHelper.CurrentSysuiState 130 private int mWindowStateDisplayId; 131 private @WindowVisibleState int mWindowState; 132 133 // Listens for changes to the assistant 134 private final ContentObserver mAssistContentObserver = new ContentObserver(mHandler) { 135 @Override 136 public void onChange(boolean selfChange, Uri uri) { 137 updateAssistantAvailability(); 138 } 139 }; 140 141 // Listens for changes to the wallpaper visibility 142 private final IWallpaperVisibilityListener mWallpaperVisibilityListener = 143 new IWallpaperVisibilityListener.Stub() { 144 @Override 145 public void onWallpaperVisibilityChanged(boolean visible, 146 int displayId) throws RemoteException { 147 mHandler.post(() -> { 148 mWallpaperVisible = visible; 149 dispatchWallpaperVisibilityChanged(visible, displayId); 150 }); 151 } 152 }; 153 154 // Listens for changes to display rotation 155 private final IRotationWatcher mRotationWatcher = new IRotationWatcher.Stub() { 156 @Override 157 public void onRotationChanged(final int rotation) { 158 // We need this to be scheduled as early as possible to beat the redrawing of 159 // window in response to the orientation change. 160 mHandler.postAtFrontOfQueue(() -> { 161 mRotationWatcherRotation = rotation; 162 dispatchRotationChanged(rotation); 163 }); 164 } 165 }; 166 167 /** 168 * @param context This is not display specific, then again neither is any of the code in 169 * this class. Once there's display specific code, we may want to create an 170 * instance of this class per navbar vs having it be a singleton. 171 */ 172 @Inject NavBarHelper(Context context, AccessibilityManager accessibilityManager, AccessibilityButtonModeObserver accessibilityButtonModeObserver, AccessibilityButtonTargetsObserver accessibilityButtonTargetsObserver, SystemActions systemActions, OverviewProxyService overviewProxyService, Lazy<AssistManager> assistManagerLazy, Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy, KeyguardStateController keyguardStateController, NavigationModeController navigationModeController, EdgeBackGestureHandler.Factory edgeBackGestureHandlerFactory, IWindowManager wm, UserTracker userTracker, DisplayTracker displayTracker, NotificationShadeWindowController notificationShadeWindowController, DumpManager dumpManager, CommandQueue commandQueue)173 public NavBarHelper(Context context, AccessibilityManager accessibilityManager, 174 AccessibilityButtonModeObserver accessibilityButtonModeObserver, 175 AccessibilityButtonTargetsObserver accessibilityButtonTargetsObserver, 176 SystemActions systemActions, 177 OverviewProxyService overviewProxyService, 178 Lazy<AssistManager> assistManagerLazy, 179 Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy, 180 KeyguardStateController keyguardStateController, 181 NavigationModeController navigationModeController, 182 EdgeBackGestureHandler.Factory edgeBackGestureHandlerFactory, 183 IWindowManager wm, 184 UserTracker userTracker, 185 DisplayTracker displayTracker, 186 NotificationShadeWindowController notificationShadeWindowController, 187 DumpManager dumpManager, 188 CommandQueue commandQueue) { 189 mContext = context; 190 mNotificationShadeWindowController = notificationShadeWindowController; 191 mCommandQueue = commandQueue; 192 mContentResolver = mContext.getContentResolver(); 193 mAccessibilityManager = accessibilityManager; 194 mAssistManagerLazy = assistManagerLazy; 195 mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy; 196 mKeyguardStateController = keyguardStateController; 197 mUserTracker = userTracker; 198 mSystemActions = systemActions; 199 mAccessibilityButtonModeObserver = accessibilityButtonModeObserver; 200 mAccessibilityButtonTargetsObserver = accessibilityButtonTargetsObserver; 201 mWm = wm; 202 mDefaultDisplayId = displayTracker.getDefaultDisplayId(); 203 mEdgeBackGestureHandler = edgeBackGestureHandlerFactory.create(context); 204 205 mNavBarMode = navigationModeController.addListener(this); 206 mCommandQueue.addCallback(this); 207 overviewProxyService.addCallback(this); 208 dumpManager.registerDumpable(this); 209 } 210 211 /** 212 * Hints to the helper that bars are being replaced, which is a signal to potentially suppress 213 * normal setup/cleanup when no bars are present. 214 */ setTogglingNavbarTaskbar(boolean togglingNavbarTaskbar)215 public void setTogglingNavbarTaskbar(boolean togglingNavbarTaskbar) { 216 mTogglingNavbarTaskbar = togglingNavbarTaskbar; 217 } 218 219 /** 220 * Called when the first (non-replacing) bar is registered. 221 */ setupOnFirstBar()222 private void setupOnFirstBar() { 223 // Setup accessibility listeners 224 mAccessibilityManager.addAccessibilityServicesStateChangeListener(this); 225 mAccessibilityButtonModeObserver.addListener(this); 226 mAccessibilityButtonTargetsObserver.addListener(this); 227 228 // Setup assistant listener 229 mContentResolver.registerContentObserver( 230 Settings.Secure.getUriFor(Settings.Secure.ASSISTANT), 231 false /* notifyForDescendants */, mAssistContentObserver, UserHandle.USER_ALL); 232 mContentResolver.registerContentObserver( 233 Settings.Secure.getUriFor(Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED), 234 false, mAssistContentObserver, UserHandle.USER_ALL); 235 mContentResolver.registerContentObserver( 236 Settings.Secure.getUriFor(Secure.SEARCH_LONG_PRESS_HOME_ENABLED), 237 false, mAssistContentObserver, UserHandle.USER_ALL); 238 mContentResolver.registerContentObserver( 239 Settings.Secure.getUriFor(Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED), 240 false, mAssistContentObserver, UserHandle.USER_ALL); 241 242 // Setup display rotation watcher 243 try { 244 mWm.watchRotation(mRotationWatcher, mDefaultDisplayId); 245 } catch (Exception e) { 246 Log.w(TAG, "Failed to register rotation watcher", e); 247 } 248 249 // Setup wallpaper visibility listener 250 try { 251 mWallpaperVisible = mWm.registerWallpaperVisibilityListener( 252 mWallpaperVisibilityListener, mDefaultDisplayId); 253 } catch (Exception e) { 254 Log.w(TAG, "Failed to register wallpaper visibility listener", e); 255 } 256 257 // Attach the back handler only when the first bar is registered 258 mEdgeBackGestureHandler.onNavBarAttached(); 259 } 260 261 /** 262 * Called after the last (non-replacing) bar is unregistered. 263 */ cleanupAfterLastBar()264 private void cleanupAfterLastBar() { 265 // Clean up accessibility listeners 266 mAccessibilityManager.removeAccessibilityServicesStateChangeListener(this); 267 mAccessibilityButtonModeObserver.removeListener(this); 268 mAccessibilityButtonTargetsObserver.removeListener(this); 269 270 // Clean up assistant listeners 271 mContentResolver.unregisterContentObserver(mAssistContentObserver); 272 273 // Clean up display rotation watcher 274 try { 275 mWm.removeRotationWatcher(mRotationWatcher); 276 } catch (Exception e) { 277 Log.w(TAG, "Failed to unregister rotation watcher", e); 278 } 279 280 // Clean up wallpaper visibility listener 281 try { 282 mWm.unregisterWallpaperVisibilityListener(mWallpaperVisibilityListener, 283 mDefaultDisplayId); 284 } catch (Exception e) { 285 Log.w(TAG, "Failed to register wallpaper visibility listener", e); 286 } 287 288 // No more bars, detach the back handler for now 289 mEdgeBackGestureHandler.onNavBarDetached(); 290 } 291 292 /** 293 * Registers a listener for future updates to the shared navbar/taskbar state. 294 * @param listener Will immediately get callbacks based on current state 295 */ registerNavTaskStateUpdater(NavbarTaskbarStateUpdater listener)296 public void registerNavTaskStateUpdater(NavbarTaskbarStateUpdater listener) { 297 mStateListeners.add(listener); 298 if (!mTogglingNavbarTaskbar && mStateListeners.size() == 1) { 299 setupOnFirstBar(); 300 301 // Update the state once the first bar is registered 302 updateAssistantAvailability(); 303 updateA11yState(); 304 mCommandQueue.recomputeDisableFlags(mContext.getDisplayId(), false /* animate */); 305 } else { 306 listener.updateAccessibilityServicesState(); 307 listener.updateAssistantAvailable(mAssistantAvailable, mLongPressHomeEnabled); 308 } 309 listener.updateWallpaperVisibility(mWallpaperVisible, mDefaultDisplayId); 310 listener.updateRotationWatcherState(mRotationWatcherRotation); 311 } 312 313 /** 314 * Removes a previously registered listener. 315 */ removeNavTaskStateUpdater(NavbarTaskbarStateUpdater listener)316 public void removeNavTaskStateUpdater(NavbarTaskbarStateUpdater listener) { 317 mStateListeners.remove(listener); 318 if (!mTogglingNavbarTaskbar && mStateListeners.isEmpty()) { 319 cleanupAfterLastBar(); 320 } 321 } 322 dispatchA11yEventUpdate()323 private void dispatchA11yEventUpdate() { 324 for (NavbarTaskbarStateUpdater listener : mStateListeners) { 325 listener.updateAccessibilityServicesState(); 326 } 327 } 328 dispatchAssistantEventUpdate(boolean assistantAvailable, boolean longPressHomeEnabled)329 private void dispatchAssistantEventUpdate(boolean assistantAvailable, 330 boolean longPressHomeEnabled) { 331 for (NavbarTaskbarStateUpdater listener : mStateListeners) { 332 listener.updateAssistantAvailable(assistantAvailable, longPressHomeEnabled); 333 } 334 } 335 336 @Override onAccessibilityServicesStateChanged(AccessibilityManager manager)337 public void onAccessibilityServicesStateChanged(AccessibilityManager manager) { 338 updateA11yState(); 339 } 340 341 @Override onAccessibilityButtonModeChanged(int mode)342 public void onAccessibilityButtonModeChanged(int mode) { 343 updateA11yState(); 344 } 345 346 @Override onAccessibilityButtonTargetsChanged(String targets)347 public void onAccessibilityButtonTargetsChanged(String targets) { 348 updateA11yState(); 349 } 350 351 /** 352 * Updates the current accessibility button state. The accessibility button state is only 353 * used for {@link Secure#ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR} and 354 * {@link Secure#ACCESSIBILITY_BUTTON_MODE_GESTURE}, otherwise it is reset to 0. 355 */ updateA11yState()356 private void updateA11yState() { 357 final int prevState = mA11yButtonState; 358 final boolean clickable; 359 final boolean longClickable; 360 if (mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode() 361 == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU) { 362 // If accessibility button is floating menu mode, click and long click state should be 363 // disabled. 364 clickable = false; 365 longClickable = false; 366 mA11yButtonState = 0; 367 } else { 368 // AccessibilityManagerService resolves services for the current user since the local 369 // AccessibilityManager is created from a Context with the INTERACT_ACROSS_USERS 370 // permission 371 final List<String> a11yButtonTargets = 372 mAccessibilityManager.getAccessibilityShortcutTargets( 373 AccessibilityManager.ACCESSIBILITY_BUTTON); 374 final int requestingServices = a11yButtonTargets.size(); 375 376 clickable = requestingServices >= 1; 377 378 // `longClickable` is used to determine whether to pop up the accessibility chooser 379 // dialog or not, and it’s also only for multiple services. 380 longClickable = requestingServices >= 2; 381 mA11yButtonState = (clickable ? SYSUI_STATE_A11Y_BUTTON_CLICKABLE : 0) 382 | (longClickable ? SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE : 0); 383 } 384 385 // Update the system actions if the state has changed 386 if (prevState != mA11yButtonState) { 387 updateSystemAction(clickable, SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON); 388 updateSystemAction(longClickable, SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER); 389 } 390 391 dispatchA11yEventUpdate(); 392 } 393 394 /** 395 * Registers/unregisters the given system action id. 396 */ updateSystemAction(boolean register, int actionId)397 private void updateSystemAction(boolean register, int actionId) { 398 if (register) { 399 mSystemActions.register(actionId); 400 } else { 401 mSystemActions.unregister(actionId); 402 } 403 } 404 405 /** 406 * Gets the accessibility button state based on the {@link Secure#ACCESSIBILITY_BUTTON_MODE}. 407 * 408 * @return the accessibility button state: 409 * 0 = disable state 410 * 16 = {@link QuickStepContract#SYSUI_STATE_A11Y_BUTTON_CLICKABLE} 411 * 48 = the combination of {@link QuickStepContract#SYSUI_STATE_A11Y_BUTTON_CLICKABLE} and 412 * {@link QuickStepContract#SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE} 413 */ getA11yButtonState()414 public int getA11yButtonState() { 415 return mA11yButtonState; 416 } 417 418 @Override onConnectionChanged(boolean isConnected)419 public void onConnectionChanged(boolean isConnected) { 420 if (isConnected) { 421 updateAssistantAvailability(); 422 } 423 } 424 updateAssistantAvailability()425 private void updateAssistantAvailability() { 426 boolean assistantAvailableForUser = mAssistManagerLazy.get() 427 .getAssistInfoForUser(mUserTracker.getUserId()) != null; 428 429 boolean overrideLongPressHome = mAssistManagerLazy.get() 430 .shouldOverrideAssist(AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS); 431 boolean longPressDefault = mContext.getResources().getBoolean(overrideLongPressHome 432 ? com.android.internal.R.bool.config_searchLongPressHomeEnabledDefault 433 : com.android.internal.R.bool.config_assistLongPressHomeEnabledDefault); 434 mLongPressHomeEnabled = Settings.Secure.getIntForUser(mContentResolver, 435 overrideLongPressHome ? Secure.SEARCH_LONG_PRESS_HOME_ENABLED 436 : Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, longPressDefault ? 1 : 0, 437 mUserTracker.getUserId()) != 0; 438 439 boolean gestureDefault = mContext.getResources().getBoolean( 440 com.android.internal.R.bool.config_assistTouchGestureEnabledDefault); 441 mAssistantTouchGestureEnabled = Settings.Secure.getIntForUser(mContentResolver, 442 Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED, gestureDefault ? 1 : 0, 443 mUserTracker.getUserId()) != 0; 444 445 mAssistantAvailable = assistantAvailableForUser 446 && mAssistantTouchGestureEnabled 447 && QuickStepContract.isGesturalMode(mNavBarMode); 448 dispatchAssistantEventUpdate(mAssistantAvailable, mLongPressHomeEnabled); 449 } 450 getLongPressHomeEnabled()451 public boolean getLongPressHomeEnabled() { 452 return mLongPressHomeEnabled; 453 } 454 getEdgeBackGestureHandler()455 public EdgeBackGestureHandler getEdgeBackGestureHandler() { 456 return mEdgeBackGestureHandler; 457 } 458 459 @Override startAssistant(Bundle bundle)460 public void startAssistant(Bundle bundle) { 461 mAssistManagerLazy.get().startAssist(bundle); 462 } 463 464 @Override setAssistantOverridesRequested(int[] invocationTypes)465 public void setAssistantOverridesRequested(int[] invocationTypes) { 466 mAssistManagerLazy.get().setAssistantOverridesRequested(invocationTypes); 467 updateAssistantAvailability(); 468 } 469 470 @Override onNavigationModeChanged(int mode)471 public void onNavigationModeChanged(int mode) { 472 mNavBarMode = mode; 473 updateAssistantAvailability(); 474 } 475 476 /** 477 * @return Whether the IME is shown on top of the screen given the {@code vis} flag of 478 * {@link InputMethodService} and the keyguard states. 479 */ isImeShown(int vis)480 public boolean isImeShown(int vis) { 481 View shadeWindowView = mNotificationShadeWindowController.getWindowRootView(); 482 boolean isKeyguardShowing = mKeyguardStateController.isShowing(); 483 boolean imeVisibleOnShade = shadeWindowView != null && shadeWindowView.isAttachedToWindow() 484 && shadeWindowView.getRootWindowInsets().isVisible(WindowInsets.Type.ime()); 485 return imeVisibleOnShade 486 || (!isKeyguardShowing && (vis & InputMethodService.IME_VISIBLE) != 0); 487 } 488 489 @Override setWindowState(int displayId, int window, int state)490 public void setWindowState(int displayId, int window, int state) { 491 CommandQueue.Callbacks.super.setWindowState(displayId, window, state); 492 if (window != WINDOW_NAVIGATION_BAR) { 493 return; 494 } 495 mWindowStateDisplayId = displayId; 496 mWindowState = state; 497 } 498 dispatchWallpaperVisibilityChanged(boolean visible, int displayId)499 private void dispatchWallpaperVisibilityChanged(boolean visible, int displayId) { 500 for (NavbarTaskbarStateUpdater listener : mStateListeners) { 501 listener.updateWallpaperVisibility(visible, displayId); 502 } 503 } 504 dispatchRotationChanged(int rotation)505 private void dispatchRotationChanged(int rotation) { 506 for (NavbarTaskbarStateUpdater listener : mStateListeners) { 507 listener.updateRotationWatcherState(rotation); 508 } 509 } 510 getCurrentSysuiState()511 public CurrentSysuiState getCurrentSysuiState() { 512 return new CurrentSysuiState(); 513 } 514 515 /** 516 * Callbacks will get fired once immediately after registering via 517 * {@link #registerNavTaskStateUpdater(NavbarTaskbarStateUpdater)} 518 */ 519 public interface NavbarTaskbarStateUpdater { updateAccessibilityServicesState()520 void updateAccessibilityServicesState(); updateAssistantAvailable(boolean available, boolean longPressHomeEnabled)521 void updateAssistantAvailable(boolean available, boolean longPressHomeEnabled); updateWallpaperVisibility(boolean visible, int displayId)522 default void updateWallpaperVisibility(boolean visible, int displayId) {} updateRotationWatcherState(int rotation)523 default void updateRotationWatcherState(int rotation) {} 524 } 525 526 /** Data class to help Taskbar/Navbar initiate state correctly when switching between the two.*/ 527 public class CurrentSysuiState { 528 public final int mWindowStateDisplayId; 529 public final @WindowVisibleState int mWindowState; 530 CurrentSysuiState()531 public CurrentSysuiState() { 532 mWindowStateDisplayId = NavBarHelper.this.mWindowStateDisplayId; 533 mWindowState = NavBarHelper.this.mWindowState; 534 } 535 } 536 transitionMode(boolean isTransient, int appearance)537 static @TransitionMode int transitionMode(boolean isTransient, int appearance) { 538 final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_NAVIGATION_BARS; 539 if (isTransient) { 540 return MODE_SEMI_TRANSPARENT; 541 } else if ((appearance & lightsOutOpaque) == lightsOutOpaque) { 542 return MODE_LIGHTS_OUT; 543 } else if ((appearance & APPEARANCE_LOW_PROFILE_BARS) != 0) { 544 return MODE_LIGHTS_OUT_TRANSPARENT; 545 } else if ((appearance & APPEARANCE_OPAQUE_NAVIGATION_BARS) != 0) { 546 return MODE_OPAQUE; 547 } else if ((appearance & APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS) != 0) { 548 return MODE_SEMI_TRANSPARENT; 549 } else { 550 return MODE_TRANSPARENT; 551 } 552 } 553 554 @Override dump(@onNull PrintWriter pw, @NonNull String[] args)555 public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { 556 pw.println("NavbarTaskbarFriendster"); 557 pw.println(" longPressHomeEnabled=" + mLongPressHomeEnabled); 558 pw.println(" mAssistantTouchGestureEnabled=" + mAssistantTouchGestureEnabled); 559 pw.println(" mAssistantAvailable=" + mAssistantAvailable); 560 pw.println(" mNavBarMode=" + mNavBarMode); 561 } 562 } 563