1 /*
2  * Copyright (C) 2019 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 package com.android.launcher3;
17 
18 import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
19 import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
20 import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON;
21 import static com.android.launcher3.LauncherState.NORMAL;
22 import static com.android.launcher3.LauncherState.NO_OFFSET;
23 import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
24 import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
25 import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
26 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
27 import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
28 import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
29 import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
30 
31 import android.animation.AnimatorSet;
32 import android.animation.ValueAnimator;
33 import android.app.ActivityOptions;
34 import android.content.Context;
35 import android.content.Intent;
36 import android.content.IntentSender;
37 import android.graphics.Insets;
38 import android.hardware.SensorManager;
39 import android.hardware.devicestate.DeviceStateManager;
40 import android.os.Bundle;
41 import android.os.CancellationSignal;
42 import android.view.View;
43 import android.view.WindowInsets;
44 import android.window.SplashScreen;
45 
46 import androidx.annotation.Nullable;
47 
48 import com.android.launcher3.config.FeatureFlags;
49 import com.android.launcher3.dragndrop.DragOptions;
50 import com.android.launcher3.model.WellbeingModel;
51 import com.android.launcher3.model.data.ItemInfo;
52 import com.android.launcher3.popup.SystemShortcut;
53 import com.android.launcher3.proxy.ProxyActivityStarter;
54 import com.android.launcher3.proxy.StartActivityParams;
55 import com.android.launcher3.statehandlers.BackButtonAlphaHandler;
56 import com.android.launcher3.statehandlers.DepthController;
57 import com.android.launcher3.statemanager.StateManager.StateHandler;
58 import com.android.launcher3.taskbar.LauncherTaskbarUIController;
59 import com.android.launcher3.taskbar.TaskbarManager;
60 import com.android.launcher3.uioverrides.RecentsViewStateController;
61 import com.android.launcher3.util.ActivityOptionsWrapper;
62 import com.android.launcher3.util.DisplayController;
63 import com.android.launcher3.util.IntSet;
64 import com.android.launcher3.util.ObjectWrapper;
65 import com.android.launcher3.util.UiThreadHelper;
66 import com.android.quickstep.OverviewCommandHelper;
67 import com.android.quickstep.RecentsModel;
68 import com.android.quickstep.SysUINavigationMode;
69 import com.android.quickstep.SysUINavigationMode.Mode;
70 import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
71 import com.android.quickstep.SystemUiProxy;
72 import com.android.quickstep.TaskUtils;
73 import com.android.quickstep.TouchInteractionService.TISBinder;
74 import com.android.quickstep.util.LauncherUnfoldAnimationController;
75 import com.android.quickstep.util.ProxyScreenStatusProvider;
76 import com.android.quickstep.util.RemoteAnimationProvider;
77 import com.android.quickstep.util.RemoteFadeOutAnimationListener;
78 import com.android.quickstep.util.SplitSelectStateController;
79 import com.android.quickstep.util.TISBindHelper;
80 import com.android.quickstep.views.OverviewActionsView;
81 import com.android.quickstep.views.RecentsView;
82 import com.android.systemui.shared.system.ActivityManagerWrapper;
83 import com.android.systemui.shared.system.ActivityOptionsCompat;
84 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
85 import com.android.systemui.unfold.UnfoldTransitionFactory;
86 import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
87 import com.android.systemui.unfold.config.UnfoldTransitionConfig;
88 
89 import java.io.FileDescriptor;
90 import java.io.PrintWriter;
91 import java.util.List;
92 import java.util.stream.Stream;
93 
94 /**
95  * Extension of Launcher activity to provide quickstep specific functionality
96  */
97 public abstract class BaseQuickstepLauncher extends Launcher
98         implements NavigationModeChangeListener {
99 
100     private DepthController mDepthController = new DepthController(this);
101     private QuickstepTransitionManager mAppTransitionManager;
102 
103     /**
104      * Reusable command for applying the back button alpha on the background thread.
105      */
106     public static final UiThreadHelper.AsyncCommand SET_BACK_BUTTON_ALPHA =
107             (context, arg1, arg2) -> SystemUiProxy.INSTANCE.get(context).setNavBarButtonAlpha(
108                     Float.intBitsToFloat(arg1), arg2 != 0);
109 
110     private OverviewActionsView mActionsView;
111 
112     private TISBindHelper mTISBindHelper;
113     private @Nullable TaskbarManager mTaskbarManager;
114     private @Nullable OverviewCommandHelper mOverviewCommandHelper;
115     private @Nullable LauncherTaskbarUIController mTaskbarUIController;
116 
117     // Will be updated when dragging from taskbar.
118     private @Nullable DragOptions mNextWorkspaceDragOptions = null;
119 
120     private @Nullable UnfoldTransitionProgressProvider mUnfoldTransitionProgressProvider;
121     private @Nullable LauncherUnfoldAnimationController mLauncherUnfoldAnimationController;
122 
123     @Override
onCreate(Bundle savedInstanceState)124     protected void onCreate(Bundle savedInstanceState) {
125         super.onCreate(savedInstanceState);
126         SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this);
127         addMultiWindowModeChangedListener(mDepthController);
128         initUnfoldTransitionProgressProvider();
129     }
130 
131     @Override
onResume()132     protected void onResume() {
133         super.onResume();
134 
135         if (mLauncherUnfoldAnimationController != null) {
136             mLauncherUnfoldAnimationController.onResume();
137         }
138     }
139 
140     @Override
onPause()141     protected void onPause() {
142         if (mLauncherUnfoldAnimationController != null) {
143             mLauncherUnfoldAnimationController.onPause();
144         }
145 
146         super.onPause();
147     }
148 
149     @Override
onDestroy()150     public void onDestroy() {
151         mAppTransitionManager.onActivityDestroyed();
152         if (mUnfoldTransitionProgressProvider != null) {
153             mUnfoldTransitionProgressProvider.destroy();
154         }
155 
156         SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
157 
158         mTISBindHelper.onDestroy();
159         if (mTaskbarManager != null) {
160             mTaskbarManager.clearActivity(this);
161         }
162 
163         if (mLauncherUnfoldAnimationController != null) {
164             mLauncherUnfoldAnimationController.onDestroy();
165         }
166 
167         super.onDestroy();
168     }
169 
170     @Override
onNewIntent(Intent intent)171     protected void onNewIntent(Intent intent) {
172         super.onNewIntent(intent);
173 
174         if (mOverviewCommandHelper != null) {
175             mOverviewCommandHelper.clearPendingCommands();
176         }
177     }
178 
getAppTransitionManager()179     public QuickstepTransitionManager getAppTransitionManager() {
180         return mAppTransitionManager;
181     }
182 
183     @Override
onNavigationModeChanged(Mode newMode)184     public void onNavigationModeChanged(Mode newMode) {
185         getDragLayer().recreateControllers();
186         if (mActionsView != null) {
187             mActionsView.updateVerticalMargin(newMode);
188         }
189     }
190 
191     @Override
onEnterAnimationComplete()192     public void onEnterAnimationComplete() {
193         super.onEnterAnimationComplete();
194         // After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
195         // as a part of quickstep, so that high-res thumbnails can load the next time we enter
196         // overview
197         RecentsModel.INSTANCE.get(this).getThumbnailCache()
198                 .getHighResLoadingState().setVisible(true);
199     }
200 
201     @Override
handleGestureContract(Intent intent)202     protected void handleGestureContract(Intent intent) {
203         if (FeatureFlags.SEPARATE_RECENTS_ACTIVITY.get()) {
204             super.handleGestureContract(intent);
205         }
206     }
207 
208     @Override
onTrimMemory(int level)209     public void onTrimMemory(int level) {
210         super.onTrimMemory(level);
211         RecentsModel.INSTANCE.get(this).onTrimMemory(level);
212     }
213 
214     @Override
onUiChangedWhileSleeping()215     public void onUiChangedWhileSleeping() {
216         // Remove the snapshot because the content view may have obvious changes.
217         UI_HELPER_EXECUTOR.execute(
218                 () -> ActivityManagerWrapper.getInstance().invalidateHomeTaskSnapshot(this));
219     }
220 
221     @Override
onScreenOff()222     protected void onScreenOff() {
223         super.onScreenOff();
224         if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
225             RecentsView recentsView = getOverviewPanel();
226             recentsView.finishRecentsAnimation(true /* toRecents */, null);
227         }
228     }
229 
230     /**
231      * {@code LauncherOverlayCallbacks} scroll amount.
232      * Indicates transition progress to -1 screen.
233      * @param progress From 0 to 1.
234      */
235     @Override
onScrollChanged(float progress)236     public void onScrollChanged(float progress) {
237         super.onScrollChanged(progress);
238         mDepthController.onOverlayScrollChanged(progress);
239     }
240 
241     @Override
startIntentSenderForResult(IntentSender intent, int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options)242     public void startIntentSenderForResult(IntentSender intent, int requestCode,
243             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {
244         if (requestCode != -1) {
245             mPendingActivityRequestCode = requestCode;
246             StartActivityParams params = new StartActivityParams(this, requestCode);
247             params.intentSender = intent;
248             params.fillInIntent = fillInIntent;
249             params.flagsMask = flagsMask;
250             params.flagsValues = flagsValues;
251             params.extraFlags = extraFlags;
252             params.options = options;
253             startActivity(ProxyActivityStarter.getLaunchIntent(this, params));
254         } else {
255             super.startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
256                     flagsValues, extraFlags, options);
257         }
258     }
259 
260     @Override
startActivityForResult(Intent intent, int requestCode, Bundle options)261     public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
262         if (requestCode != -1) {
263             mPendingActivityRequestCode = requestCode;
264             StartActivityParams params = new StartActivityParams(this, requestCode);
265             params.intent = intent;
266             params.options = options;
267             startActivity(ProxyActivityStarter.getLaunchIntent(this, params));
268         } else {
269             super.startActivityForResult(intent, requestCode, options);
270         }
271     }
272 
273     @Override
onDeferredResumed()274     protected void onDeferredResumed() {
275         super.onDeferredResumed();
276         handlePendingActivityRequest();
277     }
278 
279     @Override
onStateSetEnd(LauncherState state)280     public void onStateSetEnd(LauncherState state) {
281         super.onStateSetEnd(state);
282         handlePendingActivityRequest();
283     }
284 
handlePendingActivityRequest()285     private void handlePendingActivityRequest() {
286         if (mPendingActivityRequestCode != -1 && isInState(NORMAL)
287                 && ((getActivityFlags() & ACTIVITY_STATE_DEFERRED_RESUMED) != 0)) {
288             // Remove any active ProxyActivityStarter task and send RESULT_CANCELED to Launcher.
289             onActivityResult(mPendingActivityRequestCode, RESULT_CANCELED, null);
290             // ProxyActivityStarter is started with clear task to reset the task after which it
291             // removes the task itself.
292             startActivity(ProxyActivityStarter.getLaunchIntent(this, null));
293         }
294     }
295 
296     @Override
setupViews()297     protected void setupViews() {
298         super.setupViews();
299 
300         SysUINavigationMode.INSTANCE.get(this).updateMode();
301         mActionsView = findViewById(R.id.overview_actions_view);
302         RecentsView overviewPanel = (RecentsView) getOverviewPanel();
303         SplitSelectStateController controller =
304                 new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this),
305                         getStateManager(), getDepthController());
306         overviewPanel.init(mActionsView, controller);
307         mActionsView.setDp(getDeviceProfile());
308         mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this));
309 
310         mAppTransitionManager = new QuickstepTransitionManager(this);
311         mAppTransitionManager.registerRemoteAnimations();
312         mAppTransitionManager.registerRemoteTransitions();
313 
314         mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
315     }
316 
onTISConnected(TISBinder binder)317     private void onTISConnected(TISBinder binder) {
318         mTaskbarManager = binder.getTaskbarManager();
319         mTaskbarManager.setActivity(this);
320         mOverviewCommandHelper = binder.getOverviewCommandHelper();
321     }
322 
323     @Override
runOnBindToTouchInteractionService(Runnable r)324     public void runOnBindToTouchInteractionService(Runnable r) {
325         mTISBindHelper.runOnBindToTouchInteractionService(r);
326     }
327 
initUnfoldTransitionProgressProvider()328     private void initUnfoldTransitionProgressProvider() {
329         final UnfoldTransitionConfig config = UnfoldTransitionFactory.createConfig(this);
330         if (config.isEnabled()) {
331             mUnfoldTransitionProgressProvider =
332                     UnfoldTransitionFactory.createUnfoldTransitionProgressProvider(
333                             this,
334                             config,
335                             ProxyScreenStatusProvider.INSTANCE,
336                             getSystemService(DeviceStateManager.class),
337                             getSystemService(SensorManager.class),
338                             getMainThreadHandler(),
339                             getMainExecutor()
340                     );
341 
342             mLauncherUnfoldAnimationController = new LauncherUnfoldAnimationController(
343                     this,
344                     getWindowManager(),
345                     mUnfoldTransitionProgressProvider
346             );
347         }
348     }
349 
setTaskbarUIController(LauncherTaskbarUIController taskbarUIController)350     public void setTaskbarUIController(LauncherTaskbarUIController taskbarUIController) {
351         mTaskbarUIController = taskbarUIController;
352     }
353 
getTaskbarUIController()354     public @Nullable LauncherTaskbarUIController getTaskbarUIController() {
355         return mTaskbarUIController;
356     }
357 
getActionsView()358     public <T extends OverviewActionsView> T getActionsView() {
359         return (T) mActionsView;
360     }
361 
362     @Override
closeOpenViews(boolean animate)363     protected void closeOpenViews(boolean animate) {
364         super.closeOpenViews(animate);
365         TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
366     }
367 
368     @Override
collectStateHandlers(List<StateHandler> out)369     protected void collectStateHandlers(List<StateHandler> out) {
370         super.collectStateHandlers(out);
371         out.add(getDepthController());
372         out.add(new RecentsViewStateController(this));
373         out.add(new BackButtonAlphaHandler(this));
374     }
375 
getDepthController()376     public DepthController getDepthController() {
377         return mDepthController;
378     }
379 
380     @Nullable
getUnfoldTransitionProgressProvider()381     public UnfoldTransitionProgressProvider getUnfoldTransitionProgressProvider() {
382         return mUnfoldTransitionProgressProvider;
383     }
384 
385     @Override
supportsAdaptiveIconAnimation(View clickedView)386     public boolean supportsAdaptiveIconAnimation(View clickedView) {
387         return mAppTransitionManager.hasControlRemoteAppTransitionPermission()
388                 && FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM.get();
389     }
390 
391     @Override
getDefaultWorkspaceDragOptions()392     public DragOptions getDefaultWorkspaceDragOptions() {
393         if (mNextWorkspaceDragOptions != null) {
394             DragOptions options = mNextWorkspaceDragOptions;
395             mNextWorkspaceDragOptions = null;
396             return options;
397         }
398         return super.getDefaultWorkspaceDragOptions();
399     }
400 
setNextWorkspaceDragOptions(DragOptions dragOptions)401     public void setNextWorkspaceDragOptions(DragOptions dragOptions) {
402         mNextWorkspaceDragOptions = dragOptions;
403     }
404 
405     @Override
useFadeOutAnimationForLauncherStart(CancellationSignal signal)406     public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) {
407         QuickstepTransitionManager appTransitionManager = getAppTransitionManager();
408         appTransitionManager.setRemoteAnimationProvider(new RemoteAnimationProvider() {
409             @Override
410             public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets,
411                     RemoteAnimationTargetCompat[] wallpaperTargets) {
412 
413                 // On the first call clear the reference.
414                 signal.cancel();
415 
416                 ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0);
417                 fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(appTargets,
418                         wallpaperTargets));
419                 AnimatorSet anim = new AnimatorSet();
420                 anim.play(fadeAnimation);
421                 return anim;
422             }
423         }, signal);
424     }
425 
426     @Override
getNormalOverviewScaleAndOffset()427     public float[] getNormalOverviewScaleAndOffset() {
428         return SysUINavigationMode.getMode(this).hasGestures
429                 ? new float[] {1, 1} : new float[] {1.1f, NO_OFFSET};
430     }
431 
432     @Override
onDragLayerHierarchyChanged()433     public void onDragLayerHierarchyChanged() {
434         onLauncherStateOrFocusChanged();
435     }
436 
437     @Override
onActivityFlagsChanged(int changeBits)438     protected void onActivityFlagsChanged(int changeBits) {
439         if ((changeBits
440                 & (ACTIVITY_STATE_WINDOW_FOCUSED | ACTIVITY_STATE_TRANSITION_ACTIVE)) != 0) {
441             onLauncherStateOrFocusChanged();
442         }
443 
444         if ((changeBits & ACTIVITY_STATE_STARTED) != 0) {
445             mDepthController.setActivityStarted(isStarted());
446         }
447 
448         if ((changeBits & ACTIVITY_STATE_RESUMED) != 0) {
449             if (mTaskbarUIController != null) {
450                 mTaskbarUIController.onLauncherResumedOrPaused(hasBeenResumed());
451             }
452         }
453 
454         super.onActivityFlagsChanged(changeBits);
455     }
456 
shouldBackButtonBeHidden(LauncherState toState)457     public boolean shouldBackButtonBeHidden(LauncherState toState) {
458         Mode mode = SysUINavigationMode.getMode(this);
459         boolean shouldBackButtonBeHidden = mode.hasGestures
460                 && toState.hasFlag(FLAG_HIDE_BACK_BUTTON)
461                 && hasWindowFocus()
462                 && (getActivityFlags() & ACTIVITY_STATE_TRANSITION_ACTIVE) == 0;
463         if (shouldBackButtonBeHidden) {
464             // Show the back button if there is a floating view visible.
465             shouldBackButtonBeHidden = AbstractFloatingView.getTopOpenViewWithType(this,
466                     TYPE_ALL & ~TYPE_HIDE_BACK_BUTTON) == null;
467         }
468         return shouldBackButtonBeHidden;
469     }
470 
471     /**
472      * Sets the back button visibility based on the current state/window focus.
473      */
onLauncherStateOrFocusChanged()474     private void onLauncherStateOrFocusChanged() {
475         boolean shouldBackButtonBeHidden = shouldBackButtonBeHidden(getStateManager().getState());
476         if (SysUINavigationMode.getMode(this) == TWO_BUTTONS) {
477             UiThreadHelper.setBackButtonAlphaAsync(this, SET_BACK_BUTTON_ALPHA,
478                     shouldBackButtonBeHidden ? 0f : 1f, true /* animate */);
479         }
480         if (getDragLayer() != null) {
481             getRootView().setDisallowBackGesture(shouldBackButtonBeHidden);
482         }
483     }
484 
485     @Override
finishBindingItems(IntSet pagesBoundFirst)486     public void finishBindingItems(IntSet pagesBoundFirst) {
487         super.finishBindingItems(pagesBoundFirst);
488         // Instantiate and initialize WellbeingModel now that its loading won't interfere with
489         // populating workspace.
490         // TODO: Find a better place for this
491         WellbeingModel.INSTANCE.get(this);
492     }
493 
494     @Override
getSupportedShortcuts()495     public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
496         return Stream.concat(Stream.of(WellbeingModel.SHORTCUT_FACTORY),
497                 super.getSupportedShortcuts());
498     }
499 
500     @Override
getActivityLaunchOptions(View v, @Nullable ItemInfo item)501     public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
502         ActivityOptionsWrapper activityOptions =
503                 mAppTransitionManager.hasControlRemoteAppTransitionPermission()
504                         ? mAppTransitionManager.getActivityLaunchOptions(v)
505                         : super.getActivityLaunchOptions(v, item);
506         if (mLastTouchUpTime > 0) {
507             ActivityOptionsCompat.setLauncherSourceInfo(
508                     activityOptions.options, mLastTouchUpTime);
509         }
510         activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
511         addLaunchCookie(item, activityOptions.options);
512         return activityOptions;
513     }
514 
515     /**
516      * Adds a new launch cookie for the activity launch of the given {@param info} if supported.
517      */
addLaunchCookie(ItemInfo info, ActivityOptions opts)518     public void addLaunchCookie(ItemInfo info, ActivityOptions opts) {
519         if (info == null) {
520             return;
521         }
522         switch (info.container) {
523             case LauncherSettings.Favorites.CONTAINER_DESKTOP:
524             case LauncherSettings.Favorites.CONTAINER_HOTSEAT:
525                 // Fall through and continue it's on the workspace (we don't support swiping back
526                 // to other containers like all apps or the hotseat predictions (which can change)
527                 break;
528             default:
529                 if (info.container >= 0) {
530                     // Also allow swiping to folders
531                     break;
532                 }
533                 // Reset any existing launch cookies associated with the cookie
534                 opts.setLaunchCookie(ObjectWrapper.wrap(NO_MATCHING_ID));
535                 return;
536         }
537         switch (info.itemType) {
538             case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
539             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
540             case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
541             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
542                 // Fall through and continue if it's an app, shortcut, or widget
543                 break;
544             default:
545                 // Reset any existing launch cookies associated with the cookie
546                 opts.setLaunchCookie(ObjectWrapper.wrap(NO_MATCHING_ID));
547                 return;
548         }
549         opts.setLaunchCookie(ObjectWrapper.wrap(new Integer(info.id)));
550     }
551 
setHintUserWillBeActive()552     public void setHintUserWillBeActive() {
553         addActivityFlags(ACTIVITY_STATE_USER_WILL_BE_ACTIVE);
554     }
555 
556     @Override
onDisplayInfoChanged(Context context, DisplayController.Info info, int flags)557     public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
558         super.onDisplayInfoChanged(context, info, flags);
559         // When changing screens, force moving to rest state similar to StatefulActivity.onStop, as
560         // StatefulActivity isn't called consistently.
561         if ((flags & CHANGE_ACTIVE_SCREEN) != 0) {
562             getStateManager().moveToRestState();
563         }
564     }
565 
566     @Override
dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args)567     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
568         super.dump(prefix, fd, writer, args);
569         if (mDepthController != null) {
570             mDepthController.dump(prefix, writer);
571         }
572     }
573 
574     @Override
updateWindowInsets(WindowInsets.Builder updatedInsetsBuilder, WindowInsets oldInsets)575     public void updateWindowInsets(WindowInsets.Builder updatedInsetsBuilder,
576             WindowInsets oldInsets) {
577         // Override the tappable insets to be 0 on the bottom for gesture nav (otherwise taskbar
578         // would count towards it). This is used for the bottom protection in All Apps for example.
579         if (SysUINavigationMode.getMode(this) == NO_BUTTON) {
580             Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement());
581             Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top,
582                     oldTappableInsets.right, 0);
583             updatedInsetsBuilder.setInsets(WindowInsets.Type.tappableElement(), newTappableInsets);
584         }
585     }
586 }
587