1 /*
2  * Copyright 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.ActivityManager.LOCK_TASK_MODE_PINNED;
20 import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
21 import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
22 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
23 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
24 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
25 
26 import static com.android.systemui.navigationbar.NavBarHelper.transitionMode;
27 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
28 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
29 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
30 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED;
31 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
32 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
33 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
34 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
35 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
36 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
37 import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
38 
39 import android.app.StatusBarManager;
40 import android.app.StatusBarManager.WindowVisibleState;
41 import android.content.Context;
42 import android.graphics.Rect;
43 import android.hardware.display.DisplayManager;
44 import android.inputmethodservice.InputMethodService;
45 import android.os.IBinder;
46 import android.os.RemoteException;
47 import android.os.Trace;
48 import android.util.Log;
49 import android.view.Display;
50 import android.view.View;
51 import android.view.WindowInsets;
52 import android.view.WindowInsets.Type.InsetsType;
53 import android.view.WindowInsetsController.Appearance;
54 import android.view.WindowInsetsController.Behavior;
55 
56 import androidx.annotation.NonNull;
57 import androidx.annotation.VisibleForTesting;
58 
59 import com.android.internal.statusbar.LetterboxDetails;
60 import com.android.internal.view.AppearanceRegion;
61 import com.android.systemui.Dumpable;
62 import com.android.systemui.dagger.SysUISingleton;
63 import com.android.systemui.dump.DumpManager;
64 import com.android.systemui.model.SysUiState;
65 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
66 import com.android.systemui.recents.OverviewProxyService;
67 import com.android.systemui.shared.recents.utilities.Utilities;
68 import com.android.systemui.shared.system.QuickStepContract;
69 import com.android.systemui.shared.system.TaskStackChangeListener;
70 import com.android.systemui.shared.system.TaskStackChangeListeners;
71 import com.android.systemui.statusbar.AutoHideUiElement;
72 import com.android.systemui.statusbar.CommandQueue;
73 import com.android.systemui.statusbar.phone.AutoHideController;
74 import com.android.systemui.statusbar.phone.LightBarController;
75 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
76 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
77 import com.android.wm.shell.back.BackAnimation;
78 import com.android.wm.shell.pip.Pip;
79 
80 import java.io.PrintWriter;
81 import java.util.Optional;
82 import java.util.function.Consumer;
83 
84 import javax.inject.Inject;
85 
86 /** */
87 @SysUISingleton
88 public class TaskbarDelegate implements CommandQueue.Callbacks,
89         OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener,
90         Dumpable {
91     private static final String TAG = TaskbarDelegate.class.getSimpleName();
92 
93     private EdgeBackGestureHandler mEdgeBackGestureHandler;
94     private final LightBarTransitionsController.Factory mLightBarTransitionsControllerFactory;
95     private boolean mInitialized;
96     private CommandQueue mCommandQueue;
97     private OverviewProxyService mOverviewProxyService;
98     private NavBarHelper mNavBarHelper;
99     private NavigationModeController mNavigationModeController;
100     private SysUiState mSysUiState;
101     private AutoHideController mAutoHideController;
102     private LightBarController mLightBarController;
103     private LightBarTransitionsController mLightBarTransitionsController;
104     private TaskStackChangeListeners mTaskStackChangeListeners;
105     private Optional<Pip> mPipOptional;
106     private int mDisplayId;
107     private int mNavigationIconHints;
108     private final NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater =
109             new NavBarHelper.NavbarTaskbarStateUpdater() {
110                 @Override
111                 public void updateAccessibilityServicesState() {
112                     updateSysuiFlags();
113                 }
114 
115                 @Override
116                 public void updateAssistantAvailable(boolean available,
117                         boolean longPressHomeEnabled) {
118                     updateAssistantAvailability(available, longPressHomeEnabled);
119                 }
120             };
121     private int mDisabledFlags;
122     private @WindowVisibleState int mTaskBarWindowState = WINDOW_STATE_SHOWING;
123 
124     private @TransitionMode int mTransitionMode;
125     private @Appearance int mAppearance;
126     private @Behavior int mBehavior;
127     private final Context mContext;
128     private final DisplayManager mDisplayManager;
129     private Context mWindowContext;
130     private ScreenPinningNotify mScreenPinningNotify;
131     private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
132         @Override
133         public void onLockTaskModeChanged(int mode) {
134             mSysUiState.setFlag(SYSUI_STATE_SCREEN_PINNING, mode == LOCK_TASK_MODE_PINNED)
135                     .commitUpdate(mDisplayId);
136         }
137     };
138 
139     private int mNavigationMode = -1;
140     private final Consumer<Rect> mPipListener;
141 
142     /**
143      * Tracks the system calls for when taskbar should transiently show or hide so we can return
144      * this value in {@link AutoHideUiElement#isVisible()} below.
145      *
146      * This also gets set by {@link #onTaskbarAutohideSuspend(boolean)} to force show the transient
147      * taskbar if launcher has requested to suspend auto-hide behavior.
148      */
149     private boolean mTaskbarTransientShowing;
150     private final AutoHideUiElement mAutoHideUiElement = new AutoHideUiElement() {
151         @Override
152         public void synchronizeState() {
153         }
154 
155         @Override
156         public boolean isVisible() {
157             return mTaskbarTransientShowing;
158         }
159 
160         @Override
161         public void hide() {
162             clearTransient();
163         }
164     };
165 
166     private BackAnimation mBackAnimation;
167 
168     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
169     @Inject
TaskbarDelegate(Context context, LightBarTransitionsController.Factory lightBarTransitionsControllerFactory, StatusBarKeyguardViewManager statusBarKeyguardViewManager)170     public TaskbarDelegate(Context context,
171             LightBarTransitionsController.Factory lightBarTransitionsControllerFactory,
172             StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
173         mLightBarTransitionsControllerFactory = lightBarTransitionsControllerFactory;
174 
175         mContext = context;
176         mDisplayManager = mContext.getSystemService(DisplayManager.class);
177         mPipListener = (bounds) -> {
178             mEdgeBackGestureHandler.setPipStashExclusionBounds(bounds);
179         };
180         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
181         mStatusBarKeyguardViewManager.setTaskbarDelegate(this);
182     }
183 
setDependencies(CommandQueue commandQueue, OverviewProxyService overviewProxyService, NavBarHelper navBarHelper, NavigationModeController navigationModeController, SysUiState sysUiState, DumpManager dumpManager, AutoHideController autoHideController, LightBarController lightBarController, Optional<Pip> pipOptional, BackAnimation backAnimation, TaskStackChangeListeners taskStackChangeListeners)184     public void setDependencies(CommandQueue commandQueue,
185             OverviewProxyService overviewProxyService,
186             NavBarHelper navBarHelper,
187             NavigationModeController navigationModeController,
188             SysUiState sysUiState, DumpManager dumpManager,
189             AutoHideController autoHideController,
190             LightBarController lightBarController,
191             Optional<Pip> pipOptional,
192             BackAnimation backAnimation,
193             TaskStackChangeListeners taskStackChangeListeners) {
194         // TODO: adding this in the ctor results in a dagger dependency cycle :(
195         mCommandQueue = commandQueue;
196         mOverviewProxyService = overviewProxyService;
197         mNavBarHelper = navBarHelper;
198         mNavigationModeController = navigationModeController;
199         mSysUiState = sysUiState;
200         dumpManager.registerDumpable(this);
201         mAutoHideController = autoHideController;
202         mLightBarController = lightBarController;
203         mPipOptional = pipOptional;
204         mBackAnimation = backAnimation;
205         mLightBarTransitionsController = createLightBarTransitionsController();
206         mTaskStackChangeListeners = taskStackChangeListeners;
207         mEdgeBackGestureHandler = navBarHelper.getEdgeBackGestureHandler();
208     }
209 
210     // Separated into a method to keep setDependencies() clean/readable.
createLightBarTransitionsController()211     private LightBarTransitionsController createLightBarTransitionsController() {
212 
213         LightBarTransitionsController controller =  mLightBarTransitionsControllerFactory.create(
214                 new LightBarTransitionsController.DarkIntensityApplier() {
215                     @Override
216                     public void applyDarkIntensity(float darkIntensity) {
217                         mOverviewProxyService.onNavButtonsDarkIntensityChanged(darkIntensity);
218                     }
219 
220                     @Override
221                     public int getTintAnimationDuration() {
222                         return LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION;
223                     }
224                 });
225 
226         return controller;
227     }
228 
init(int displayId)229     public void init(int displayId) {
230         Trace.beginSection("TaskbarDelegate#init");
231         try {
232             if (mInitialized) {
233                 return;
234             }
235             mDisplayId = displayId;
236             parseCurrentSysuiState();
237             mCommandQueue.addCallback(this);
238             mOverviewProxyService.addCallback(this);
239             onNavigationModeChanged(mNavigationModeController.addListener(this));
240             mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
241             // Initialize component callback
242             Display display = mDisplayManager.getDisplay(displayId);
243             mWindowContext = mContext.createWindowContext(display, TYPE_APPLICATION, null);
244             mScreenPinningNotify = new ScreenPinningNotify(mWindowContext);
245             // Set initial state for any listeners
246             updateSysuiFlags();
247             mAutoHideController.setNavigationBar(mAutoHideUiElement);
248             mLightBarController.setNavigationBar(mLightBarTransitionsController);
249             mPipOptional.ifPresent(this::addPipExclusionBoundsChangeListener);
250             mEdgeBackGestureHandler.setBackAnimation(mBackAnimation);
251             mTaskStackChangeListeners.registerTaskStackListener(mTaskStackListener);
252             mInitialized = true;
253         } finally {
254             Trace.endSection();
255         }
256     }
257 
destroy()258     public void destroy() {
259         if (!mInitialized) {
260             return;
261         }
262         mCommandQueue.removeCallback(this);
263         mOverviewProxyService.removeCallback(this);
264         mNavigationModeController.removeListener(this);
265         mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
266         mScreenPinningNotify = null;
267         mWindowContext = null;
268         mAutoHideController.setNavigationBar(null);
269         mLightBarTransitionsController.destroy();
270         mLightBarController.setNavigationBar(null);
271         mPipOptional.ifPresent(this::removePipExclusionBoundsChangeListener);
272         mTaskStackChangeListeners.unregisterTaskStackListener(mTaskStackListener);
273         mInitialized = false;
274     }
275 
addPipExclusionBoundsChangeListener(Pip pip)276     void addPipExclusionBoundsChangeListener(Pip pip) {
277         pip.addPipExclusionBoundsChangeListener(mPipListener);
278     }
279 
removePipExclusionBoundsChangeListener(Pip pip)280     void removePipExclusionBoundsChangeListener(Pip pip) {
281         pip.removePipExclusionBoundsChangeListener(mPipListener);
282     }
283 
284     /**
285      * Returns {@code true} if this taskBar is {@link #init(int)}.
286      * Returns {@code false} if this taskbar has not yet been {@link #init(int)}
287      * or has been {@link #destroy()}.
288      */
isInitialized()289     public boolean isInitialized() {
290         return mInitialized;
291     }
292 
parseCurrentSysuiState()293     private void parseCurrentSysuiState() {
294         NavBarHelper.CurrentSysuiState state = mNavBarHelper.getCurrentSysuiState();
295         if (state.mWindowStateDisplayId == mDisplayId) {
296             mTaskBarWindowState = state.mWindowState;
297         }
298     }
299 
updateSysuiFlags()300     private void updateSysuiFlags() {
301         long a11yFlags = mNavBarHelper.getA11yButtonState();
302         boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
303         boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
304 
305         mSysUiState.setFlag(SYSUI_STATE_A11Y_BUTTON_CLICKABLE, clickable)
306                 .setFlag(SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, longClickable)
307                 .setFlag(SYSUI_STATE_IME_SHOWING,
308                         (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0)
309                 .setFlag(SYSUI_STATE_IME_SWITCHER_SHOWING,
310                         (mNavigationIconHints & NAVIGATION_HINT_IME_SWITCHER_SHOWN) != 0)
311                 .setFlag(SYSUI_STATE_OVERVIEW_DISABLED,
312                         (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0)
313                 .setFlag(SYSUI_STATE_HOME_DISABLED,
314                         (mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0)
315                 .setFlag(SYSUI_STATE_BACK_DISABLED,
316                         (mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0)
317                 .setFlag(SYSUI_STATE_NAV_BAR_HIDDEN, !isWindowVisible())
318                 .setFlag(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY,
319                         allowSystemGestureIgnoringBarVisibility())
320                 .commitUpdate(mDisplayId);
321     }
322 
isOverviewEnabled()323     boolean isOverviewEnabled() {
324         return (mSysUiState.getFlags() & View.STATUS_BAR_DISABLE_RECENT) == 0;
325     }
326 
updateAssistantAvailability(boolean assistantAvailable, boolean longPressHomeEnabled)327     private void updateAssistantAvailability(boolean assistantAvailable,
328             boolean longPressHomeEnabled) {
329         if (mOverviewProxyService.getProxy() == null) {
330             return;
331         }
332 
333         try {
334             mOverviewProxyService.getProxy().onAssistantAvailable(assistantAvailable,
335                     longPressHomeEnabled);
336         } catch (RemoteException e) {
337             Log.e(TAG, "onAssistantAvailable() failed, available: " + assistantAvailable, e);
338         }
339     }
340 
341     @Override
setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher)342     public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
343             boolean showImeSwitcher) {
344         boolean imeShown = mNavBarHelper.isImeShown(vis);
345         if (!imeShown) {
346             // Count imperceptible changes as visible so we transition taskbar out quickly.
347             imeShown = (vis & InputMethodService.IME_VISIBLE_IMPERCEPTIBLE) != 0;
348         }
349         showImeSwitcher = imeShown && showImeSwitcher;
350         int hints = Utilities.calculateBackDispositionHints(mNavigationIconHints, backDisposition,
351                 imeShown, showImeSwitcher);
352         if (hints != mNavigationIconHints) {
353             mNavigationIconHints = hints;
354             updateSysuiFlags();
355         }
356     }
357 
358     @Override
setWindowState(int displayId, int window, int state)359     public void setWindowState(int displayId, int window, int state) {
360         if (displayId == mDisplayId
361                 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
362                 && mTaskBarWindowState != state) {
363             mTaskBarWindowState = state;
364             updateSysuiFlags();
365         }
366     }
367 
368     @Override
onRotationProposal(int rotation, boolean isValid)369     public void onRotationProposal(int rotation, boolean isValid) {
370         mOverviewProxyService.onRotationProposal(rotation, isValid);
371     }
372 
373     @Override
disable(int displayId, int state1, int state2, boolean animate)374     public void disable(int displayId, int state1, int state2, boolean animate) {
375         mDisabledFlags = state1;
376         updateSysuiFlags();
377         mOverviewProxyService.disable(displayId, state1, state2, animate);
378     }
379 
380     @Override
onSystemBarAttributesChanged(int displayId, int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, int behavior, @InsetsType int requestedVisibleTypes, String packageName, LetterboxDetails[] letterboxDetails)381     public void onSystemBarAttributesChanged(int displayId, int appearance,
382             AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, int behavior,
383             @InsetsType int requestedVisibleTypes, String packageName,
384             LetterboxDetails[] letterboxDetails) {
385         mOverviewProxyService.onSystemBarAttributesChanged(displayId, behavior);
386         boolean nbModeChanged = false;
387         if (mAppearance != appearance) {
388             mAppearance = appearance;
389             nbModeChanged = updateTransitionMode(
390                     transitionMode(mTaskbarTransientShowing, appearance));
391         }
392         if (displayId == mDisplayId) {
393             mLightBarController.onNavigationBarAppearanceChanged(appearance, nbModeChanged,
394                     mTransitionMode, navbarColorManagedByIme);
395         }
396         if (mBehavior != behavior) {
397             mBehavior = behavior;
398             updateSysuiFlags();
399         }
400     }
401 
402     @Override
showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar)403     public void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar) {
404         if (displayId != mDisplayId) {
405             return;
406         }
407         if ((types & WindowInsets.Type.navigationBars()) == 0) {
408             return;
409         }
410         if (!mTaskbarTransientShowing) {
411             mTaskbarTransientShowing = true;
412             onTransientStateChanged();
413         }
414     }
415 
416     @Override
abortTransient(int displayId, @InsetsType int types)417     public void abortTransient(int displayId, @InsetsType int types) {
418         if (displayId != mDisplayId) {
419             return;
420         }
421         if ((types & WindowInsets.Type.navigationBars()) == 0) {
422             return;
423         }
424         clearTransient();
425     }
426 
427     @Override
onTaskbarAutohideSuspend(boolean suspend)428     public void onTaskbarAutohideSuspend(boolean suspend) {
429         if (suspend) {
430             mAutoHideController.suspendAutoHide();
431         } else {
432             mAutoHideController.resumeSuspendedAutoHide();
433         }
434     }
435 
436     @Override
toggleTaskbar()437     public void toggleTaskbar() {
438         if (mOverviewProxyService.getProxy() == null) {
439             return;
440         }
441 
442         try {
443             mOverviewProxyService.getProxy().onTaskbarToggled();
444         } catch (RemoteException e) {
445             Log.e(TAG, "onTaskbarToggled() failed", e);
446         }
447     }
448 
clearTransient()449     private void clearTransient() {
450         if (mTaskbarTransientShowing) {
451             mTaskbarTransientShowing = false;
452             onTransientStateChanged();
453         }
454     }
455 
onTransientStateChanged()456     private void onTransientStateChanged() {
457         mEdgeBackGestureHandler.onNavBarTransientStateChanged(mTaskbarTransientShowing);
458 
459         final int transitionMode = transitionMode(mTaskbarTransientShowing, mAppearance);
460         if (updateTransitionMode(transitionMode)) {
461             mLightBarController.onNavigationBarModeChanged(transitionMode);
462         }
463     }
464 
updateTransitionMode(int barMode)465     private boolean updateTransitionMode(int barMode) {
466         if (mTransitionMode != barMode) {
467             mTransitionMode = barMode;
468             if (mAutoHideController != null) {
469                 mAutoHideController.touchAutoHide();
470             }
471             return true;
472         }
473         return false;
474     }
475 
476     @Override
onRecentsAnimationStateChanged(boolean running)477     public void onRecentsAnimationStateChanged(boolean running) {
478     }
479 
480     @Override
onNavigationModeChanged(int mode)481     public void onNavigationModeChanged(int mode) {
482         mNavigationMode = mode;
483         mEdgeBackGestureHandler.onNavigationModeChanged(mode);
484     }
485 
isWindowVisible()486     private boolean isWindowVisible() {
487         return mTaskBarWindowState == WINDOW_STATE_SHOWING;
488     }
489 
allowSystemGestureIgnoringBarVisibility()490     private boolean allowSystemGestureIgnoringBarVisibility() {
491         return mBehavior != BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
492     }
493 
494     @Override
setNavigationBarLumaSamplingEnabled(int displayId, boolean enable)495     public void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {
496         mOverviewProxyService.onNavigationBarLumaSamplingEnabled(displayId, enable);
497     }
498 
499     @Override
showPinningEnterExitToast(boolean entering)500     public void showPinningEnterExitToast(boolean entering) {
501         updateSysuiFlags();
502         if (mScreenPinningNotify == null) {
503             return;
504         }
505         if (entering) {
506             mScreenPinningNotify.showPinningStartToast();
507         } else {
508             mScreenPinningNotify.showPinningExitToast();
509         }
510     }
511 
512     @Override
showPinningEscapeToast()513     public void showPinningEscapeToast() {
514         updateSysuiFlags();
515         if (mScreenPinningNotify == null) {
516             return;
517         }
518         mScreenPinningNotify.showEscapeToast(QuickStepContract.isGesturalMode(mNavigationMode),
519                 !QuickStepContract.isGesturalMode(mNavigationMode));
520     }
521 
522     @VisibleForTesting
getNavigationMode()523     int getNavigationMode() {
524         return mNavigationMode;
525     }
526 
527     @Override
dump(@onNull PrintWriter pw, @NonNull String[] args)528     public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
529         pw.println("TaskbarDelegate (displayId=" + mDisplayId + "):");
530         pw.println("  mNavigationIconHints=" + mNavigationIconHints);
531         pw.println("  mNavigationMode=" + mNavigationMode);
532         pw.println("  mDisabledFlags=" + mDisabledFlags);
533         pw.println("  mTaskBarWindowState=" + mTaskBarWindowState);
534         pw.println("  mBehavior=" + mBehavior);
535         pw.println("  mTaskbarTransientShowing=" + mTaskbarTransientShowing);
536         mEdgeBackGestureHandler.dump(pw);
537     }
538 }
539