blob: 857467208b6ea9f0c5d3a31f9b3636ef2a1c222d [file] [log] [blame]
Craig Mautner59c00972012-07-30 12:10:24 -07001/*
2 * Copyright (C) 2012 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
17package com.android.server.wm;
18
Louis Chang677921f2019-12-06 16:44:24 +080019import static android.app.ActivityTaskManager.INVALID_STACK_ID;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070020import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwale61911492017-10-11 08:50:50 -070021import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -080022import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
Louis Chang677921f2019-12-06 16:44:24 +080023import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
Wale Ogunwaleb62139d2017-09-20 15:37:35 -070024import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Louis Chang677921f2019-12-06 16:44:24 +080025import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
26import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
Tarandeep Singh215929b2019-01-11 18:24:37 -080027import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Louis Chang677921f2019-12-06 16:44:24 +080028import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale194435b2019-12-23 12:56:51 -080029import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
Wale Ogunwaleb62139d2017-09-20 15:37:35 -070030import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
31import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Louis Chang677921f2019-12-06 16:44:24 +080032import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
33import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwalea77e1462016-09-28 10:09:46 -070034import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
Wale Ogunwale51362492016-09-08 17:49:17 -070035import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
36import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Tiger Huang86e6d072019-05-02 20:23:47 +080037import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
Wale Ogunwale687b4272017-07-27 02:56:23 -070038import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
39import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
Louis Chang677921f2019-12-06 16:44:24 +080040import static android.os.Build.VERSION_CODES.N;
Jorim Jaggi4981f152019-03-26 18:58:45 +010041import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
Adrian Roosbf3bc1b2019-06-18 16:13:53 +020042import static android.util.DisplayMetrics.DENSITY_DEFAULT;
Wale Ogunwale19e452e2016-10-12 12:36:29 -070043import static android.view.Display.DEFAULT_DISPLAY;
44import static android.view.Display.FLAG_PRIVATE;
Andrii Kuliandd989612019-02-21 12:13:28 -080045import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
Tiger Huang04dc4cc2019-01-17 18:41:41 +080046import static android.view.Display.INVALID_DISPLAY;
Louis Chang677921f2019-12-06 16:44:24 +080047import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
Tiger Huang332793b2019-10-29 23:21:27 +080048import static android.view.InsetsState.ITYPE_IME;
49import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
50import static android.view.InsetsState.ITYPE_RIGHT_GESTURES;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -070051import static android.view.Surface.ROTATION_0;
52import static android.view.Surface.ROTATION_180;
53import static android.view.Surface.ROTATION_270;
54import static android.view.Surface.ROTATION_90;
Wale Ogunwalef7cab102016-10-25 15:25:14 -070055import static android.view.View.GONE;
Adrian Roosbf3bc1b2019-06-18 16:13:53 +020056import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
57import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
Wale Ogunwale10124582016-09-15 20:25:50 -070058import static android.view.WindowManager.DOCKED_BOTTOM;
59import static android.view.WindowManager.DOCKED_INVALID;
60import static android.view.WindowManager.DOCKED_TOP;
Winson Chungc5fe7ff2019-02-19 14:49:25 -080061import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -080062import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
63import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
64import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Wale Ogunwale494009b82016-10-21 09:01:38 -070065import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070066import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Tiger Huang04dc4cc2019-01-17 18:41:41 +080067import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
Winson Chungc5fe7ff2019-02-19 14:49:25 -080068import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
chaviw8065f442019-11-18 13:20:58 -080069import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -070070import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Riddle Hsub2297ad2019-07-26 23:37:25 -060071import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Wale Ogunwale494009b82016-10-21 09:01:38 -070072import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
Wale Ogunwalef7cab102016-10-25 15:25:14 -070073import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
Wale Ogunwale3a931692016-11-02 16:49:48 -070074import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
75import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Adrian Roos5f2c9a12019-07-03 18:31:46 +020076import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
wilsonshihe8321942019-10-18 18:39:46 +080077import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
Wale Ogunwalef7cab102016-10-25 15:25:14 -070078import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
79import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
Svetoslav Ganovaa076532016-08-01 19:16:43 -070080import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
Wale Ogunwaleec731152016-09-08 20:18:57 -070081import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Wale Ogunwale3a256e62018-12-06 14:41:18 -080082import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Riddle Hsua4d6fa22018-08-11 00:50:39 +080083import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
Wale Ogunwale3a256e62018-12-06 14:41:18 -080084import static android.view.WindowManager.TRANSIT_TASK_OPEN;
85import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Tiger Huang51c5a1d2018-12-11 20:24:51 +080086
Louis Chang677921f2019-12-06 16:44:24 +080087import static com.android.server.am.ActivityDisplayProto.DISPLAY;
88import static com.android.server.am.ActivityDisplayProto.FOCUSED_STACK_ID;
89import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY;
90import static com.android.server.am.ActivityDisplayProto.SINGLE_TASK_INSTANCE;
Adrian Roose99bc052017-11-20 17:55:31 +010091import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
92import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
93import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
94import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Louis Chang677921f2019-12-06 16:44:24 +080095import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
96import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
97import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
98import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
99import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
100import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800101import static com.android.server.wm.DisplayContentProto.ABOVE_APP_WINDOWS;
lumark588a3e82018-07-20 18:53:54 +0800102import static com.android.server.wm.DisplayContentProto.APP_TRANSITION;
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800103import static com.android.server.wm.DisplayContentProto.BELOW_APP_WINDOWS;
Louis Changa9350fe2019-04-25 17:14:20 +0800104import static com.android.server.wm.DisplayContentProto.CHANGING_APPS;
105import static com.android.server.wm.DisplayContentProto.CLOSING_APPS;
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800106import static com.android.server.wm.DisplayContentProto.DISPLAY_FRAMES;
107import static com.android.server.wm.DisplayContentProto.DISPLAY_INFO;
108import static com.android.server.wm.DisplayContentProto.DOCKED_STACK_DIVIDER_CONTROLLER;
109import static com.android.server.wm.DisplayContentProto.DPI;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800110import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800111import static com.android.server.wm.DisplayContentProto.ID;
112import static com.android.server.wm.DisplayContentProto.IME_WINDOWS;
Louis Changa9350fe2019-04-25 17:14:20 +0800113import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
chaviw8065f442019-11-18 13:20:58 -0800114import static com.android.server.wm.DisplayContentProto.OVERLAY_WINDOWS;
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800115import static com.android.server.wm.DisplayContentProto.ROTATION;
116import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
117import static com.android.server.wm.DisplayContentProto.STACKS;
118import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER;
Adrian Roosb125e0b2019-10-02 14:55:14 +0200119import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
120import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
121import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS;
122import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
123import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
124import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
125import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
Louis Chang149d5c82019-12-30 09:47:39 +0800126import static com.android.server.wm.RootWindowContainer.TAG_STATES;
lumark9bca6b42019-10-17 18:35:22 +0800127import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
128import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
Wale Ogunwale10124582016-09-15 20:25:50 -0700129import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700130import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700131import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700132import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700133import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
Andrii Kulian839def92016-11-02 10:58:58 -0700134import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700135import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700136import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700137import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800138import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800139import static com.android.server.wm.WindowManagerService.H.REPORT_FOCUS_CHANGE;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800140import static com.android.server.wm.WindowManagerService.H.REPORT_HARD_KEYBOARD_STATUS_CHANGE;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800141import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700142import static com.android.server.wm.WindowManagerService.H.UPDATE_DOCKED_STACK_DIVIDER;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700143import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700144import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
Andrii Kulian06d07d62017-03-14 11:11:47 -0700145import static com.android.server.wm.WindowManagerService.SEAMLESS_ROTATION_TIMEOUT_DURATION;
Louis Chang677921f2019-12-06 16:44:24 +0800146import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800147import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
148import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_REMOVING_FOCUS;
149import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_ASSIGN_LAYERS;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700150import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
Wale Ogunwale494009b82016-10-21 09:01:38 -0700151import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700152import static com.android.server.wm.WindowManagerService.dipToPixel;
Adrian Roos5f2c9a12019-07-03 18:31:46 +0200153import static com.android.server.wm.WindowState.EXCLUSION_LEFT;
154import static com.android.server.wm.WindowState.EXCLUSION_RIGHT;
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700155import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700156import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
Adrian Roos2351d5f2019-07-03 15:35:07 +0200157import static com.android.server.wm.utils.RegionUtils.forEachRectReverse;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100158import static com.android.server.wm.utils.RegionUtils.rectListToRegion;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700159
lumark588a3e82018-07-20 18:53:54 +0800160import android.animation.AnimationHandler;
Riddle Hsuf53da812018-08-15 22:00:27 +0800161import android.annotation.IntDef;
Andrii Kulian3a507b52016-09-19 18:14:12 -0700162import android.annotation.NonNull;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200163import android.annotation.Nullable;
Louis Chang677921f2019-12-06 16:44:24 +0800164import android.app.ActivityManager;
165import android.app.ActivityManagerInternal;
166import android.app.ActivityOptions;
167import android.app.WindowConfiguration;
Charles Chen173ae782019-11-11 20:39:02 +0800168import android.content.Context;
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800169import android.content.Intent;
Louis Chang677921f2019-12-06 16:44:24 +0800170import android.content.pm.ActivityInfo;
Riddle Hsuccf09402019-08-13 00:33:06 +0800171import android.content.pm.ActivityInfo.ScreenOrientation;
Wale Ogunwale8f93b642019-12-26 12:10:52 -0800172import android.content.pm.ApplicationInfo;
Andrii Kulian06d07d62017-03-14 11:11:47 -0700173import android.content.res.CompatibilityInfo;
Andrii Kulian441e4492016-09-29 15:25:00 -0700174import android.content.res.Configuration;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700175import android.graphics.Bitmap;
Issei Suzukia5dbf522019-02-01 17:58:15 +0100176import android.graphics.Insets;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700177import android.graphics.Matrix;
Tiger Huangd8ec9382019-04-18 14:35:09 -0700178import android.graphics.Point;
Craig Mautnerc00204b2013-03-05 15:02:14 -0800179import android.graphics.Rect;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700180import android.graphics.RectF;
Craig Mautner6601b7b2013-04-29 10:29:11 -0700181import android.graphics.Region;
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100182import android.graphics.Region.Op;
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700183import android.hardware.display.DisplayManagerInternal;
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500184import android.metrics.LogMaker;
Tiger Huang04dc4cc2019-01-17 18:41:41 +0800185import android.os.Binder;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700186import android.os.Debug;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700187import android.os.Handler;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700188import android.os.IBinder;
Louis Chang677921f2019-12-06 16:44:24 +0800189import android.os.Message;
Tiger Huang04dc4cc2019-01-17 18:41:41 +0800190import android.os.Process;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100191import android.os.RemoteCallbackList;
Wale Ogunwale494009b82016-10-21 09:01:38 -0700192import android.os.RemoteException;
193import android.os.SystemClock;
Jorim Jaggiffe128d2017-11-30 13:54:36 +0100194import android.os.Trace;
Riddle Hsuf53da812018-08-15 22:00:27 +0800195import android.os.UserHandle;
Louis Chang677921f2019-12-06 16:44:24 +0800196import android.provider.Settings;
Andrii Kulian4b6599e2018-01-15 17:24:08 -0800197import android.util.ArraySet;
Chong Zhang8e89b312015-09-09 15:09:30 -0700198import android.util.DisplayMetrics;
Louis Chang677921f2019-12-06 16:44:24 +0800199import android.util.IntArray;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700200import android.util.Slog;
Evan Rosky22b6bbd2019-09-26 14:29:57 -0700201import android.util.SparseArray;
Riddle Hsub2297ad2019-07-26 23:37:25 -0600202import android.util.SparseBooleanArray;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700203import android.util.proto.ProtoOutputStream;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700204import android.view.Display;
Adrian Roos1cf585052018-01-03 18:43:27 +0100205import android.view.DisplayCutout;
Craig Mautner59c00972012-07-30 12:10:24 -0700206import android.view.DisplayInfo;
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800207import android.view.Gravity;
Evan Rosky8d782e02019-10-14 15:43:53 -0700208import android.view.IDisplayWindowInsetsController;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100209import android.view.ISystemGestureExclusionListener;
Evan Rosky22b6bbd2019-09-26 14:29:57 -0700210import android.view.IWindow;
Arthur Hungbe5ce212018-09-13 18:41:56 +0800211import android.view.InputChannel;
Andrii Kulian06d07d62017-03-14 11:11:47 -0700212import android.view.InputDevice;
Tiger Huang04dc4cc2019-01-17 18:41:41 +0800213import android.view.InputWindowHandle;
Tiger Huang332793b2019-10-29 23:21:27 +0800214import android.view.InsetsState.InternalInsetsType;
Robert Carrb1579c82017-09-05 14:54:47 -0700215import android.view.MagnificationSpec;
Evan Rosky966759f2019-01-15 10:33:58 -0800216import android.view.RemoteAnimationDefinition;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700217import android.view.Surface;
218import android.view.SurfaceControl;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100219import android.view.SurfaceControl.Transaction;
Robert Carrb1579c82017-09-05 14:54:47 -0700220import android.view.SurfaceSession;
Tiger Huang7c610aa2018-10-27 00:01:01 +0800221import android.view.View;
Tiger Huang41ae5e82020-01-17 18:17:20 +0800222import android.view.ViewRootImpl;
Evan Rosky8d782e02019-10-14 15:43:53 -0700223import android.view.WindowInsets;
lumark588a3e82018-07-20 18:53:54 +0800224import android.view.WindowManager;
Evan Rosky39b6f232018-10-30 18:35:41 -0700225import android.view.WindowManagerPolicyConstants.PointerEventListener;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700226
Bryce Lee48f4b572017-04-10 10:54:15 -0700227import com.android.internal.annotations.VisibleForTesting;
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500228import com.android.internal.logging.MetricsLogger;
229import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800230import com.android.internal.util.ToBooleanFunction;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200231import com.android.internal.util.function.TriConsumer;
Winson Chungc5fe7ff2019-02-19 14:49:25 -0800232import com.android.internal.util.function.pooled.PooledConsumer;
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900233import com.android.internal.util.function.pooled.PooledFunction;
Winson Chungc5fe7ff2019-02-19 14:49:25 -0800234import com.android.internal.util.function.pooled.PooledLambda;
Louis Chang677921f2019-12-06 16:44:24 +0800235import com.android.internal.util.function.pooled.PooledPredicate;
Adrian Roose99bc052017-11-20 17:55:31 +0100236import com.android.server.policy.WindowManagerPolicy;
Adrian Roosb125e0b2019-10-02 14:55:14 +0200237import com.android.server.protolog.common.ProtoLog;
Issei Suzuki43190bd2018-08-20 17:28:41 +0200238import com.android.server.wm.utils.DisplayRotationUtil;
Adrian Roos2aa0fcd2018-02-19 18:07:49 +0100239import com.android.server.wm.utils.RotationCache;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100240import com.android.server.wm.utils.WmDisplayCutout;
Craig Mautner59c00972012-07-30 12:10:24 -0700241
242import java.io.PrintWriter;
Riddle Hsuf53da812018-08-15 22:00:27 +0800243import java.lang.annotation.Retention;
244import java.lang.annotation.RetentionPolicy;
Craig Mautner59c00972012-07-30 12:10:24 -0700245import java.util.ArrayList;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700246import java.util.Comparator;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700247import java.util.HashMap;
248import java.util.Iterator;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700249import java.util.LinkedList;
Andrii Kulian3a507b52016-09-19 18:14:12 -0700250import java.util.List;
Adrian Roos1cf585052018-01-03 18:43:27 +0100251import java.util.Objects;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800252import java.util.function.Consumer;
253import java.util.function.Predicate;
Craig Mautner59c00972012-07-30 12:10:24 -0700254
Craig Mautner59c00972012-07-30 12:10:24 -0700255/**
256 * Utility class for keeping track of the WindowStates and other pertinent contents of a
257 * particular Display.
Craig Mautner59c00972012-07-30 12:10:24 -0700258 */
Riddle Hsuad256a12018-07-18 16:11:30 +0800259class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer>
Louis Chang2453d062019-11-19 22:30:48 +0800260 implements WindowManagerPolicy.DisplayContentInfo {
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700261 private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
Louis Chang677921f2019-12-06 16:44:24 +0800262 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Craig Mautner59c00972012-07-30 12:10:24 -0700263
Riddle Hsuf53da812018-08-15 22:00:27 +0800264 /** The default scaling mode that scales content automatically. */
265 static final int FORCE_SCALING_MODE_AUTO = 0;
266 /** For {@link #setForcedScalingMode} to apply flag {@link Display#FLAG_SCALING_DISABLED}. */
267 static final int FORCE_SCALING_MODE_DISABLED = 1;
268
269 @IntDef(prefix = { "FORCE_SCALING_MODE_" }, value = {
270 FORCE_SCALING_MODE_AUTO,
271 FORCE_SCALING_MODE_DISABLED
272 })
273 @Retention(RetentionPolicy.SOURCE)
274 @interface ForceScalingMode {}
275
Louis Chang2453d062019-11-19 22:30:48 +0800276 ActivityTaskManagerService mAtmService;
Craig Mautner59c00972012-07-30 12:10:24 -0700277
Louis Chang2453d062019-11-19 22:30:48 +0800278 /** Unique identifier of this display. */
Louis Chang677921f2019-12-06 16:44:24 +0800279 final int mDisplayId;
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800280
chaviw8065f442019-11-18 13:20:58 -0800281 /**
282 * Most surfaces will be a child of this window. There are some special layers and windows
283 * which are always on top of others and omitted from Screen-Magnification, for example the
284 * strict mode flash or the magnification overlay itself. Those layers will be children of
285 * {@link #mOverlayContainers} where mWindowContainers contains everything else.
286 */
287 private final WindowContainers mWindowContainers =
288 new WindowContainers("mWindowContainers", mWmService);
289
290 // Contains some special windows which are always on top of others and omitted from
291 // Screen-Magnification, for example the WindowMagnification windows.
292 private final NonAppWindowContainers mOverlayContainers =
293 new NonAppWindowContainers("mOverlayContainers", mWmService);
294
295 /** The containers below are the only child containers {@link #mWindowContainers} can have. */
Wale Ogunwale3a931692016-11-02 16:49:48 -0700296 // Contains all window containers that are related to apps (Activities)
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -0800297 private final TaskContainers mTaskContainers = new TaskContainers(mWmService);
Wale Ogunwale3a931692016-11-02 16:49:48 -0700298 // Contains all non-app window containers that should be displayed above the app containers
299 // (e.g. Status bar)
Robert Carree4d4b92017-11-22 12:21:46 -0800300 private final AboveAppWindowContainers mAboveAppWindowsContainers =
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800301 new AboveAppWindowContainers("mAboveAppWindowsContainers", mWmService);
Wale Ogunwale3a931692016-11-02 16:49:48 -0700302 // Contains all non-app window containers that should be displayed below the app containers
303 // (e.g. Wallpaper).
304 private final NonAppWindowContainers mBelowAppWindowsContainers =
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800305 new NonAppWindowContainers("mBelowAppWindowsContainers", mWmService);
Wale Ogunwale3a931692016-11-02 16:49:48 -0700306 // Contains all IME window containers. Note that the z-ordering of the IME windows will depend
307 // on the IME target. We mainly have this container grouping so we can keep track of all the IME
Robert Carr9034d962018-01-04 18:27:42 -0800308 // window containers together and move them in-sync if/when needed. We use a subclass of
309 // WindowContainer which is omitted from screen magnification, as the IME is never magnified.
Adrian Roosefa40702020-01-08 17:58:45 +0100310 // TODO(display-area): is "no magnification" in the comment still true?
311 private final ImeContainer mImeWindowsContainers = new ImeContainer(mWmService);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700312
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000313 private WindowState mTmpWindow;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800314 private WindowState mTmpWindow2;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800315 private boolean mUpdateImeTarget;
316 private boolean mTmpInitial;
Bryce Lee27cec322017-03-21 09:41:37 -0700317 private int mMaxUiWidth;
Craig Mautner59c00972012-07-30 12:10:24 -0700318
lumark588a3e82018-07-20 18:53:54 +0800319 final AppTransition mAppTransition;
320 final AppTransitionController mAppTransitionController;
321 boolean mSkipAppTransitionAnimation = false;
322
Garfield Tane8d84ab2019-10-11 09:49:40 -0700323 final ArraySet<ActivityRecord> mOpeningApps = new ArraySet<>();
324 final ArraySet<ActivityRecord> mClosingApps = new ArraySet<>();
325 final ArraySet<ActivityRecord> mChangingApps = new ArraySet<>();
lumark588a3e82018-07-20 18:53:54 +0800326 final UnknownAppVisibilityController mUnknownAppVisibilityController;
327 BoundsAnimationController mBoundsAnimationController;
328
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500329 private MetricsLogger mMetricsLogger;
330
lumark588a3e82018-07-20 18:53:54 +0800331 /**
332 * List of clients without a transtiton animation that we notify once we are done
333 * transitioning since they won't be notified through the app window animator.
334 */
335 final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
336
Wale Ogunwale02319a62016-09-26 15:21:22 -0700337 // Mapping from a token IBinder to a WindowToken object on this display.
338 private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap();
339
Andrii Kuliancd097992017-03-23 18:31:59 -0700340 // Initial display metrics.
Craig Mautner59c00972012-07-30 12:10:24 -0700341 int mInitialDisplayWidth = 0;
342 int mInitialDisplayHeight = 0;
Dianne Hackborndde331c2012-08-03 14:01:57 -0700343 int mInitialDisplayDensity = 0;
Andrii Kuliancd097992017-03-23 18:31:59 -0700344
Adrian Roos1cf585052018-01-03 18:43:27 +0100345 DisplayCutout mInitialDisplayCutout;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100346 private final RotationCache<DisplayCutout, WmDisplayCutout> mDisplayCutoutCache
Adrian Roos2aa0fcd2018-02-19 18:07:49 +0100347 = new RotationCache<>(this::calculateDisplayCutoutForRotationUncached);
Adrian Roos1cf585052018-01-03 18:43:27 +0100348
Andrii Kuliancd097992017-03-23 18:31:59 -0700349 /**
350 * Overridden display size. Initialized with {@link #mInitialDisplayWidth}
351 * and {@link #mInitialDisplayHeight}, but can be set via shell command "adb shell wm size".
352 * @see WindowManagerService#setForcedDisplaySize(int, int, int)
353 */
Craig Mautner59c00972012-07-30 12:10:24 -0700354 int mBaseDisplayWidth = 0;
355 int mBaseDisplayHeight = 0;
Andrii Kuliancd097992017-03-23 18:31:59 -0700356 /**
357 * Overridden display density for current user. Initialized with {@link #mInitialDisplayDensity}
358 * but can be set from Settings or via shell command "adb shell wm density".
359 * @see WindowManagerService#setForcedDisplayDensityForUser(int, int, int)
360 */
Dianne Hackborndde331c2012-08-03 14:01:57 -0700361 int mBaseDisplayDensity = 0;
Riddle Hsuf53da812018-08-15 22:00:27 +0800362
363 /**
364 * Whether to disable display scaling. This can be set via shell command "adb shell wm scaling".
365 * @see WindowManagerService#setForcedDisplayScalingMode(int, int)
366 */
Jeff Brownd46747a2015-04-15 19:02:36 -0700367 boolean mDisplayScalingDisabled;
Louis Chang677921f2019-12-06 16:44:24 +0800368 final Display mDisplay;
Craig Mautner2d5618c2012-10-18 13:55:47 -0700369 private final DisplayInfo mDisplayInfo = new DisplayInfo();
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700370 private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800371 private final DisplayPolicy mDisplayPolicy;
Riddle Hsuccf09402019-08-13 00:33:06 +0800372 private final DisplayRotation mDisplayRotation;
Wale Ogunwale828ff7e2017-11-14 01:01:29 +0000373 DisplayFrames mDisplayFrames;
374
Adrian Roos4ffc8972019-02-07 20:45:11 +0100375 private final RemoteCallbackList<ISystemGestureExclusionListener>
376 mSystemGestureExclusionListeners = new RemoteCallbackList<>();
377 private final Region mSystemGestureExclusion = new Region();
Adrian Roos5f2c9a12019-07-03 18:31:46 +0200378 private boolean mSystemGestureExclusionWasRestricted = false;
379 private final Region mSystemGestureExclusionUnrestricted = new Region();
Adrian Roosbf3bc1b2019-06-18 16:13:53 +0200380 private int mSystemGestureExclusionLimit;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100381
Andrii Kulian06d07d62017-03-14 11:11:47 -0700382 /**
383 * For default display it contains real metrics, empty for others.
chaviw619da692019-06-10 15:39:40 -0700384 * @see WindowManagerService#createWatermark()
Andrii Kulian06d07d62017-03-14 11:11:47 -0700385 */
386 final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
Tiger Huang7c610aa2018-10-27 00:01:01 +0800387
388 /** @see #computeCompatSmallestWidth(boolean, int, int, int, DisplayCutout) */
Andrii Kulian06d07d62017-03-14 11:11:47 -0700389 private final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
Lucas Dupin1ead7fc2017-05-24 14:14:44 -0700390
Andrii Kulian06d07d62017-03-14 11:11:47 -0700391 /**
392 * Compat metrics computed based on {@link #mDisplayMetrics}.
393 * @see #updateDisplayAndOrientation(int)
394 */
395 private final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
396
397 /** The desired scaling factor for compatible apps. */
398 float mCompatibleScreenScale;
Craig Mautner59c00972012-07-30 12:10:24 -0700399
Riddle Hsu7f704b52019-12-10 23:10:45 +0800400 /** @see #getCurrentOverrideConfigurationChanges */
401 private int mCurrentOverrideConfigurationChanges;
402
Andrii Kulian8ee72852017-03-10 10:36:45 -0800403 /**
Andrii Kulian8ee72852017-03-10 10:36:45 -0800404 * Last orientation forced by the keyguard. It is applied when keyguard is shown and is not
405 * occluded.
406 *
407 * @see NonAppWindowContainers#getOrientation()
408 */
409 private int mLastKeyguardForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
410
Lucas Dupin1ead7fc2017-05-24 14:14:44 -0700411 /**
Tiger Huang86e6d072019-05-02 20:23:47 +0800412 * The maximum aspect ratio (longerSide/shorterSide) that is treated as close-to-square. The
413 * orientation requests from apps would be ignored if the display is close-to-square.
414 */
415 @VisibleForTesting
416 final float mCloseToSquareMaxAspectRatio;
417
418 /**
419 * If this is true, we would not rotate the display for apps. The rotation would be either the
420 * sensor rotation or the user rotation, controlled by
421 * {@link WindowManagerPolicy.UserRotationMode}.
422 */
423 private boolean mIgnoreRotationForApps;
424
425 /**
Lucas Dupin1ead7fc2017-05-24 14:14:44 -0700426 * Keep track of wallpaper visibility to notify changes.
427 */
428 private boolean mLastWallpaperVisible = false;
429
Andrii Kulian06d07d62017-03-14 11:11:47 -0700430 private Rect mBaseDisplayRect = new Rect();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700431
Craig Mautner39834192012-09-02 07:47:24 -0700432 // Accessed directly by all users.
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700433 private boolean mLayoutNeeded;
Craig Mautner76a71652012-09-03 23:23:58 -0700434 int pendingLayoutChanges;
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800435
Vishnu Nairba183352018-11-21 11:16:49 -0800436 /**
437 * Used to gate application window layout until we have sent the complete configuration.
438 * TODO: There are still scenarios where we may be out of sync with the client. Ideally
439 * we want to replace this flag with a mechanism that will confirm the configuration
440 * applied by the client is the one expected by the system server.
441 */
442 boolean mWaitingForConfig;
443
Andrii Kulian839def92016-11-02 10:58:58 -0700444 // TODO(multi-display): remove some of the usages.
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800445 @VisibleForTesting
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800446 boolean isDefaultDisplay;
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800447
Andrii Kulianf0379de2018-03-14 16:24:07 -0700448 /**
449 * Flag indicating whether WindowManager should override info for this display in
450 * DisplayManager.
451 */
452 boolean mShouldOverrideDisplayConfiguration = true;
Craig Mautner39834192012-09-02 07:47:24 -0700453
Craig Mautnerdc548482014-02-05 13:35:24 -0800454 /** Window tokens that are in the process of exiting, but still on screen for animations. */
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700455 final ArrayList<WindowToken> mExitingTokens = new ArrayList<>();
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800456
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700457 /** Detect user tapping outside of current focused task bounds .*/
Riddle Hsu2588ab02019-02-25 14:23:56 +0800458 @VisibleForTesting
459 final TaskTapPointerEventListener mTapDetector;
Craig Mautnercf910b02013-04-23 11:23:27 -0700460
Craig Mautner6601b7b2013-04-29 10:29:11 -0700461 /** Detect user tapping outside of current focused stack bounds .*/
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700462 private Region mTouchExcludeRegion = new Region();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700463
Craig Mautner6601b7b2013-04-29 10:29:11 -0700464 /** Save allocating when calculating rects */
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800465 private final Rect mTmpRect = new Rect();
466 private final Rect mTmpRect2 = new Rect();
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700467 private final RectF mTmpRectF = new RectF();
468 private final Matrix mTmpMatrix = new Matrix();
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800469 private final Region mTmpRegion = new Region();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700470
Bryce Leef3c6a472017-11-14 14:53:06 -0800471 /** Used for handing back size of display */
472 private final Rect mTmpBounds = new Rect();
473
Garfield Tan90b04282018-12-11 14:04:42 -0800474 private final Configuration mTmpConfiguration = new Configuration();
475
Craig Mautner95da1082014-02-24 17:54:35 -0800476 /** Remove this display when animation on it has completed. */
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700477 private boolean mDeferredRemoval;
Craig Mautner1bf2b872014-02-05 15:37:40 -0800478
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700479 final DockedStackDividerController mDividerControllerLocked;
Winson Chung655332c2016-10-31 13:14:28 -0700480 final PinnedStackController mPinnedStackControllerLocked;
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700481
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800482 final ArrayList<WindowState> mTapExcludedWindows = new ArrayList<>();
Andrii Kulian4b6599e2018-01-15 17:24:08 -0800483 /** A collection of windows that provide tap exclude regions inside of them. */
484 final ArraySet<WindowState> mTapExcludeProvidingWindows = new ArraySet<>();
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800485
Garfield Tane8d84ab2019-10-11 09:49:40 -0700486 private final LinkedList<ActivityRecord> mTmpUpdateAllDrawn = new LinkedList();
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700487
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700488 private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult =
489 new TaskForResizePointSearchResult();
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000490 private final ApplySurfaceChangesTransactionState mTmpApplySurfaceChangesTransactionState =
491 new ApplySurfaceChangesTransactionState();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700492
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700493 // True if this display is in the process of being removed. Used to determine if the removal of
494 // the display's direct children should be allowed.
495 private boolean mRemovingDisplay = false;
496
Bryce Leed1871262017-06-12 14:12:29 -0700497 // {@code false} if this display is in the processing of being created.
498 private boolean mDisplayReady = false;
499
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800500 WallpaperController mWallpaperController;
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700501
wilsonshihc32538e2018-11-07 17:27:34 +0800502 boolean mWallpaperMayChange = false;
503
Robert Carrb1579c82017-09-05 14:54:47 -0700504 private final SurfaceSession mSession = new SurfaceSession();
505
506 /**
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800507 * Window that is currently interacting with the user. This window is responsible for receiving
508 * key events and pointer events from the user.
509 */
510 WindowState mCurrentFocus = null;
511
512 /**
513 * The last focused window that we've notified the client that the focus is changed.
514 */
515 WindowState mLastFocus = null;
516
517 /**
518 * Windows that have lost input focus and are waiting for the new focus window to be displayed
519 * before they are told about this.
520 */
521 ArrayList<WindowState> mLosingFocus = new ArrayList<>();
522
523 /**
524 * The foreground app of this display. Windows below this app cannot be the focused window. If
525 * the user taps on the area outside of the task of the focused app, we will notify AM about the
526 * new task the user wants to interact with.
527 */
Garfield Tane8d84ab2019-10-11 09:49:40 -0700528 ActivityRecord mFocusedApp = null;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800529
530 /** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
531 final ArrayList<WindowState> mWinAddedSinceNullFocus = new ArrayList<>();
532
533 /** Windows removed since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
534 final ArrayList<WindowState> mWinRemovedSinceNullFocus = new ArrayList<>();
535
Vadim Caenb3715832019-08-13 17:06:38 +0200536 private ScreenRotationAnimation mScreenRotationAnimation;
537
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800538 /**
Adrian Roos5251b1d2018-03-23 18:57:43 +0100539 * Sequence number for the current layout pass.
540 */
541 int mLayoutSeq = 0;
542
Chavi Weingarten3a748552018-05-14 17:32:42 +0000543 /**
544 * Specifies the count to determine whether to defer updating the IME target until ready.
545 */
546 private int mDeferUpdateImeTargetCount;
547
Robert Carr24be9ab2018-04-30 17:54:53 -0700548 private MagnificationSpec mMagnificationSpec;
549
Arthur Hung95b38a92018-07-20 18:56:12 +0800550 private InputMonitor mInputMonitor;
551
Jorim Jaggif1292892018-09-10 11:58:13 +0200552 /** Caches the value whether told display manager that we have content. */
553 private boolean mLastHasContent;
554
Issei Suzuki43190bd2018-08-20 17:28:41 +0200555 private DisplayRotationUtil mRotationUtil = new DisplayRotationUtil();
556
lumark90120a82018-08-15 00:33:03 +0800557 /**
558 * The input method window for this display.
559 */
560 WindowState mInputMethodWindow;
561
lumarkff0ab692018-11-05 20:32:30 +0800562 /**
563 * This just indicates the window the input method is on top of, not
564 * necessarily the window its input is going to.
565 */
566 WindowState mInputMethodTarget;
567
Evan Rosky8d782e02019-10-14 15:43:53 -0700568 InsetsControlTarget mInputMethodControlTarget;
569
lumarkff0ab692018-11-05 20:32:30 +0800570 /** If true hold off on modifying the animation layer of mInputMethodTarget */
571 boolean mInputMethodTargetWaitingAnim;
572
Arthur Hungbe5ce212018-09-13 18:41:56 +0800573 private final PointerEventDispatcher mPointerEventDispatcher;
574
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200575 private final InsetsStateController mInsetsStateController;
Jorim Jaggi28620472019-01-02 23:21:49 +0100576 private final InsetsPolicy mInsetsPolicy;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200577
Tiger Huangd8ec9382019-04-18 14:35:09 -0700578 /** @see #getParentWindow() */
579 private WindowState mParentWindow;
580
581 private Point mLocationInParentWindow = new Point();
Tiger Huang04dc4cc2019-01-17 18:41:41 +0800582 private SurfaceControl mParentSurfaceControl;
583 private InputWindowHandle mPortalWindowHandle;
584
Tiger Huang7c610aa2018-10-27 00:01:01 +0800585 // Last systemUiVisibility we received from status bar.
586 private int mLastStatusBarVisibility = 0;
587 // Last systemUiVisibility we dispatched to windows.
588 private int mLastDispatchedSystemUiVisibility = 0;
589
Louis Changdc077272019-11-12 16:52:56 +0800590 private final ArrayList<ActivityStack> mTmpAlwaysOnTopStacks = new ArrayList<>();
591 private final ArrayList<ActivityStack> mTmpNormalStacks = new ArrayList<>();
592 private final ArrayList<ActivityStack> mTmpHomeStacks = new ArrayList<>();
Issei Suzuki25a9e2b2019-08-14 16:46:26 +0200593
Tiger Huang43b8fc22019-04-26 11:49:29 +0800594 /** Corner radius that windows should have in order to match the display. */
595 private final float mWindowCornerRadius;
596
Evan Rosky22b6bbd2019-09-26 14:29:57 -0700597 private final SparseArray<ShellRoot> mShellRoots = new SparseArray<>();
Evan Rosky8d782e02019-10-14 15:43:53 -0700598 RemoteInsetsControlTarget mRemoteInsetsControlTarget = null;
599 private final IBinder.DeathRecipient mRemoteInsetsDeath =
600 () -> {
601 synchronized (mWmService.mGlobalLock) {
602 mRemoteInsetsControlTarget = null;
603 }
604 };
Evan Rosky22b6bbd2019-09-26 14:29:57 -0700605
Louis Chang149d5c82019-12-30 09:47:39 +0800606 private RootWindowContainer mRootWindowContainer;
Louis Chang677921f2019-12-06 16:44:24 +0800607
608 /**
609 * All of the stacks on this display. Order matters, topmost stack is in front of all other
610 * stacks, bottommost behind. Accessed directly by ActivityManager package classes. Any calls
611 * changing the list should also call {@link #onStackOrderChanged()}.
612 */
613 private ArrayList<OnStackOrderChangedListener> mStackOrderChangedCallbacks = new ArrayList<>();
614
615 /** Array of all UIDs that are present on the display. */
616 private IntArray mDisplayAccessUIDs = new IntArray();
617
618 /** All tokens used to put activities on this stack to sleep (including mOffToken) */
619 final ArrayList<ActivityTaskManagerInternal.SleepToken> mAllSleepTokens = new ArrayList<>();
620 /** The token acquired by ActivityStackSupervisor to put stacks on the display to sleep */
621 ActivityTaskManagerInternal.SleepToken mOffToken;
622
623 private boolean mSleeping;
624
625 /** We started the process of removing the display from the system. */
626 private boolean mRemoving;
627
628 /**
629 * The display is removed from the system and we are just waiting for all activities on it to be
630 * finished before removing this object.
631 */
632 private boolean mRemoved;
633
634 /** The display can only contain one task. */
635 private boolean mSingleTaskInstance;
636
637 /**
638 * Non-null if the last size compatibility mode activity is using non-native screen
639 * configuration. The activity is not able to put in multi-window mode, so it exists only one
640 * per display.
641 */
642 private ActivityRecord mLastCompatModeActivity;
643
644 /**
645 * A focusable stack that is purposely to be positioned at the top. Although the stack may not
646 * have the topmost index, it is used as a preferred candidate to prevent being unable to resume
647 * target stack properly when there are other focusable always-on-top stacks.
648 */
649 private ActivityStack mPreferredTopFocusableStack;
650
651 /**
652 * If this is the same as {@link #getFocusedStack} then the activity on the top of the focused
653 * stack has been resumed. If stacks are changing position this will hold the old stack until
654 * the new stack becomes resumed after which it will be set to current focused stack.
655 */
656 private ActivityStack mLastFocusedStack;
657
658 // Used in updating the display size
659 private Point mTmpDisplaySize = new Point();
660
661 // Used in updating override configurations
662 private final Configuration mTempConfig = new Configuration();
663
Louis Chang149d5c82019-12-30 09:47:39 +0800664 private final RootWindowContainer.FindTaskResult
665 mTmpFindTaskResult = new RootWindowContainer.FindTaskResult();
Louis Chang677921f2019-12-06 16:44:24 +0800666
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800667 private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
668 WindowStateAnimator winAnimator = w.mWinAnimator;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700669 final ActivityRecord activity = w.mActivityRecord;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800670 if (winAnimator.mDrawState == READY_TO_SHOW) {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700671 if (activity == null || activity.canShowWindows()) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800672 if (w.performShowLocked()) {
673 pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
674 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800675 mWmService.mWindowPlacerLocked.debugLayoutRepeats(
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800676 "updateWindowsAndWallpaperLocked 5", pendingLayoutChanges);
677 }
678 }
679 }
680 }
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800681 };
682
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800683 private final Consumer<WindowState> mScheduleToastTimeout = w -> {
684 final int lostFocusUid = mTmpWindow.mOwnerUid;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800685 final Handler handler = mWmService.mH;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800686 if (w.mAttrs.type == TYPE_TOAST && w.mOwnerUid == lostFocusUid) {
687 if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, w)) {
688 handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, w),
689 w.mAttrs.hideTimeoutMilliseconds);
690 }
691 }
692 };
693
694 private final ToBooleanFunction<WindowState> mFindFocusedWindow = w -> {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700695 final ActivityRecord focusedApp = mFocusedApp;
Adrian Roosb125e0b2019-10-02 14:55:14 +0200696 ProtoLog.v(WM_DEBUG_FOCUS, "Looking for focus: %s, flags=%d, canReceive=%b",
697 w, w.mAttrs.flags, w.canReceiveKeys());
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800698
699 if (!w.canReceiveKeys()) {
700 return false;
701 }
702
Garfield Tane8d84ab2019-10-11 09:49:40 -0700703 final ActivityRecord activity = w.mActivityRecord;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800704
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800705 if (focusedApp == null) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200706 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
707 "findFocusedWindow: focusedApp=null using new focus @ %s", w);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800708 mTmpWindow = w;
709 return true;
710 }
711
712 if (!focusedApp.windowsAreFocusable()) {
713 // Current focused app windows aren't focusable...
Adrian Roosb125e0b2019-10-02 14:55:14 +0200714 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: focusedApp windows not"
715 + " focusable using new focus @ %s", w);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800716 mTmpWindow = w;
717 return true;
718 }
719
720 // Descend through all of the app tokens and find the first that either matches
Garfield Tane8d84ab2019-10-11 09:49:40 -0700721 // win.mActivityRecord (return win) or mFocusedApp (return null).
722 if (activity != null && w.mAttrs.type != TYPE_APPLICATION_STARTING) {
723 if (focusedApp.compareTo(activity) > 0) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800724 // App stack below focused app stack. No focus for you!!!
Adrian Roosb125e0b2019-10-02 14:55:14 +0200725 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
726 "findFocusedWindow: Reached focused app=%s", focusedApp);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800727 mTmpWindow = null;
728 return true;
729 }
730 }
731
Adrian Roosb125e0b2019-10-02 14:55:14 +0200732 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: Found new focus @ %s", w);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800733 mTmpWindow = w;
734 return true;
735 };
736
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800737 private final Consumer<WindowState> mPerformLayout = w -> {
738 // Don't do layout of a window if it is not visible, or soon won't be visible, to avoid
739 // wasting time and funky changes while a window is animating away.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800740 final boolean gone = (mTmpWindow != null && mWmService.mPolicy.canBeHiddenByKeyguardLw(w))
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800741 || w.isGoneForLayoutLw();
742
743 if (DEBUG_LAYOUT && !w.mLayoutAttached) {
744 Slog.v(TAG, "1ST PASS " + w + ": gone=" + gone + " mHaveFrame=" + w.mHaveFrame
745 + " mLayoutAttached=" + w.mLayoutAttached
Jorim Jaggi381cd722019-03-27 17:33:02 +0100746 + " config reported=" + w.isLastConfigReportedToClient());
Garfield Tane8d84ab2019-10-11 09:49:40 -0700747 final ActivityRecord activity = w.mActivityRecord;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800748 if (gone) Slog.v(TAG, " GONE: mViewVisibility=" + w.mViewVisibility
Issei Suzukif2f6c912019-11-08 11:24:18 +0100749 + " mRelayoutCalled=" + w.mRelayoutCalled + " visible=" + w.mToken.isVisible()
Issei Suzuki1669ea42019-11-06 14:20:59 +0100750 + " visibleRequested=" + (activity != null && activity.mVisibleRequested)
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800751 + " parentHidden=" + w.isParentWindowHidden());
752 else Slog.v(TAG, " VIS: mViewVisibility=" + w.mViewVisibility
Issei Suzukif2f6c912019-11-08 11:24:18 +0100753 + " mRelayoutCalled=" + w.mRelayoutCalled + " visible=" + w.mToken.isVisible()
Issei Suzuki1669ea42019-11-06 14:20:59 +0100754 + " visibleRequested=" + (activity != null && activity.mVisibleRequested)
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800755 + " parentHidden=" + w.isParentWindowHidden());
756 }
757
758 // If this view is GONE, then skip it -- keep the current frame, and let the caller know
759 // so they can ignore it if they want. (We do the normal layout for INVISIBLE windows,
760 // since that means "perform layout as normal, just don't display").
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100761 if ((!gone || !w.mHaveFrame || w.mLayoutNeeded) && !w.mLayoutAttached) {
762 if (mTmpInitial) {
763 w.resetContentChanged();
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800764 }
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100765 if (w.mAttrs.type == TYPE_DREAM) {
766 // Don't layout windows behind a dream, so that if it does stuff like hide
767 // the status bar we won't get a bad transition when it goes away.
768 mTmpWindow = w;
769 }
770 w.mLayoutNeeded = false;
771 w.prelayout();
772 final boolean firstLayout = !w.isLaidOut();
773 getDisplayPolicy().layoutWindowLw(w, null, mDisplayFrames);
774 w.mLayoutSeq = mLayoutSeq;
775
Riddle Hsuf64e1342019-12-05 17:38:41 +0800776 // If this is the first layout, we need to initialize the last frames and inset values,
777 // as otherwise we'd immediately cause an unnecessary resize.
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100778 if (firstLayout) {
Riddle Hsu12c05452020-01-09 00:39:52 +0800779 // The client may compute its actual requested size according to the first layout,
780 // so we still request the window to resize if the current frame is empty.
781 if (!w.getFrameLw().isEmpty()) {
782 w.updateLastFrames();
783 }
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100784 w.updateLastInsetValues();
Riddle Hsuf64e1342019-12-05 17:38:41 +0800785 w.updateLocationInParentDisplayIfNeeded();
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100786 }
787
Garfield Tane8d84ab2019-10-11 09:49:40 -0700788 if (w.mActivityRecord != null) {
789 w.mActivityRecord.layoutLetterbox(w);
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100790 }
791
792 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrameLw()
793 + " mContainingFrame=" + w.getContainingFrame()
794 + " mDisplayFrame=" + w.getDisplayFrameLw());
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800795 }
796 };
797
798 private final Consumer<WindowState> mPerformLayoutAttached = w -> {
799 if (w.mLayoutAttached) {
800 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + w + " mHaveFrame=" + w.mHaveFrame
801 + " mViewVisibility=" + w.mViewVisibility
802 + " mRelayoutCalled=" + w.mRelayoutCalled);
803 // If this view is GONE, then skip it -- keep the current frame, and let the caller
804 // know so they can ignore it if they want. (We do the normal layout for INVISIBLE
805 // windows, since that means "perform layout as normal, just don't display").
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800806 if (mTmpWindow != null && mWmService.mPolicy.canBeHiddenByKeyguardLw(w)) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800807 return;
808 }
809 if ((w.mViewVisibility != GONE && w.mRelayoutCalled) || !w.mHaveFrame
810 || w.mLayoutNeeded) {
811 if (mTmpInitial) {
812 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
chaviw1454b392018-08-06 09:54:04 -0700813 w.resetContentChanged();
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800814 }
815 w.mLayoutNeeded = false;
816 w.prelayout();
Tiger Huang7c610aa2018-10-27 00:01:01 +0800817 getDisplayPolicy().layoutWindowLw(w, w.getParentWindow(), mDisplayFrames);
Adrian Roos5251b1d2018-03-23 18:57:43 +0100818 w.mLayoutSeq = mLayoutSeq;
chaviw492139a2018-07-16 16:07:35 -0700819 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrameLw()
chaviw553b0212018-07-12 13:37:01 -0700820 + " mContainingFrame=" + w.getContainingFrame()
821 + " mDisplayFrame=" + w.getDisplayFrameLw());
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800822 }
823 } else if (w.mAttrs.type == TYPE_DREAM) {
824 // Don't layout windows behind a dream, so that if it does stuff like hide the
825 // status bar we won't get a bad transition when it goes away.
826 mTmpWindow = mTmpWindow2;
827 }
828 };
829
830 private final Predicate<WindowState> mComputeImeTargetPredicate = w -> {
831 if (DEBUG_INPUT_METHOD && mUpdateImeTarget) Slog.i(TAG_WM, "Checking window @" + w
832 + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
833 return w.canBeImeTarget();
834 };
835
836 private final Consumer<WindowState> mApplyPostLayoutPolicy =
Tiger Huang7c610aa2018-10-27 00:01:01 +0800837 w -> getDisplayPolicy().applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(),
lumarkff0ab692018-11-05 20:32:30 +0800838 mInputMethodTarget);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800839
840 private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800841 final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800842 final boolean obscuredChanged = w.mObscured !=
843 mTmpApplySurfaceChangesTransactionState.obscured;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800844 final RootWindowContainer root = mWmService.mRoot;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800845
846 // Update effect.
847 w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured;
Galia Peycheva056b3ee2019-06-26 14:05:12 +0200848
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800849 if (!mTmpApplySurfaceChangesTransactionState.obscured) {
850 final boolean isDisplayed = w.isDisplayedLw();
851
852 if (isDisplayed && w.isObscuringDisplay()) {
853 // This window completely covers everything behind it, so we want to leave all
854 // of them as undimmed (for performance reasons).
855 root.mObscuringWindow = w;
856 mTmpApplySurfaceChangesTransactionState.obscured = true;
857 }
858
Arthur Hungfbc8f412019-08-01 19:57:54 +0800859 final boolean displayHasContent = root.handleNotObscuredLocked(w,
860 mTmpApplySurfaceChangesTransactionState.obscured,
861 mTmpApplySurfaceChangesTransactionState.syswin);
862
863 if (!mTmpApplySurfaceChangesTransactionState.displayHasContent
864 && !getDisplayPolicy().isWindowExcludedFromContent(w)) {
865 mTmpApplySurfaceChangesTransactionState.displayHasContent |= displayHasContent;
866 }
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800867
868 if (w.mHasSurface && isDisplayed) {
869 final int type = w.mAttrs.type;
870 if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR
wilsonshihe8321942019-10-18 18:39:46 +0800871 || mWmService.mPolicy.isKeyguardShowing()) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800872 mTmpApplySurfaceChangesTransactionState.syswin = true;
873 }
874 if (mTmpApplySurfaceChangesTransactionState.preferredRefreshRate == 0
875 && w.mAttrs.preferredRefreshRate != 0) {
876 mTmpApplySurfaceChangesTransactionState.preferredRefreshRate
877 = w.mAttrs.preferredRefreshRate;
878 }
Galia Peycheva056b3ee2019-06-26 14:05:12 +0200879
880 mTmpApplySurfaceChangesTransactionState.preferMinimalPostProcessing
881 |= w.mAttrs.preferMinimalPostProcessing;
882
Ady Abrahamf3e05312019-05-13 18:04:59 -0700883 final int preferredModeId = getDisplayPolicy().getRefreshRatePolicy()
884 .getPreferredModeId(w);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800885 if (mTmpApplySurfaceChangesTransactionState.preferredModeId == 0
Ady Abrahamf3e05312019-05-13 18:04:59 -0700886 && preferredModeId != 0) {
887 mTmpApplySurfaceChangesTransactionState.preferredModeId = preferredModeId;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800888 }
889 }
890 }
891
wilsonshihc32538e2018-11-07 17:27:34 +0800892 if (obscuredChanged && w.isVisibleLw() && mWallpaperController.isWallpaperTarget(w)) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800893 // This is the wallpaper target and its obscured state changed... make sure the
894 // current wallpaper's visibility has been updated accordingly.
895 mWallpaperController.updateWallpaperVisibility();
896 }
897
chaviw161ea3e2018-01-31 12:01:12 -0800898 w.handleWindowMovedIfNeeded();
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800899
900 final WindowStateAnimator winAnimator = w.mWinAnimator;
901
902 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
chaviw1454b392018-08-06 09:54:04 -0700903 w.resetContentChanged();
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800904
905 // Moved from updateWindowsAndWallpaperLocked().
906 if (w.mHasSurface) {
907 // Take care of the window being ready to display.
908 final boolean committed = winAnimator.commitFinishDrawingLocked();
909 if (isDefaultDisplay && committed) {
910 if (w.mAttrs.type == TYPE_DREAM) {
911 // HACK: When a dream is shown, it may at that point hide the lock screen.
912 // So we need to redo the layout to let the phone window manager make this
913 // happen.
914 pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
915 if (DEBUG_LAYOUT_REPEATS) {
916 surfacePlacer.debugLayoutRepeats(
917 "dream and commitFinishDrawingLocked true",
918 pendingLayoutChanges);
919 }
920 }
921 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
922 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
923 "First draw done in potential wallpaper target " + w);
wilsonshihc32538e2018-11-07 17:27:34 +0800924 mWallpaperMayChange = true;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800925 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
926 if (DEBUG_LAYOUT_REPEATS) {
927 surfacePlacer.debugLayoutRepeats(
928 "wallpaper and commitFinishDrawingLocked true",
929 pendingLayoutChanges);
930 }
931 }
932 }
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800933 }
934
Garfield Tane8d84ab2019-10-11 09:49:40 -0700935 final ActivityRecord activity = w.mActivityRecord;
936 if (activity != null) {
937 activity.updateLetterboxSurface(w);
938 final boolean updateAllDrawn = activity.updateDrawnWindowStates(w);
939 if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(activity)) {
940 mTmpUpdateAllDrawn.add(activity);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800941 }
942 }
943
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800944 if (!mLosingFocus.isEmpty() && w.isFocused() && w.isDisplayedLw()) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800945 mWmService.mH.obtainMessage(REPORT_LOSING_FOCUS, this).sendToTarget();
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800946 }
947
948 w.updateResizingWindowIfNeeded();
949 };
950
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800951 /**
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800952 * Create new {@link DisplayContent} instance, add itself to the root window container and
953 * initialize direct children.
Craig Mautner2d5618c2012-10-18 13:55:47 -0700954 * @param display May not be null.
Louis Chang149d5c82019-12-30 09:47:39 +0800955 * @param root {@link RootWindowContainer}
Craig Mautner2d5618c2012-10-18 13:55:47 -0700956 */
Louis Chang149d5c82019-12-30 09:47:39 +0800957 DisplayContent(Display display, RootWindowContainer root) {
Louis Chang677921f2019-12-06 16:44:24 +0800958 super(root.mWindowManager);
959 if (mWmService.mRoot.getDisplayContent(display.getDisplayId()) != null) {
Wale Ogunwale1666e312016-12-16 11:27:18 -0800960 throw new IllegalArgumentException("Display with ID=" + display.getDisplayId()
Louis Chang677921f2019-12-06 16:44:24 +0800961 + " already exists="
962 + mWmService.mRoot.getDisplayContent(display.getDisplayId())
Wale Ogunwale1666e312016-12-16 11:27:18 -0800963 + " new=" + display);
964 }
965
Louis Chang149d5c82019-12-30 09:47:39 +0800966 mRootWindowContainer = root;
Louis Chang2453d062019-11-19 22:30:48 +0800967 mAtmService = mWmService.mAtmService;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700968 mDisplay = display;
969 mDisplayId = display.getDisplayId();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800970 mWallpaperController = new WallpaperController(mWmService, this);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700971 display.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700972 display.getMetrics(mDisplayMetrics);
Adrian Roos1c2e9a12019-08-20 18:23:47 +0200973 mSystemGestureExclusionLimit = mWmService.mConstants.mSystemGestureExclusionLimitDp
Adrian Roosbf3bc1b2019-06-18 16:13:53 +0200974 * mDisplayMetrics.densityDpi / DENSITY_DEFAULT;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700975 isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100976 mDisplayFrames = new DisplayFrames(mDisplayId, mDisplayInfo,
977 calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700978 initializeDisplayBaseInfo();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700979
Louis Chang677921f2019-12-06 16:44:24 +0800980 mAppTransition = new AppTransition(mWmService.mContext, mWmService, this);
981 mAppTransition.registerListenerLocked(mWmService.mActivityManagerAppTransitionNotifier);
982 mAppTransitionController = new AppTransitionController(mWmService, this);
983 mUnknownAppVisibilityController = new UnknownAppVisibilityController(mWmService, this);
lumark588a3e82018-07-20 18:53:54 +0800984
985 AnimationHandler animationHandler = new AnimationHandler();
Louis Chang677921f2019-12-06 16:44:24 +0800986 mBoundsAnimationController = new BoundsAnimationController(mWmService.mContext,
Riddle Hsue459c632020-01-03 22:37:47 +0800987 mAppTransition, mWmService.mAnimationHandler, animationHandler);
lumark588a3e82018-07-20 18:53:54 +0800988
Riddle Hsu2588ab02019-02-25 14:23:56 +0800989 final InputChannel inputChannel = mWmService.mInputManager.monitorInput(
990 "PointerEventDispatcher" + mDisplayId, mDisplayId);
991 mPointerEventDispatcher = new PointerEventDispatcher(inputChannel);
992
993 // Tap Listeners are supported for:
994 // 1. All physical displays (multi-display).
995 // 2. VirtualDisplays on VR, AA (and everything else).
996 mTapDetector = new TaskTapPointerEventListener(mWmService, this);
997 registerPointerEventListener(mTapDetector);
998 registerPointerEventListener(mWmService.mMousePositionTracker);
Winson Chungc5fe7ff2019-02-19 14:49:25 -0800999 if (mWmService.mAtmService.getRecentTasks() != null) {
1000 registerPointerEventListener(
1001 mWmService.mAtmService.getRecentTasks().getInputListener());
1002 }
Riddle Hsu2588ab02019-02-25 14:23:56 +08001003
Louis Chang677921f2019-12-06 16:44:24 +08001004 mDisplayPolicy = new DisplayPolicy(mWmService, this);
1005 mDisplayRotation = new DisplayRotation(mWmService, this);
1006 mCloseToSquareMaxAspectRatio = mWmService.mContext.getResources().getFloat(
Tiger Huang86e6d072019-05-02 20:23:47 +08001007 com.android.internal.R.dimen.config_closeToSquareDisplayMaxAspectRatio);
Tiger Huang7c610aa2018-10-27 00:01:01 +08001008 if (isDefaultDisplay) {
1009 // The policy may be invoked right after here, so it requires the necessary default
1010 // fields of this display content.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001011 mWmService.mPolicy.setDefaultDisplay(this);
Tiger Huang7c610aa2018-10-27 00:01:01 +08001012 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001013 if (mWmService.mDisplayReady) {
Tiger Huang7c610aa2018-10-27 00:01:01 +08001014 mDisplayPolicy.onConfigurationChanged();
1015 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001016 if (mWmService.mSystemReady) {
Tiger Huang7c610aa2018-10-27 00:01:01 +08001017 mDisplayPolicy.systemReady();
1018 }
Tiger Huang43b8fc22019-04-26 11:49:29 +08001019 mWindowCornerRadius = mDisplayPolicy.getWindowCornerRadius();
Louis Chang677921f2019-12-06 16:44:24 +08001020 mDividerControllerLocked = new DockedStackDividerController(mWmService, this);
1021 mPinnedStackControllerLocked = new PinnedStackController(mWmService, this);
Tiger Huang7c610aa2018-10-27 00:01:01 +08001022
Chavi Weingarten6ef9cc62019-02-07 16:28:45 +00001023 final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(mSession)
1024 .setOpaque(true)
1025 .setContainerLayer();
Vadim Caen1812c762019-08-12 11:38:22 +02001026 mSurfaceControl = b.setName("Root").setContainerLayer().build();
Robert Carrb1579c82017-09-05 14:54:47 -07001027
Vadim Caen1812c762019-08-12 11:38:22 +02001028 getPendingTransaction()
1029 .setLayer(mSurfaceControl, 0)
1030 .setLayerStack(mSurfaceControl, mDisplayId)
chaviw8065f442019-11-18 13:20:58 -08001031 .show(mSurfaceControl);
Robert Carrf59b8dd2017-10-02 18:58:36 -07001032 getPendingTransaction().apply();
Robert Carrb1579c82017-09-05 14:54:47 -07001033
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001034 // These are the only direct children we should ever have and they are permanent.
chaviw8065f442019-11-18 13:20:58 -08001035 super.addChild(mWindowContainers, null);
1036 super.addChild(mOverlayContainers, null);
1037
1038 mWindowContainers.addChildren();
1039
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07001040 // Sets the display content for the children.
1041 onDisplayChanged(this);
Andrii Kulian367ff7f2017-01-25 19:45:34 -08001042
Garfield Tanfbd233a2019-12-26 12:39:25 -08001043 mInputMonitor = new InputMonitor(mWmService, this);
Jorim Jaggif96c90a2018-09-26 16:55:15 +02001044 mInsetsStateController = new InsetsStateController(this);
Jorim Jaggi28620472019-01-02 23:21:49 +01001045 mInsetsPolicy = new InsetsPolicy(mInsetsStateController, this);
Louis Chang677921f2019-12-06 16:44:24 +08001046
Garfield Tanfbd233a2019-12-26 12:39:25 -08001047 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Creating display=" + display);
Louis Chang677921f2019-12-06 16:44:24 +08001048
1049 mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this);
Bryce Leed1871262017-06-12 14:12:29 -07001050 }
1051
1052 boolean isReady() {
1053 // The display is ready when the system and the individual display are both ready.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001054 return mWmService.mDisplayReady && mDisplayReady;
Craig Mautner59c00972012-07-30 12:10:24 -07001055 }
1056
1057 int getDisplayId() {
1058 return mDisplayId;
1059 }
1060
Tiger Huang43b8fc22019-04-26 11:49:29 +08001061 float getWindowCornerRadius() {
1062 return mWindowCornerRadius;
1063 }
1064
Wale Ogunwale02319a62016-09-26 15:21:22 -07001065 WindowToken getWindowToken(IBinder binder) {
1066 return mTokenMap.get(binder);
1067 }
1068
Garfield Tane8d84ab2019-10-11 09:49:40 -07001069 ActivityRecord getActivityRecord(IBinder binder) {
Wale Ogunwale02319a62016-09-26 15:21:22 -07001070 final WindowToken token = getWindowToken(binder);
1071 if (token == null) {
1072 return null;
1073 }
Garfield Tane8d84ab2019-10-11 09:49:40 -07001074 return token.asActivityRecord();
Wale Ogunwale02319a62016-09-26 15:21:22 -07001075 }
1076
lumarkbde15132019-12-18 22:29:43 +08001077 void addWindowToken(IBinder binder, WindowToken token) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001078 final DisplayContent dc = mWmService.mRoot.getWindowTokenDisplay(token);
Wale Ogunwale02319a62016-09-26 15:21:22 -07001079 if (dc != null) {
1080 // We currently don't support adding a window token to the display if the display
1081 // already has the binder mapped to another token. If there is a use case for supporting
1082 // this moving forward we will either need to merge the WindowTokens some how or have
1083 // the binder map to a list of window tokens.
Wale Ogunwale2f569ed2017-05-08 09:15:49 -07001084 throw new IllegalArgumentException("Can't map token=" + token + " to display="
1085 + getName() + " already mapped to display=" + dc + " tokens=" + dc.mTokenMap);
Wale Ogunwale02319a62016-09-26 15:21:22 -07001086 }
Wale Ogunwale2f569ed2017-05-08 09:15:49 -07001087 if (binder == null) {
1088 throw new IllegalArgumentException("Can't map token=" + token + " to display="
1089 + getName() + " binder is null");
1090 }
1091 if (token == null) {
1092 throw new IllegalArgumentException("Can't map null token to display="
1093 + getName() + " binder=" + binder);
1094 }
1095
Wale Ogunwale02319a62016-09-26 15:21:22 -07001096 mTokenMap.put(binder, token);
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001097
Garfield Tane8d84ab2019-10-11 09:49:40 -07001098 if (token.asActivityRecord() == null) {
lumarkbde15132019-12-18 22:29:43 +08001099 // Set displayContent for non-app token to prevent same token will add twice after
1100 // onDisplayChanged.
1101 // TODO: Check if it's fine that super.onDisplayChanged of WindowToken
1102 // (WindowsContainer#onDisplayChanged) may skipped when token.mDisplayContent assigned.
1103 token.mDisplayContent = this;
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001104 // Add non-app token to container hierarchy on the display. App tokens are added through
1105 // the parent container managing them (e.g. Tasks).
Wale Ogunwale3a931692016-11-02 16:49:48 -07001106 switch (token.windowType) {
1107 case TYPE_WALLPAPER:
1108 mBelowAppWindowsContainers.addChild(token);
1109 break;
1110 case TYPE_INPUT_METHOD:
1111 case TYPE_INPUT_METHOD_DIALOG:
1112 mImeWindowsContainers.addChild(token);
1113 break;
chaviw8065f442019-11-18 13:20:58 -08001114 case TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY:
1115 mOverlayContainers.addChild(token);
1116 break;
Wale Ogunwale3a931692016-11-02 16:49:48 -07001117 default:
1118 mAboveAppWindowsContainers.addChild(token);
1119 break;
1120 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001121 }
Wale Ogunwale02319a62016-09-26 15:21:22 -07001122 }
1123
1124 WindowToken removeWindowToken(IBinder binder) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001125 final WindowToken token = mTokenMap.remove(binder);
Garfield Tane8d84ab2019-10-11 09:49:40 -07001126 if (token != null && token.asActivityRecord() == null) {
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -08001127 token.setExiting();
1128 }
1129 return token;
1130 }
1131
Evan Rosky22b6bbd2019-09-26 14:29:57 -07001132 SurfaceControl addShellRoot(@NonNull IWindow client, int windowType) {
1133 ShellRoot root = mShellRoots.get(windowType);
1134 if (root != null) {
1135 if (root.getClient() == client) {
1136 return root.getSurfaceControl();
1137 }
1138 root.clear();
1139 mShellRoots.remove(windowType);
1140 }
1141 root = new ShellRoot(client, this, windowType);
1142 SurfaceControl rootLeash = root.getSurfaceControl();
1143 if (rootLeash == null) {
1144 // Root didn't finish initializing, so don't add it.
1145 root.clear();
1146 return null;
1147 }
1148 mShellRoots.put(windowType, root);
1149 SurfaceControl out = new SurfaceControl();
1150 out.copyFrom(rootLeash);
1151 return out;
1152 }
1153
1154 void removeShellRoot(int windowType) {
1155 ShellRoot root = mShellRoots.get(windowType);
1156 if (root == null) {
1157 return;
1158 }
1159 root.clear();
1160 mShellRoots.remove(windowType);
1161 }
1162
Evan Rosky8d782e02019-10-14 15:43:53 -07001163 void setRemoteInsetsController(IDisplayWindowInsetsController controller) {
1164 if (mRemoteInsetsControlTarget != null) {
1165 mRemoteInsetsControlTarget.mRemoteInsetsController.asBinder().unlinkToDeath(
1166 mRemoteInsetsDeath, 0);
1167 mRemoteInsetsControlTarget = null;
1168 }
1169 if (controller != null) {
1170 try {
1171 controller.asBinder().linkToDeath(mRemoteInsetsDeath, 0);
1172 mRemoteInsetsControlTarget = new RemoteInsetsControlTarget(controller);
1173 } catch (RemoteException e) {
1174 return;
1175 }
1176 }
1177 }
1178
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -08001179 /** Changes the display the input window token is housed on to this one. */
1180 void reParentWindowToken(WindowToken token) {
1181 final DisplayContent prevDc = token.getDisplayContent();
1182 if (prevDc == this) {
1183 return;
1184 }
Riddle Hsu85bd04b2018-11-17 00:34:36 +08001185 if (prevDc != null) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07001186 if (prevDc.mTokenMap.remove(token.token) != null && token.asActivityRecord() == null) {
Riddle Hsu85bd04b2018-11-17 00:34:36 +08001187 // Removed the token from the map, but made sure it's not an app token before
1188 // removing from parent.
1189 token.getParent().removeChild(token);
1190 }
lumark280cb212019-09-09 09:47:22 +08001191 if (token.hasChild(prevDc.mLastFocus)) {
1192 // If the reparent window token contains previous display's last focus window, means
1193 // it will end up to gain window focus on the target display, so it should not be
1194 // notified that it lost focus from the previous display.
Riddle Hsu85bd04b2018-11-17 00:34:36 +08001195 prevDc.mLastFocus = null;
1196 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001197 }
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -08001198
1199 addWindowToken(token.token, token);
RyanlwLin925e8222019-08-30 15:08:48 +08001200
1201 if (mWmService.mAccessibilityController != null) {
1202 final int prevDisplayId = prevDc != null ? prevDc.getDisplayId() : INVALID_DISPLAY;
1203 mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(prevDisplayId,
1204 getDisplayId());
1205 }
Wale Ogunwale02319a62016-09-26 15:21:22 -07001206 }
1207
Wale Ogunwaleac2561e2016-11-01 15:43:46 -07001208 void removeAppToken(IBinder binder) {
1209 final WindowToken token = removeWindowToken(binder);
1210 if (token == null) {
1211 Slog.w(TAG_WM, "removeAppToken: Attempted to remove non-existing token: " + binder);
1212 return;
1213 }
1214
Garfield Tane8d84ab2019-10-11 09:49:40 -07001215 final ActivityRecord activity = token.asActivityRecord();
Wale Ogunwaleac2561e2016-11-01 15:43:46 -07001216
Garfield Tane8d84ab2019-10-11 09:49:40 -07001217 if (activity == null) {
Wale Ogunwaleac2561e2016-11-01 15:43:46 -07001218 Slog.w(TAG_WM, "Attempted to remove non-App token: " + binder + " token=" + token);
1219 return;
1220 }
1221
Garfield Tane8d84ab2019-10-11 09:49:40 -07001222 activity.onRemovedFromDisplay();
Wale Ogunwaleac2561e2016-11-01 15:43:46 -07001223 }
1224
Riddle Hsuad256a12018-07-18 16:11:30 +08001225 @Override
1226 public Display getDisplay() {
Craig Mautnerb47bbc32012-08-22 17:41:48 -07001227 return mDisplay;
1228 }
1229
Craig Mautner59c00972012-07-30 12:10:24 -07001230 DisplayInfo getDisplayInfo() {
1231 return mDisplayInfo;
1232 }
1233
Wale Ogunwale231b06e2015-09-16 12:03:09 -07001234 DisplayMetrics getDisplayMetrics() {
1235 return mDisplayMetrics;
1236 }
1237
Riddle Hsu5ce4bb32018-07-18 16:11:30 +08001238 DisplayPolicy getDisplayPolicy() {
1239 return mDisplayPolicy;
1240 }
1241
Riddle Hsuad256a12018-07-18 16:11:30 +08001242 @Override
1243 public DisplayRotation getDisplayRotation() {
1244 return mDisplayRotation;
1245 }
1246
Jorim Jaggi9b4f4202020-01-28 17:05:06 +01001247 void setInsetProvider(@InternalInsetsType int type, WindowState win,
1248 @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider){
1249 setInsetProvider(type, win, frameProvider, null /* imeFrameProvider */);
1250 }
1251
Jorim Jaggif96c90a2018-09-26 16:55:15 +02001252 /**
1253 * Marks a window as providing insets for the rest of the windows in the system.
1254 *
1255 * @param type The type of inset this window provides.
1256 * @param win The window.
1257 * @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
1258 * the window should be taken.
Jorim Jaggi9b4f4202020-01-28 17:05:06 +01001259 * @param imeFrameProvider Function to compute the frame when dispatching insets to the IME, or
1260 * {@code null} if the normal frame should be taken.
Jorim Jaggif96c90a2018-09-26 16:55:15 +02001261 */
Tiger Huang332793b2019-10-29 23:21:27 +08001262 void setInsetProvider(@InternalInsetsType int type, WindowState win,
Jorim Jaggi9b4f4202020-01-28 17:05:06 +01001263 @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider,
1264 @Nullable TriConsumer<DisplayFrames, WindowState, Rect> imeFrameProvider) {
1265 mInsetsStateController.getSourceProvider(type).setWindow(win, frameProvider,
1266 imeFrameProvider);
Jorim Jaggif96c90a2018-09-26 16:55:15 +02001267 }
1268
1269 InsetsStateController getInsetsStateController() {
1270 return mInsetsStateController;
1271 }
1272
Jorim Jaggi28620472019-01-02 23:21:49 +01001273 InsetsPolicy getInsetsPolicy() {
1274 return mInsetsPolicy;
1275 }
1276
Riddle Hsuccf09402019-08-13 00:33:06 +08001277 @Surface.Rotation
Andrii Kulian8ee72852017-03-10 10:36:45 -08001278 int getRotation() {
Riddle Hsuccf09402019-08-13 00:33:06 +08001279 return mDisplayRotation.getRotation();
Andrii Kulian8ee72852017-03-10 10:36:45 -08001280 }
1281
Riddle Hsuccf09402019-08-13 00:33:06 +08001282 @ScreenOrientation
Andrii Kulian8ee72852017-03-10 10:36:45 -08001283 int getLastOrientation() {
Riddle Hsuccf09402019-08-13 00:33:06 +08001284 return mDisplayRotation.getLastOrientation();
Andrii Kulian8ee72852017-03-10 10:36:45 -08001285 }
1286
Evan Rosky966759f2019-01-15 10:33:58 -08001287 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
1288 mAppTransitionController.registerRemoteAnimations(definition);
1289 }
1290
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07001291 void reconfigureDisplayLocked() {
1292 if (!isReady()) {
1293 return;
1294 }
1295 configureDisplayPolicy();
1296 setLayoutNeeded();
1297
Riddle Hsuccf09402019-08-13 00:33:06 +08001298 boolean configChanged = updateOrientation();
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07001299 final Configuration currentDisplayConfig = getConfiguration();
1300 mTmpConfiguration.setTo(currentDisplayConfig);
1301 computeScreenConfiguration(mTmpConfiguration);
1302 configChanged |= currentDisplayConfig.diff(mTmpConfiguration) != 0;
1303
1304 if (configChanged) {
1305 mWaitingForConfig = true;
1306 mWmService.startFreezingDisplayLocked(0 /* exitAnim */, 0 /* enterAnim */, this);
1307 sendNewConfiguration();
1308 }
1309
1310 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Riddle Hsu4e611772018-10-31 18:58:28 +08001311 }
1312
Shivam Agrawal1d3db652019-07-01 15:26:11 -07001313 void sendNewConfiguration() {
Louis Chang2453d062019-11-19 22:30:48 +08001314 if (!isReady()) {
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07001315 return;
1316 }
Evan Rosky69cace42019-09-20 16:28:13 -07001317 if (mDisplayRotation.isWaitingForRemoteRotation()) {
1318 return;
1319 }
Louis Chang677921f2019-12-06 16:44:24 +08001320 final boolean configUpdated = updateDisplayOverrideConfigurationLocked();
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07001321 if (configUpdated) {
1322 return;
1323 }
1324 // Something changed (E.g. device rotation), but no configuration update is needed.
1325 // E.g. changing device rotation by 180 degrees. Go ahead and perform surface placement to
1326 // unfreeze the display since we froze it when the rotation was updated in
1327 // DisplayContent#updateRotationUnchecked.
1328 if (mWaitingForConfig) {
1329 mWaitingForConfig = false;
1330 mWmService.mLastFinishedFreezeSource = "config-unchanged";
1331 setLayoutNeeded();
1332 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Shivam Agrawal1d3db652019-07-01 15:26:11 -07001333 }
1334 }
1335
Garfield Tan90b04282018-12-11 14:04:42 -08001336 @Override
1337 boolean onDescendantOrientationChanged(IBinder freezeDisplayToken,
1338 ConfigurationContainer requestingContainer) {
Riddle Hsuccf09402019-08-13 00:33:06 +08001339 final Configuration config = updateOrientation(
1340 getRequestedOverrideConfiguration(), freezeDisplayToken, false /* forceUpdate */);
Garfield Tan49dae102019-02-04 09:51:59 -08001341 // If display rotation class tells us that it doesn't consider app requested orientation,
1342 // this display won't rotate just because of an app changes its requested orientation. Thus
1343 // it indicates that this display chooses not to handle this request.
1344 final boolean handled = getDisplayRotation().respectAppRequestedOrientation();
Garfield Tan90b04282018-12-11 14:04:42 -08001345 if (config == null) {
1346 return handled;
1347 }
1348
1349 if (handled && requestingContainer instanceof ActivityRecord) {
1350 final ActivityRecord activityRecord = (ActivityRecord) requestingContainer;
Louis Chang677921f2019-12-06 16:44:24 +08001351 final boolean kept = updateDisplayOverrideConfigurationLocked(config, activityRecord,
1352 false /* deferResume */, null /* result */);
Garfield Tan90b04282018-12-11 14:04:42 -08001353 activityRecord.frozenBeforeDestroy = true;
1354 if (!kept) {
Louis Chang149d5c82019-12-30 09:47:39 +08001355 mRootWindowContainer.resumeFocusedStacksTopActivities();
Garfield Tan90b04282018-12-11 14:04:42 -08001356 }
1357 } else {
1358 // We have a new configuration to push so we need to update ATMS for now.
1359 // TODO: Clean up display configuration push between ATMS and WMS after unification.
Louis Chang677921f2019-12-06 16:44:24 +08001360 updateDisplayOverrideConfigurationLocked(config, null /* starting */,
1361 false /* deferResume */, null);
Garfield Tan90b04282018-12-11 14:04:42 -08001362 }
1363 return handled;
1364 }
1365
Garfield Tan49dae102019-02-04 09:51:59 -08001366 @Override
1367 boolean handlesOrientationChangeFromDescendant() {
1368 return getDisplayRotation().respectAppRequestedOrientation();
1369 }
1370
Riddle Hsu4e611772018-10-31 18:58:28 +08001371 /**
1372 * Determine the new desired orientation of this display.
1373 *
Riddle Hsuccf09402019-08-13 00:33:06 +08001374 * @see #getOrientation()
1375 * @return {@code true} if the orientation is changed and the caller should call
1376 * {@link #sendNewConfiguration} if the method returns {@code true}.
Riddle Hsu4e611772018-10-31 18:58:28 +08001377 */
Riddle Hsuccf09402019-08-13 00:33:06 +08001378 boolean updateOrientation() {
1379 return mDisplayRotation.updateOrientation(getOrientation(), false /* forceUpdate */);
Riddle Hsu4e611772018-10-31 18:58:28 +08001380 }
1381
Garfield Tan90b04282018-12-11 14:04:42 -08001382 /**
Riddle Hsuccf09402019-08-13 00:33:06 +08001383 * Update orientation of the display, returning a non-null new Configuration if it has
Garfield Tan90b04282018-12-11 14:04:42 -08001384 * changed from the current orientation. If a non-null configuration is returned, someone must
1385 * call {@link WindowManagerService#setNewDisplayOverrideConfiguration(Configuration,
1386 * DisplayContent)} to tell the window manager it can unfreeze the screen. This will typically
Riddle Hsuccf09402019-08-13 00:33:06 +08001387 * be done by calling {@link #sendNewConfiguration}.
1388 *
1389 * @param currentConfig The current requested override configuration (it is usually set from
1390 * the last {@link #sendNewConfiguration}) of the display. It is used to
1391 * check if the configuration container has the latest state.
1392 * @param freezeDisplayToken Freeze the app window token if the orientation is changed.
1393 * @param forceUpdate See {@link DisplayRotation#updateRotationUnchecked(boolean)}
Garfield Tan90b04282018-12-11 14:04:42 -08001394 */
Riddle Hsuccf09402019-08-13 00:33:06 +08001395 Configuration updateOrientation(Configuration currentConfig, IBinder freezeDisplayToken,
1396 boolean forceUpdate) {
Garfield Tan90b04282018-12-11 14:04:42 -08001397 if (!mDisplayReady) {
1398 return null;
1399 }
1400
1401 Configuration config = null;
Riddle Hsuccf09402019-08-13 00:33:06 +08001402 if (mDisplayRotation.updateOrientation(getOrientation(), forceUpdate)) {
Garfield Tan90b04282018-12-11 14:04:42 -08001403 // If we changed the orientation but mOrientationChangeComplete is already true,
1404 // we used seamless rotation, and we don't need to freeze the screen.
1405 if (freezeDisplayToken != null && !mWmService.mRoot.mOrientationChangeComplete) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07001406 final ActivityRecord activity = getActivityRecord(freezeDisplayToken);
1407 if (activity != null) {
1408 activity.startFreezingScreen();
Garfield Tan90b04282018-12-11 14:04:42 -08001409 }
1410 }
1411 config = new Configuration();
1412 computeScreenConfiguration(config);
1413 } else if (currentConfig != null) {
1414 // No obvious action we need to take, but if our current state mismatches the
1415 // activity manager's, update it, disregarding font scale, which should remain set
1416 // to the value of the previous configuration.
1417 // Here we're calling Configuration#unset() instead of setToDefaults() because we
1418 // need to keep override configs clear of non-empty values (e.g. fontSize).
1419 mTmpConfiguration.unset();
1420 mTmpConfiguration.updateFrom(currentConfig);
1421 computeScreenConfiguration(mTmpConfiguration);
1422 if (currentConfig.diff(mTmpConfiguration) != 0) {
1423 mWaitingForConfig = true;
1424 setLayoutNeeded();
Riddle Hsuccf09402019-08-13 00:33:06 +08001425 mDisplayRotation.prepareNormalRotationAnimation();
Garfield Tan90b04282018-12-11 14:04:42 -08001426 config = new Configuration(mTmpConfiguration);
1427 }
1428 }
1429
1430 return config;
1431 }
1432
Riddle Hsu5ce4bb32018-07-18 16:11:30 +08001433 /**
Andrii Kulian06d07d62017-03-14 11:11:47 -07001434 * Update rotation of the display.
1435 *
Andrii Kulian6cdcfe42018-05-23 17:59:43 -07001436 * @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
Riddle Hsuccf09402019-08-13 00:33:06 +08001437 * {@link #sendNewConfiguration} TO UNFREEZE THE SCREEN.
Andrii Kulian06d07d62017-03-14 11:11:47 -07001438 */
Robert Carrae606b42018-02-15 15:36:23 -08001439 boolean updateRotationUnchecked() {
Riddle Hsuccf09402019-08-13 00:33:06 +08001440 return mDisplayRotation.updateRotationUnchecked(false /* forceUpdate */);
Evan Roskye747c3e2018-10-30 20:06:41 -07001441 }
1442
1443 /**
1444 * Applies the rotation transaction. This must be called after {@link #updateRotationUnchecked}
1445 * (if it returned {@code true}) to actually finish the rotation.
1446 *
1447 * @param oldRotation the rotation we are coming from.
1448 * @param rotation the rotation to apply.
1449 */
1450 void applyRotationLocked(final int oldRotation, final int rotation) {
Riddle Hsuccf09402019-08-13 00:33:06 +08001451 mDisplayRotation.applyCurrentRotation(rotation);
1452 final boolean rotateSeamlessly = mDisplayRotation.isRotatingSeamlessly();
Riddle Hsuccf09402019-08-13 00:33:06 +08001453 final Transaction transaction = getPendingTransaction();
Vadim Caenb3715832019-08-13 17:06:38 +02001454 ScreenRotationAnimation screenRotationAnimation = rotateSeamlessly
1455 ? null : getRotationAnimation();
Andrii Kulian06d07d62017-03-14 11:11:47 -07001456 // We need to update our screen size information to match the new rotation. If the rotation
1457 // has actually changed then this method will return true and, according to the comment at
1458 // the top of the method, the caller is obligated to call computeNewConfigurationLocked().
1459 // By updating the Display info here it will be available to
1460 // #computeScreenConfiguration() later.
Tiger Huanga817b1f2019-05-09 20:04:17 +08001461 updateDisplayAndOrientation(getConfiguration().uiMode, null /* outConfig */);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001462
Robert Carrae606b42018-02-15 15:36:23 -08001463 // NOTE: We disable the rotation in the emulator because
1464 // it doesn't support hardware OpenGL emulation yet.
Vadim Caenba4fd6c2019-08-05 16:45:46 +02001465 if (screenRotationAnimation != null && screenRotationAnimation.hasScreenshot()) {
Riddle Hsuccf09402019-08-13 00:33:06 +08001466 screenRotationAnimation.setRotation(transaction, rotation);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001467 }
1468
Vishnu Nair83537a72018-07-19 21:27:48 -07001469 forAllWindows(w -> {
Riddle Hsuccf09402019-08-13 00:33:06 +08001470 w.seamlesslyRotateIfAllowed(transaction, oldRotation, rotation, rotateSeamlessly);
Vishnu Nair83537a72018-07-19 21:27:48 -07001471 }, true /* traverseTopToBottom */);
1472
Riddle Hsuccf09402019-08-13 00:33:06 +08001473 mWmService.mDisplayManagerInternal.performTraversal(transaction);
Robert Carrae606b42018-02-15 15:36:23 -08001474 scheduleAnimation();
1475
Andrii Kulian06d07d62017-03-14 11:11:47 -07001476 forAllWindows(w -> {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001477 if (w.mHasSurface && !rotateSeamlessly) {
Adrian Roosb125e0b2019-10-02 14:55:14 +02001478 ProtoLog.v(WM_DEBUG_ORIENTATION, "Set mOrientationChanging of %s", w);
Bryce Lee8c3cf382017-07-06 19:47:10 -07001479 w.setOrientationChanging(true);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001480 mWmService.mRoot.mOrientationChangeComplete = false;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001481 w.mLastFreezeDuration = 0;
1482 }
1483 w.mReportOrientationChanged = true;
1484 }, true /* traverseTopToBottom */);
1485
1486 if (rotateSeamlessly) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001487 mWmService.mH.sendNewMessageDelayed(WindowManagerService.H.SEAMLESS_ROTATION_TIMEOUT,
Riddle Hsu654a6f92018-07-13 22:59:36 +08001488 this, SEAMLESS_ROTATION_TIMEOUT_DURATION);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001489 }
1490
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001491 for (int i = mWmService.mRotationWatchers.size() - 1; i >= 0; i--) {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001492 final WindowManagerService.RotationWatcher rotationWatcher
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001493 = mWmService.mRotationWatchers.get(i);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001494 if (rotationWatcher.mDisplayId == mDisplayId) {
1495 try {
1496 rotationWatcher.mWatcher.onRotationChanged(rotation);
1497 } catch (RemoteException e) {
1498 // Ignore
1499 }
1500 }
1501 }
1502
Andrii Kulian06d07d62017-03-14 11:11:47 -07001503 // Announce rotation only if we will not animate as we already have the
1504 // windows in final state. Otherwise, we make this call at the rotation end.
Rhed Jao02655dc2018-10-30 20:44:52 +08001505 if (screenRotationAnimation == null && mWmService.mAccessibilityController != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001506 mWmService.mAccessibilityController.onRotationChangedLocked(this);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001507 }
Andrii Kulian06d07d62017-03-14 11:11:47 -07001508 }
1509
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00001510 void configureDisplayPolicy() {
Riddle Hsu5ce4bb32018-07-18 16:11:30 +08001511 final int width = mBaseDisplayWidth;
1512 final int height = mBaseDisplayHeight;
1513 final int shortSize;
1514 final int longSize;
1515 if (width > height) {
1516 shortSize = height;
1517 longSize = width;
1518 } else {
1519 shortSize = width;
1520 longSize = height;
1521 }
1522
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02001523 final int shortSizeDp = shortSize * DENSITY_DEFAULT / mBaseDisplayDensity;
1524 final int longSizeDp = longSize * DENSITY_DEFAULT / mBaseDisplayDensity;
Riddle Hsu5ce4bb32018-07-18 16:11:30 +08001525
Winson Chung4723b4e2019-03-25 16:49:36 -07001526 mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors();
Tiger Huang3d2b8982019-01-29 22:56:48 +08001527 mDisplayRotation.configure(width, height, shortSizeDp, longSizeDp);
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00001528
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001529 mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
1530 calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
Tiger Huang86e6d072019-05-02 20:23:47 +08001531
1532 // Not much of use to rotate the display for apps since it's close to square.
1533 mIgnoreRotationForApps = isNonDecorDisplayCloseToSquare(Surface.ROTATION_0, width, height);
1534 }
1535
1536 private boolean isNonDecorDisplayCloseToSquare(int rotation, int width, int height) {
1537 final DisplayCutout displayCutout =
1538 calculateDisplayCutoutForRotation(rotation).getDisplayCutout();
1539 final int uiMode = mWmService.mPolicy.getUiMode();
1540 final int w = mDisplayPolicy.getNonDecorDisplayWidth(
1541 width, height, rotation, uiMode, displayCutout);
1542 final int h = mDisplayPolicy.getNonDecorDisplayHeight(
1543 width, height, rotation, uiMode, displayCutout);
1544 final float aspectRatio = Math.max(w, h) / (float) Math.min(w, h);
1545 return aspectRatio <= mCloseToSquareMaxAspectRatio;
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00001546 }
1547
Andrii Kulian06d07d62017-03-14 11:11:47 -07001548 /**
1549 * Update {@link #mDisplayInfo} and other internal variables when display is rotated or config
1550 * changed.
1551 * Do not call if {@link WindowManagerService#mDisplayReady} == false.
1552 */
Tiger Huanga817b1f2019-05-09 20:04:17 +08001553 private DisplayInfo updateDisplayAndOrientation(int uiMode, Configuration outConfig) {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001554 // Use the effective "visual" dimensions based on current rotation
Riddle Hsuccf09402019-08-13 00:33:06 +08001555 final int rotation = getRotation();
1556 final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
Garfield Tan4bb83472019-01-16 14:37:04 -08001557 final int dw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
1558 final int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001559
1560 // Update application display metrics.
Riddle Hsuccf09402019-08-13 00:33:06 +08001561 final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001562 final DisplayCutout displayCutout = wmDisplayCutout.getDisplayCutout();
1563
Riddle Hsuccf09402019-08-13 00:33:06 +08001564 final int appWidth = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001565 displayCutout);
Riddle Hsuccf09402019-08-13 00:33:06 +08001566 final int appHeight = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001567 displayCutout);
Riddle Hsuccf09402019-08-13 00:33:06 +08001568 mDisplayInfo.rotation = rotation;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001569 mDisplayInfo.logicalWidth = dw;
1570 mDisplayInfo.logicalHeight = dh;
1571 mDisplayInfo.logicalDensityDpi = mBaseDisplayDensity;
1572 mDisplayInfo.appWidth = appWidth;
1573 mDisplayInfo.appHeight = appHeight;
1574 if (isDefaultDisplay) {
1575 mDisplayInfo.getLogicalMetrics(mRealDisplayMetrics,
1576 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
1577 }
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001578 mDisplayInfo.displayCutout = displayCutout.isEmpty() ? null : displayCutout;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001579 mDisplayInfo.getAppMetrics(mDisplayMetrics);
1580 if (mDisplayScalingDisabled) {
1581 mDisplayInfo.flags |= Display.FLAG_SCALING_DISABLED;
1582 } else {
1583 mDisplayInfo.flags &= ~Display.FLAG_SCALING_DISABLED;
1584 }
1585
Tiger Huanga817b1f2019-05-09 20:04:17 +08001586 computeSizeRangesAndScreenLayout(mDisplayInfo, rotated, uiMode, dw, dh,
1587 mDisplayMetrics.density, outConfig);
1588
Andrii Kulianf0379de2018-03-14 16:24:07 -07001589 // We usually set the override info in DisplayManager so that we get consistent display
1590 // metrics values when displays are changing and don't send out new values until WM is aware
1591 // of them. However, we don't do this for displays that serve as containers for ActivityView
1592 // because we don't want letter-/pillar-boxing during resize.
1593 final DisplayInfo overrideDisplayInfo = mShouldOverrideDisplayConfiguration
1594 ? mDisplayInfo : null;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001595 mWmService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(mDisplayId,
Andrii Kulianf0379de2018-03-14 16:24:07 -07001596 overrideDisplayInfo);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001597
1598 mBaseDisplayRect.set(0, 0, dw, dh);
1599
1600 if (isDefaultDisplay) {
1601 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(mDisplayMetrics,
1602 mCompatDisplayMetrics);
1603 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001604
Andrii Kulian06d07d62017-03-14 11:11:47 -07001605 return mDisplayInfo;
1606 }
1607
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001608 WmDisplayCutout calculateDisplayCutoutForRotation(int rotation) {
Adrian Roos2aa0fcd2018-02-19 18:07:49 +01001609 return mDisplayCutoutCache.getOrCompute(mInitialDisplayCutout, rotation);
1610 }
1611
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001612 private WmDisplayCutout calculateDisplayCutoutForRotationUncached(
Adrian Roos2aa0fcd2018-02-19 18:07:49 +01001613 DisplayCutout cutout, int rotation) {
Adrian Roos24264212018-02-19 16:26:15 +01001614 if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) {
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001615 return WmDisplayCutout.NO_CUTOUT;
Adrian Roos1cf585052018-01-03 18:43:27 +01001616 }
Adrian Roos11c25582018-02-19 18:06:36 +01001617 if (rotation == ROTATION_0) {
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001618 return WmDisplayCutout.computeSafeInsets(
1619 cutout, mInitialDisplayWidth, mInitialDisplayHeight);
Adrian Roos24264212018-02-19 16:26:15 +01001620 }
Adrian Roosbed538e2018-02-21 17:50:07 +01001621 final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
Issei Suzuki43190bd2018-08-20 17:28:41 +02001622 final Rect[] newBounds = mRotationUtil.getRotatedBounds(
1623 WmDisplayCutout.computeSafeInsets(
Jorim Jaggi60640512018-06-29 01:14:31 +02001624 cutout, mInitialDisplayWidth, mInitialDisplayHeight)
Issei Suzuki43190bd2018-08-20 17:28:41 +02001625 .getDisplayCutout().getBoundingRectsAll(),
1626 rotation, mInitialDisplayWidth, mInitialDisplayHeight);
1627 return WmDisplayCutout.computeSafeInsets(DisplayCutout.fromBounds(newBounds),
Adrian Roos24264212018-02-19 16:26:15 +01001628 rotated ? mInitialDisplayHeight : mInitialDisplayWidth,
1629 rotated ? mInitialDisplayWidth : mInitialDisplayHeight);
Adrian Roos1cf585052018-01-03 18:43:27 +01001630 }
1631
Andrii Kulian06d07d62017-03-14 11:11:47 -07001632 /**
1633 * Compute display configuration based on display properties and policy settings.
1634 * Do not call if mDisplayReady == false.
1635 */
1636 void computeScreenConfiguration(Configuration config) {
Tiger Huanga817b1f2019-05-09 20:04:17 +08001637 final DisplayInfo displayInfo = updateDisplayAndOrientation(config.uiMode, config);
Evan Roskye747c3e2018-10-30 20:06:41 -07001638 calculateBounds(displayInfo, mTmpBounds);
1639 config.windowConfiguration.setBounds(mTmpBounds);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001640
1641 final int dw = displayInfo.logicalWidth;
1642 final int dh = displayInfo.logicalHeight;
Wale Ogunwale687b4272017-07-27 02:56:23 -07001643 config.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
Garfield Tane0846042018-07-26 13:42:04 -07001644 config.windowConfiguration.setWindowingMode(getWindowingMode());
Yunfan Chen7daa6ac2018-11-29 18:16:44 -08001645 config.windowConfiguration.setDisplayWindowingMode(getWindowingMode());
Evan Roskye747c3e2018-10-30 20:06:41 -07001646 config.windowConfiguration.setRotation(displayInfo.rotation);
Bryce Leec1f2f2a2017-06-22 15:29:42 -07001647
Adrian Roos11c25582018-02-19 18:06:36 +01001648 final float density = mDisplayMetrics.density;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001649 config.screenWidthDp =
Tiger Huang7c610aa2018-10-27 00:01:01 +08001650 (int)(mDisplayPolicy.getConfigDisplayWidth(dw, dh, displayInfo.rotation,
1651 config.uiMode, displayInfo.displayCutout) / density);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001652 config.screenHeightDp =
Tiger Huang7c610aa2018-10-27 00:01:01 +08001653 (int)(mDisplayPolicy.getConfigDisplayHeight(dw, dh, displayInfo.rotation,
1654 config.uiMode, displayInfo.displayCutout) / density);
Bryce Lee7566d762017-03-30 09:34:15 -07001655
Tiger Huang7c610aa2018-10-27 00:01:01 +08001656 mDisplayPolicy.getNonDecorInsetsLw(displayInfo.rotation, dw, dh,
Adrian Roos11c25582018-02-19 18:06:36 +01001657 displayInfo.displayCutout, mTmpRect);
Bryce Lee7566d762017-03-30 09:34:15 -07001658 final int leftInset = mTmpRect.left;
1659 final int topInset = mTmpRect.top;
1660 // appBounds at the root level should mirror the app screen size.
Wale Ogunwale822e5122017-07-26 06:02:24 -07001661 config.windowConfiguration.setAppBounds(leftInset /* left */, topInset /* top */,
1662 leftInset + displayInfo.appWidth /* right */,
1663 topInset + displayInfo.appHeight /* bottom */);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001664 final boolean rotated = (displayInfo.rotation == Surface.ROTATION_90
1665 || displayInfo.rotation == Surface.ROTATION_270);
1666
Andrii Kulian06d07d62017-03-14 11:11:47 -07001667 config.screenLayout = (config.screenLayout & ~Configuration.SCREENLAYOUT_ROUND_MASK)
1668 | ((displayInfo.flags & Display.FLAG_ROUND) != 0
1669 ? Configuration.SCREENLAYOUT_ROUND_YES
1670 : Configuration.SCREENLAYOUT_ROUND_NO);
1671
1672 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
1673 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
1674 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, config.uiMode, dw,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001675 dh, displayInfo.displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001676 config.densityDpi = displayInfo.logicalDensityDpi;
1677
1678 config.colorMode =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001679 ((displayInfo.isHdr() && mWmService.hasHdrSupport())
Andrii Kulian06d07d62017-03-14 11:11:47 -07001680 ? Configuration.COLOR_MODE_HDR_YES
1681 : Configuration.COLOR_MODE_HDR_NO)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001682 | (displayInfo.isWideColorGamut() && mWmService.hasWideColorGamutSupport()
Andrii Kulian06d07d62017-03-14 11:11:47 -07001683 ? Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_YES
1684 : Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_NO);
1685
1686 // Update the configuration based on available input devices, lid switch,
1687 // and platform configuration.
1688 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
1689 config.keyboard = Configuration.KEYBOARD_NOKEYS;
1690 config.navigation = Configuration.NAVIGATION_NONAV;
1691
1692 int keyboardPresence = 0;
1693 int navigationPresence = 0;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001694 final InputDevice[] devices = mWmService.mInputManager.getInputDevices();
Andrii Kulian06d07d62017-03-14 11:11:47 -07001695 final int len = devices != null ? devices.length : 0;
1696 for (int i = 0; i < len; i++) {
1697 InputDevice device = devices[i];
Arthur Hung82bbfc32018-11-29 20:24:51 +08001698 // Ignore virtual input device.
1699 if (device.isVirtual()) {
1700 continue;
1701 }
Andrii Kulian06d07d62017-03-14 11:11:47 -07001702
Arthur Hung82bbfc32018-11-29 20:24:51 +08001703 // Check if input device can dispatch events to current display.
1704 // If display type is virtual, will follow the default display.
1705 if (!mWmService.mInputManager.canDispatchToDisplay(device.getId(),
1706 displayInfo.type == Display.TYPE_VIRTUAL ? DEFAULT_DISPLAY : mDisplayId)) {
1707 continue;
1708 }
Andrii Kulian06d07d62017-03-14 11:11:47 -07001709
Arthur Hung82bbfc32018-11-29 20:24:51 +08001710 final int sources = device.getSources();
1711 final int presenceFlag = device.isExternal()
1712 ? WindowManagerPolicy.PRESENCE_EXTERNAL : WindowManagerPolicy.PRESENCE_INTERNAL;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001713
Arthur Hung82bbfc32018-11-29 20:24:51 +08001714 if (mWmService.mIsTouchDevice) {
1715 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) == InputDevice.SOURCE_TOUCHSCREEN) {
1716 config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001717 }
Arthur Hung82bbfc32018-11-29 20:24:51 +08001718 } else {
1719 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
1720 }
1721
1722 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
1723 config.navigation = Configuration.NAVIGATION_TRACKBALL;
1724 navigationPresence |= presenceFlag;
1725 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
1726 && config.navigation == Configuration.NAVIGATION_NONAV) {
1727 config.navigation = Configuration.NAVIGATION_DPAD;
1728 navigationPresence |= presenceFlag;
1729 }
1730
1731 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
1732 config.keyboard = Configuration.KEYBOARD_QWERTY;
1733 keyboardPresence |= presenceFlag;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001734 }
1735 }
1736
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001737 if (config.navigation == Configuration.NAVIGATION_NONAV && mWmService.mHasPermanentDpad) {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001738 config.navigation = Configuration.NAVIGATION_DPAD;
1739 navigationPresence |= WindowManagerPolicy.PRESENCE_INTERNAL;
1740 }
1741
1742 // Determine whether a hard keyboard is available and enabled.
1743 // TODO(multi-display): Should the hardware keyboard be tied to a display or to a device?
1744 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001745 if (hardKeyboardAvailable != mWmService.mHardKeyboardAvailable) {
1746 mWmService.mHardKeyboardAvailable = hardKeyboardAvailable;
1747 mWmService.mH.removeMessages(REPORT_HARD_KEYBOARD_STATUS_CHANGE);
1748 mWmService.mH.sendEmptyMessage(REPORT_HARD_KEYBOARD_STATUS_CHANGE);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001749 }
1750
Winson Chung4723b4e2019-03-25 16:49:36 -07001751 mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors();
Tiger Huang7c610aa2018-10-27 00:01:01 +08001752
Andrii Kulian06d07d62017-03-14 11:11:47 -07001753 // Let the policy update hidden states.
1754 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
1755 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
1756 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001757 mWmService.mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001758 }
1759
1760 private int computeCompatSmallestWidth(boolean rotated, int uiMode, int dw, int dh,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001761 DisplayCutout displayCutout) {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001762 mTmpDisplayMetrics.setTo(mDisplayMetrics);
1763 final DisplayMetrics tmpDm = mTmpDisplayMetrics;
1764 final int unrotDw, unrotDh;
1765 if (rotated) {
1766 unrotDw = dh;
1767 unrotDh = dw;
1768 } else {
1769 unrotDw = dw;
1770 unrotDh = dh;
1771 }
1772 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, unrotDh,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001773 displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001774 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, unrotDw,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001775 displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001776 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, unrotDh,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001777 displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001778 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, unrotDw,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001779 displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001780 return sw;
1781 }
1782
1783 private int reduceCompatConfigWidthSize(int curSize, int rotation, int uiMode,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001784 DisplayMetrics dm, int dw, int dh, DisplayCutout displayCutout) {
1785 dm.noncompatWidthPixels = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
1786 displayCutout);
1787 dm.noncompatHeightPixels = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
1788 displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001789 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
1790 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
1791 if (curSize == 0 || size < curSize) {
1792 curSize = size;
1793 }
1794 return curSize;
1795 }
1796
Tiger Huang7c610aa2018-10-27 00:01:01 +08001797 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
1798 int uiMode, int dw, int dh, float density, Configuration outConfig) {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001799
1800 // We need to determine the smallest width that will occur under normal
1801 // operation. To this, start with the base screen size and compute the
1802 // width under the different possible rotations. We need to un-rotate
1803 // the current screen dimensions before doing this.
1804 int unrotDw, unrotDh;
1805 if (rotated) {
1806 unrotDw = dh;
1807 unrotDh = dw;
1808 } else {
1809 unrotDw = dw;
1810 unrotDh = dh;
1811 }
1812 displayInfo.smallestNominalAppWidth = 1<<30;
1813 displayInfo.smallestNominalAppHeight = 1<<30;
1814 displayInfo.largestNominalAppWidth = 0;
1815 displayInfo.largestNominalAppHeight = 0;
Tiger Huang7c610aa2018-10-27 00:01:01 +08001816 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, uiMode, unrotDw, unrotDh);
1817 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, uiMode, unrotDh, unrotDw);
1818 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, uiMode, unrotDw, unrotDh);
1819 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, uiMode, unrotDh, unrotDw);
Tiger Huanga817b1f2019-05-09 20:04:17 +08001820
1821 if (outConfig == null) {
1822 return;
1823 }
Andrii Kulian06d07d62017-03-14 11:11:47 -07001824 int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
1825 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001826 displayInfo.displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001827 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001828 displayInfo.displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001829 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001830 displayInfo.displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001831 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001832 displayInfo.displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001833 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
1834 outConfig.screenLayout = sl;
1835 }
1836
1837 private int reduceConfigLayout(int curLayout, int rotation, float density, int dw, int dh,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001838 int uiMode, DisplayCutout displayCutout) {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001839 // Get the app screen size at this rotation.
Tiger Huang7c610aa2018-10-27 00:01:01 +08001840 int w = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayCutout);
1841 int h = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001842
1843 // Compute the screen layout size class for this rotation.
1844 int longSize = w;
1845 int shortSize = h;
1846 if (longSize < shortSize) {
1847 int tmp = longSize;
1848 longSize = shortSize;
1849 shortSize = tmp;
1850 }
1851 longSize = (int)(longSize/density);
1852 shortSize = (int)(shortSize/density);
1853 return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
1854 }
1855
Tiger Huang7c610aa2018-10-27 00:01:01 +08001856 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation,
Andrii Kulian06d07d62017-03-14 11:11:47 -07001857 int uiMode, int dw, int dh) {
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001858 final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(
1859 rotation).getDisplayCutout();
Tiger Huang7c610aa2018-10-27 00:01:01 +08001860 final int width = mDisplayPolicy.getConfigDisplayWidth(dw, dh, rotation, uiMode,
1861 displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001862 if (width < displayInfo.smallestNominalAppWidth) {
1863 displayInfo.smallestNominalAppWidth = width;
1864 }
1865 if (width > displayInfo.largestNominalAppWidth) {
1866 displayInfo.largestNominalAppWidth = width;
1867 }
Tiger Huang7c610aa2018-10-27 00:01:01 +08001868 final int height = mDisplayPolicy.getConfigDisplayHeight(dw, dh, rotation, uiMode,
1869 displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001870 if (height < displayInfo.smallestNominalAppHeight) {
1871 displayInfo.smallestNominalAppHeight = height;
1872 }
1873 if (height > displayInfo.largestNominalAppHeight) {
1874 displayInfo.largestNominalAppHeight = height;
1875 }
1876 }
1877
Riddle Hsua4d6fa22018-08-11 00:50:39 +08001878 /**
1879 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
1880 * theme attribute) on devices that feature a physical options menu key attempt to position
1881 * their menu panel window along the edge of the screen nearest the physical menu key.
1882 * This lowers the travel distance between invoking the menu panel and selecting
1883 * a menu option.
1884 *
1885 * This method helps control where that menu is placed. Its current implementation makes
1886 * assumptions about the menu key and its relationship to the screen based on whether
1887 * the device's natural orientation is portrait (width < height) or landscape.
1888 *
1889 * The menu key is assumed to be located along the bottom edge of natural-portrait
1890 * devices and along the right edge of natural-landscape devices. If these assumptions
1891 * do not hold for the target device, this method should be changed to reflect that.
1892 *
1893 * @return A {@link Gravity} value for placing the options menu window.
1894 */
1895 int getPreferredOptionsPanelGravity() {
1896 final int rotation = getRotation();
1897 if (mInitialDisplayWidth < mInitialDisplayHeight) {
1898 // On devices with a natural orientation of portrait.
1899 switch (rotation) {
1900 default:
1901 case Surface.ROTATION_0:
1902 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
1903 case Surface.ROTATION_90:
1904 return Gravity.RIGHT | Gravity.BOTTOM;
1905 case Surface.ROTATION_180:
1906 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
1907 case Surface.ROTATION_270:
1908 return Gravity.START | Gravity.BOTTOM;
1909 }
1910 }
1911
1912 // On devices with a natural orientation of landscape.
1913 switch (rotation) {
1914 default:
1915 case Surface.ROTATION_0:
1916 return Gravity.RIGHT | Gravity.BOTTOM;
1917 case Surface.ROTATION_90:
1918 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
1919 case Surface.ROTATION_180:
1920 return Gravity.START | Gravity.BOTTOM;
1921 case Surface.ROTATION_270:
1922 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
1923 }
1924 }
1925
Jorim Jaggi61f39a72015-10-29 16:54:18 +01001926 DockedStackDividerController getDockedDividerController() {
1927 return mDividerControllerLocked;
1928 }
1929
Winson Chung655332c2016-10-31 13:14:28 -07001930 PinnedStackController getPinnedStackController() {
1931 return mPinnedStackControllerLocked;
1932 }
1933
Jeff Browna506a6e2013-06-04 00:02:38 -07001934 /**
1935 * Returns true if the specified UID has access to this display.
1936 */
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001937 boolean hasAccess(int uid) {
Jeff Browna506a6e2013-06-04 00:02:38 -07001938 return mDisplay.hasAccess(uid);
1939 }
1940
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001941 boolean isPrivate() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001942 return (mDisplay.getFlags() & FLAG_PRIVATE) != 0;
keunyounga446bf02013-06-21 19:07:57 -07001943 }
1944
Wale Ogunwale734b8962020-01-21 12:17:42 -08001945 ActivityStack getRootHomeTask() {
1946 return mTaskContainers.getRootHomeTask();
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -07001947 }
1948
Wale Ogunwale734b8962020-01-21 12:17:42 -08001949 /** @return The primary split-screen task, and {@code null} otherwise. */
1950 ActivityStack getRootSplitScreenPrimaryTask() {
1951 return mTaskContainers.getRootSplitScreenPrimaryTask();
Louis Chang2453d062019-11-19 22:30:48 +08001952 }
1953
Wale Ogunwale734b8962020-01-21 12:17:42 -08001954 boolean hasSplitScreenPrimaryTask() {
1955 return getRootSplitScreenPrimaryTask() != null;
Wale Ogunwale61911492017-10-11 08:50:50 -07001956 }
1957
Wale Ogunwale734b8962020-01-21 12:17:42 -08001958 ActivityStack getRootPinnedTask() {
1959 return mTaskContainers.getRootPinnedTask();
Robert Carr9785cf32018-04-25 15:06:07 -07001960 }
1961
Wale Ogunwale734b8962020-01-21 12:17:42 -08001962 boolean hasPinnedTask() {
1963 return mTaskContainers.getRootPinnedTask() != null;
Chong Zhangd9d35bd2016-08-04 17:55:21 -07001964 }
1965
Wale Ogunwaleb62139d2017-09-20 15:37:35 -07001966 /**
1967 * Returns the topmost stack on the display that is compatible with the input windowing mode.
1968 * Null is no compatible stack on the display.
1969 */
Louis Changdc077272019-11-12 16:52:56 +08001970 ActivityStack getTopStackInWindowingMode(int windowingMode) {
Wale Ogunwaleb62139d2017-09-20 15:37:35 -07001971 return getStack(windowingMode, ACTIVITY_TYPE_UNDEFINED);
1972 }
1973
1974 /**
1975 * Returns the topmost stack on the display that is compatible with the input windowing mode and
1976 * activity type. Null is no compatible stack on the display.
1977 */
Louis Changdc077272019-11-12 16:52:56 +08001978 ActivityStack getStack(int windowingMode, int activityType) {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08001979 return mTaskContainers.getStack(windowingMode, activityType);
Wale Ogunwaleb62139d2017-09-20 15:37:35 -07001980 }
1981
Louis Chang2453d062019-11-19 22:30:48 +08001982 protected int getStackCount() {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08001983 return mTaskContainers.mChildren.size();
Louis Chang2453d062019-11-19 22:30:48 +08001984 }
1985
1986 protected ActivityStack getStackAt(int index) {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08001987 return mTaskContainers.mChildren.get(index);
Louis Chang2453d062019-11-19 22:30:48 +08001988 }
1989
1990 int getIndexOf(ActivityStack stack) {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08001991 return mTaskContainers.getIndexOf(stack);
Louis Chang2453d062019-11-19 22:30:48 +08001992 }
1993
1994 void removeStack(ActivityStack stack) {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08001995 mTaskContainers.removeChild(stack);
Louis Chang2453d062019-11-19 22:30:48 +08001996 }
1997
Bryce Lee48f4b572017-04-10 10:54:15 -07001998 @VisibleForTesting
Louis Changdc077272019-11-12 16:52:56 +08001999 WindowList<ActivityStack> getStacks() {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002000 return mTaskContainers.mChildren;
Kazuki Takise148d00a2018-05-31 15:32:19 +09002001 }
2002
2003 @VisibleForTesting
Louis Changdc077272019-11-12 16:52:56 +08002004 ActivityStack getTopStack() {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002005 return mTaskContainers.getTopStack();
Bryce Lee48f4b572017-04-10 10:54:15 -07002006 }
2007
Winson Chunge2d72172018-01-25 17:46:20 +00002008 ArrayList<Task> getVisibleTasks() {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002009 return mTaskContainers.getVisibleTasks();
Winson Chunge2d72172018-01-25 17:46:20 +00002010 }
2011
Adrian Roosefa40702020-01-08 17:58:45 +01002012 SurfaceControl getSplitScreenDividerAnchor() {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002013 return mTaskContainers.getSplitScreenDividerAnchor();
Adrian Roosefa40702020-01-08 17:58:45 +01002014 }
2015
Louis Changdc077272019-11-12 16:52:56 +08002016 void onStackWindowingModeChanged(ActivityStack stack) {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002017 mTaskContainers.onStackWindowingModeChanged(stack);
Bryce Lee48f4b572017-04-10 10:54:15 -07002018 }
2019
Riddle Hsu7f704b52019-12-10 23:10:45 +08002020 /**
2021 * The value is only valid in the scope {@link #onRequestedOverrideConfigurationChanged} of the
2022 * changing hierarchy and the {@link #onConfigurationChanged} of its children.
2023 *
2024 * @return The current changes ({@link android.content.pm.ActivityInfo.Config}) of requested
2025 * override configuration.
2026 */
2027 int getCurrentOverrideConfigurationChanges() {
2028 return mCurrentOverrideConfigurationChanges;
2029 }
2030
2031 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -07002032 public void onConfigurationChanged(Configuration newParentConfig) {
Louis Chang677921f2019-12-06 16:44:24 +08002033 // update resources before cascade so that docked/pinned stacks use the correct info
2034 preOnConfigurationChanged();
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -05002035 final int lastOrientation = getConfiguration().orientation;
Andrii Kulian441e4492016-09-29 15:25:00 -07002036 super.onConfigurationChanged(newParentConfig);
Tiger Huang7c610aa2018-10-27 00:01:01 +08002037 if (mDisplayPolicy != null) {
2038 mDisplayPolicy.onConfigurationChanged();
2039 }
Andrii Kulian441e4492016-09-29 15:25:00 -07002040
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -05002041 if (lastOrientation != getConfiguration().orientation) {
2042 getMetricsLogger().write(
2043 new LogMaker(MetricsEvent.ACTION_PHONE_ORIENTATION_CHANGED)
chaviw8065f442019-11-18 13:20:58 -08002044 .setSubtype(getConfiguration().orientation)
2045 .addTaggedData(MetricsEvent.FIELD_DISPLAY_ID, getDisplayId()));
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -05002046 }
2047
Evan Roskye747c3e2018-10-30 20:06:41 -07002048 // If there was no pinned stack, we still need to notify the controller of the display info
2049 // update as a result of the config change.
Wale Ogunwale734b8962020-01-21 12:17:42 -08002050 if (mPinnedStackControllerLocked != null && !hasPinnedTask()) {
Evan Roskye747c3e2018-10-30 20:06:41 -07002051 mPinnedStackControllerLocked.onDisplayInfoChanged(getDisplayInfo());
2052 }
Evan Roskye747c3e2018-10-30 20:06:41 -07002053 }
2054
2055 /**
2056 * Updates the resources used by docked/pinned controllers. This needs to be called at the
2057 * beginning of a configuration update cascade since the metrics from these resources are used
Louis Chang677921f2019-12-06 16:44:24 +08002058 * for bounds calculations.
Evan Roskye747c3e2018-10-30 20:06:41 -07002059 */
2060 void preOnConfigurationChanged() {
Bryce Leef3c6a472017-11-14 14:53:06 -08002061 final DockedStackDividerController dividerController = getDockedDividerController();
2062
2063 if (dividerController != null) {
2064 getDockedDividerController().onConfigurationChanged();
2065 }
2066
2067 final PinnedStackController pinnedStackController = getPinnedStackController();
2068
2069 if (pinnedStackController != null) {
2070 getPinnedStackController().onConfigurationChanged();
2071 }
Andrii Kulian441e4492016-09-29 15:25:00 -07002072 }
Andrii Kulian3a507b52016-09-19 18:14:12 -07002073
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07002074 @Override
2075 boolean fillsParent() {
2076 return true;
2077 }
2078
2079 @Override
2080 boolean isVisible() {
2081 return true;
2082 }
2083
2084 @Override
Wale Ogunwale9adfe572016-09-08 20:43:58 -07002085 void onAppTransitionDone() {
Wale Ogunwale10124582016-09-15 20:25:50 -07002086 super.onAppTransitionDone();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002087 mWmService.mWindowsChanged = true;
Wale Ogunwale9adfe572016-09-08 20:43:58 -07002088 }
2089
Yunfan Chen7daa6ac2018-11-29 18:16:44 -08002090 @Override
2091 public void setWindowingMode(int windowingMode) {
2092 super.setWindowingMode(windowingMode);
2093 super.setDisplayWindowingMode(windowingMode);
2094 }
2095
2096 @Override
2097 void setDisplayWindowingMode(int windowingMode) {
2098 setWindowingMode(windowingMode);
2099 }
2100
Wale Ogunwale3c1170d2016-12-02 14:44:52 -08002101 boolean forAllImeWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
Adrian Roosefa40702020-01-08 17:58:45 +01002102 return mImeWindowsContainers.forAllWindowForce(callback, traverseTopToBottom);
Wale Ogunwale3c1170d2016-12-02 14:44:52 -08002103 }
2104
Riddle Hsuccf09402019-08-13 00:33:06 +08002105 /**
2106 * In the general case, the orientation is computed from the above app windows first. If none of
2107 * the above app windows specify orientation, the orientation is computed from the child window
2108 * container, e.g. {@link AppWindowToken#getOrientation(int)}.
2109 */
Vadim Caenfc14c662020-01-20 16:00:31 +01002110 @ScreenOrientation
Wale Ogunwale399c8692017-05-08 14:22:42 -07002111 @Override
2112 int getOrientation() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002113 final WindowManagerPolicy policy = mWmService.mPolicy;
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07002114
Tiger Huang86e6d072019-05-02 20:23:47 +08002115 if (mIgnoreRotationForApps) {
2116 return SCREEN_ORIENTATION_USER;
2117 }
2118
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002119 if (mWmService.mDisplayFrozen) {
Adrian Roos0384f122020-01-10 19:39:43 +01002120 if (policy.isKeyguardLocked()) {
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07002121 // Use the last orientation the while the display is frozen with the keyguard
2122 // locked. This could be the keyguard forced orientation or from a SHOW_WHEN_LOCKED
2123 // window. We don't want to check the show when locked window directly though as
2124 // things aren't stable while the display is frozen, for example the window could be
2125 // momentarily unavailable due to activity relaunch.
Adrian Roosb125e0b2019-10-02 14:55:14 +02002126 ProtoLog.v(WM_DEBUG_ORIENTATION,
2127 "Display id=%d is frozen while keyguard locked, return %d",
chaviw8065f442019-11-18 13:20:58 -08002128 mDisplayId, getLastOrientation());
Riddle Hsuccf09402019-08-13 00:33:06 +08002129 return getLastOrientation();
Wale Ogunwale51362492016-09-08 17:49:17 -07002130 }
Adrian Roos0384f122020-01-10 19:39:43 +01002131 }
2132 final int orientation = mAboveAppWindowsContainers.getOrientation();
2133 if (orientation != SCREEN_ORIENTATION_UNSET) {
2134 return orientation;
Wale Ogunwale51362492016-09-08 17:49:17 -07002135 }
2136
Wale Ogunwale399c8692017-05-08 14:22:42 -07002137 // Top system windows are not requesting an orientation. Start searching from apps.
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002138 return mTaskContainers.getOrientation();
Wale Ogunwale51362492016-09-08 17:49:17 -07002139 }
2140
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002141 void updateDisplayInfo() {
Andrii Kuliancd097992017-03-23 18:31:59 -07002142 // Check if display metrics changed and update base values if needed.
2143 updateBaseDisplayMetricsIfNeeded();
2144
Craig Mautner722285e2012-09-07 13:55:58 -07002145 mDisplay.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -07002146 mDisplay.getMetrics(mDisplayMetrics);
Andrii Kuliancd097992017-03-23 18:31:59 -07002147
Garfield Tan2f145f22018-11-01 15:27:03 -07002148 onDisplayChanged(this);
Craig Mautner722285e2012-09-07 13:55:58 -07002149 }
2150
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02002151 @Override
2152 void onDisplayChanged(DisplayContent dc) {
2153 super.onDisplayChanged(dc);
2154 updateSystemGestureExclusionLimit();
2155 }
2156
2157 void updateSystemGestureExclusionLimit() {
Adrian Roos1c2e9a12019-08-20 18:23:47 +02002158 mSystemGestureExclusionLimit = mWmService.mConstants.mSystemGestureExclusionLimitDp
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02002159 * mDisplayMetrics.densityDpi / DENSITY_DEFAULT;
2160 updateSystemGestureExclusion();
2161 }
2162
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -07002163 void initializeDisplayBaseInfo() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002164 final DisplayManagerInternal displayManagerInternal = mWmService.mDisplayManagerInternal;
Wale Ogunwaleb699ce02016-07-18 12:05:30 -07002165 if (displayManagerInternal != null) {
2166 // Bootstrap the default logical display from the display manager.
2167 final DisplayInfo newDisplayInfo = displayManagerInternal.getDisplayInfo(mDisplayId);
2168 if (newDisplayInfo != null) {
2169 mDisplayInfo.copyFrom(newDisplayInfo);
2170 }
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -07002171 }
Wale Ogunwaleb699ce02016-07-18 12:05:30 -07002172
Andrii Kuliancd097992017-03-23 18:31:59 -07002173 updateBaseDisplayMetrics(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight,
2174 mDisplayInfo.logicalDensityDpi);
2175 mInitialDisplayWidth = mDisplayInfo.logicalWidth;
2176 mInitialDisplayHeight = mDisplayInfo.logicalHeight;
2177 mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi;
Adrian Roos1cf585052018-01-03 18:43:27 +01002178 mInitialDisplayCutout = mDisplayInfo.displayCutout;
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -07002179 }
2180
Andrii Kuliancd097992017-03-23 18:31:59 -07002181 /**
2182 * If display metrics changed, overrides are not set and it's not just a rotation - update base
2183 * values.
2184 */
2185 private void updateBaseDisplayMetricsIfNeeded() {
2186 // Get real display metrics without overrides from WM.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002187 mWmService.mDisplayManagerInternal.getNonOverrideDisplayInfo(mDisplayId, mDisplayInfo);
Andrii Kuliancd097992017-03-23 18:31:59 -07002188 final int orientation = mDisplayInfo.rotation;
2189 final boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
2190 final int newWidth = rotated ? mDisplayInfo.logicalHeight : mDisplayInfo.logicalWidth;
2191 final int newHeight = rotated ? mDisplayInfo.logicalWidth : mDisplayInfo.logicalHeight;
2192 final int newDensity = mDisplayInfo.logicalDensityDpi;
Adrian Roos1cf585052018-01-03 18:43:27 +01002193 final DisplayCutout newCutout = mDisplayInfo.displayCutout;
Andrii Kuliancd097992017-03-23 18:31:59 -07002194
2195 final boolean displayMetricsChanged = mInitialDisplayWidth != newWidth
2196 || mInitialDisplayHeight != newHeight
Adrian Roos1cf585052018-01-03 18:43:27 +01002197 || mInitialDisplayDensity != mDisplayInfo.logicalDensityDpi
2198 || !Objects.equals(mInitialDisplayCutout, newCutout);
Andrii Kuliancd097992017-03-23 18:31:59 -07002199
2200 if (displayMetricsChanged) {
2201 // Check if display size or density is forced.
2202 final boolean isDisplaySizeForced = mBaseDisplayWidth != mInitialDisplayWidth
2203 || mBaseDisplayHeight != mInitialDisplayHeight;
2204 final boolean isDisplayDensityForced = mBaseDisplayDensity != mInitialDisplayDensity;
2205
2206 // If there is an override set for base values - use it, otherwise use new values.
2207 updateBaseDisplayMetrics(isDisplaySizeForced ? mBaseDisplayWidth : newWidth,
2208 isDisplaySizeForced ? mBaseDisplayHeight : newHeight,
2209 isDisplayDensityForced ? mBaseDisplayDensity : newDensity);
2210
2211 // Real display metrics changed, so we should also update initial values.
2212 mInitialDisplayWidth = newWidth;
2213 mInitialDisplayHeight = newHeight;
2214 mInitialDisplayDensity = newDensity;
Adrian Roos1cf585052018-01-03 18:43:27 +01002215 mInitialDisplayCutout = newCutout;
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07002216 reconfigureDisplayLocked();
Andrii Kuliancd097992017-03-23 18:31:59 -07002217 }
2218 }
2219
Bryce Lee27cec322017-03-21 09:41:37 -07002220 /** Sets the maximum width the screen resolution can be */
2221 void setMaxUiWidth(int width) {
2222 if (DEBUG_DISPLAY) {
2223 Slog.v(TAG_WM, "Setting max ui width:" + width + " on display:" + getDisplayId());
2224 }
2225
2226 mMaxUiWidth = width;
2227
2228 // Update existing metrics.
2229 updateBaseDisplayMetrics(mBaseDisplayWidth, mBaseDisplayHeight, mBaseDisplayDensity);
2230 }
2231
2232 /** Update base (override) display metrics. */
2233 void updateBaseDisplayMetrics(int baseWidth, int baseHeight, int baseDensity) {
2234 mBaseDisplayWidth = baseWidth;
2235 mBaseDisplayHeight = baseHeight;
2236 mBaseDisplayDensity = baseDensity;
2237
2238 if (mMaxUiWidth > 0 && mBaseDisplayWidth > mMaxUiWidth) {
2239 mBaseDisplayHeight = (mMaxUiWidth * mBaseDisplayHeight) / mBaseDisplayWidth;
2240 mBaseDisplayDensity = (mMaxUiWidth * mBaseDisplayDensity) / mBaseDisplayWidth;
2241 mBaseDisplayWidth = mMaxUiWidth;
2242
2243 if (DEBUG_DISPLAY) {
2244 Slog.v(TAG_WM, "Applying config restraints:" + mBaseDisplayWidth + "x"
2245 + mBaseDisplayHeight + " at density:" + mBaseDisplayDensity
2246 + " on display:" + getDisplayId());
2247 }
2248 }
2249
2250 mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
Bryce Leef3c6a472017-11-14 14:53:06 -08002251
2252 updateBounds();
Bryce Lee27cec322017-03-21 09:41:37 -07002253 }
2254
Riddle Hsuf53da812018-08-15 22:00:27 +08002255 /**
2256 * Forces this display to use the specified density.
2257 *
2258 * @param density The density in DPI to use. If the value equals to initial density, the setting
2259 * will be cleared.
2260 * @param userId The target user to apply. Only meaningful when this is default display. If the
2261 * user id is {@link UserHandle#USER_CURRENT}, it means to apply current settings
2262 * so only need to configure display.
2263 */
2264 void setForcedDensity(int density, int userId) {
Riddle Hsuf53da812018-08-15 22:00:27 +08002265 final boolean updateCurrent = userId == UserHandle.USER_CURRENT;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002266 if (mWmService.mCurrentUserId == userId || updateCurrent) {
Riddle Hsuf53da812018-08-15 22:00:27 +08002267 mBaseDisplayDensity = density;
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07002268 reconfigureDisplayLocked();
Riddle Hsuf53da812018-08-15 22:00:27 +08002269 }
2270 if (updateCurrent) {
2271 // We are applying existing settings so no need to save it again.
2272 return;
2273 }
2274
2275 if (density == mInitialDisplayDensity) {
2276 density = 0;
2277 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002278 mWmService.mDisplayWindowSettings.setForcedDensity(this, density, userId);
Riddle Hsuf53da812018-08-15 22:00:27 +08002279 }
2280
2281 /** @param mode {@link #FORCE_SCALING_MODE_AUTO} or {@link #FORCE_SCALING_MODE_DISABLED}. */
2282 void setForcedScalingMode(@ForceScalingMode int mode) {
2283 if (mode != FORCE_SCALING_MODE_DISABLED) {
2284 mode = FORCE_SCALING_MODE_AUTO;
2285 }
2286
2287 mDisplayScalingDisabled = (mode != FORCE_SCALING_MODE_AUTO);
2288 Slog.i(TAG_WM, "Using display scaling mode: " + (mDisplayScalingDisabled ? "off" : "auto"));
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07002289 reconfigureDisplayLocked();
Riddle Hsuf53da812018-08-15 22:00:27 +08002290
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002291 mWmService.mDisplayWindowSettings.setForcedScalingMode(this, mode);
Riddle Hsuf53da812018-08-15 22:00:27 +08002292 }
2293
2294 /** If the given width and height equal to initial size, the setting will be cleared. */
2295 void setForcedSize(int width, int height) {
2296 final boolean clear = mInitialDisplayWidth == width && mInitialDisplayHeight == height;
2297 if (!clear) {
2298 // Set some sort of reasonable bounds on the size of the display that we will try
2299 // to emulate.
2300 final int minSize = 200;
2301 final int maxScale = 2;
2302 width = Math.min(Math.max(width, minSize), mInitialDisplayWidth * maxScale);
2303 height = Math.min(Math.max(height, minSize), mInitialDisplayHeight * maxScale);
2304 }
2305
2306 Slog.i(TAG_WM, "Using new display size: " + width + "x" + height);
2307 updateBaseDisplayMetrics(width, height, mBaseDisplayDensity);
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07002308 reconfigureDisplayLocked();
Riddle Hsuf53da812018-08-15 22:00:27 +08002309
2310 if (clear) {
2311 width = height = 0;
2312 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002313 mWmService.mDisplayWindowSettings.setForcedSize(this, width, height);
Riddle Hsuf53da812018-08-15 22:00:27 +08002314 }
2315
Wale Ogunwaledb506192017-12-08 10:57:32 -08002316 void getStableRect(Rect out) {
2317 out.set(mDisplayFrames.mStable);
Chong Zhangf66db432016-01-13 10:39:51 -08002318 }
2319
Louis Changdc077272019-11-12 16:52:56 +08002320 void setStackOnDisplay(ActivityStack stack, int position) {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07002321 if (DEBUG_STACK) Slog.d(TAG_WM, "Set stack=" + stack + " on displayId=" + mDisplayId);
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002322 mTaskContainers.addChild(stack, position);
Andrii Kulian839def92016-11-02 10:58:58 -07002323 }
2324
Louis Changdc077272019-11-12 16:52:56 +08002325 void moveStackToDisplay(ActivityStack stack, boolean onTop) {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002326 stack.reparent(mTaskContainers, onTop ? POSITION_TOP: POSITION_BOTTOM);
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07002327 }
Andrii Kulian839def92016-11-02 10:58:58 -07002328
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002329 @Override
2330 protected void addChild(DisplayChildWindowContainer child,
2331 Comparator<DisplayChildWindowContainer> comparator) {
2332 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
2333 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -07002334
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002335 @Override
2336 protected void addChild(DisplayChildWindowContainer child, int index) {
2337 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
2338 }
2339
2340 @Override
2341 protected void removeChild(DisplayChildWindowContainer child) {
Wale Ogunwale601a3f02016-10-17 08:39:39 -07002342 // Only allow removal of direct children from this display if the display is in the process
2343 // of been removed.
2344 if (mRemovingDisplay) {
2345 super.removeChild(child);
2346 return;
2347 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002348 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002349 }
2350
Adrian Roosefa40702020-01-08 17:58:45 +01002351 void positionDisplayAt(int position, boolean includingParents) {
2352 getParent().positionChildAt(position, this, includingParents);
2353 }
2354
Andrii Kuliand2765632016-12-12 22:26:34 -08002355 @Override
2356 void positionChildAt(int position, DisplayChildWindowContainer child, boolean includingParents) {
2357 // Children of the display are statically ordered, so the real intention here is to perform
2358 // the operation on the display and not the static direct children.
Adrian Roosefa40702020-01-08 17:58:45 +01002359 positionDisplayAt(position, includingParents);
Andrii Kuliand2765632016-12-12 22:26:34 -08002360 }
2361
Louis Changdc077272019-11-12 16:52:56 +08002362 void positionStackAt(int position, ActivityStack child, boolean includingParents) {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002363 mTaskContainers.positionChildAt(position, child, includingParents);
Winson Chung59a47ded2018-01-25 17:46:06 +00002364 layoutAndAssignWindowLayersIfNeeded();
2365 }
2366
Garfield Tan4f71c5a2018-10-10 10:12:02 -07002367 /**
Winson Chungc5fe7ff2019-02-19 14:49:25 -08002368 * Returns true if the input point is within an app window.
2369 */
2370 boolean pointWithinAppWindow(int x, int y) {
2371 final int[] targetWindowType = {-1};
Wale Ogunwalef5f3f1b2019-11-12 09:47:30 -08002372 final PooledConsumer fn = PooledLambda.obtainConsumer((w, nonArg) -> {
Winson Chungc5fe7ff2019-02-19 14:49:25 -08002373 if (targetWindowType[0] != -1) {
2374 return;
2375 }
2376
2377 if (w.isOnScreen() && w.isVisibleLw() && w.getFrameLw().contains(x, y)) {
2378 targetWindowType[0] = w.mAttrs.type;
2379 return;
2380 }
2381 }, PooledLambda.__(WindowState.class), mTmpRect);
2382 forAllWindows(fn, true /* traverseTopToBottom */);
Wale Ogunwalef5f3f1b2019-11-12 09:47:30 -08002383 fn.recycle();
Winson Chungc5fe7ff2019-02-19 14:49:25 -08002384 return FIRST_APPLICATION_WINDOW <= targetWindowType[0]
chaviw8065f442019-11-18 13:20:58 -08002385 && targetWindowType[0] <= LAST_APPLICATION_WINDOW;
Winson Chungc5fe7ff2019-02-19 14:49:25 -08002386 }
2387
2388 /**
Chong Zhangd8ceb852015-11-11 14:53:41 -08002389 * Find the task whose outside touch area (for resizing) (x, y) falls within.
Chong Zhang9184ec62015-09-24 12:32:21 -07002390 * Returns null if the touch doesn't fall into a resizing area.
Chong Zhang8e89b312015-09-09 15:09:30 -07002391 */
Wale Ogunwale15ead902016-09-02 14:30:11 -07002392 Task findTaskForResizePoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002393 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002394 return mTmpTaskForResizePointSearchResult.process(mTaskContainers, x, y, delta);
Chong Zhang8e89b312015-09-09 15:09:30 -07002395 }
2396
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002397 void updateTouchExcludeRegion() {
2398 final Task focusedTask = (mFocusedApp != null ? mFocusedApp.getTask() : null);
David Stevensee9e2772017-02-09 16:30:27 -08002399 if (focusedTask == null) {
2400 mTouchExcludeRegion.setEmpty();
2401 } else {
2402 mTouchExcludeRegion.set(mBaseDisplayRect);
2403 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002404 mTmpRect.setEmpty();
David Stevensee9e2772017-02-09 16:30:27 -08002405 mTmpRect2.setEmpty();
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002406
2407 final PooledConsumer c = PooledLambda.obtainConsumer(
2408 DisplayContent::processTaskForTouchExcludeRegion, this,
2409 PooledLambda.__(Task.class), focusedTask, delta);
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002410 mTaskContainers.forAllTasks(c);
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002411 c.recycle();
2412
David Stevensee9e2772017-02-09 16:30:27 -08002413 // If we removed the focused task above, add it back and only leave its
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002414 // outside touch area in the exclusion. TapDetector is not interested in
David Stevensee9e2772017-02-09 16:30:27 -08002415 // any touch inside the focused task itself.
2416 if (!mTmpRect2.isEmpty()) {
2417 mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION);
2418 }
Chong Zhangd8ceb852015-11-11 14:53:41 -08002419 }
lumark90120a82018-08-15 00:33:03 +08002420 if (mInputMethodWindow != null && mInputMethodWindow.isVisibleLw()) {
Filip Gruszczynski912d9192015-12-01 16:14:04 -08002421 // If the input method is visible and the user is typing, we don't want these touch
2422 // events to be intercepted and used to change focus. This would likely cause a
2423 // disappearance of the input method.
lumark90120a82018-08-15 00:33:03 +08002424 mInputMethodWindow.getTouchableRegion(mTmpRegion);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002425 mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
Filip Gruszczynski912d9192015-12-01 16:14:04 -08002426 }
Filip Gruszczynskiecf67222015-12-11 15:16:36 -08002427 for (int i = mTapExcludedWindows.size() - 1; i >= 0; i--) {
Andrii Kulian4b6599e2018-01-15 17:24:08 -08002428 final WindowState win = mTapExcludedWindows.get(i);
Filip Gruszczynskiecf67222015-12-11 15:16:36 -08002429 win.getTouchableRegion(mTmpRegion);
2430 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
2431 }
Tiger Huang04dc4cc2019-01-17 18:41:41 +08002432 amendWindowTapExcludeRegion(mTouchExcludeRegion);
Andrii Kulian03c403d2016-11-11 11:14:12 -08002433 // TODO(multi-display): Support docked stacks on secondary displays.
Wale Ogunwale734b8962020-01-21 12:17:42 -08002434 if (mDisplayId == DEFAULT_DISPLAY && getRootSplitScreenPrimaryTask() != null) {
Jorim Jaggid47e7e12016-03-01 09:57:38 +01002435 mDividerControllerLocked.getTouchRegion(mTmpRect);
Jorim Jaggi7f19cb82016-03-25 19:37:44 -07002436 mTmpRegion.set(mTmpRect);
Jorim Jaggid47e7e12016-03-01 09:57:38 +01002437 mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
2438 }
Riddle Hsu2588ab02019-02-25 14:23:56 +08002439 mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
Craig Mautner6601b7b2013-04-29 10:29:11 -07002440 }
2441
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002442 private void processTaskForTouchExcludeRegion(Task task, Task focusedTask, int delta) {
2443 final ActivityRecord topVisibleActivity = task.getTopVisibleActivity();
2444
2445 if (topVisibleActivity == null || !topVisibleActivity.hasContentToDisplay()) {
2446 return;
2447 }
2448
2449 // Exclusion region is the region that TapDetector doesn't care about.
2450 // Here we want to remove all non-focused tasks from the exclusion region.
2451 // We also remove the outside touch area for resizing for all freeform
2452 // tasks (including the focused).
2453 // We save the focused task region once we find it, and add it back at the end.
2454 // If the task is home stack and it is resizable in the minimized state, we want to
2455 // exclude the docked stack from touch so we need the entire screen area and not just a
2456 // small portion which the home stack currently is resized to.
2457 if (task.isActivityTypeHome() && task.getStack().isMinimizedDockAndHomeStackResizable()) {
2458 mDisplayContent.getBounds(mTmpRect);
2459 } else {
2460 task.getDimBounds(mTmpRect);
2461 }
2462
2463 if (task == focusedTask) {
2464 // Add the focused task rect back into the exclude region once we are done
2465 // processing stacks.
2466 mTmpRect2.set(mTmpRect);
2467 }
2468
2469 final boolean isFreeformed = task.inFreeformWindowingMode();
2470 if (task != focusedTask || isFreeformed) {
2471 if (isFreeformed) {
2472 // If the task is freeformed, enlarge the area to account for outside
2473 // touch area for resize.
2474 mTmpRect.inset(-delta, -delta);
2475 // Intersect with display content rect. If we have system decor (status bar/
2476 // navigation bar), we want to exclude that from the tap detection.
2477 // Otherwise, if the app is partially placed under some system button (eg.
2478 // Recents, Home), pressing that button would cause a full series of
2479 // unwanted transfer focus/resume/pause, before we could go home.
2480 mTmpRect.intersect(mDisplayFrames.mContent);
2481 }
2482 mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
2483 }
2484 }
2485
Tiger Huang04dc4cc2019-01-17 18:41:41 +08002486 /**
2487 * Union the region with all the tap exclude region provided by windows on this display.
2488 *
2489 * @param inOutRegion The region to be amended.
2490 */
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002491 private void amendWindowTapExcludeRegion(Region inOutRegion) {
chaviwaa0d74e2019-12-26 14:13:40 -08002492 final Region region = Region.obtain();
Tiger Huang04dc4cc2019-01-17 18:41:41 +08002493 for (int i = mTapExcludeProvidingWindows.size() - 1; i >= 0; i--) {
2494 final WindowState win = mTapExcludeProvidingWindows.valueAt(i);
chaviwaa0d74e2019-12-26 14:13:40 -08002495 win.getTapExcludeRegion(region);
2496 inOutRegion.op(region, Op.UNION);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08002497 }
chaviwaa0d74e2019-12-26 14:13:40 -08002498 region.recycle();
Tiger Huang04dc4cc2019-01-17 18:41:41 +08002499 }
2500
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002501 @Override
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07002502 void switchUser(int userId) {
2503 super.switchUser(userId);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002504 mWmService.mWindowsChanged = true;
Winson Chungda20fec2019-04-10 12:19:59 -07002505 mDisplayPolicy.switchUser();
Craig Mautner858d8a62013-04-23 17:08:34 -07002506 }
2507
Wale Ogunwale10124582016-09-15 20:25:50 -07002508 @Override
2509 void removeIfPossible() {
lumark9bca6b42019-10-17 18:35:22 +08002510 if (isAnimating(TRANSITION | PARENTS)) {
Wale Ogunwale10124582016-09-15 20:25:50 -07002511 mDeferredRemoval = true;
2512 return;
Craig Mautner2eb15342013-08-07 13:13:35 -07002513 }
Wale Ogunwale10124582016-09-15 20:25:50 -07002514 removeImmediately();
Craig Mautner2eb15342013-08-07 13:13:35 -07002515 }
2516
Wale Ogunwale10124582016-09-15 20:25:50 -07002517 @Override
2518 void removeImmediately() {
Wale Ogunwale601a3f02016-10-17 08:39:39 -07002519 mRemovingDisplay = true;
2520 try {
Jackal Guoc43a0a62019-04-23 09:15:14 +08002521 if (mParentWindow != null) {
2522 mParentWindow.removeEmbeddedDisplayContent(this);
2523 }
lumark588a3e82018-07-20 18:53:54 +08002524 // Clear all transitions & screen frozen states when removing display.
2525 mOpeningApps.clear();
2526 mClosingApps.clear();
Evan Rosky2289ba12018-11-19 18:28:18 -08002527 mChangingApps.clear();
lumark588a3e82018-07-20 18:53:54 +08002528 mUnknownAppVisibilityController.clear();
2529 mAppTransition.removeAppTransitionTimeoutCallbacks();
2530 handleAnimatingStoppedAndTransition();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002531 mWmService.stopFreezingDisplayLocked();
Wale Ogunwale601a3f02016-10-17 08:39:39 -07002532 super.removeImmediately();
2533 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
Riddle Hsu2588ab02019-02-25 14:23:56 +08002534 mPointerEventDispatcher.dispose();
Vadim Caenb3715832019-08-13 17:06:38 +02002535 setRotationAnimation(null);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002536 mWmService.mAnimator.removeDisplayLocked(mDisplayId);
Jorim Jaggiae962e62018-12-27 17:23:48 +01002537 mInputMonitor.onDisplayRemoved();
Louis Chang677921f2019-12-06 16:44:24 +08002538 mWmService.mDisplayNotificationController.dispatchDisplayRemoved(this);
Wale Ogunwale601a3f02016-10-17 08:39:39 -07002539 } finally {
Riddle Hsu4e611772018-10-31 18:58:28 +08002540 mDisplayReady = false;
Wale Ogunwale601a3f02016-10-17 08:39:39 -07002541 mRemovingDisplay = false;
Craig Mautner95da1082014-02-24 17:54:35 -08002542 }
Robert Carr679ccb02018-08-08 15:32:35 -07002543
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002544 mWmService.mWindowPlacerLocked.requestTraversal();
Craig Mautner95da1082014-02-24 17:54:35 -08002545 }
2546
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002547 /** Returns true if a removal action is still being deferred. */
Wale Ogunwale10124582016-09-15 20:25:50 -07002548 @Override
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002549 boolean checkCompleteDeferredRemoval() {
Riddle Hsu793442c52019-11-05 01:04:55 +08002550 boolean stillDeferringRemoval = false;
2551
2552 for (int i = getChildCount() - 1; i >= 0; --i) {
2553 final DisplayChildWindowContainer child = getChildAt(i);
2554 stillDeferringRemoval |= child.checkCompleteDeferredRemoval();
2555 if (getChildCount() == 0) {
2556 // If this display is pending to be removed because it contains an activity with
2557 // {@link ActivityRecord#mIsExiting} is true, this display may be removed when
2558 // completing the removal of the last activity from
2559 // {@link ActivityRecord#checkCompleteDeferredRemoval}.
2560 return false;
2561 }
2562 }
Wale Ogunwale10124582016-09-15 20:25:50 -07002563
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002564 if (!stillDeferringRemoval && mDeferredRemoval) {
Wale Ogunwale10124582016-09-15 20:25:50 -07002565 removeImmediately();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002566 return false;
Craig Mautner95da1082014-02-24 17:54:35 -08002567 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002568 return true;
Craig Mautner95da1082014-02-24 17:54:35 -08002569 }
2570
Andrii Kulian0214ed92017-05-16 13:44:05 -07002571 /** @return 'true' if removal of this display content is deferred due to active animation. */
2572 boolean isRemovalDeferred() {
2573 return mDeferredRemoval;
2574 }
2575
Wale Ogunwale10124582016-09-15 20:25:50 -07002576 boolean animateForIme(float interpolatedValue, float animationTarget,
2577 float dividerAnimationTarget) {
2578 boolean updated = false;
2579
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002580 for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
2581 final ActivityStack stack = mTaskContainers.getChildAt(i);
Wale Ogunwale10124582016-09-15 20:25:50 -07002582 if (stack == null || !stack.isAdjustedForIme()) {
2583 continue;
2584 }
2585
2586 if (interpolatedValue >= 1f && animationTarget == 0f && dividerAnimationTarget == 0f) {
2587 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
2588 updated = true;
2589 } else {
2590 mDividerControllerLocked.mLastAnimationProgress =
2591 mDividerControllerLocked.getInterpolatedAnimationValue(interpolatedValue);
2592 mDividerControllerLocked.mLastDividerProgress =
2593 mDividerControllerLocked.getInterpolatedDividerValue(interpolatedValue);
2594 updated |= stack.updateAdjustForIme(
2595 mDividerControllerLocked.mLastAnimationProgress,
2596 mDividerControllerLocked.mLastDividerProgress,
2597 false /* force */);
2598 }
2599 if (interpolatedValue >= 1f) {
2600 stack.endImeAdjustAnimation();
2601 }
2602 }
2603
2604 return updated;
2605 }
2606
2607 boolean clearImeAdjustAnimation() {
2608 boolean changed = false;
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002609 for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
2610 final ActivityStack stack = mTaskContainers.getChildAt(i);
Wale Ogunwale10124582016-09-15 20:25:50 -07002611 if (stack != null && stack.isAdjustedForIme()) {
2612 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
2613 changed = true;
2614 }
2615 }
2616 return changed;
2617 }
2618
2619 void beginImeAdjustAnimation() {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002620 for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
2621 final ActivityStack stack = mTaskContainers.getChildAt(i);
Wale Ogunwale10124582016-09-15 20:25:50 -07002622 if (stack.isVisible() && stack.isAdjustedForIme()) {
2623 stack.beginImeAdjustAnimation();
2624 }
2625 }
2626 }
2627
2628 void adjustForImeIfNeeded() {
lumark90120a82018-08-15 00:33:03 +08002629 final WindowState imeWin = mInputMethodWindow;
Wale Ogunwale10124582016-09-15 20:25:50 -07002630 final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
2631 && !mDividerControllerLocked.isImeHideRequested();
Wale Ogunwale734b8962020-01-21 12:17:42 -08002632 final ActivityStack dockedStack = getRootSplitScreenPrimaryTask();
Riddle Hsuc6814252019-05-16 17:06:52 +08002633 final boolean dockVisible = dockedStack != null;
Wale Ogunwalea38654f2019-11-17 20:37:15 -08002634 final Task topDockedTask = dockVisible ? dockedStack.getTask((t) -> true): null;
Louis Changdc077272019-11-12 16:52:56 +08002635 final ActivityStack imeTargetStack = mWmService.getImeFocusStackLocked();
Wale Ogunwale10124582016-09-15 20:25:50 -07002636 final int imeDockSide = (dockVisible && imeTargetStack != null) ?
2637 imeTargetStack.getDockSide() : DOCKED_INVALID;
2638 final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
2639 final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00002640 final int imeHeight = mDisplayFrames.getInputMethodWindowVisibleHeight();
Wale Ogunwale10124582016-09-15 20:25:50 -07002641 final boolean imeHeightChanged = imeVisible &&
2642 imeHeight != mDividerControllerLocked.getImeHeightAdjustedFor();
2643
Riddle Hsuc6814252019-05-16 17:06:52 +08002644 // This includes a case where the docked stack is unminimizing and IME is visible for the
2645 // bottom side stack. The condition prevents adjusting the override task bounds for IME to
2646 // the minimized docked stack bounds.
2647 final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock()
2648 || (topDockedTask != null && imeOnBottom && !dockedStack.isAdjustedForIme()
chaviw8065f442019-11-18 13:20:58 -08002649 && dockedStack.getBounds().height() < topDockedTask.getBounds().height());
Riddle Hsuc6814252019-05-16 17:06:52 +08002650
Wale Ogunwale10124582016-09-15 20:25:50 -07002651 // The divider could be adjusted for IME position, or be thinner than usual,
2652 // or both. There are three possible cases:
2653 // - If IME is visible, and focus is on top, divider is not moved for IME but thinner.
2654 // - If IME is visible, and focus is on bottom, divider is moved for IME and thinner.
2655 // - If IME is not visible, divider is not moved and is normal width.
2656
2657 if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002658 for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
2659 final ActivityStack stack = mTaskContainers.getChildAt(i);
Wale Ogunwale10124582016-09-15 20:25:50 -07002660 final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
Wale Ogunwale68278562017-09-23 17:13:55 -07002661 if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)
2662 && stack.inSplitScreenWindowingMode()) {
Wale Ogunwale10124582016-09-15 20:25:50 -07002663 stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
2664 } else {
2665 stack.resetAdjustedForIme(false);
2666 }
2667 }
2668 mDividerControllerLocked.setAdjustedForIme(
2669 imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
2670 } else {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002671 for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
2672 final ActivityStack stack = mTaskContainers.getChildAt(i);
Wale Ogunwale10124582016-09-15 20:25:50 -07002673 stack.resetAdjustedForIme(!dockVisible);
2674 }
2675 mDividerControllerLocked.setAdjustedForIme(
2676 false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
2677 }
Winson Chung655332c2016-10-31 13:14:28 -07002678 mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);
Wale Ogunwale10124582016-09-15 20:25:50 -07002679 }
2680
2681 void prepareFreezingTaskBounds() {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002682 for (int stackNdx = mTaskContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2683 final ActivityStack stack = mTaskContainers.getChildAt(stackNdx);
Wale Ogunwale10124582016-09-15 20:25:50 -07002684 stack.prepareFreezingTaskBounds();
2685 }
2686 }
2687
Wale Ogunwale94744212015-09-21 19:01:47 -07002688 void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
Bryce Leef3c6a472017-11-14 14:53:06 -08002689 getBounds(mTmpRect, newRotation);
Evan Rosky39b6f232018-10-30 18:35:41 -07002690 rotateBounds(mTmpRect, oldRotation, newRotation, bounds);
2691 }
Andrii Kulian4dfb9c42016-10-11 20:06:27 -07002692
Evan Rosky39b6f232018-10-30 18:35:41 -07002693 void rotateBounds(Rect parentBounds, int oldRotation, int newRotation, Rect bounds) {
Andrii Kulian4dfb9c42016-10-11 20:06:27 -07002694 // Compute a transform matrix to undo the coordinate space transformation,
2695 // and present the window at the same physical position it previously occupied.
2696 final int deltaRotation = deltaRotation(newRotation, oldRotation);
Evan Rosky39b6f232018-10-30 18:35:41 -07002697 createRotationMatrix(
2698 deltaRotation, parentBounds.width(), parentBounds.height(), mTmpMatrix);
Andrii Kulian4dfb9c42016-10-11 20:06:27 -07002699
2700 mTmpRectF.set(bounds);
2701 mTmpMatrix.mapRect(mTmpRectF);
2702 mTmpRectF.round(bounds);
Wale Ogunwale94744212015-09-21 19:01:47 -07002703 }
2704
Wale Ogunwale4a02d812015-02-12 23:01:38 -08002705 static int deltaRotation(int oldRotation, int newRotation) {
2706 int delta = newRotation - oldRotation;
2707 if (delta < 0) delta += 4;
2708 return delta;
2709 }
2710
Vadim Caenb3715832019-08-13 17:06:38 +02002711 public void setRotationAnimation(ScreenRotationAnimation screenRotationAnimation) {
2712 if (mScreenRotationAnimation != null) {
2713 mScreenRotationAnimation.kill();
2714 }
2715 mScreenRotationAnimation = screenRotationAnimation;
2716 }
2717
2718 public ScreenRotationAnimation getRotationAnimation() {
2719 return mScreenRotationAnimation;
2720 }
2721
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002722 private static void createRotationMatrix(int rotation, float displayWidth, float displayHeight,
Andrii Kulian4dfb9c42016-10-11 20:06:27 -07002723 Matrix outMatrix) {
2724 // For rotations without Z-ordering we don't need the target rectangle's position.
2725 createRotationMatrix(rotation, 0 /* rectLeft */, 0 /* rectTop */, displayWidth,
2726 displayHeight, outMatrix);
2727 }
2728
2729 static void createRotationMatrix(int rotation, float rectLeft, float rectTop,
2730 float displayWidth, float displayHeight, Matrix outMatrix) {
2731 switch (rotation) {
2732 case ROTATION_0:
2733 outMatrix.reset();
2734 break;
2735 case ROTATION_270:
2736 outMatrix.setRotate(270, 0, 0);
2737 outMatrix.postTranslate(0, displayHeight);
2738 outMatrix.postTranslate(rectTop, 0);
2739 break;
2740 case ROTATION_180:
2741 outMatrix.reset();
2742 break;
2743 case ROTATION_90:
2744 outMatrix.setRotate(90, 0, 0);
2745 outMatrix.postTranslate(displayWidth, 0);
2746 outMatrix.postTranslate(-rectTop, rectLeft);
2747 break;
2748 }
2749 }
2750
Louis Chang677921f2019-12-06 16:44:24 +08002751 public void dumpDebug(ProtoOutputStream proto, long fieldId,
2752 @WindowTraceLogLevel int logLevel) {
2753 final long token = proto.start(fieldId);
2754 dumpDebugInner(proto, DISPLAY, logLevel);
2755 proto.write(com.android.server.am.ActivityDisplayProto.ID, mDisplayId);
2756 proto.write(SINGLE_TASK_INSTANCE, mSingleTaskInstance);
2757 final ActivityStack focusedStack = getFocusedStack();
2758 if (focusedStack != null) {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08002759 proto.write(FOCUSED_STACK_ID, focusedStack.getRootTaskId());
Louis Chang677921f2019-12-06 16:44:24 +08002760 final ActivityRecord focusedActivity = focusedStack.getDisplay().getResumedActivity();
2761 if (focusedActivity != null) {
2762 focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
2763 }
2764 } else {
2765 proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
2766 }
2767 for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
2768 final ActivityStack stack = getStackAt(stackNdx);
2769 stack.dumpDebug(proto, com.android.server.am.ActivityDisplayProto.STACKS, logLevel);
2770 }
2771 proto.end(token);
2772 }
2773
Louis Chang2453d062019-11-19 22:30:48 +08002774 // TODO(proto-merge): Remove once protos for ActivityDisplay and DisplayContent are merged.
Jeffrey Huangcb782852019-12-05 11:28:11 -08002775 public void dumpDebugInner(ProtoOutputStream proto, long fieldId,
Nataniel Borges023ecb52019-01-16 14:15:43 -08002776 @WindowTraceLogLevel int logLevel) {
2777 // Critical log level logs only visible elements to mitigate performance overheard
2778 if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
2779 return;
2780 }
2781
Steven Timotiusaf03df62017-07-18 16:56:43 -07002782 final long token = proto.start(fieldId);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002783 super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
Steven Timotiusaf03df62017-07-18 16:56:43 -07002784 proto.write(ID, mDisplayId);
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002785 for (int stackNdx = mTaskContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2786 final ActivityStack stack = mTaskContainers.getChildAt(stackNdx);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002787 stack.dumpDebugInnerStackOnly(proto, STACKS, logLevel);
Steven Timotiusaf03df62017-07-18 16:56:43 -07002788 }
Jeffrey Huangcb782852019-12-05 11:28:11 -08002789 mDividerControllerLocked.dumpDebug(proto, DOCKED_STACK_DIVIDER_CONTROLLER);
Wale Ogunwale61911492017-10-11 08:50:50 -07002790 for (int i = mAboveAppWindowsContainers.getChildCount() - 1; i >= 0; --i) {
2791 final WindowToken windowToken = mAboveAppWindowsContainers.getChildAt(i);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002792 windowToken.dumpDebug(proto, ABOVE_APP_WINDOWS, logLevel);
Steven Timotiusaf03df62017-07-18 16:56:43 -07002793 }
Wale Ogunwale61911492017-10-11 08:50:50 -07002794 for (int i = mBelowAppWindowsContainers.getChildCount() - 1; i >= 0; --i) {
2795 final WindowToken windowToken = mBelowAppWindowsContainers.getChildAt(i);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002796 windowToken.dumpDebug(proto, BELOW_APP_WINDOWS, logLevel);
Steven Timotiusaf03df62017-07-18 16:56:43 -07002797 }
Wale Ogunwale61911492017-10-11 08:50:50 -07002798 for (int i = mImeWindowsContainers.getChildCount() - 1; i >= 0; --i) {
2799 final WindowToken windowToken = mImeWindowsContainers.getChildAt(i);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002800 windowToken.dumpDebug(proto, IME_WINDOWS, logLevel);
Steven Timotiusaf03df62017-07-18 16:56:43 -07002801 }
chaviw8065f442019-11-18 13:20:58 -08002802 for (int i = mOverlayContainers.getChildCount() - 1; i >= 0; --i) {
2803 final WindowToken windowToken = mOverlayContainers.getChildAt(i);
2804 windowToken.dumpDebug(proto, OVERLAY_WINDOWS, logLevel);
2805 }
Steven Timotiusaf03df62017-07-18 16:56:43 -07002806 proto.write(DPI, mBaseDisplayDensity);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002807 mDisplayInfo.dumpDebug(proto, DISPLAY_INFO);
Riddle Hsuccf09402019-08-13 00:33:06 +08002808 proto.write(ROTATION, getRotation());
Vadim Caenb3715832019-08-13 17:06:38 +02002809 final ScreenRotationAnimation screenRotationAnimation = getRotationAnimation();
Steven Timotiusf2d68892017-08-28 17:00:01 -07002810 if (screenRotationAnimation != null) {
Jeffrey Huangcb782852019-12-05 11:28:11 -08002811 screenRotationAnimation.dumpDebug(proto, SCREEN_ROTATION_ANIMATION);
Steven Timotiusf2d68892017-08-28 17:00:01 -07002812 }
Jeffrey Huangcb782852019-12-05 11:28:11 -08002813 mDisplayFrames.dumpDebug(proto, DISPLAY_FRAMES);
2814 mAppTransition.dumpDebug(proto, APP_TRANSITION);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002815 if (mFocusedApp != null) {
2816 mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
2817 }
Jorim Jaggi1112fed2019-04-15 13:32:14 +02002818 for (int i = mOpeningApps.size() - 1; i >= 0; i--) {
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08002819 mOpeningApps.valueAt(i).writeIdentifierToProto(proto, OPENING_APPS);
Jorim Jaggi1112fed2019-04-15 13:32:14 +02002820 }
2821 for (int i = mClosingApps.size() - 1; i >= 0; i--) {
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08002822 mClosingApps.valueAt(i).writeIdentifierToProto(proto, CLOSING_APPS);
Jorim Jaggi1112fed2019-04-15 13:32:14 +02002823 }
2824 for (int i = mChangingApps.size() - 1; i >= 0; i--) {
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08002825 mChangingApps.valueAt(i).writeIdentifierToProto(proto, CHANGING_APPS);
Jorim Jaggi1112fed2019-04-15 13:32:14 +02002826 }
Steven Timotiusaf03df62017-07-18 16:56:43 -07002827 proto.end(token);
2828 }
2829
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002830 @Override
2831 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
2832 super.dump(pw, prefix, dumpAll);
Louis Chang677921f2019-12-06 16:44:24 +08002833 pw.print(prefix);
2834 pw.println("Display: mDisplayId=" + mDisplayId + " stacks=" + getStackCount() + (
2835 mSingleTaskInstance ? " mSingleTaskInstance" : ""));
Craig Mautnera91f9e22012-09-14 16:22:08 -07002836 final String subPrefix = " " + prefix;
2837 pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x");
chaviw8065f442019-11-18 13:20:58 -08002838 pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
2839 pw.print("dpi");
2840 if (mInitialDisplayWidth != mBaseDisplayWidth
2841 || mInitialDisplayHeight != mBaseDisplayHeight
2842 || mInitialDisplayDensity != mBaseDisplayDensity) {
2843 pw.print(" base=");
2844 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
2845 pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
2846 }
2847 if (mDisplayScalingDisabled) {
2848 pw.println(" noscale");
2849 }
2850 pw.print(" cur=");
2851 pw.print(mDisplayInfo.logicalWidth);
2852 pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
2853 pw.print(" app=");
2854 pw.print(mDisplayInfo.appWidth);
2855 pw.print("x"); pw.print(mDisplayInfo.appHeight);
2856 pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
2857 pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
2858 pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
2859 pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
2860 pw.print(subPrefix + "deferred=" + mDeferredRemoval
2861 + " mLayoutNeeded=" + mLayoutNeeded);
2862 pw.println(" mTouchExcludeRegion=" + mTouchExcludeRegion);
Wale Ogunwaleb429e682016-01-06 12:36:34 -08002863
Craig Mautnerdc548482014-02-05 13:35:24 -08002864 pw.println();
Adrian Roos5251b1d2018-03-23 18:57:43 +01002865 pw.print(prefix); pw.print("mLayoutSeq="); pw.println(mLayoutSeq);
2866
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002867 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
2868 if (mLastFocus != mCurrentFocus) {
2869 pw.print(" mLastFocus="); pw.println(mLastFocus);
2870 }
Louis Chang677921f2019-12-06 16:44:24 +08002871 if (mPreferredTopFocusableStack != null) {
2872 pw.println(prefix + "mPreferredTopFocusableStack=" + mPreferredTopFocusableStack);
2873 }
2874 if (mLastFocusedStack != null) {
2875 pw.println(prefix + "mLastFocusedStack=" + mLastFocusedStack);
2876 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002877 if (mLosingFocus.size() > 0) {
2878 pw.println();
2879 pw.println(" Windows losing focus:");
2880 for (int i = mLosingFocus.size() - 1; i >= 0; i--) {
2881 final WindowState w = mLosingFocus.get(i);
2882 pw.print(" Losing #"); pw.print(i); pw.print(' ');
2883 pw.print(w);
2884 if (dumpAll) {
2885 pw.println(":");
2886 w.dump(pw, " ", true);
2887 } else {
2888 pw.println();
2889 }
2890 }
2891 }
2892 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
Tiger Huang7c610aa2018-10-27 00:01:01 +08002893 if (mLastStatusBarVisibility != 0) {
2894 pw.print(" mLastStatusBarVisibility=0x");
2895 pw.println(Integer.toHexString(mLastStatusBarVisibility));
2896 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002897
Adrian Roos5251b1d2018-03-23 18:57:43 +01002898 pw.println();
wilsonshihc32538e2018-11-07 17:27:34 +08002899 mWallpaperController.dump(pw, " ");
2900
2901 pw.println();
Adrian Roos4ffc8972019-02-07 20:45:11 +01002902 pw.print("mSystemGestureExclusion=");
2903 if (mSystemGestureExclusionListeners.getRegisteredCallbackCount() > 0) {
2904 pw.println(mSystemGestureExclusion);
2905 } else {
2906 pw.println("<no lstnrs>");
2907 }
2908
2909 pw.println();
Jorim Jaggiad5d2842016-11-01 18:22:53 -07002910 pw.println(prefix + "Application tokens in top down Z order:");
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002911 for (int stackNdx = mTaskContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
2912 final ActivityStack stack = mTaskContainers.getChildAt(stackNdx);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002913 stack.dump(pw, prefix + " ", dumpAll);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002914 }
Wale Ogunwaleb429e682016-01-06 12:36:34 -08002915
Craig Mautnerdc548482014-02-05 13:35:24 -08002916 pw.println();
2917 if (!mExitingTokens.isEmpty()) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07002918 pw.println();
2919 pw.println(" Exiting tokens:");
Wale Ogunwaleb429e682016-01-06 12:36:34 -08002920 for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002921 final WindowToken token = mExitingTokens.get(i);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002922 pw.print(" Exiting #"); pw.print(i);
2923 pw.print(' '); pw.print(token);
2924 pw.println(':');
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002925 token.dump(pw, " ", dumpAll);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08002926 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002927 }
Robert Carrf59b8dd2017-10-02 18:58:36 -07002928
Vadim Caenb3715832019-08-13 17:06:38 +02002929 final ScreenRotationAnimation rotationAnimation = getRotationAnimation();
2930 if (rotationAnimation != null) {
2931 pw.print(subPrefix);
2932 pw.println(" mScreenRotationAnimation:");
2933 rotationAnimation.printTo(" ", pw);
2934 } else if (dumpAll) {
2935 pw.print(subPrefix);
2936 pw.println(" no ScreenRotationAnimation ");
2937 }
2938
Jorim Jaggi31f71702016-05-04 16:43:04 -07002939 pw.println();
Wale Ogunwale61911492017-10-11 08:50:50 -07002940
2941 // Dump stack references
Wale Ogunwale734b8962020-01-21 12:17:42 -08002942 final ActivityStack homeStack = getRootHomeTask();
Wale Ogunwale61911492017-10-11 08:50:50 -07002943 if (homeStack != null) {
2944 pw.println(prefix + "homeStack=" + homeStack.getName());
2945 }
Wale Ogunwale734b8962020-01-21 12:17:42 -08002946 final ActivityStack pinnedStack = getRootPinnedTask();
Wale Ogunwale61911492017-10-11 08:50:50 -07002947 if (pinnedStack != null) {
2948 pw.println(prefix + "pinnedStack=" + pinnedStack.getName());
2949 }
Wale Ogunwale734b8962020-01-21 12:17:42 -08002950 final ActivityStack splitScreenPrimaryStack = getRootSplitScreenPrimaryTask();
Wale Ogunwale61911492017-10-11 08:50:50 -07002951 if (splitScreenPrimaryStack != null) {
2952 pw.println(prefix + "splitScreenPrimaryStack=" + splitScreenPrimaryStack.getName());
2953 }
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08002954 final ActivityStack recentsStack =
2955 getStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS);
Louis Chang677921f2019-12-06 16:44:24 +08002956 if (recentsStack != null) {
2957 pw.println(prefix + "recentsStack=" + recentsStack.getName());
2958 }
Wale Ogunwale61911492017-10-11 08:50:50 -07002959
2960 pw.println();
Jorim Jaggiad5d2842016-11-01 18:22:53 -07002961 mDividerControllerLocked.dump(prefix, pw);
Winson Chung655332c2016-10-31 13:14:28 -07002962 pw.println();
Jorim Jaggiad5d2842016-11-01 18:22:53 -07002963 mPinnedStackControllerLocked.dump(prefix, pw);
Wale Ogunwalec69694a2016-10-18 13:51:15 -07002964
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00002965 pw.println();
2966 mDisplayFrames.dump(prefix, pw);
Arthur Hung95b38a92018-07-20 18:56:12 +08002967 pw.println();
Riddle Hsu5ce4bb32018-07-18 16:11:30 +08002968 mDisplayPolicy.dump(prefix, pw);
2969 pw.println();
Riddle Hsuad256a12018-07-18 16:11:30 +08002970 mDisplayRotation.dump(prefix, pw);
2971 pw.println();
Arthur Hung95b38a92018-07-20 18:56:12 +08002972 mInputMonitor.dump(pw, " ");
Jorim Jaggif96c90a2018-09-26 16:55:15 +02002973 pw.println();
2974 mInsetsStateController.dump(prefix, pw);
Craig Mautner59c00972012-07-30 12:10:24 -07002975 }
Craig Mautnere0a38842013-12-16 16:14:02 -08002976
2977 @Override
2978 public String toString() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002979 return "Display " + mDisplayId + " info=" + mDisplayInfo + " stacks=" + mChildren;
Wale Ogunwale9adfe572016-09-08 20:43:58 -07002980 }
2981
2982 String getName() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002983 return "Display " + mDisplayId + " name=\"" + mDisplayInfo.name + "\"";
Craig Mautnere0a38842013-12-16 16:14:02 -08002984 }
Filip Gruszczynski466f3212015-09-21 17:57:57 -07002985
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002986 /** Returns true if the stack in the windowing mode is visible. */
2987 boolean isStackVisible(int windowingMode) {
Louis Changdc077272019-11-12 16:52:56 +08002988 final ActivityStack stack = getTopStackInWindowingMode(windowingMode);
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002989 return stack != null && stack.isVisible();
Andrii Kulian7cd7c2d2017-01-18 12:14:37 -08002990 }
2991
Wale Ogunwale9adfe572016-09-08 20:43:58 -07002992 /** Find the visible, touch-deliverable window under the given point */
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08002993 WindowState getTouchableWinAtPointLocked(float xf, float yf) {
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08002994 final int x = (int) xf;
2995 final int y = (int) yf;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002996 final WindowState touchedWin = getWindow(w -> {
2997 final int flags = w.mAttrs.flags;
2998 if (!w.isVisibleLw()) {
2999 return false;
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003000 }
3001 if ((flags & FLAG_NOT_TOUCHABLE) != 0) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003002 return false;
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003003 }
3004
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003005 w.getVisibleBounds(mTmpRect);
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003006 if (!mTmpRect.contains(x, y)) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003007 return false;
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003008 }
3009
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003010 w.getTouchableRegion(mTmpRegion);
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003011
3012 final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003013 return mTmpRegion.contains(x, y) || touchFlags == 0;
3014 });
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003015
3016 return touchedWin;
3017 }
Jorim Jaggi6626f542016-08-22 13:08:44 -07003018
Svetoslav Ganovaa076532016-08-01 19:16:43 -07003019 boolean canAddToastWindowForUid(int uid) {
3020 // We allow one toast window per UID being shown at a time.
Svet Ganovdaca8ee2017-01-21 17:40:40 -08003021 // Also if the app is focused adding more than one toast at
3022 // a time for better backwards compatibility.
3023 final WindowState focusedWindowForUid = getWindow(w ->
3024 w.mOwnerUid == uid && w.isFocused());
3025 if (focusedWindowForUid != null) {
3026 return true;
3027 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003028 final WindowState win = getWindow(w ->
3029 w.mAttrs.type == TYPE_TOAST && w.mOwnerUid == uid && !w.mPermanentlyHidden
chaviw8065f442019-11-18 13:20:58 -08003030 && !w.mWindowRemovalAllowed);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003031 return win == null;
Svetoslav Ganovaa076532016-08-01 19:16:43 -07003032 }
3033
Wale Ogunwale19e452e2016-10-12 12:36:29 -07003034 void scheduleToastWindowsTimeoutIfNeededLocked(WindowState oldFocus, WindowState newFocus) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -07003035 if (oldFocus == null || (newFocus != null && newFocus.mOwnerUid == oldFocus.mOwnerUid)) {
3036 return;
3037 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003038
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003039 // Used to communicate the old focus to the callback method.
3040 mTmpWindow = oldFocus;
3041
3042 forAllWindows(mScheduleToastTimeout, false /* traverseTopToBottom */);
Svetoslav Ganovaa076532016-08-01 19:16:43 -07003043 }
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07003044
Louis Changa9350fe2019-04-25 17:14:20 +08003045 /**
3046 * Looking for the focused window on this display if the top focused display hasn't been
3047 * found yet (topFocusedDisplayId is INVALID_DISPLAY) or per-display focused was allowed.
3048 *
3049 * @param topFocusedDisplayId Id of the top focused display.
3050 * @return The focused window or null if there isn't any or no need to seek.
3051 */
3052 WindowState findFocusedWindowIfNeeded(int topFocusedDisplayId) {
3053 return (mWmService.mPerDisplayFocusEnabled || topFocusedDisplayId == INVALID_DISPLAY)
3054 ? findFocusedWindow() : null;
Tiger Huang51c5a1d2018-12-11 20:24:51 +08003055 }
3056
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07003057 WindowState findFocusedWindow() {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003058 mTmpWindow = null;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07003059
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003060 forAllWindows(mFindFocusedWindow, true /* traverseTopToBottom */);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003061
3062 if (mTmpWindow == null) {
Adrian Roosb125e0b2019-10-02 14:55:14 +02003063 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: No focusable windows.");
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003064 return null;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07003065 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003066 return mTmpWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07003067 }
3068
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003069 /**
3070 * Update the focused window and make some adjustments if the focus has changed.
3071 *
3072 * @param mode Indicates the situation we are in. Possible modes are:
3073 * {@link WindowManagerService#UPDATE_FOCUS_NORMAL},
3074 * {@link WindowManagerService#UPDATE_FOCUS_PLACING_SURFACES},
3075 * {@link WindowManagerService#UPDATE_FOCUS_WILL_PLACE_SURFACES},
3076 * {@link WindowManagerService#UPDATE_FOCUS_REMOVING_FOCUS}
3077 * @param updateInputWindows Whether to sync the window information to the input module.
Louis Changa9350fe2019-04-25 17:14:20 +08003078 * @param topFocusedDisplayId Display id of current top focused display.
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003079 * @return {@code true} if the focused window has changed.
3080 */
Louis Changa9350fe2019-04-25 17:14:20 +08003081 boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows,
3082 int topFocusedDisplayId) {
3083 WindowState newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003084 if (mCurrentFocus == newFocus) {
3085 return false;
3086 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003087 boolean imWindowChanged = false;
Tiger Huang51c5a1d2018-12-11 20:24:51 +08003088 final WindowState imWindow = mInputMethodWindow;
3089 if (imWindow != null) {
3090 final WindowState prevTarget = mInputMethodTarget;
3091 final WindowState newTarget = computeImeTarget(true /* updateImeTarget*/);
3092 imWindowChanged = prevTarget != newTarget;
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003093
Tiger Huang51c5a1d2018-12-11 20:24:51 +08003094 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
3095 && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES) {
3096 assignWindowLayers(false /* setLayoutNeeded */);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003097 }
3098 }
3099
3100 if (imWindowChanged) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003101 mWmService.mWindowsChanged = true;
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003102 setLayoutNeeded();
Louis Changa9350fe2019-04-25 17:14:20 +08003103 newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
Tiger Huang51c5a1d2018-12-11 20:24:51 +08003104 }
3105 if (mCurrentFocus != newFocus) {
3106 mWmService.mH.obtainMessage(REPORT_FOCUS_CHANGE, this).sendToTarget();
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003107 }
3108
Adrian Roosb125e0b2019-10-02 14:55:14 +02003109 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Changing focus from %s to %s displayId=%d Callers=%s",
chaviw8065f442019-11-18 13:20:58 -08003110 mCurrentFocus, newFocus, getDisplayId(), Debug.getCallers(4));
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003111 final WindowState oldFocus = mCurrentFocus;
3112 mCurrentFocus = newFocus;
3113 mLosingFocus.remove(newFocus);
3114
3115 if (newFocus != null) {
3116 mWinAddedSinceNullFocus.clear();
3117 mWinRemovedSinceNullFocus.clear();
3118
3119 if (newFocus.canReceiveKeys()) {
3120 // Displaying a window implicitly causes dispatching to be unpaused.
3121 // This is to protect against bugs if someone pauses dispatching but
3122 // forgets to resume.
3123 newFocus.mToken.paused = false;
3124 }
3125 }
3126
Vishnu Nairf6ef1c72020-01-23 16:28:33 -08003127 onWindowFocusChanged(oldFocus, newFocus);
3128
Tiger Huang7c610aa2018-10-27 00:01:01 +08003129 int focusChanged = getDisplayPolicy().focusChangedLw(oldFocus, newFocus);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003130
3131 if (imWindowChanged && oldFocus != mInputMethodWindow) {
3132 // Focus of the input method window changed. Perform layout if needed.
3133 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
3134 performLayout(true /*initial*/, updateInputWindows);
3135 focusChanged &= ~FINISH_LAYOUT_REDO_LAYOUT;
3136 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
3137 // Client will do the layout, but we need to assign layers
3138 // for handleNewWindowLocked() below.
3139 assignWindowLayers(false /* setLayoutNeeded */);
3140 }
3141 }
3142
3143 if ((focusChanged & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
3144 // The change in focus caused us to need to do a layout. Okay.
3145 setLayoutNeeded();
3146 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
3147 performLayout(true /*initial*/, updateInputWindows);
3148 } else if (mode == UPDATE_FOCUS_REMOVING_FOCUS) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003149 mWmService.mRoot.performSurfacePlacement(false);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003150 }
3151 }
3152
3153 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
3154 // If we defer assigning layers, then the caller is responsible for doing this part.
3155 getInputMonitor().setInputFocusLw(newFocus, updateInputWindows);
3156 }
3157
3158 adjustForImeIfNeeded();
3159
3160 // We may need to schedule some toast windows to be removed. The toasts for an app that
3161 // does not have input focus are removed within a timeout to prevent apps to redress
3162 // other apps' UI.
3163 scheduleToastWindowsTimeoutIfNeededLocked(oldFocus, newFocus);
3164
3165 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
3166 pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
3167 }
3168 return true;
3169 }
3170
Vishnu Nairf6ef1c72020-01-23 16:28:33 -08003171 private static void onWindowFocusChanged(WindowState oldFocus, WindowState newFocus) {
3172 final Task focusedTask = newFocus != null ? newFocus.getTask() : null;
3173 final Task unfocusedTask = oldFocus != null ? oldFocus.getTask() : null;
3174 if (focusedTask == unfocusedTask) {
3175 return;
3176 }
3177 if (focusedTask != null) {
3178 focusedTask.onWindowFocusChanged(true /* hasFocus */);
3179 }
3180 if (unfocusedTask != null) {
3181 unfocusedTask.onWindowFocusChanged(false /* hasFocus */);
3182 }
3183 }
3184
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003185 /**
3186 * Set the new focused app to this display.
3187 *
Garfield Tane8d84ab2019-10-11 09:49:40 -07003188 * @param newFocus the new focused {@link ActivityRecord}.
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003189 * @return true if the focused app is changed.
3190 */
Garfield Tane8d84ab2019-10-11 09:49:40 -07003191 boolean setFocusedApp(ActivityRecord newFocus) {
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003192 if (newFocus != null) {
3193 final DisplayContent appDisplay = newFocus.getDisplayContent();
3194 if (appDisplay != this) {
3195 throw new IllegalStateException(newFocus + " is not on " + getName()
3196 + " but " + ((appDisplay != null) ? appDisplay.getName() : "none"));
3197 }
3198 }
3199 if (mFocusedApp == newFocus) {
3200 return false;
3201 }
3202 mFocusedApp = newFocus;
3203 getInputMonitor().setFocusedAppLw(newFocus);
3204 updateTouchExcludeRegion();
3205 return true;
3206 }
3207
Wale Ogunwalec69694a2016-10-18 13:51:15 -07003208 /** Updates the layer assignment of windows on this display. */
3209 void assignWindowLayers(boolean setLayoutNeeded) {
Jorim Jaggi4981f152019-03-26 18:58:45 +01003210 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers");
Robert Carrf59b8dd2017-10-02 18:58:36 -07003211 assignChildLayers(getPendingTransaction());
Wale Ogunwalec69694a2016-10-18 13:51:15 -07003212 if (setLayoutNeeded) {
3213 setLayoutNeeded();
3214 }
Robert Carrb1579c82017-09-05 14:54:47 -07003215
Robert Carrf59b8dd2017-10-02 18:58:36 -07003216 // We accumlate the layer changes in-to "getPendingTransaction()" but we defer
Robert Carrb1579c82017-09-05 14:54:47 -07003217 // the application of this transaction until the animation pass triggers
3218 // prepareSurfaces. This allows us to synchronize Z-ordering changes with
3219 // the hiding and showing of surfaces.
3220 scheduleAnimation();
Jorim Jaggi4981f152019-03-26 18:58:45 +01003221 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
Wale Ogunwalec69694a2016-10-18 13:51:15 -07003222 }
3223
Wale Ogunwale1666e312016-12-16 11:27:18 -08003224 // TODO: This should probably be called any time a visual change is made to the hierarchy like
3225 // moving containers or resizing them. Need to investigate the best way to have it automatically
3226 // happen so we don't run into issues with programmers forgetting to do it.
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003227 void layoutAndAssignWindowLayersIfNeeded() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003228 mWmService.mWindowsChanged = true;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003229 setLayoutNeeded();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003230
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003231 if (!mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003232 false /*updateInputWindows*/)) {
3233 assignWindowLayers(false /* setLayoutNeeded */);
3234 }
3235
Arthur Hung95b38a92018-07-20 18:56:12 +08003236 mInputMonitor.setUpdateInputWindowsNeededLw();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003237 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Arthur Hung95b38a92018-07-20 18:56:12 +08003238 mInputMonitor.updateInputWindowsLw(false /*force*/);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003239 }
3240
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003241 /** Returns true if a leaked surface was destroyed */
3242 boolean destroyLeakedSurfaces() {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003243 // Used to indicate that a surface was leaked.
3244 mTmpWindow = null;
3245 forAllWindows(w -> {
3246 final WindowStateAnimator wsa = w.mWinAnimator;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003247 if (wsa.mSurfaceController == null) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003248 return;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003249 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003250 if (!mWmService.mSessions.contains(wsa.mSession)) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003251 Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003252 + w + " surface=" + wsa.mSurfaceController
3253 + " token=" + w.mToken
3254 + " pid=" + w.mSession.mPid
3255 + " uid=" + w.mSession.mUid);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003256 wsa.destroySurface();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003257 mWmService.mForceRemoves.add(w);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003258 mTmpWindow = w;
Issei Suzukid4ee1cc2019-11-08 13:20:14 +01003259 } else if (w.mActivityRecord != null && !w.mActivityRecord.isClientVisible()) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003260 Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003261 + w + " surface=" + wsa.mSurfaceController
Garfield Tane8d84ab2019-10-11 09:49:40 -07003262 + " token=" + w.mActivityRecord);
Adrian Roosb125e0b2019-10-02 14:55:14 +02003263 ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE LEAK DESTROY: %s", w);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003264 wsa.destroySurface();
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003265 mTmpWindow = w;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003266 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003267 }, false /* traverseTopToBottom */);
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003268
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003269 return mTmpWindow != null;
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003270 }
3271
Riddle Hsuccf09402019-08-13 00:33:06 +08003272 boolean hasAlertWindowSurfaces() {
3273 for (int i = mWmService.mSessions.size() - 1; i >= 0; --i) {
3274 if (mWmService.mSessions.valueAt(i).hasAlertWindowSurfaces(this)) {
3275 return true;
3276 }
3277 }
3278 return false;
3279 }
3280
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003281 /**
lumark90120a82018-08-15 00:33:03 +08003282 * Set input method window for the display.
3283 * @param win Set when window added or Null when destroyed.
3284 */
3285 void setInputMethodWindowLocked(WindowState win) {
3286 mInputMethodWindow = win;
lumark70865a82018-09-17 16:56:26 +08003287 // Update display configuration for IME process.
3288 if (mInputMethodWindow != null) {
3289 final int imePid = mInputMethodWindow.mSession.mPid;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003290 mWmService.mAtmInternal.onImeWindowSetOnDisplay(imePid,
lumark70865a82018-09-17 16:56:26 +08003291 mInputMethodWindow.getDisplayId());
3292 }
lumark90120a82018-08-15 00:33:03 +08003293 computeImeTarget(true /* updateImeTarget */);
Tiger Huang332793b2019-10-29 23:21:27 +08003294 mInsetsStateController.getSourceProvider(ITYPE_IME).setWindow(win,
Jorim Jaggi9b4f4202020-01-28 17:05:06 +01003295 null /* frameProvider */, null /* imeFrameProvider */);
lumark90120a82018-08-15 00:33:03 +08003296 }
3297
3298 /**
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003299 * Determine and return the window that should be the IME target.
3300 * @param updateImeTarget If true the system IME target will be updated to match what we found.
3301 * @return The window that should be used as the IME target or null if there isn't any.
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003302 */
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003303 WindowState computeImeTarget(boolean updateImeTarget) {
lumark90120a82018-08-15 00:33:03 +08003304 if (mInputMethodWindow == null) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003305 // There isn't an IME so there shouldn't be a target...That was easy!
3306 if (updateImeTarget) {
3307 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from "
lumarkff0ab692018-11-05 20:32:30 +08003308 + mInputMethodTarget + " to null since mInputMethodWindow is null");
3309 setInputMethodTarget(null, mInputMethodTargetWaitingAnim);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003310 }
3311 return null;
3312 }
3313
lumarkff0ab692018-11-05 20:32:30 +08003314 final WindowState curTarget = mInputMethodTarget;
Chavi Weingarten3a748552018-05-14 17:32:42 +00003315 if (!canUpdateImeTarget()) {
3316 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Defer updating IME target");
3317 return curTarget;
3318 }
3319
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003320 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
3321 // same display. Or even when the current IME/target are not on the same screen as the next
3322 // IME/target. For now only look for input windows on the main screen.
Wale Ogunwale8e44f6c2017-03-09 15:25:10 -08003323 mUpdateImeTarget = updateImeTarget;
3324 WindowState target = getWindow(mComputeImeTargetPredicate);
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003325
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003326
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003327 // Yet more tricksyness! If this window is a "starting" window, we do actually want
3328 // to be on top of it, but it is not -really- where input will go. So look down below
3329 // for a real window to target...
3330 if (target != null && target.mAttrs.type == TYPE_APPLICATION_STARTING) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003331 final ActivityRecord activity = target.mActivityRecord;
3332 if (activity != null) {
3333 final WindowState betterTarget = activity.getImeTargetBelowWindow(target);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003334 if (betterTarget != null) {
3335 target = betterTarget;
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003336 }
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003337 }
3338 }
3339
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003340 if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM,
lumarkff0ab692018-11-05 20:32:30 +08003341 "Proposed new IME target: " + target + " for display: " + getDisplayId());
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003342
chaviw1c13ad32018-06-12 16:44:23 -07003343 // Now, a special case -- if the last target's window is in the process of exiting, but
Tarandeep Singh2d0aca42019-03-28 14:08:58 -07003344 // not removed, keep on the last target to avoid IME flicker.
chaviw1c13ad32018-06-12 16:44:23 -07003345 if (curTarget != null && !curTarget.mRemoved && curTarget.isDisplayedLw()
Tarandeep Singh2d0aca42019-03-28 14:08:58 -07003346 && curTarget.isClosing()) {
3347 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Not changing target till current window is"
3348 + " closing and not removed");
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003349 return curTarget;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003350 }
3351
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003352 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target=" + target
3353 + " updateImeTarget=" + updateImeTarget);
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003354
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003355 if (target == null) {
3356 if (updateImeTarget) {
3357 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget
3358 + " to null." + (SHOW_STACK_CRAWLS ? " Callers="
3359 + Debug.getCallers(4) : ""));
lumarkff0ab692018-11-05 20:32:30 +08003360 setInputMethodTarget(null, mInputMethodTargetWaitingAnim);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003361 }
3362
3363 return null;
3364 }
3365
3366 if (updateImeTarget) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003367 ActivityRecord activity = curTarget == null ? null : curTarget.mActivityRecord;
3368 if (activity != null) {
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003369
3370 // Now some fun for dealing with window animations that modify the Z order. We need
3371 // to look at all windows below the current target that are in this app, finding the
3372 // highest visible one in layering.
3373 WindowState highestTarget = null;
lumark5341d1c2019-12-14 01:54:02 +08003374 if (activity.isAnimating(PARENTS | TRANSITION)) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003375 highestTarget = activity.getHighestAnimLayerWindow(curTarget);
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003376 }
3377
3378 if (highestTarget != null) {
lumark9bca6b42019-10-17 18:35:22 +08003379 if (DEBUG_INPUT_METHOD) {
3380 Slog.v(TAG_WM, mAppTransition + " " + highestTarget + " animating="
3381 + highestTarget.isAnimating(TRANSITION | PARENTS));
3382 }
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003383
lumark588a3e82018-07-20 18:53:54 +08003384 if (mAppTransition.isTransitionSet()) {
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003385 // If we are currently setting up for an animation, hold everything until we
3386 // can find out what will happen.
Jorim Jaggib0fc8172017-11-23 17:04:08 +00003387 setInputMethodTarget(highestTarget, true);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003388 return highestTarget;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003389 }
3390 }
3391 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003392
3393 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
3394 + target + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
Jorim Jaggib0fc8172017-11-23 17:04:08 +00003395 setInputMethodTarget(target, false);
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003396 }
3397
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003398 return target;
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003399 }
3400
lumarkff0ab692018-11-05 20:32:30 +08003401 /**
3402 * Calling {@link #computeImeTarget(boolean)} to update the input method target window in
3403 * the candidate app window token if needed.
3404 */
Garfield Tane8d84ab2019-10-11 09:49:40 -07003405 void computeImeTargetIfNeeded(ActivityRecord candidate) {
3406 if (mInputMethodTarget != null && mInputMethodTarget.mActivityRecord == candidate) {
lumarkff0ab692018-11-05 20:32:30 +08003407 computeImeTarget(true /* updateImeTarget */);
3408 }
3409 }
3410
Evan Rosky8d782e02019-10-14 15:43:53 -07003411 boolean isImeAttachedToApp() {
3412 return (mInputMethodTarget != null && mInputMethodTarget.mActivityRecord != null
3413 && mInputMethodTarget.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
3414 // An activity with override bounds should be letterboxed inside its parent bounds,
3415 // so it doesn't fill the screen.
3416 && mInputMethodTarget.mActivityRecord.matchParentBounds());
3417 }
3418
Jorim Jaggib0fc8172017-11-23 17:04:08 +00003419 private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) {
lumarkff0ab692018-11-05 20:32:30 +08003420 if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003421 return;
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003422 }
3423
lumarkff0ab692018-11-05 20:32:30 +08003424 mInputMethodTarget = target;
3425 mInputMethodTargetWaitingAnim = targetWaitingAnim;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003426 assignWindowLayers(false /* setLayoutNeeded */);
Evan Rosky8d782e02019-10-14 15:43:53 -07003427 mInputMethodControlTarget = computeImeControlTarget();
3428 mInsetsStateController.onImeTargetChanged(mInputMethodControlTarget);
Tarandeep Singha6f35612019-01-11 19:50:46 -08003429 updateImeParent();
3430 }
3431
3432 private void updateImeParent() {
Jackal Guo818c3f12019-03-08 18:00:39 +08003433 // Force attaching IME to the display when magnifying, or it would be magnified with
3434 // target app together.
3435 final boolean shouldAttachToDisplay = (mMagnificationSpec != null);
3436 final SurfaceControl newParent =
chaviw8065f442019-11-18 13:20:58 -08003437 shouldAttachToDisplay ? mWindowContainers.getSurfaceControl() : computeImeParent();
Tarandeep Singha6f35612019-01-11 19:50:46 -08003438 if (newParent != null) {
Tiger Huanged6794e2019-05-07 20:07:59 +08003439 getPendingTransaction().reparent(mImeWindowsContainers.mSurfaceControl, newParent);
Tarandeep Singha6f35612019-01-11 19:50:46 -08003440 scheduleAnimation();
3441 }
3442 }
3443
3444 /**
3445 * Computes the window the IME should be attached to.
3446 */
3447 @VisibleForTesting
3448 SurfaceControl computeImeParent() {
3449
3450 // Attach it to app if the target is part of an app and such app is covering the entire
3451 // screen. If it's not covering the entire screen the IME might extend beyond the apps
3452 // bounds.
Evan Rosky8d782e02019-10-14 15:43:53 -07003453 if (isImeAttachedToApp()) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003454 return mInputMethodTarget.mActivityRecord.getSurfaceControl();
Tarandeep Singha6f35612019-01-11 19:50:46 -08003455 }
3456
3457 // Otherwise, we just attach it to the display.
chaviw8065f442019-11-18 13:20:58 -08003458 return mWindowContainers.getSurfaceControl();
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003459 }
3460
Evan Rosky8d782e02019-10-14 15:43:53 -07003461 /**
3462 * Computes which control-target the IME should be attached to.
3463 */
3464 @VisibleForTesting
3465 InsetsControlTarget computeImeControlTarget() {
3466 if (!isImeAttachedToApp() && mRemoteInsetsControlTarget != null) {
3467 return mRemoteInsetsControlTarget;
3468 }
3469
3470 // Otherwise, we just use the ime target
3471 return mInputMethodTarget;
3472 }
3473
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07003474 void setLayoutNeeded() {
3475 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "setLayoutNeeded: callers=" + Debug.getCallers(3));
3476 mLayoutNeeded = true;
3477 }
3478
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003479 private void clearLayoutNeeded() {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07003480 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "clearLayoutNeeded: callers=" + Debug.getCallers(3));
3481 mLayoutNeeded = false;
3482 }
3483
3484 boolean isLayoutNeeded() {
3485 return mLayoutNeeded;
3486 }
3487
Wale Ogunwale02319a62016-09-26 15:21:22 -07003488 void dumpTokens(PrintWriter pw, boolean dumpAll) {
3489 if (mTokenMap.isEmpty()) {
3490 return;
3491 }
3492 pw.println(" Display #" + mDisplayId);
3493 final Iterator<WindowToken> it = mTokenMap.values().iterator();
3494 while (it.hasNext()) {
3495 final WindowToken token = it.next();
3496 pw.print(" ");
3497 pw.print(token);
3498 if (dumpAll) {
3499 pw.println(':');
Jorim Jaggif5f9e122017-10-24 18:21:09 +02003500 token.dump(pw, " ", dumpAll);
Wale Ogunwale02319a62016-09-26 15:21:22 -07003501 } else {
3502 pw.println();
3503 }
3504 }
lumark588a3e82018-07-20 18:53:54 +08003505
Evan Rosky2289ba12018-11-19 18:28:18 -08003506 if (!mOpeningApps.isEmpty() || !mClosingApps.isEmpty() || !mChangingApps.isEmpty()) {
lumark588a3e82018-07-20 18:53:54 +08003507 pw.println();
3508 if (mOpeningApps.size() > 0) {
3509 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
3510 }
3511 if (mClosingApps.size() > 0) {
3512 pw.print(" mClosingApps="); pw.println(mClosingApps);
3513 }
Evan Rosky2289ba12018-11-19 18:28:18 -08003514 if (mChangingApps.size() > 0) {
3515 pw.print(" mChangingApps="); pw.println(mChangingApps);
3516 }
lumark588a3e82018-07-20 18:53:54 +08003517 }
3518
3519 mUnknownAppVisibilityController.dump(pw, " ");
Wale Ogunwale02319a62016-09-26 15:21:22 -07003520 }
3521
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07003522 void dumpWindowAnimators(PrintWriter pw, String subPrefix) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003523 final int[] index = new int[1];
3524 forAllWindows(w -> {
3525 final WindowStateAnimator wAnim = w.mWinAnimator;
3526 pw.println(subPrefix + "Window #" + index[0] + ": " + wAnim);
3527 index[0] = index[0] + 1;
3528 }, false /* traverseTopToBottom */);
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07003529 }
3530
Jorim Jaggife762342016-10-13 14:33:27 +02003531 /**
3532 * Starts the Keyguard exit animation on all windows that don't belong to an app token.
3533 */
Issei Suzuki5609ccb2019-06-13 15:04:08 +02003534 void startKeyguardExitOnNonAppWindows(boolean onWallpaper, boolean goingToShade,
3535 boolean subtle) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003536 final WindowManagerPolicy policy = mWmService.mPolicy;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003537 forAllWindows(w -> {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003538 if (w.mActivityRecord == null && policy.canBeHiddenByKeyguardLw(w)
Jorim Jaggic6ae42a2017-05-08 23:42:02 +02003539 && w.wouldBeVisibleIfPolicyIgnored() && !w.isVisible()) {
Issei Suzuki5609ccb2019-06-13 15:04:08 +02003540 w.startAnimation(policy.createHiddenByKeyguardExit(
3541 onWallpaper, goingToShade, subtle));
Jorim Jaggife762342016-10-13 14:33:27 +02003542 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003543 }, true /* traverseTopToBottom */);
Jorim Jaggife762342016-10-13 14:33:27 +02003544 }
3545
Riddle Hsub2297ad2019-07-26 23:37:25 -06003546 /** @return {@code true} if there is window to wait before enabling the screen. */
3547 boolean shouldWaitForSystemDecorWindowsOnBoot() {
3548 if (!isDefaultDisplay && !supportsSystemDecorations()) {
3549 // Nothing to wait because the secondary display doesn't support system decorations,
3550 // there is no wallpaper, keyguard (status bar) or application (home) window to show
3551 // during booting.
3552 return false;
3553 }
Wale Ogunwale494009b82016-10-21 09:01:38 -07003554
Riddle Hsub2297ad2019-07-26 23:37:25 -06003555 final SparseBooleanArray drawnWindowTypes = new SparseBooleanArray();
3556 // Presuppose keyguard is drawn because if its window isn't attached, we don't know if it
3557 // wants to be shown or hidden, then it should not delay enabling the screen.
wilsonshihe8321942019-10-18 18:39:46 +08003558 drawnWindowTypes.put(TYPE_NOTIFICATION_SHADE, true);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003559
Riddle Hsub2297ad2019-07-26 23:37:25 -06003560 final WindowState visibleNotDrawnWindow = getWindow(w -> {
3561 if (w.mViewVisibility == View.VISIBLE && !w.mObscured && !w.isDrawnLw()) {
Wale Ogunwale494009b82016-10-21 09:01:38 -07003562 return true;
3563 }
3564 if (w.isDrawnLw()) {
Riddle Hsub2297ad2019-07-26 23:37:25 -06003565 final int type = w.mAttrs.type;
3566 if (type == TYPE_BOOT_PROGRESS || type == TYPE_BASE_APPLICATION
3567 || type == TYPE_WALLPAPER) {
3568 drawnWindowTypes.put(type, true);
wilsonshihe8321942019-10-18 18:39:46 +08003569 } else if (type == TYPE_NOTIFICATION_SHADE) {
3570 drawnWindowTypes.put(TYPE_NOTIFICATION_SHADE,
3571 mWmService.mPolicy.isKeyguardDrawnLw());
Wale Ogunwale494009b82016-10-21 09:01:38 -07003572 }
3573 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003574 return false;
3575 });
3576
Riddle Hsub2297ad2019-07-26 23:37:25 -06003577 if (visibleNotDrawnWindow != null) {
3578 // Wait for the visible window to be drawn.
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003579 return true;
Wale Ogunwale494009b82016-10-21 09:01:38 -07003580 }
3581
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003582 // if the wallpaper service is disabled on the device, we're never going to have
3583 // wallpaper, don't bother waiting for it
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003584 boolean wallpaperEnabled = mWmService.mContext.getResources().getBoolean(
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003585 com.android.internal.R.bool.config_enableWallpaperService)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003586 && mWmService.mContext.getResources().getBoolean(
chaviw8065f442019-11-18 13:20:58 -08003587 com.android.internal.R.bool.config_checkWallpaperAtBoot)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003588 && !mWmService.mOnlyCore;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003589
Riddle Hsub2297ad2019-07-26 23:37:25 -06003590 final boolean haveBootMsg = drawnWindowTypes.get(TYPE_BOOT_PROGRESS);
3591 final boolean haveApp = drawnWindowTypes.get(TYPE_BASE_APPLICATION);
3592 final boolean haveWallpaper = drawnWindowTypes.get(TYPE_WALLPAPER);
wilsonshihe8321942019-10-18 18:39:46 +08003593 final boolean haveKeyguard = drawnWindowTypes.get(TYPE_NOTIFICATION_SHADE);
Riddle Hsub2297ad2019-07-26 23:37:25 -06003594
Adrian Roosb125e0b2019-10-02 14:55:14 +02003595 ProtoLog.i(WM_DEBUG_SCREEN_ON,
Riddle Hsub2297ad2019-07-26 23:37:25 -06003596 "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b "
3597 + "wallEnabled=%b haveKeyguard=%b",
3598 mWmService.mSystemBooted, mWmService.mShowingBootMessages, haveBootMsg,
3599 haveApp, haveWallpaper, wallpaperEnabled, haveKeyguard);
Wale Ogunwale494009b82016-10-21 09:01:38 -07003600
3601 // If we are turning on the screen to show the boot message, don't do it until the boot
3602 // message is actually displayed.
Riddle Hsub2297ad2019-07-26 23:37:25 -06003603 if (!mWmService.mSystemBooted && !haveBootMsg) {
Wale Ogunwale494009b82016-10-21 09:01:38 -07003604 return true;
3605 }
3606
3607 // If we are turning on the screen after the boot is completed normally, don't do so until
3608 // we have the application and wallpaper.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003609 if (mWmService.mSystemBooted
Riddle Hsub2297ad2019-07-26 23:37:25 -06003610 && ((!haveApp && !haveKeyguard) || (wallpaperEnabled && !haveWallpaper))) {
Wale Ogunwale494009b82016-10-21 09:01:38 -07003611 return true;
3612 }
3613
3614 return false;
3615 }
3616
Jorim Jaggi8f520872018-08-14 17:00:20 +02003617 void updateWindowsForAnimator() {
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003618 forAllWindows(mUpdateWindowsForAnimator, true /* traverseTopToBottom */);
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07003619 }
3620
Yohei Yukawa41f89c32018-09-19 14:30:04 -07003621 boolean isInputMethodClientFocus(int uid, int pid) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003622 final WindowState imFocus = computeImeTarget(false /* updateImeTarget */);
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003623 if (imFocus == null) {
3624 return false;
3625 }
3626
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003627 if (DEBUG_INPUT_METHOD) {
3628 Slog.i(TAG_WM, "Desired input method target: " + imFocus);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003629 Slog.i(TAG_WM, "Current focus: " + mCurrentFocus + " displayId=" + mDisplayId);
3630 Slog.i(TAG_WM, "Last focus: " + mLastFocus + " displayId=" + mDisplayId);
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003631 }
3632
Wale Ogunwale494009b82016-10-21 09:01:38 -07003633 if (DEBUG_INPUT_METHOD) {
Yohei Yukawa41f89c32018-09-19 14:30:04 -07003634 Slog.i(TAG_WM, "IM target uid/pid: " + imFocus.mSession.mUid
3635 + "/" + imFocus.mSession.mPid);
3636 Slog.i(TAG_WM, "Requesting client uid/pid: " + uid + "/" + pid);
Wale Ogunwale494009b82016-10-21 09:01:38 -07003637 }
3638
Yohei Yukawa41f89c32018-09-19 14:30:04 -07003639 return imFocus.mSession.mUid == uid && imFocus.mSession.mPid == pid;
Wale Ogunwale494009b82016-10-21 09:01:38 -07003640 }
3641
3642 boolean hasSecureWindowOnScreen() {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003643 final WindowState win = getWindow(
3644 w -> w.isOnScreen() && (w.mAttrs.flags & FLAG_SECURE) != 0);
3645 return win != null;
Wale Ogunwale494009b82016-10-21 09:01:38 -07003646 }
3647
Jorim Jaggi956ca412019-01-07 14:49:14 +01003648 void hideTransientBars() {
3649 // TODO(b/118118435): Remove this after migration
3650 final int transientFlags = View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
3651 statusBarVisibilityChanged(mLastStatusBarVisibility & ~transientFlags);
3652
3653 getInsetsPolicy().hideTransient();
3654 }
3655
Tiger Huang7c610aa2018-10-27 00:01:01 +08003656 void statusBarVisibilityChanged(int visibility) {
3657 mLastStatusBarVisibility = visibility;
3658 visibility = getDisplayPolicy().adjustSystemUiVisibilityLw(visibility);
3659 updateStatusBarVisibilityLocked(visibility);
3660 }
3661
3662 private boolean updateStatusBarVisibilityLocked(int visibility) {
3663 if (mLastDispatchedSystemUiVisibility == visibility) {
3664 return false;
3665 }
3666 final int globalDiff = (visibility ^ mLastDispatchedSystemUiVisibility)
3667 // We are only interested in differences of one of the
3668 // clearable flags...
3669 & View.SYSTEM_UI_CLEARABLE_FLAGS
3670 // ...if it has actually been cleared.
3671 & ~visibility;
3672
3673 mLastDispatchedSystemUiVisibility = visibility;
3674 if (isDefaultDisplay) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003675 mWmService.mInputManager.setSystemUiVisibility(visibility);
Tiger Huang7c610aa2018-10-27 00:01:01 +08003676 }
3677 updateSystemUiVisibility(visibility, globalDiff);
3678 return true;
3679 }
3680
Wale Ogunwale494009b82016-10-21 09:01:38 -07003681 void updateSystemUiVisibility(int visibility, int globalDiff) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003682 forAllWindows(w -> {
Wale Ogunwale494009b82016-10-21 09:01:38 -07003683 try {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003684 final int curValue = w.mSystemUiVisibility;
3685 final int diff = (curValue ^ visibility) & globalDiff;
3686 final int newValue = (curValue & ~diff) | (visibility & diff);
Wale Ogunwale494009b82016-10-21 09:01:38 -07003687 if (newValue != curValue) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003688 w.mSeq++;
3689 w.mSystemUiVisibility = newValue;
Wale Ogunwale494009b82016-10-21 09:01:38 -07003690 }
Tiger Huang41ae5e82020-01-17 18:17:20 +08003691 if ((newValue != curValue || w.mAttrs.hasSystemUiListeners)
3692 && ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003693 w.mClient.dispatchSystemUiVisibilityChanged(w.mSeq,
Wale Ogunwale494009b82016-10-21 09:01:38 -07003694 visibility, newValue, diff);
3695 }
3696 } catch (RemoteException e) {
3697 // so sorry
3698 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003699 }, true /* traverseTopToBottom */);
Wale Ogunwale494009b82016-10-21 09:01:38 -07003700 }
3701
Tiger Huang7c610aa2018-10-27 00:01:01 +08003702 void reevaluateStatusBarVisibility() {
3703 int visibility = getDisplayPolicy().adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
3704 if (updateStatusBarVisibilityLocked(visibility)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003705 mWmService.mWindowPlacerLocked.requestTraversal();
Tiger Huang7c610aa2018-10-27 00:01:01 +08003706 }
3707 }
3708
Wale Ogunwale494009b82016-10-21 09:01:38 -07003709 void onWindowFreezeTimeout() {
3710 Slog.w(TAG_WM, "Window freeze timeout expired.");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003711 mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003712
3713 forAllWindows(w -> {
Bryce Lee8c3cf382017-07-06 19:47:10 -07003714 if (!w.getOrientationChanging()) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003715 return;
Wale Ogunwale494009b82016-10-21 09:01:38 -07003716 }
Robert Carr9c1c3a02017-08-08 12:59:01 -07003717 w.orientationChangeTimedOut();
Wale Ogunwale494009b82016-10-21 09:01:38 -07003718 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003719 - mWmService.mDisplayFreezeTime);
Wale Ogunwale494009b82016-10-21 09:01:38 -07003720 Slog.w(TAG_WM, "Force clearing orientation change: " + w);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003721 }, true /* traverseTopToBottom */);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003722 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale494009b82016-10-21 09:01:38 -07003723 }
3724
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003725 // TODO: Super crazy long method that should be broken down...
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003726 void applySurfaceChangesTransaction(boolean recoveringMemory) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003727 final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003728
3729 mTmpUpdateAllDrawn.clear();
3730
3731 int repeats = 0;
3732 do {
3733 repeats++;
3734 if (repeats > 6) {
3735 Slog.w(TAG, "Animation repeat aborted after too many iterations");
3736 clearLayoutNeeded();
3737 break;
3738 }
3739
3740 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("On entry to LockedInner",
3741 pendingLayoutChanges);
3742
wilsonshihc32538e2018-11-07 17:27:34 +08003743 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
3744 mWallpaperController.adjustWallpaperWindows();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003745 }
3746
Riddle Hsu654a6f92018-07-13 22:59:36 +08003747 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003748 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Riddle Hsuccf09402019-08-13 00:33:06 +08003749 if (updateOrientation()) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003750 setLayoutNeeded();
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07003751 sendNewConfiguration();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003752 }
3753 }
3754
3755 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
3756 setLayoutNeeded();
3757 }
3758
3759 // FIRST LOOP: Perform a layout, if needed.
3760 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
3761 performLayout(repeats == 1, false /* updateInputWindows */);
3762 } else {
3763 Slog.w(TAG, "Layout repeat skipped after too many iterations");
3764 }
3765
3766 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think it is animating.
3767 pendingLayoutChanges = 0;
3768
Jorim Jaggi4981f152019-03-26 18:58:45 +01003769 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy");
3770 try {
3771 mDisplayPolicy.beginPostLayoutPolicyLw();
3772 forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */);
3773 pendingLayoutChanges |= mDisplayPolicy.finishPostLayoutPolicyLw();
3774 } finally {
3775 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
3776 }
Tiger Huang7c610aa2018-10-27 00:01:01 +08003777 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
3778 "after finishPostLayoutPolicyLw", pendingLayoutChanges);
chaviw8065f442019-11-18 13:20:58 -08003779 mInsetsStateController.onPostLayout();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003780 } while (pendingLayoutChanges != 0);
3781
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003782 mTmpApplySurfaceChangesTransactionState.reset();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003783
Jorim Jaggi4981f152019-03-26 18:58:45 +01003784 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyWindowSurfaceChanges");
3785 try {
3786 forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
3787 } finally {
3788 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
3789 }
Jorim Jaggi6b0f8462018-01-05 17:23:47 +01003790 prepareSurfaces();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003791
Jorim Jaggif1292892018-09-10 11:58:13 +02003792 mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003793 mWmService.mDisplayManagerInternal.setDisplayProperties(mDisplayId,
Jorim Jaggif1292892018-09-10 11:58:13 +02003794 mLastHasContent,
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003795 mTmpApplySurfaceChangesTransactionState.preferredRefreshRate,
3796 mTmpApplySurfaceChangesTransactionState.preferredModeId,
Galia Peycheva056b3ee2019-06-26 14:05:12 +02003797 mTmpApplySurfaceChangesTransactionState.preferMinimalPostProcessing,
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003798 true /* inTraversal, must call performTraversalInTrans... below */);
3799
Lucas Dupin1ead7fc2017-05-24 14:14:44 -07003800 final boolean wallpaperVisible = mWallpaperController.isWallpaperVisible();
3801 if (wallpaperVisible != mLastWallpaperVisible) {
3802 mLastWallpaperVisible = wallpaperVisible;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003803 mWmService.mWallpaperVisibilityListeners.notifyWallpaperVisibilityChanged(this);
Lucas Dupin1ead7fc2017-05-24 14:14:44 -07003804 }
3805
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003806 while (!mTmpUpdateAllDrawn.isEmpty()) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003807 final ActivityRecord activity = mTmpUpdateAllDrawn.removeLast();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003808 // See if any windows have been drawn, so they (and others associated with them)
3809 // can now be shown.
Garfield Tane8d84ab2019-10-11 09:49:40 -07003810 activity.updateAllDrawn();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003811 }
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003812 }
3813
Bryce Leef3c6a472017-11-14 14:53:06 -08003814 private void updateBounds() {
Evan Rosky39b6f232018-10-30 18:35:41 -07003815 calculateBounds(mDisplayInfo, mTmpBounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08003816 setBounds(mTmpBounds);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08003817 if (mPortalWindowHandle != null && mParentSurfaceControl != null) {
3818 mPortalWindowHandle.touchableRegion.getBounds(mTmpRect);
3819 if (!mTmpBounds.equals(mTmpRect)) {
3820 mPortalWindowHandle.touchableRegion.set(mTmpBounds);
Tiger Huanged6794e2019-05-07 20:07:59 +08003821 getPendingTransaction().setInputWindowInfo(
3822 mParentSurfaceControl, mPortalWindowHandle);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08003823 }
3824 }
Bryce Leef3c6a472017-11-14 14:53:06 -08003825 }
3826
3827 // Determines the current display bounds based on the current state
Evan Rosky39b6f232018-10-30 18:35:41 -07003828 private void calculateBounds(DisplayInfo displayInfo, Rect out) {
Bryce Leef3c6a472017-11-14 14:53:06 -08003829 // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
Evan Rosky39b6f232018-10-30 18:35:41 -07003830 final int rotation = displayInfo.rotation;
3831 boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
Bryce Leef3c6a472017-11-14 14:53:06 -08003832 final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
3833 final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
Evan Rosky39b6f232018-10-30 18:35:41 -07003834 int width = displayInfo.logicalWidth;
Bryce Leef3c6a472017-11-14 14:53:06 -08003835 int left = (physWidth - width) / 2;
Evan Rosky39b6f232018-10-30 18:35:41 -07003836 int height = displayInfo.logicalHeight;
Bryce Leef3c6a472017-11-14 14:53:06 -08003837 int top = (physHeight - height) / 2;
3838 out.set(left, top, left + width, top + height);
3839 }
3840
Bryce Leef3c6a472017-11-14 14:53:06 -08003841 private void getBounds(Rect out, int orientation) {
3842 getBounds(out);
3843
3844 // Rotate the Rect if needed.
3845 final int currentRotation = mDisplayInfo.rotation;
3846 final int rotationDelta = deltaRotation(currentRotation, orientation);
3847 if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
3848 createRotationMatrix(rotationDelta, mBaseDisplayWidth, mBaseDisplayHeight, mTmpMatrix);
3849 mTmpRectF.set(out);
3850 mTmpMatrix.mapRect(mTmpRectF);
3851 mTmpRectF.round(out);
3852 }
3853 }
3854
Evan Rosky730f6e82018-12-03 17:40:11 -08003855 /** @returns the orientation of the display when it's rotation is ROTATION_0. */
3856 int getNaturalOrientation() {
3857 return mBaseDisplayWidth < mBaseDisplayHeight
3858 ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
3859 }
3860
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003861 void performLayout(boolean initial, boolean updateInputWindows) {
Jorim Jaggi4981f152019-03-26 18:58:45 +01003862 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performLayout");
3863 try {
3864 performLayoutNoTrace(initial, updateInputWindows);
3865 } finally {
3866 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
3867 }
3868 }
3869
3870 private void performLayoutNoTrace(boolean initial, boolean updateInputWindows) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003871 if (!isLayoutNeeded()) {
3872 return;
3873 }
3874 clearLayoutNeeded();
3875
3876 final int dw = mDisplayInfo.logicalWidth;
3877 final int dh = mDisplayInfo.logicalHeight;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003878 if (DEBUG_LAYOUT) {
3879 Slog.v(TAG, "-------------------------------------");
Jorim Jaggi4981f152019-03-26 18:58:45 +01003880 Slog.v(TAG, "performLayout: needed=" + isLayoutNeeded() + " dw=" + dw
3881 + " dh=" + dh);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003882 }
3883
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01003884 mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
3885 calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
Jorim Jaggi4981f152019-03-26 18:58:45 +01003886 // TODO: Not sure if we really need to set the rotation here since we are updating from
3887 // the display info above...
Riddle Hsuccf09402019-08-13 00:33:06 +08003888 mDisplayFrames.mRotation = getRotation();
Tiger Huang7c610aa2018-10-27 00:01:01 +08003889 mDisplayPolicy.beginLayoutLw(mDisplayFrames, getConfiguration().uiMode);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003890
Adrian Roos5251b1d2018-03-23 18:57:43 +01003891 int seq = mLayoutSeq + 1;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003892 if (seq < 0) seq = 0;
Adrian Roos5251b1d2018-03-23 18:57:43 +01003893 mLayoutSeq = seq;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003894
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003895 // Used to indicate that we have processed the dream window and all additional windows are
3896 // behind it.
3897 mTmpWindow = null;
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003898 mTmpInitial = initial;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003899
3900 // First perform layout of any root windows (not attached to another window).
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003901 forAllWindows(mPerformLayout, true /* traverseTopToBottom */);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003902
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003903 // Used to indicate that we have processed the dream window and all additional attached
3904 // windows are behind it.
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003905 mTmpWindow2 = mTmpWindow;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003906 mTmpWindow = null;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003907
3908 // Now perform layout of attached windows, which usually depend on the position of the
3909 // window they are attached to. XXX does not deal with windows that are attached to windows
3910 // that are themselves attached.
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003911 forAllWindows(mPerformLayoutAttached, true /* traverseTopToBottom */);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003912
3913 // Window frames may have changed. Tell the input dispatcher about it.
Arthur Hung95b38a92018-07-20 18:56:12 +08003914 mInputMonitor.layoutInputConsumers(dw, dh);
3915 mInputMonitor.setUpdateInputWindowsNeededLw();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003916 if (updateInputWindows) {
Arthur Hung95b38a92018-07-20 18:56:12 +08003917 mInputMonitor.updateInputWindowsLw(false /*force*/);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003918 }
3919
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003920 mWmService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003921 }
3922
3923 /**
3924 * Takes a snapshot of the display. In landscape mode this grabs the whole screen.
3925 * In portrait mode, it grabs the full screenshot.
3926 *
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003927 * @param config of the output bitmap
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003928 */
chaviw0315a1a2018-03-05 15:28:35 -08003929 Bitmap screenshotDisplayLocked(Bitmap.Config config) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003930 if (!mWmService.mPolicy.isScreenOn()) {
chaviw0315a1a2018-03-05 15:28:35 -08003931 if (DEBUG_SCREENSHOT) {
3932 Slog.i(TAG_WM, "Attempted to take screenshot while display was off.");
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003933 }
chaviw0315a1a2018-03-05 15:28:35 -08003934 return null;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003935 }
chaviwfbe47df2017-11-10 16:14:49 -08003936
chaviw0315a1a2018-03-05 15:28:35 -08003937 int dw = mDisplayInfo.logicalWidth;
3938 int dh = mDisplayInfo.logicalHeight;
chaviwfbe47df2017-11-10 16:14:49 -08003939
chaviw0315a1a2018-03-05 15:28:35 -08003940 if (dw <= 0 || dh <= 0) {
3941 return null;
3942 }
chaviwfbe47df2017-11-10 16:14:49 -08003943
chaviw0315a1a2018-03-05 15:28:35 -08003944 final Rect frame = new Rect(0, 0, dw, dh);
chaviwfbe47df2017-11-10 16:14:49 -08003945
chaviw0315a1a2018-03-05 15:28:35 -08003946 // The screenshot API does not apply the current screen rotation.
3947 int rot = mDisplay.getRotation();
chaviwfbe47df2017-11-10 16:14:49 -08003948
chaviw0315a1a2018-03-05 15:28:35 -08003949 if (rot == ROTATION_90 || rot == ROTATION_270) {
3950 rot = (rot == ROTATION_90) ? ROTATION_270 : ROTATION_90;
3951 }
chaviwfbe47df2017-11-10 16:14:49 -08003952
chaviw0315a1a2018-03-05 15:28:35 -08003953 // SurfaceFlinger is not aware of orientation, so convert our logical
3954 // crop to SurfaceFlinger's portrait orientation.
3955 convertCropForSurfaceFlinger(frame, rot, dw, dh);
3956
3957 final ScreenRotationAnimation screenRotationAnimation =
Vadim Caenb3715832019-08-13 17:06:38 +02003958 mWmService.mRoot.getDisplayContent(DEFAULT_DISPLAY).getRotationAnimation();
chaviw0315a1a2018-03-05 15:28:35 -08003959 final boolean inRotation = screenRotationAnimation != null &&
3960 screenRotationAnimation.isAnimating();
3961 if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG_WM, "Taking screenshot while rotating");
3962
3963 // TODO(b/68392460): We should screenshot Task controls directly
3964 // but it's difficult at the moment as the Task doesn't have the
3965 // correct size set.
chaviw08520a02018-09-10 16:44:56 -07003966 final Bitmap bitmap = SurfaceControl.screenshot(frame, dw, dh, inRotation, rot);
chaviw0315a1a2018-03-05 15:28:35 -08003967 if (bitmap == null) {
3968 Slog.w(TAG_WM, "Failed to take screenshot");
3969 return null;
3970 }
3971
3972 // Create a copy of the screenshot that is immutable and backed in ashmem.
3973 // This greatly reduces the overhead of passing the bitmap between processes.
3974 final Bitmap ret = bitmap.createAshmemBitmap(config);
3975 bitmap.recycle();
3976 return ret;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003977 }
3978
3979 // TODO: Can this use createRotationMatrix()?
3980 private static void convertCropForSurfaceFlinger(Rect crop, int rot, int dw, int dh) {
3981 if (rot == Surface.ROTATION_90) {
3982 final int tmp = crop.top;
3983 crop.top = dw - crop.right;
3984 crop.right = crop.bottom;
3985 crop.bottom = dw - crop.left;
3986 crop.left = tmp;
3987 } else if (rot == Surface.ROTATION_180) {
3988 int tmp = crop.top;
3989 crop.top = dh - crop.bottom;
3990 crop.bottom = dh - tmp;
3991 tmp = crop.right;
3992 crop.right = dw - crop.left;
3993 crop.left = dw - tmp;
3994 } else if (rot == Surface.ROTATION_270) {
3995 final int tmp = crop.top;
3996 crop.top = crop.left;
3997 crop.left = dh - crop.bottom;
3998 crop.bottom = crop.right;
3999 crop.right = dh - tmp;
4000 }
4001 }
4002
Wale Ogunwale1666e312016-12-16 11:27:18 -08004003 void setExitingTokensHasVisible(boolean hasVisible) {
4004 for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
4005 mExitingTokens.get(i).hasVisible = hasVisible;
4006 }
4007
4008 // Initialize state of exiting applications.
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08004009 mTaskContainers.setExitingTokensHasVisible(hasVisible);
Wale Ogunwale1666e312016-12-16 11:27:18 -08004010 }
4011
4012 void removeExistingTokensIfPossible() {
4013 for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
4014 final WindowToken token = mExitingTokens.get(i);
4015 if (!token.hasVisible) {
4016 mExitingTokens.remove(i);
4017 }
4018 }
4019
4020 // Time to remove any exiting applications?
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08004021 mTaskContainers.removeExistingAppTokensIfPossible();
Wale Ogunwale1666e312016-12-16 11:27:18 -08004022 }
4023
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07004024 @Override
4025 void onDescendantOverrideConfigurationChanged() {
4026 setLayoutNeeded();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004027 mWmService.requestTraversal();
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07004028 }
4029
David Stevens9440dc82017-03-16 19:00:20 -07004030 boolean okToDisplay() {
lumark3b8bbc82019-12-02 16:22:08 +08004031 return okToDisplay(false);
4032 }
4033
4034 boolean okToDisplay(boolean ignoreFrozen) {
David Stevens9440dc82017-03-16 19:00:20 -07004035 if (mDisplayId == DEFAULT_DISPLAY) {
lumark3b8bbc82019-12-02 16:22:08 +08004036 return (!mWmService.mDisplayFrozen || ignoreFrozen)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004037 && mWmService.mDisplayEnabled && mWmService.mPolicy.isScreenOn();
David Stevens9440dc82017-03-16 19:00:20 -07004038 }
4039 return mDisplayInfo.state == Display.STATE_ON;
4040 }
4041
4042 boolean okToAnimate() {
lumark3b8bbc82019-12-02 16:22:08 +08004043 return okToAnimate(false);
4044 }
4045
4046 boolean okToAnimate(boolean ignoreFrozen) {
4047 return okToDisplay(ignoreFrozen) &&
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004048 (mDisplayId != DEFAULT_DISPLAY || mWmService.mPolicy.okToAnimate());
David Stevens9440dc82017-03-16 19:00:20 -07004049 }
4050
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07004051 static final class TaskForResizePointSearchResult {
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09004052 private Task taskForResize;
4053 private int x;
4054 private int y;
4055 private int delta;
4056 private Rect mTmpRect = new Rect();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07004057
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09004058 Task process(WindowContainer root, int x, int y, int delta) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07004059 taskForResize = null;
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09004060 this.x = x;
4061 this.y = y;
4062 this.delta = delta;
4063 mTmpRect.setEmpty();
4064
4065 final PooledFunction f = PooledLambda.obtainFunction(
4066 TaskForResizePointSearchResult::processTask, this, PooledLambda.__(Task.class));
4067 root.forAllTasks(f);
4068 f.recycle();
4069
4070 return taskForResize;
4071 }
4072
4073 private boolean processTask(Task task) {
4074 if (!task.getStack().getWindowConfiguration().canResizeTask()) {
4075 return true;
4076 }
4077
4078 if (task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
4079 return true;
4080 }
4081
4082 // We need to use the task's dim bounds (which is derived from the visible bounds of
4083 // its apps windows) for any touch-related tests. Can't use the task's original
4084 // bounds because it might be adjusted to fit the content frame. One example is when
4085 // the task is put to top-left quadrant, the actual visible area would not start at
4086 // (0,0) after it's adjusted for the status bar.
4087 task.getDimBounds(mTmpRect);
4088 mTmpRect.inset(-delta, -delta);
4089 if (mTmpRect.contains(x, y)) {
4090 mTmpRect.inset(delta, delta);
4091
4092 if (!mTmpRect.contains(x, y)) {
4093 taskForResize = task;
4094 return true;
4095 }
4096 // User touched inside the task. No need to look further,
4097 // focus transfer will be handled in ACTION_UP.
4098 return true;
4099 }
4100
4101 return false;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07004102 }
4103 }
Robert Carr3b716242016-08-16 16:02:21 -07004104
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004105 private static final class ApplySurfaceChangesTransactionState {
4106 boolean displayHasContent;
4107 boolean obscured;
4108 boolean syswin;
Galia Peycheva056b3ee2019-06-26 14:05:12 +02004109 boolean preferMinimalPostProcessing;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004110 float preferredRefreshRate;
4111 int preferredModeId;
4112
4113 void reset() {
4114 displayHasContent = false;
4115 obscured = false;
4116 syswin = false;
Galia Peycheva056b3ee2019-06-26 14:05:12 +02004117 preferMinimalPostProcessing = false;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004118 preferredRefreshRate = 0;
4119 preferredModeId = 0;
4120 }
4121 }
4122
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004123 /**
4124 * Base class for any direct child window container of {@link #DisplayContent} need to inherit
4125 * from. This is mainly a pass through class that allows {@link #DisplayContent} to have
4126 * homogeneous children type which is currently required by sub-classes of
4127 * {@link WindowContainer} class.
4128 */
4129 static class DisplayChildWindowContainer<E extends WindowContainer> extends WindowContainer<E> {
4130
Jorim Jaggiffe128d2017-11-30 13:54:36 +01004131 DisplayChildWindowContainer(WindowManagerService service) {
4132 super(service);
Adrian Roos0384f122020-01-10 19:39:43 +01004133 // TODO(display-area): move to ConfigurationContainer?
4134 mOrientation = SCREEN_ORIENTATION_UNSET;
Jorim Jaggiffe128d2017-11-30 13:54:36 +01004135 }
4136
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004137 @Override
4138 boolean fillsParent() {
4139 return true;
4140 }
4141
4142 @Override
4143 boolean isVisible() {
4144 return true;
Robert Carr3b716242016-08-16 16:02:21 -07004145 }
4146 }
4147
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004148 /**
4149 * Window container class that contains all containers on this display relating to Apps.
4150 * I.e Activities.
4151 */
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08004152 private final class TaskContainers extends DisplayChildWindowContainer<ActivityStack> {
Robert Carrb1579c82017-09-05 14:54:47 -07004153 /**
4154 * A control placed at the appropriate level for transitions to occur.
4155 */
chaviw23ee71c2017-12-18 11:29:41 -08004156 SurfaceControl mAppAnimationLayer = null;
Jorim Jaggibe418292018-03-26 16:14:12 +02004157 SurfaceControl mBoostedAppAnimationLayer = null;
Jorim Jaggi391790622018-04-18 15:30:44 +02004158 SurfaceControl mHomeAppAnimationLayer = null;
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004159
Robert Carrf7a7ca82017-12-06 13:17:07 -08004160 /**
4161 * Given that the split-screen divider does not have an AppWindowToken, it
4162 * will have to live inside of a "NonAppWindowContainer", in particular
4163 * {@link DisplayContent#mAboveAppWindowsContainers}. However, in visual Z order
4164 * it will need to be interleaved with some of our children, appearing on top of
4165 * both docked stacks but underneath any assistant stacks.
4166 *
4167 * To solve this problem we have this anchor control, which will always exist so
4168 * we can always assign it the correct value in our {@link #assignChildLayers}.
4169 * Likewise since it always exists, {@link AboveAppWindowContainers} can always
4170 * assign the divider a layer relative to it. This way we prevent linking lifecycle
4171 * events between the two containers.
4172 */
4173 SurfaceControl mSplitScreenDividerAnchor = null;
4174
Wale Ogunwale734b8962020-01-21 12:17:42 -08004175 // Cached reference to some special tasks we tend to get a lot so we don't need to loop
Wale Ogunwale61911492017-10-11 08:50:50 -07004176 // through the list to find them.
Wale Ogunwale734b8962020-01-21 12:17:42 -08004177 private ActivityStack mRootHomeTask = null;
4178 private ActivityStack mRootPinnedTask = null;
4179 private ActivityStack mRootSplitScreenPrimaryTask = null;
Wale Ogunwale61911492017-10-11 08:50:50 -07004180
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08004181 TaskContainers(WindowManagerService service) {
Jorim Jaggiffe128d2017-11-30 13:54:36 +01004182 super(service);
4183 }
4184
Wale Ogunwale61911492017-10-11 08:50:50 -07004185 /**
4186 * Returns the topmost stack on the display that is compatible with the input windowing mode
4187 * and activity type. Null is no compatible stack on the display.
4188 */
Louis Changdc077272019-11-12 16:52:56 +08004189 ActivityStack getStack(int windowingMode, int activityType) {
Wale Ogunwale61911492017-10-11 08:50:50 -07004190 if (activityType == ACTIVITY_TYPE_HOME) {
Wale Ogunwale734b8962020-01-21 12:17:42 -08004191 return mRootHomeTask;
Wale Ogunwale61911492017-10-11 08:50:50 -07004192 }
4193 if (windowingMode == WINDOWING_MODE_PINNED) {
Wale Ogunwale734b8962020-01-21 12:17:42 -08004194 return mRootPinnedTask;
Wale Ogunwale61911492017-10-11 08:50:50 -07004195 } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
Wale Ogunwale734b8962020-01-21 12:17:42 -08004196 return mRootSplitScreenPrimaryTask;
Wale Ogunwale61911492017-10-11 08:50:50 -07004197 }
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08004198 for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
4199 final ActivityStack stack = mTaskContainers.getChildAt(i);
Wale Ogunwale30e441d2017-11-09 08:28:45 -08004200 if (activityType == ACTIVITY_TYPE_UNDEFINED
4201 && windowingMode == stack.getWindowingMode()) {
4202 // Passing in undefined type means we want to match the topmost stack with the
4203 // windowing mode.
4204 return stack;
4205 }
Wale Ogunwale61911492017-10-11 08:50:50 -07004206 if (stack.isCompatible(windowingMode, activityType)) {
4207 return stack;
4208 }
4209 }
4210 return null;
4211 }
4212
4213 @VisibleForTesting
Louis Changdc077272019-11-12 16:52:56 +08004214 ActivityStack getTopStack() {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08004215 return mTaskContainers.getChildCount() > 0
4216 ? mTaskContainers.getChildAt(mTaskContainers.getChildCount() - 1) : null;
Wale Ogunwale61911492017-10-11 08:50:50 -07004217 }
4218
Louis Chang2453d062019-11-19 22:30:48 +08004219 int getIndexOf(ActivityStack stack) {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08004220 return mTaskContainers.mChildren.indexOf(stack);
Louis Chang2453d062019-11-19 22:30:48 +08004221 }
4222
Wale Ogunwale734b8962020-01-21 12:17:42 -08004223 ActivityStack getRootHomeTask() {
4224 if (mRootHomeTask == null && mDisplayId == DEFAULT_DISPLAY) {
Wale Ogunwale61911492017-10-11 08:50:50 -07004225 Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
4226 }
Wale Ogunwale734b8962020-01-21 12:17:42 -08004227 return mRootHomeTask;
Wale Ogunwale61911492017-10-11 08:50:50 -07004228 }
4229
Wale Ogunwale734b8962020-01-21 12:17:42 -08004230 ActivityStack getRootPinnedTask() {
4231 return mRootPinnedTask;
Louis Chang2453d062019-11-19 22:30:48 +08004232 }
4233
Wale Ogunwale734b8962020-01-21 12:17:42 -08004234 ActivityStack getRootSplitScreenPrimaryTask() {
4235 return mRootSplitScreenPrimaryTask;
Wale Ogunwale61911492017-10-11 08:50:50 -07004236 }
4237
Winson Chunge2d72172018-01-25 17:46:20 +00004238 ArrayList<Task> getVisibleTasks() {
4239 final ArrayList<Task> visibleTasks = new ArrayList<>();
4240 forAllTasks(task -> {
Wale Ogunwale8f93b642019-12-26 12:10:52 -08004241 if (!task.isRootTask() && task.isVisible()) {
Winson Chunge2d72172018-01-25 17:46:20 +00004242 visibleTasks.add(task);
4243 }
4244 });
4245 return visibleTasks;
4246 }
4247
Louis Changdc077272019-11-12 16:52:56 +08004248 void onStackWindowingModeChanged(ActivityStack stack) {
Wale Ogunwale61911492017-10-11 08:50:50 -07004249 removeStackReferenceIfNeeded(stack);
4250 addStackReferenceIfNeeded(stack);
Wale Ogunwale734b8962020-01-21 12:17:42 -08004251 if (stack == mRootPinnedTask && getTopStack() != stack) {
Wale Ogunwale61911492017-10-11 08:50:50 -07004252 // Looks like this stack changed windowing mode to pinned. Move it to the top.
4253 positionChildAt(POSITION_TOP, stack, false /* includingParents */);
4254 }
4255 }
4256
Louis Changdc077272019-11-12 16:52:56 +08004257 private void addStackReferenceIfNeeded(ActivityStack stack) {
Wale Ogunwale61911492017-10-11 08:50:50 -07004258 if (stack.isActivityTypeHome()) {
Wale Ogunwale734b8962020-01-21 12:17:42 -08004259 if (mRootHomeTask != null) {
4260 if (!stack.isDescendantOf(mRootHomeTask)) {
Wale Ogunwale8f93b642019-12-26 12:10:52 -08004261 throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack="
Wale Ogunwale734b8962020-01-21 12:17:42 -08004262 + mRootHomeTask + " already exist on display=" + this
Wale Ogunwale8f93b642019-12-26 12:10:52 -08004263 + " stack=" + stack);
4264 }
4265 } else {
Wale Ogunwale734b8962020-01-21 12:17:42 -08004266 mRootHomeTask = stack;
Louis Chang2453d062019-11-19 22:30:48 +08004267 }
Wale Ogunwale61911492017-10-11 08:50:50 -07004268 }
4269 final int windowingMode = stack.getWindowingMode();
4270 if (windowingMode == WINDOWING_MODE_PINNED) {
Wale Ogunwale734b8962020-01-21 12:17:42 -08004271 if (mRootPinnedTask != null) {
4272 if (!stack.isDescendantOf(mRootPinnedTask)) {
Wale Ogunwale8f93b642019-12-26 12:10:52 -08004273 throw new IllegalArgumentException(
Wale Ogunwale734b8962020-01-21 12:17:42 -08004274 "addStackReferenceIfNeeded: pinned stack=" + mRootPinnedTask
Wale Ogunwale8f93b642019-12-26 12:10:52 -08004275 + " already exist on display=" + this + " stack=" + stack);
4276 }
4277 } else {
Wale Ogunwale734b8962020-01-21 12:17:42 -08004278 mRootPinnedTask = stack;
Wale Ogunwale61911492017-10-11 08:50:50 -07004279 }
Wale Ogunwale61911492017-10-11 08:50:50 -07004280 } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
Wale Ogunwale734b8962020-01-21 12:17:42 -08004281 if (mRootSplitScreenPrimaryTask != null) {
4282 if (!stack.isDescendantOf(mRootSplitScreenPrimaryTask)) {
Wale Ogunwale8f93b642019-12-26 12:10:52 -08004283 throw new IllegalArgumentException("addStackReferenceIfNeeded:"
Wale Ogunwale734b8962020-01-21 12:17:42 -08004284 + " split-screen-primary" + " stack=" + mRootSplitScreenPrimaryTask
Wale Ogunwale8f93b642019-12-26 12:10:52 -08004285 + " already exist on display=" + this + " stack=" + stack);
4286 }
4287 } else {
Wale Ogunwale734b8962020-01-21 12:17:42 -08004288 mRootSplitScreenPrimaryTask = stack;
Wale Ogunwale8f93b642019-12-26 12:10:52 -08004289 mDisplayContent.onSplitScreenModeActivated();
4290 mDividerControllerLocked.notifyDockedStackExistsChanged(true);
Wale Ogunwale61911492017-10-11 08:50:50 -07004291 }
Wale Ogunwale61911492017-10-11 08:50:50 -07004292 }
4293 }
4294
Louis Chang2453d062019-11-19 22:30:48 +08004295 void removeStackReferenceIfNeeded(ActivityStack stack) {
Wale Ogunwale734b8962020-01-21 12:17:42 -08004296 if (stack == mRootHomeTask) {
4297 mRootHomeTask = null;
4298 } else if (stack == mRootPinnedTask) {
4299 mRootPinnedTask = null;
4300 } else if (stack == mRootSplitScreenPrimaryTask) {
4301 mRootSplitScreenPrimaryTask = null;
Louis Chang677921f2019-12-06 16:44:24 +08004302 mDisplayContent.onSplitScreenModeDismissed();
Wale Ogunwale30e441d2017-11-09 08:28:45 -08004303 // Re-set the split-screen create mode whenever the split-screen stack is removed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004304 mWmService.setDockedStackCreateStateLocked(
Wale Ogunwale30e441d2017-11-09 08:28:45 -08004305 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
4306 mDividerControllerLocked.notifyDockedStackExistsChanged(false);
Wale Ogunwale61911492017-10-11 08:50:50 -07004307 }
Andrii Kulian839def92016-11-02 10:58:58 -07004308 }
4309
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07004310 @Override
Louis Changdc077272019-11-12 16:52:56 +08004311 void addChild(ActivityStack stack, int position) {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07004312 addStackReferenceIfNeeded(stack);
4313 position = findPositionForStack(position, stack, true /* adding */);
4314
4315 super.addChild(stack, position);
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07004316
4317 // The reparenting case is handled in WindowContainer.
4318 if (!stack.mReparenting) {
4319 setLayoutNeeded();
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07004320 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004321 }
4322
Wale Ogunwale61911492017-10-11 08:50:50 -07004323 @Override
Louis Changdc077272019-11-12 16:52:56 +08004324 protected void removeChild(ActivityStack stack) {
Wale Ogunwale61911492017-10-11 08:50:50 -07004325 super.removeChild(stack);
Louis Chang677921f2019-12-06 16:44:24 +08004326 mDisplayContent.onStackRemoved(stack);
Wale Ogunwale61911492017-10-11 08:50:50 -07004327 removeStackReferenceIfNeeded(stack);
4328 }
Bryce Lee00d586d2017-07-28 20:48:43 -07004329
4330 @Override
4331 boolean isOnTop() {
4332 // Considered always on top
4333 return true;
4334 }
4335
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07004336 @Override
Louis Changdc077272019-11-12 16:52:56 +08004337 void positionChildAt(int position, ActivityStack child, boolean includingParents) {
Adrian Roosefa40702020-01-08 17:58:45 +01004338 final boolean moveToTop = (position == POSITION_TOP || position == getChildCount());
4339 final boolean moveToBottom = (position == POSITION_BOTTOM || position == 0);
4340 if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
Andrii Kuliand2765632016-12-12 22:26:34 -08004341 // This stack is always-on-top, override the default behavior.
4342 Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + this + " to bottom");
4343
4344 // Moving to its current position, as we must call super but we don't want to
4345 // perform any meaningful action.
4346 final int currentPosition = mChildren.indexOf(child);
4347 super.positionChildAt(currentPosition, child, false /* includingParents */);
4348 return;
4349 }
lumarkd0b5c8f2019-09-29 11:30:37 +08004350 // We don't allow untrusted display to top when task stack moves to top,
4351 // until user tapping this display to change display position as top intentionally.
4352 if (isUntrustedVirtualDisplay() && !getParent().isOnTop()) {
4353 includingParents = false;
4354 }
Andrii Kuliancd5dcb8b2017-01-03 17:09:45 -08004355 final int targetPosition = findPositionForStack(position, child, false /* adding */);
Adrian Roosefa40702020-01-08 17:58:45 +01004356 super.positionChildAt(targetPosition, child, false /* includingParents */);
Andrii Kuliancd5dcb8b2017-01-03 17:09:45 -08004357
Adrian Roosefa40702020-01-08 17:58:45 +01004358 if (includingParents && (moveToTop || moveToBottom)) {
4359 // The DisplayContent children do not re-order, but we still want to move the
4360 // display of this stack container because the intention of positioning is to have
4361 // higher z-order to gain focus.
4362 positionDisplayAt(moveToTop ? POSITION_TOP : POSITION_BOTTOM,
4363 true /* includingParents */);
Riddle Hsu2f6e1742018-08-23 22:44:36 +08004364 }
4365
Andrii Kuliancd5dcb8b2017-01-03 17:09:45 -08004366 setLayoutNeeded();
4367 }
4368
4369 /**
4370 * When stack is added or repositioned, find a proper position for it.
4371 * This will make sure that pinned stack always stays on top.
4372 * @param requestedPosition Position requested by caller.
4373 * @param stack Stack to be added or positioned.
4374 * @param adding Flag indicates whether we're adding a new stack or positioning an existing.
4375 * @return The proper position for the stack.
4376 */
Louis Changdc077272019-11-12 16:52:56 +08004377 private int findPositionForStack(int requestedPosition, ActivityStack stack,
4378 boolean adding) {
Kazuki Takise148d00a2018-05-31 15:32:19 +09004379 if (stack.inPinnedWindowingMode()) {
Kazuki Takisef85197b2018-06-18 18:18:36 +09004380 return POSITION_TOP;
Kazuki Takise148d00a2018-05-31 15:32:19 +09004381 }
4382
Kazuki Takisef85197b2018-06-18 18:18:36 +09004383 final int topChildPosition = mChildren.size() - 1;
4384 int belowAlwaysOnTopPosition = POSITION_BOTTOM;
4385 for (int i = topChildPosition; i >= 0; --i) {
Louis Chang2453d062019-11-19 22:30:48 +08004386 // Since a stack could be repositioned while being one of the child, return
4387 // current index if that's the same stack we are positioning and it is always on
4388 // top.
4389 final boolean sameStack = getStacks().get(i) == stack;
4390 if ((sameStack && stack.isAlwaysOnTop())
4391 || (!sameStack && !getStacks().get(i).isAlwaysOnTop())) {
Kazuki Takisef85197b2018-06-18 18:18:36 +09004392 belowAlwaysOnTopPosition = i;
4393 break;
4394 }
4395 }
4396
4397 // The max possible position we can insert the stack at.
4398 int maxPosition = POSITION_TOP;
4399 // The min possible position we can insert the stack at.
4400 int minPosition = POSITION_BOTTOM;
4401
4402 if (stack.isAlwaysOnTop()) {
Wale Ogunwale734b8962020-01-21 12:17:42 -08004403 if (hasPinnedTask()) {
Kazuki Takisef85197b2018-06-18 18:18:36 +09004404 // Always-on-top stacks go below the pinned stack.
Wale Ogunwale734b8962020-01-21 12:17:42 -08004405 maxPosition = getStacks().indexOf(mRootPinnedTask) - 1;
Kazuki Takisef85197b2018-06-18 18:18:36 +09004406 }
4407 // Always-on-top stacks need to be above all other stacks.
4408 minPosition = belowAlwaysOnTopPosition !=
4409 POSITION_BOTTOM ? belowAlwaysOnTopPosition : topChildPosition;
4410 } else {
4411 // Other stacks need to be below the always-on-top stacks.
4412 maxPosition = belowAlwaysOnTopPosition !=
Arthur Hung928d8dc2018-07-18 15:38:05 +08004413 POSITION_BOTTOM ? belowAlwaysOnTopPosition : 0;
Kazuki Takisef85197b2018-06-18 18:18:36 +09004414 }
4415
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07004416 // Cap the requested position to something reasonable for the previous position check
4417 // below.
4418 if (requestedPosition == POSITION_TOP) {
4419 requestedPosition = mChildren.size();
4420 } else if (requestedPosition == POSITION_BOTTOM) {
4421 requestedPosition = 0;
4422 }
4423
Louis Chang2453d062019-11-19 22:30:48 +08004424 int targetPosition = requestedPosition;
4425 targetPosition = Math.min(targetPosition, maxPosition);
4426 targetPosition = Math.max(targetPosition, minPosition);
4427
Kazuki Takisef85197b2018-06-18 18:18:36 +09004428 int prevPosition = getStacks().indexOf(stack);
4429 // The positions we calculated above (maxPosition, minPosition) do not take into
4430 // consideration the following edge cases.
4431 // 1) We need to adjust the position depending on the value "adding".
4432 // 2) When we are moving a stack to another position, we also need to adjust the
4433 // position depending on whether the stack is moving to a higher or lower position.
4434 if ((targetPosition != requestedPosition) &&
4435 (adding || targetPosition < prevPosition)) {
Kazuki Takise148d00a2018-05-31 15:32:19 +09004436 targetPosition++;
4437 }
4438
Andrii Kuliancd5dcb8b2017-01-03 17:09:45 -08004439 return targetPosition;
Andrii Kuliand2765632016-12-12 22:26:34 -08004440 }
4441
4442 @Override
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08004443 boolean forAllWindows(ToBooleanFunction<WindowState> callback,
4444 boolean traverseTopToBottom) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07004445 if (traverseTopToBottom) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08004446 if (super.forAllWindows(callback, traverseTopToBottom)) {
4447 return true;
4448 }
4449 if (forAllExitingAppTokenWindows(callback, traverseTopToBottom)) {
4450 return true;
4451 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07004452 } else {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08004453 if (forAllExitingAppTokenWindows(callback, traverseTopToBottom)) {
4454 return true;
4455 }
4456 if (super.forAllWindows(callback, traverseTopToBottom)) {
4457 return true;
4458 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07004459 }
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08004460 return false;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07004461 }
4462
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08004463 private boolean forAllExitingAppTokenWindows(ToBooleanFunction<WindowState> callback,
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07004464 boolean traverseTopToBottom) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07004465 // For legacy reasons we process the TaskStack.mExitingActivities first here before the
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07004466 // app tokens.
4467 // TODO: Investigate if we need to continue to do this or if we can just process them
4468 // in-order.
4469 if (traverseTopToBottom) {
4470 for (int i = mChildren.size() - 1; i >= 0; --i) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07004471 final List<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
4472 for (int j = activities.size() - 1; j >= 0; --j) {
4473 if (activities.get(j).forAllWindowsUnchecked(callback,
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08004474 traverseTopToBottom)) {
4475 return true;
4476 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07004477 }
4478 }
4479 } else {
4480 final int count = mChildren.size();
4481 for (int i = 0; i < count; ++i) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07004482 final List<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
4483 final int appTokensCount = activities.size();
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07004484 for (int j = 0; j < appTokensCount; j++) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07004485 if (activities.get(j).forAllWindowsUnchecked(callback,
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08004486 traverseTopToBottom)) {
4487 return true;
4488 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07004489 }
4490 }
4491 }
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08004492 return false;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07004493 }
4494
Wale Ogunwale1666e312016-12-16 11:27:18 -08004495 void setExitingTokensHasVisible(boolean hasVisible) {
4496 for (int i = mChildren.size() - 1; i >= 0; --i) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07004497 final ArrayList<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
4498 for (int j = activities.size() - 1; j >= 0; --j) {
4499 activities.get(j).hasVisible = hasVisible;
Wale Ogunwale1666e312016-12-16 11:27:18 -08004500 }
4501 }
4502 }
4503
4504 void removeExistingAppTokensIfPossible() {
4505 for (int i = mChildren.size() - 1; i >= 0; --i) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07004506 final ArrayList<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
4507 for (int j = activities.size() - 1; j >= 0; --j) {
4508 final ActivityRecord activity = activities.get(j);
4509 if (!activity.hasVisible && !mClosingApps.contains(activity)
4510 && (!activity.mIsExiting || activity.isEmpty())) {
4511 // Make sure there is no animation running on this activity, so any windows
Wale Ogunwale1666e312016-12-16 11:27:18 -08004512 // associated with it will be removed as soon as their animations are
4513 // complete.
Jorim Jaggif5f9e122017-10-24 18:21:09 +02004514 cancelAnimation();
Adrian Roosb125e0b2019-10-02 14:55:14 +02004515 ProtoLog.v(WM_DEBUG_ADD_REMOVE,
Garfield Tane8d84ab2019-10-11 09:49:40 -07004516 "performLayout: Activity exiting now removed %s", activity);
4517 activity.removeIfPossible();
Wale Ogunwale1666e312016-12-16 11:27:18 -08004518 }
4519 }
4520 }
4521 }
4522
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07004523 @Override
Adrian Roos0384f122020-01-10 19:39:43 +01004524 int getOrientation(int candidate) {
Garfield Tan98eead32019-11-18 13:24:53 -08004525 if (isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07004526 // Apps and their containers are not allowed to specify an orientation while the
Garfield Tan98eead32019-11-18 13:24:53 -08004527 // docked stack is visible...except for the home stack if the docked stack is
4528 // minimized and it actually set something and the bounds is different from the
4529 // display.
Wale Ogunwale734b8962020-01-21 12:17:42 -08004530 if (mRootHomeTask != null && mRootHomeTask.isVisible()
Wale Ogunwalecf2d6472018-06-14 08:55:42 -07004531 && mDividerControllerLocked.isMinimizedDock()
Wale Ogunwalecf2d6472018-06-14 08:55:42 -07004532 && !(mDividerControllerLocked.isHomeStackResizable()
Wale Ogunwale734b8962020-01-21 12:17:42 -08004533 && mRootHomeTask.matchParentBounds())) {
4534 final int orientation = mRootHomeTask.getOrientation();
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07004535 if (orientation != SCREEN_ORIENTATION_UNSET) {
4536 return orientation;
4537 }
4538 }
4539 return SCREEN_ORIENTATION_UNSPECIFIED;
4540 }
4541
Adrian Roos0384f122020-01-10 19:39:43 +01004542 final int orientation = super.getOrientation(candidate);
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07004543 if (orientation != SCREEN_ORIENTATION_UNSET
4544 && orientation != SCREEN_ORIENTATION_BEHIND) {
Adrian Roosb125e0b2019-10-02 14:55:14 +02004545 ProtoLog.v(WM_DEBUG_ORIENTATION,
chaviw8065f442019-11-18 13:20:58 -08004546 "App is requesting an orientation, return %d for display id=%d",
4547 orientation, mDisplayId);
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07004548 return orientation;
4549 }
4550
Adrian Roosb125e0b2019-10-02 14:55:14 +02004551 ProtoLog.v(WM_DEBUG_ORIENTATION,
chaviw8065f442019-11-18 13:20:58 -08004552 "No app is requesting an orientation, return %d for display id=%d",
4553 getLastOrientation(), mDisplayId);
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07004554 // The next app has not been requested to be visible, so we keep the current orientation
4555 // to prevent freezing/unfreezing the display too early.
Riddle Hsuccf09402019-08-13 00:33:06 +08004556 return getLastOrientation();
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07004557 }
Robert Carrb1579c82017-09-05 14:54:47 -07004558
4559 @Override
4560 void assignChildLayers(SurfaceControl.Transaction t) {
Robert Carr2f8aa392018-01-31 14:46:51 -08004561 assignStackOrdering(t);
Robert Carrf7a7ca82017-12-06 13:17:07 -08004562
Robert Carr2f8aa392018-01-31 14:46:51 -08004563 for (int i = 0; i < mChildren.size(); i++) {
Louis Changdc077272019-11-12 16:52:56 +08004564 final ActivityStack s = mChildren.get(i);
Robert Carr2f8aa392018-01-31 14:46:51 -08004565 s.assignChildLayers(t);
4566 }
4567 }
4568
4569 void assignStackOrdering(SurfaceControl.Transaction t) {
Issei Suzuki25a9e2b2019-08-14 16:46:26 +02004570 if (getParent() == null) {
4571 return;
4572 }
4573 mTmpAlwaysOnTopStacks.clear();
4574 mTmpHomeStacks.clear();
4575 mTmpNormalStacks.clear();
4576 for (int i = 0; i < mChildren.size(); ++i) {
Louis Changdc077272019-11-12 16:52:56 +08004577 final ActivityStack s = mChildren.get(i);
Issei Suzuki25a9e2b2019-08-14 16:46:26 +02004578 if (s.isAlwaysOnTop()) {
4579 mTmpAlwaysOnTopStacks.add(s);
4580 } else if (s.isActivityTypeHome()) {
4581 mTmpHomeStacks.add(s);
4582 } else {
4583 mTmpNormalStacks.add(s);
4584 }
4585 }
Robert Carrf7a7ca82017-12-06 13:17:07 -08004586
Jorim Jaggiffe128d2017-11-30 13:54:36 +01004587 int layer = 0;
Issei Suzuki25a9e2b2019-08-14 16:46:26 +02004588 // Place home stacks to the bottom.
4589 for (int i = 0; i < mTmpHomeStacks.size(); i++) {
4590 mTmpHomeStacks.get(i).assignLayer(t, layer++);
4591 }
4592 // The home animation layer is between the home stacks and the normal stacks.
4593 final int layerForHomeAnimationLayer = layer++;
4594 int layerForSplitScreenDividerAnchor = layer++;
4595 int layerForAnimationLayer = layer++;
4596 for (int i = 0; i < mTmpNormalStacks.size(); i++) {
Louis Changdc077272019-11-12 16:52:56 +08004597 final ActivityStack s = mTmpNormalStacks.get(i);
Issei Suzuki25a9e2b2019-08-14 16:46:26 +02004598 s.assignLayer(t, layer++);
4599 if (s.inSplitScreenWindowingMode()) {
4600 // The split screen divider anchor is located above the split screen window.
4601 layerForSplitScreenDividerAnchor = layer++;
4602 }
lumark9bca6b42019-10-17 18:35:22 +08004603 if (s.isTaskAnimating() || s.isAppTransitioning()) {
Issei Suzuki25a9e2b2019-08-14 16:46:26 +02004604 // The animation layer is located above the highest animating stack and no
4605 // higher.
4606 layerForAnimationLayer = layer++;
4607 }
4608 }
4609 // The boosted animation layer is between the normal stacks and the always on top
4610 // stacks.
4611 final int layerForBoostedAnimationLayer = layer++;
4612 for (int i = 0; i < mTmpAlwaysOnTopStacks.size(); i++) {
4613 mTmpAlwaysOnTopStacks.get(i).assignLayer(t, layer++);
4614 }
Robert Carr2f8aa392018-01-31 14:46:51 -08004615
Issei Suzuki25a9e2b2019-08-14 16:46:26 +02004616 t.setLayer(mHomeAppAnimationLayer, layerForHomeAnimationLayer);
4617 t.setLayer(mAppAnimationLayer, layerForAnimationLayer);
4618 t.setLayer(mSplitScreenDividerAnchor, layerForSplitScreenDividerAnchor);
4619 t.setLayer(mBoostedAppAnimationLayer, layerForBoostedAnimationLayer);
Robert Carrb1579c82017-09-05 14:54:47 -07004620 }
4621
4622 @Override
Jorim Jaggi391790622018-04-18 15:30:44 +02004623 SurfaceControl getAppAnimationLayer(@AnimationLayer int animationLayer) {
4624 switch (animationLayer) {
4625 case ANIMATION_LAYER_BOOSTED:
4626 return mBoostedAppAnimationLayer;
4627 case ANIMATION_LAYER_HOME:
4628 return mHomeAppAnimationLayer;
4629 case ANIMATION_LAYER_STANDARD:
4630 default:
4631 return mAppAnimationLayer;
4632 }
chaviw23ee71c2017-12-18 11:29:41 -08004633 }
4634
Robert Carrf7a7ca82017-12-06 13:17:07 -08004635 SurfaceControl getSplitScreenDividerAnchor() {
4636 return mSplitScreenDividerAnchor;
4637 }
4638
chaviw23ee71c2017-12-18 11:29:41 -08004639 @Override
Wale Ogunwalec17418e2019-10-13 23:00:40 +02004640 void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
Robert Carrb1579c82017-09-05 14:54:47 -07004641 if (getParent() != null) {
Wale Ogunwalec17418e2019-10-13 23:00:40 +02004642 super.onParentChanged(newParent, oldParent, () -> {
Issei Suzuki25a9e2b2019-08-14 16:46:26 +02004643 mAppAnimationLayer = makeChildSurface(null)
4644 .setName("animationLayer")
4645 .build();
4646 mBoostedAppAnimationLayer = makeChildSurface(null)
4647 .setName("boostedAnimationLayer")
4648 .build();
4649 mHomeAppAnimationLayer = makeChildSurface(null)
4650 .setName("homeAnimationLayer")
4651 .build();
4652 mSplitScreenDividerAnchor = makeChildSurface(null)
4653 .setName("splitScreenDividerAnchor")
4654 .build();
4655 getPendingTransaction()
4656 .show(mAppAnimationLayer)
4657 .show(mBoostedAppAnimationLayer)
4658 .show(mHomeAppAnimationLayer)
4659 .show(mSplitScreenDividerAnchor);
4660 });
Robert Carrb1579c82017-09-05 14:54:47 -07004661 } else {
Wale Ogunwalec17418e2019-10-13 23:00:40 +02004662 super.onParentChanged(newParent, oldParent);
Vishnu Nair33197392019-08-30 10:29:37 -07004663 mWmService.mTransactionFactory.get()
chaviw9f6171e2019-06-07 16:33:50 -07004664 .remove(mAppAnimationLayer)
4665 .remove(mBoostedAppAnimationLayer)
4666 .remove(mHomeAppAnimationLayer)
4667 .remove(mSplitScreenDividerAnchor)
4668 .apply();
chaviw23ee71c2017-12-18 11:29:41 -08004669 mAppAnimationLayer = null;
Jorim Jaggibe418292018-03-26 16:14:12 +02004670 mBoostedAppAnimationLayer = null;
Jorim Jaggi391790622018-04-18 15:30:44 +02004671 mHomeAppAnimationLayer = null;
Robert Carrf7a7ca82017-12-06 13:17:07 -08004672 mSplitScreenDividerAnchor = null;
Robert Carrb1579c82017-09-05 14:54:47 -07004673 }
4674 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004675 }
4676
Robert Carree4d4b92017-11-22 12:21:46 -08004677 private final class AboveAppWindowContainers extends NonAppWindowContainers {
Jorim Jaggiffe128d2017-11-30 13:54:36 +01004678 AboveAppWindowContainers(String name, WindowManagerService service) {
4679 super(name, service);
Robert Carree4d4b92017-11-22 12:21:46 -08004680 }
4681
Robert Carrb9506032018-02-13 13:54:00 -08004682 @Override
4683 void assignChildLayers(SurfaceControl.Transaction t) {
Adrian Roosefa40702020-01-08 17:58:45 +01004684 boolean needAssignIme = mImeWindowsContainers.getSurfaceControl() != null;
Robert Carree4d4b92017-11-22 12:21:46 -08004685 for (int j = 0; j < mChildren.size(); ++j) {
4686 final WindowToken wt = mChildren.get(j);
Robert Carrf7a7ca82017-12-06 13:17:07 -08004687
Robert Carree4d4b92017-11-22 12:21:46 -08004688 wt.assignLayer(t, j);
4689 wt.assignChildLayers(t);
4690
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004691 int layer = mWmService.mPolicy.getWindowLayerFromTypeLw(
Robert Carree4d4b92017-11-22 12:21:46 -08004692 wt.windowType, wt.mOwnerCanManageAppTokens);
Robert Carrb8e78fa2017-11-28 13:07:58 -08004693
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004694 if (needAssignIme && layer >= mWmService.mPolicy.getWindowLayerFromTypeLw(
chaviw8065f442019-11-18 13:20:58 -08004695 TYPE_INPUT_METHOD_DIALOG, true)) {
Adrian Roosefa40702020-01-08 17:58:45 +01004696 mImeWindowsContainers.assignRelativeLayer(t, wt.getSurfaceControl(), -1);
Robert Carree4d4b92017-11-22 12:21:46 -08004697 needAssignIme = false;
4698 }
4699 }
Robert Carree4d4b92017-11-22 12:21:46 -08004700 }
4701 }
4702
chaviw8065f442019-11-18 13:20:58 -08004703 private class WindowContainers extends DisplayChildWindowContainer<WindowContainer> {
4704 private final String mName;
4705
4706 WindowContainers(String name, WindowManagerService service) {
4707 super(service);
4708 mName = name;
4709 }
4710
4711 @Override
4712 void assignChildLayers(SurfaceControl.Transaction t) {
Adrian Roosefa40702020-01-08 17:58:45 +01004713 mImeWindowsContainers.setNeedsLayer();
chaviw8065f442019-11-18 13:20:58 -08004714 mBelowAppWindowsContainers.assignLayer(t, 0);
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08004715 mTaskContainers.assignLayer(t, 1);
chaviw8065f442019-11-18 13:20:58 -08004716 mAboveAppWindowsContainers.assignLayer(t, 2);
4717
4718 final WindowState imeTarget = mInputMethodTarget;
4719 boolean needAssignIme = true;
4720
4721 // In the case where we have an IME target that is not in split-screen mode IME
4722 // assignment is easy. We just need the IME to go directly above the target. This way
4723 // children of the target will naturally go above the IME and everyone is happy.
4724 //
4725 // In the case of split-screen windowing mode, we need to elevate the IME above the
4726 // docked divider while keeping the app itself below the docked divider, so instead
4727 // we use relative layering of the IME targets child windows, and place the IME in
4728 // the non-app layer (see {@link AboveAppWindowContainers#assignChildLayers}).
4729 //
4730 // In the case the IME target is animating, the animation Z order may be different
4731 // than the WindowContainer Z order, so it's difficult to be sure we have the correct
4732 // IME target. In this case we just layer the IME over all transitions by placing it
4733 // in the above applications layer.
4734 //
4735 // In the case where we have no IME target we assign it where its base layer would
4736 // place it in the AboveAppWindowContainers.
4737 //
4738 // Keep IME window in mAboveAppWindowsContainers as long as app's starting window
4739 // exists so it get's layered above the starting window.
4740 if (imeTarget != null && !(imeTarget.mActivityRecord != null
4741 && imeTarget.mActivityRecord.hasStartingWindow()) && (
Robert Carr599d83c2020-01-24 14:45:14 -08004742 !(imeTarget.inMultiWindowMode()
chaviw8065f442019-11-18 13:20:58 -08004743 || imeTarget.mToken.isAppTransitioning()) && (
4744 imeTarget.getSurfaceControl() != null))) {
4745 mImeWindowsContainers.assignRelativeLayer(t, imeTarget.getSurfaceControl(),
4746 // TODO: We need to use an extra level on the app surface to ensure
4747 // this is always above SurfaceView but always below attached window.
4748 1);
chaviw8065f442019-11-18 13:20:58 -08004749 }
4750
4751 // Above we have assigned layers to our children, now we ask them to assign
4752 // layers to their children.
4753 mBelowAppWindowsContainers.assignChildLayers(t);
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08004754 mTaskContainers.assignChildLayers(t);
Adrian Roosefa40702020-01-08 17:58:45 +01004755 mAboveAppWindowsContainers.assignChildLayers(t);
4756 mImeWindowsContainers.assignRelativeLayer(t, getSurfaceControl(), Integer.MAX_VALUE);
chaviw8065f442019-11-18 13:20:58 -08004757 mImeWindowsContainers.assignChildLayers(t);
4758 }
4759
4760 @Override
4761 String getName() {
4762 return mName;
4763 }
4764
4765 void addChildren() {
4766 addChild(mBelowAppWindowsContainers, null);
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08004767 addChild(mTaskContainers, null);
chaviw8065f442019-11-18 13:20:58 -08004768 addChild(mAboveAppWindowsContainers, null);
4769 addChild(mImeWindowsContainers, null);
4770 }
4771
chaviw8065f442019-11-18 13:20:58 -08004772 @Override
4773 void positionChildAt(int position, WindowContainer child, boolean includingParents) {
4774 // Children of the WindowContainers are statically ordered, so the real intention here
4775 // is to perform the operation on the display and not the static direct children.
4776 getParent().positionChildAt(position, this, includingParents);
4777 }
4778 }
4779
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004780 /**
4781 * Window container class that contains all containers on this display that are not related to
4782 * Apps. E.g. status bar.
4783 */
Robert Carree4d4b92017-11-22 12:21:46 -08004784 private class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
Wale Ogunwale3a931692016-11-02 16:49:48 -07004785 /**
4786 * Compares two child window tokens returns -1 if the first is lesser than the second in
4787 * terms of z-order and 1 otherwise.
4788 */
Wale Ogunwale1e129a42016-11-21 13:03:47 -08004789 private final Comparator<WindowToken> mWindowComparator = (token1, token2) ->
Wale Ogunwale3a931692016-11-02 16:49:48 -07004790 // Tokens with higher base layer are z-ordered on-top.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004791 mWmService.mPolicy.getWindowLayerFromTypeLw(token1.windowType,
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08004792 token1.mOwnerCanManageAppTokens)
chaviw8065f442019-11-18 13:20:58 -08004793 < mWmService.mPolicy.getWindowLayerFromTypeLw(token2.windowType,
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08004794 token2.mOwnerCanManageAppTokens) ? -1 : 1;
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004795
Wale Ogunwale1e129a42016-11-21 13:03:47 -08004796 private final Predicate<WindowState> mGetOrientingWindow = w -> {
Adrian Roos0384f122020-01-10 19:39:43 +01004797 final WindowManagerPolicy policy = mWmService.mPolicy;
4798 if (policy.isKeyguardHostWindow(w.mAttrs)) {
4799 if (mWmService.mKeyguardGoingAway) {
4800 return false;
4801 }
4802 // Consider unoccluding only when all unknown visibilities have been
4803 // resolved, as otherwise we just may be starting another occluding activity.
4804 final boolean isUnoccluding =
4805 mDisplayContent.mAppTransition.getAppTransition()
4806 == TRANSIT_KEYGUARD_UNOCCLUDE
4807 && mDisplayContent.mUnknownAppVisibilityController.allResolved();
4808 // If keyguard is showing, or we're unoccluding, force the keyguard's orientation,
4809 // even if SystemUI hasn't updated the attrs yet.
4810 if (policy.isKeyguardShowingAndNotOccluded() || isUnoccluding) {
4811 return true;
4812 }
Wale Ogunwale1e129a42016-11-21 13:03:47 -08004813 }
4814 final int req = w.mAttrs.screenOrientation;
Adrian Roos0384f122020-01-10 19:39:43 +01004815 if (req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND
Wale Ogunwale1e129a42016-11-21 13:03:47 -08004816 || req == SCREEN_ORIENTATION_UNSET) {
4817 return false;
4818 }
4819 return true;
4820 };
4821
Wale Ogunwale3a931692016-11-02 16:49:48 -07004822 private final String mName;
chaviwf29223e2018-01-31 13:23:51 -08004823 private final Dimmer mDimmer = new Dimmer(this);
4824 private final Rect mTmpDimBoundsRect = new Rect();
4825
Jorim Jaggiffe128d2017-11-30 13:54:36 +01004826 NonAppWindowContainers(String name, WindowManagerService service) {
4827 super(service);
Wale Ogunwale3a931692016-11-02 16:49:48 -07004828 mName = name;
4829 }
4830
Wale Ogunwaledfbeed72019-11-20 08:57:39 -08004831 @Override
4832 boolean hasActivity() {
4833 // I am a non-app-window-container :P
4834 return false;
4835 }
4836
Wale Ogunwale3a931692016-11-02 16:49:48 -07004837 void addChild(WindowToken token) {
4838 addChild(token, mWindowComparator);
4839 }
4840
4841 @Override
Adrian Roos0384f122020-01-10 19:39:43 +01004842 int getOrientation(int candidate) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004843 // Find a window requesting orientation.
Wale Ogunwale1e129a42016-11-21 13:03:47 -08004844 final WindowState win = getWindow(mGetOrientingWindow);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004845
4846 if (win != null) {
Adrian Roos0384f122020-01-10 19:39:43 +01004847 int req = win.mAttrs.screenOrientation;
Adrian Roosb125e0b2019-10-02 14:55:14 +02004848 ProtoLog.v(WM_DEBUG_ORIENTATION,
4849 "%s forcing orientation to %d for display id=%d", win, req,
chaviw8065f442019-11-18 13:20:58 -08004850 mDisplayId);
Adrian Roos0384f122020-01-10 19:39:43 +01004851 if (mWmService.mPolicy.isKeyguardHostWindow(win.mAttrs)) {
4852 // SystemUI controls the Keyguard orientation asynchronously, and mAttrs may be
4853 // stale. We record / use the last known override.
4854 if (req != SCREEN_ORIENTATION_UNSET && req != SCREEN_ORIENTATION_UNSPECIFIED) {
4855 mDisplayContent.mLastKeyguardForcedOrientation = req;
4856 } else {
4857 req = mDisplayContent.mLastKeyguardForcedOrientation;
4858 }
4859 }
4860 return req;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004861 }
Adrian Roos0384f122020-01-10 19:39:43 +01004862 return candidate;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004863 }
4864
4865 @Override
Wale Ogunwale3a931692016-11-02 16:49:48 -07004866 String getName() {
4867 return mName;
4868 }
chaviwf29223e2018-01-31 13:23:51 -08004869
4870 @Override
4871 Dimmer getDimmer() {
4872 return mDimmer;
4873 }
4874
4875 @Override
4876 void prepareSurfaces() {
4877 mDimmer.resetDimStates();
4878 super.prepareSurfaces();
4879 getBounds(mTmpDimBoundsRect);
4880
4881 if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
4882 scheduleAnimation();
4883 }
4884 }
Robert Carr3b716242016-08-16 16:02:21 -07004885 }
Jorim Jaggi6a7a8592017-01-12 00:44:33 +01004886
Adrian Roosefa40702020-01-08 17:58:45 +01004887 /**
4888 * Container for IME windows.
4889 *
4890 * This has some special behaviors:
4891 * - layers assignment is ignored except if setNeedsLayer() has been called before (and no
4892 * layer has been assigned since), to facilitate assigning the layer from the IME target, or
4893 * fall back if there is no target.
4894 * - the container doesn't always participate in window traversal, according to
4895 * {@link #skipImeWindowsDuringTraversal()}
4896 */
4897 private class ImeContainer extends NonAppWindowContainers {
4898 boolean mNeedsLayer = false;
4899
4900 ImeContainer(WindowManagerService wms) {
4901 super("ImeContainer", wms);
4902 }
4903
4904 public void setNeedsLayer() {
4905 mNeedsLayer = true;
4906 }
4907
4908 @Override
Adrian Roos0384f122020-01-10 19:39:43 +01004909 int getOrientation(int candidate) {
4910 // IME does not participate in orientation.
4911 return candidate;
4912 }
4913
4914 @Override
Adrian Roosefa40702020-01-08 17:58:45 +01004915 boolean forAllWindows(ToBooleanFunction<WindowState> callback,
4916 boolean traverseTopToBottom) {
4917 final DisplayContent dc = mDisplayContent;
4918 if (skipImeWindowsDuringTraversal(dc)) {
4919 return false;
4920 }
4921 return super.forAllWindows(callback, traverseTopToBottom);
4922 }
4923
4924 private boolean skipImeWindowsDuringTraversal(DisplayContent dc) {
4925 // We skip IME windows so they're processed just above their target, except
4926 // in split-screen mode where we process the IME containers above the docked divider.
Wale Ogunwale734b8962020-01-21 12:17:42 -08004927 return dc.mInputMethodTarget != null && !dc.hasSplitScreenPrimaryTask();
Adrian Roosefa40702020-01-08 17:58:45 +01004928 }
4929
4930 /** Like {@link #forAllWindows}, but ignores {@link #skipImeWindowsDuringTraversal} */
4931 boolean forAllWindowForce(ToBooleanFunction<WindowState> callback,
4932 boolean traverseTopToBottom) {
4933 return super.forAllWindows(callback, traverseTopToBottom);
4934 }
4935
4936 @Override
4937 void assignLayer(Transaction t, int layer) {
4938 if (!mNeedsLayer) {
4939 return;
4940 }
4941 super.assignLayer(t, layer);
4942 mNeedsLayer = false;
4943 }
4944
4945 @Override
4946 void assignRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
4947 if (!mNeedsLayer) {
4948 return;
4949 }
4950 super.assignRelativeLayer(t, relativeTo, layer);
4951 mNeedsLayer = false;
4952 }
4953 }
4954
Robert Carrb1579c82017-09-05 14:54:47 -07004955 @Override
4956 SurfaceSession getSession() {
4957 return mSession;
4958 }
4959
4960 @Override
4961 SurfaceControl.Builder makeChildSurface(WindowContainer child) {
Robert Carrf59b8dd2017-10-02 18:58:36 -07004962 SurfaceSession s = child != null ? child.getSession() : getSession();
Chavi Weingarten6ef9cc62019-02-07 16:28:45 +00004963 final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(s).setContainerLayer();
Robert Carrf59b8dd2017-10-02 18:58:36 -07004964 if (child == null) {
4965 return b;
4966 }
4967
Robert Carree4d4b92017-11-22 12:21:46 -08004968 return b.setName(child.getName())
chaviw8065f442019-11-18 13:20:58 -08004969 .setParent(mSurfaceControl);
Robert Carrb1579c82017-09-05 14:54:47 -07004970 }
4971
4972 /**
4973 * The makeSurface variants are for use by the window-container
4974 * hierarchy. makeOverlay here is a function for various non windowing
4975 * overlays like the ScreenRotation screenshot, the Strict Mode Flash
4976 * and other potpourii.
4977 */
4978 SurfaceControl.Builder makeOverlay() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004979 return mWmService.makeSurfaceBuilder(mSession)
chaviw8065f442019-11-18 13:20:58 -08004980 .setParent(mOverlayContainers.getSurfaceControl());
Robert Carrb1579c82017-09-05 14:54:47 -07004981 }
4982
Daichi Hironoa1fb9be2017-12-18 17:02:54 +09004983 /**
chaviw8065f442019-11-18 13:20:58 -08004984 * Reparents the given surface to {@link #mOverlayContainers}' SurfaceControl.
Daichi Hironoa1fb9be2017-12-18 17:02:54 +09004985 */
4986 void reparentToOverlay(Transaction transaction, SurfaceControl surface) {
chaviw8065f442019-11-18 13:20:58 -08004987 transaction.reparent(surface, mOverlayContainers.getSurfaceControl());
Daichi Hironoa1fb9be2017-12-18 17:02:54 +09004988 }
4989
Robert Carrb1579c82017-09-05 14:54:47 -07004990 void applyMagnificationSpec(MagnificationSpec spec) {
Robert Carr24be9ab2018-04-30 17:54:53 -07004991 if (spec.scale != 1.0) {
4992 mMagnificationSpec = spec;
4993 } else {
4994 mMagnificationSpec = null;
4995 }
Jackal Guo818c3f12019-03-08 18:00:39 +08004996 // Re-parent IME's SurfaceControl when MagnificationSpec changed.
4997 updateImeParent();
Robert Carr24be9ab2018-04-30 17:54:53 -07004998
Robert Carr7603dea2019-07-17 13:16:21 -07004999 if (spec.scale != 1.0) {
5000 applyMagnificationSpec(getPendingTransaction(), spec);
5001 } else {
5002 clearMagnificationSpec(getPendingTransaction());
5003 }
Robert Carrf59b8dd2017-10-02 18:58:36 -07005004 getPendingTransaction().apply();
Robert Carrb1579c82017-09-05 14:54:47 -07005005 }
5006
Robert Carr24be9ab2018-04-30 17:54:53 -07005007 void reapplyMagnificationSpec() {
5008 if (mMagnificationSpec != null) {
5009 applyMagnificationSpec(getPendingTransaction(), mMagnificationSpec);
5010 }
5011 }
5012
Robert Carrb1579c82017-09-05 14:54:47 -07005013 @Override
Wale Ogunwalec17418e2019-10-13 23:00:40 +02005014 void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
Robert Carrb1579c82017-09-05 14:54:47 -07005015 // Since we are the top of the SurfaceControl hierarchy here
5016 // we create the root surfaces explicitly rather than chaining
Riddle Hsu3a4bb612019-01-31 00:02:22 +08005017 // up as the default implementation in onParentChanged does. So we
Robert Carrb1579c82017-09-05 14:54:47 -07005018 // explicitly do NOT call super here.
Garfield Tanfbd233a2019-12-26 12:39:25 -08005019
5020 if (!isReady()) {
5021 // TODO(b/62541591): evaluate whether this is the best spot to declare the
5022 // {@link DisplayContent} ready for use.
5023 mDisplayReady = true;
5024
5025 mWmService.mAnimator.addDisplayLocked(mDisplayId);
5026
5027 if (mWmService.mDisplayManagerInternal != null) {
5028 mWmService.mDisplayManagerInternal
5029 .setDisplayInfoOverrideFromWindowManager(mDisplayId, getDisplayInfo());
5030 configureDisplayPolicy();
5031 }
5032
5033 reconfigureDisplayLocked();
5034 onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration());
5035 mWmService.mDisplayNotificationController.dispatchDisplayAdded(this);
5036 }
Robert Carrb1579c82017-09-05 14:54:47 -07005037 }
5038
5039 @Override
5040 void assignChildLayers(SurfaceControl.Transaction t) {
chaviw8065f442019-11-18 13:20:58 -08005041 mWindowContainers.assignLayer(t, 0);
5042 mOverlayContainers.assignLayer(t, 1);
Robert Carrb1579c82017-09-05 14:54:47 -07005043
chaviw8065f442019-11-18 13:20:58 -08005044 mWindowContainers.assignChildLayers(t);
5045 mOverlayContainers.assignChildLayers(t);
Robert Carrb1579c82017-09-05 14:54:47 -07005046 }
5047
5048 /**
5049 * Here we satisfy an unfortunate special case of the IME in split-screen mode. Imagine
5050 * that the IME target is one of the docked applications. We'd like the docked divider to be
5051 * above both of the applications, and we'd like the IME to be above the docked divider.
5052 * However we need child windows of the applications to be above the IME (Text drag handles).
5053 * This is a non-strictly hierarcical layering and we need to break out of the Z ordering
5054 * somehow. We do this by relatively ordering children of the target to the IME in cooperation
Tiger Huang7c610aa2018-10-27 00:01:01 +08005055 * with {@link WindowState#assignLayer}
Robert Carrb1579c82017-09-05 14:54:47 -07005056 */
5057 void assignRelativeLayerForImeTargetChild(SurfaceControl.Transaction t, WindowContainer child) {
Adrian Roosefa40702020-01-08 17:58:45 +01005058 mImeWindowsContainers.setNeedsLayer();
Robert Carrbb5de662018-04-26 13:29:51 -07005059 child.assignRelativeLayer(t, mImeWindowsContainers.getSurfaceControl(), 1);
Robert Carrb1579c82017-09-05 14:54:47 -07005060 }
5061
5062 @Override
Jorim Jaggi9af095b2017-12-12 17:18:57 +01005063 void prepareSurfaces() {
Jorim Jaggi4981f152019-03-26 18:58:45 +01005064 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareSurfaces");
5065 try {
Tiger Huanged6794e2019-05-07 20:07:59 +08005066 final Transaction transaction = getPendingTransaction();
Jorim Jaggi4981f152019-03-26 18:58:45 +01005067 super.prepareSurfaces();
Tiger Huanged6794e2019-05-07 20:07:59 +08005068
5069 // TODO: Once we totally eliminate global transaction we will pass transaction in here
5070 // rather than merging to global.
5071 SurfaceControl.mergeToGlobalTransaction(transaction);
Jorim Jaggi4981f152019-03-26 18:58:45 +01005072 } finally {
5073 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
5074 }
Jorim Jaggi9af095b2017-12-12 17:18:57 +01005075 }
Robert Carr2f8aa392018-01-31 14:46:51 -08005076
Jorim Jaggibe418292018-03-26 16:14:12 +02005077 void assignStackOrdering() {
Wale Ogunwalec17e5cf2020-01-21 10:04:46 -08005078 mTaskContainers.assignStackOrdering(getPendingTransaction());
Robert Carr2f8aa392018-01-31 14:46:51 -08005079 }
Chavi Weingarten3a748552018-05-14 17:32:42 +00005080
5081 /**
5082 * Increment the deferral count to determine whether to update the IME target.
5083 */
5084 void deferUpdateImeTarget() {
5085 mDeferUpdateImeTargetCount++;
5086 }
5087
5088 /**
5089 * Decrement the deferral count to determine whether to update the IME target. If the count
5090 * reaches 0, a new ime target will get computed.
5091 */
5092 void continueUpdateImeTarget() {
5093 if (mDeferUpdateImeTargetCount == 0) {
5094 return;
5095 }
5096
5097 mDeferUpdateImeTargetCount--;
5098 if (mDeferUpdateImeTargetCount == 0) {
5099 computeImeTarget(true /* updateImeTarget */);
5100 }
5101 }
5102
5103 /**
5104 * @return Whether a new IME target should be computed.
5105 */
5106 private boolean canUpdateImeTarget() {
5107 return mDeferUpdateImeTargetCount == 0;
5108 }
Arthur Hung95b38a92018-07-20 18:56:12 +08005109
5110 InputMonitor getInputMonitor() {
5111 return mInputMonitor;
5112 }
Jorim Jaggif1292892018-09-10 11:58:13 +02005113
5114 /**
5115 * @return Cached value whether we told display manager that we have content.
5116 */
5117 boolean getLastHasContent() {
5118 return mLastHasContent;
5119 }
Arthur Hungbe5ce212018-09-13 18:41:56 +08005120
5121 void registerPointerEventListener(@NonNull PointerEventListener listener) {
Riddle Hsu2588ab02019-02-25 14:23:56 +08005122 mPointerEventDispatcher.registerInputEventListener(listener);
Arthur Hungbe5ce212018-09-13 18:41:56 +08005123 }
5124
5125 void unregisterPointerEventListener(@NonNull PointerEventListener listener) {
Riddle Hsu2588ab02019-02-25 14:23:56 +08005126 mPointerEventDispatcher.unregisterInputEventListener(listener);
Arthur Hungbe5ce212018-09-13 18:41:56 +08005127 }
lumark588a3e82018-07-20 18:53:54 +08005128
5129 void prepareAppTransition(@WindowManager.TransitionType int transit,
Wale Ogunwale3a256e62018-12-06 14:41:18 -08005130 boolean alwaysKeepCurrent) {
5131 prepareAppTransition(transit, alwaysKeepCurrent, 0 /* flags */, false /* forceOverride */);
5132 }
5133
5134 void prepareAppTransition(@WindowManager.TransitionType int transit,
lumark588a3e82018-07-20 18:53:54 +08005135 boolean alwaysKeepCurrent, @WindowManager.TransitionFlags int flags,
5136 boolean forceOverride) {
5137 final boolean prepared = mAppTransition.prepareAppTransitionLocked(
5138 transit, alwaysKeepCurrent, flags, forceOverride);
5139 if (prepared && okToAnimate()) {
5140 mSkipAppTransitionAnimation = false;
5141 }
5142 }
5143
5144 void executeAppTransition() {
5145 if (mAppTransition.isTransitionSet()) {
Adrian Roosb125e0b2019-10-02 14:55:14 +02005146 ProtoLog.w(WM_DEBUG_APP_TRANSITIONS,
5147 "Execute app transition: %s, displayId: %d Callers=%s",
chaviw8065f442019-11-18 13:20:58 -08005148 mAppTransition, mDisplayId, Debug.getCallers(5));
lumark588a3e82018-07-20 18:53:54 +08005149 mAppTransition.setReady();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005150 mWmService.mWindowPlacerLocked.requestTraversal();
lumark588a3e82018-07-20 18:53:54 +08005151 }
5152 }
5153
5154 /**
5155 * Update pendingLayoutChanges after app transition has finished.
5156 */
5157 void handleAnimatingStoppedAndTransition() {
5158 int changes = 0;
5159
5160 mAppTransition.setIdle();
5161
5162 for (int i = mNoAnimationNotifyOnTransitionFinished.size() - 1; i >= 0; i--) {
5163 final IBinder token = mNoAnimationNotifyOnTransitionFinished.get(i);
5164 mAppTransition.notifyAppTransitionFinishedLocked(token);
5165 }
5166 mNoAnimationNotifyOnTransitionFinished.clear();
5167
5168 mWallpaperController.hideDeferredWallpapersIfNeeded();
5169
5170 onAppTransitionDone();
5171
5172 changes |= FINISH_LAYOUT_REDO_LAYOUT;
5173 if (DEBUG_WALLPAPER_LIGHT) {
5174 Slog.v(TAG_WM, "Wallpaper layer changed: assigning layers + relayout");
5175 }
5176 computeImeTarget(true /* updateImeTarget */);
wilsonshihc32538e2018-11-07 17:27:34 +08005177 mWallpaperMayChange = true;
lumark588a3e82018-07-20 18:53:54 +08005178 // Since the window list has been rebuilt, focus might have to be recomputed since the
5179 // actual order of windows might have changed again.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08005180 mWmService.mFocusMayChange = true;
lumark588a3e82018-07-20 18:53:54 +08005181
5182 pendingLayoutChanges |= changes;
5183 }
Andrii Kulian15cfb422018-11-07 13:38:49 -08005184
Wale Ogunwale3a256e62018-12-06 14:41:18 -08005185 /** Check if pending app transition is for activity / task launch. */
5186 boolean isNextTransitionForward() {
5187 final int transit = mAppTransition.getAppTransition();
5188 return transit == TRANSIT_ACTIVITY_OPEN
5189 || transit == TRANSIT_TASK_OPEN
5190 || transit == TRANSIT_TASK_TO_FRONT;
5191 }
5192
Andrii Kulian15cfb422018-11-07 13:38:49 -08005193 /**
5194 * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
5195 */
5196 boolean supportsSystemDecorations() {
Arthur Hung879a8ab2019-03-13 19:51:10 +08005197 return (mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(this)
Andrii Kuliandd989612019-02-21 12:13:28 -08005198 || (mDisplay.getFlags() & FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0
Chilun891aed22019-05-02 18:08:47 +08005199 || (mWmService.mForceDesktopModeOnExternalDisplays && !isUntrustedVirtualDisplay()))
Arthur Hung879a8ab2019-03-13 19:51:10 +08005200 // VR virtual display will be used to run and render 2D app within a VR experience.
5201 && mDisplayId != mWmService.mVr2dDisplayId;
Andrii Kulian15cfb422018-11-07 13:38:49 -08005202 }
chaviwff2e7d82018-11-02 11:11:27 -07005203
Tiger Huang04dc4cc2019-01-17 18:41:41 +08005204 /**
Chilun891aed22019-05-02 18:08:47 +08005205 * @return {@code true} if the display is non-system created virtual display.
5206 */
5207 boolean isUntrustedVirtualDisplay() {
5208 return mDisplay.getType() == Display.TYPE_VIRTUAL
5209 && mDisplay.getOwnerUid() != Process.SYSTEM_UID;
5210 }
5211
5212 /**
chaviw8065f442019-11-18 13:20:58 -08005213 * Re-parent the DisplayContent's top surface, {@link #mSurfaceControl} to the specified
5214 * SurfaceControl.
chaviwff2e7d82018-11-02 11:11:27 -07005215 *
Tiger Huangd8ec9382019-04-18 14:35:09 -07005216 * @param win The window which owns the SurfaceControl. This indicates the z-order of the
5217 * windows of this display against the windows on the parent display.
Tiger Huang04dc4cc2019-01-17 18:41:41 +08005218 * @param sc The new SurfaceControl, where the DisplayContent's surfaces will be re-parented to.
chaviwff2e7d82018-11-02 11:11:27 -07005219 */
Tiger Huangd8ec9382019-04-18 14:35:09 -07005220 void reparentDisplayContent(WindowState win, SurfaceControl sc) {
5221 mParentWindow = win;
Jackal Guoc43a0a62019-04-23 09:15:14 +08005222 mParentWindow.addEmbeddedDisplayContent(this);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08005223 mParentSurfaceControl = sc;
5224 if (mPortalWindowHandle == null) {
5225 mPortalWindowHandle = createPortalWindowHandle(sc.toString());
5226 }
Tiger Huanged6794e2019-05-07 20:07:59 +08005227 getPendingTransaction().setInputWindowInfo(sc, mPortalWindowHandle)
Vadim Caen1812c762019-08-12 11:38:22 +02005228 .reparent(mSurfaceControl, sc);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08005229 }
5230
Tiger Huangd8ec9382019-04-18 14:35:09 -07005231 /**
5232 * Get the window which owns the surface that this DisplayContent is re-parented to.
5233 *
5234 * @return the parent window.
5235 */
5236 WindowState getParentWindow() {
5237 return mParentWindow;
5238 }
5239
5240 /**
5241 * Update the location of this display in the parent window. This enables windows in this
5242 * display to compute the global transformation matrix.
5243 *
5244 * @param win The parent window of this display.
5245 * @param x The x coordinate in the parent window.
5246 * @param y The y coordinate in the parent window.
5247 */
5248 void updateLocation(WindowState win, int x, int y) {
5249 if (mParentWindow != win) {
5250 throw new IllegalArgumentException(
5251 "The given window is not the parent window of this display.");
5252 }
Jackal Guoc43a0a62019-04-23 09:15:14 +08005253 if (!mLocationInParentWindow.equals(x, y)) {
5254 mLocationInParentWindow.set(x, y);
Tiger Huangd8ec9382019-04-18 14:35:09 -07005255 if (mWmService.mAccessibilityController != null) {
Jacky Kaof93252b2019-07-18 15:19:52 +08005256 mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(mDisplayId);
Tiger Huangd8ec9382019-04-18 14:35:09 -07005257 }
Jackal Guoc43a0a62019-04-23 09:15:14 +08005258 notifyLocationInParentDisplayChanged();
Tiger Huangd8ec9382019-04-18 14:35:09 -07005259 }
5260 }
5261
5262 Point getLocationInParentWindow() {
5263 return mLocationInParentWindow;
5264 }
5265
Jackal Guoc43a0a62019-04-23 09:15:14 +08005266 Point getLocationInParentDisplay() {
5267 final Point location = new Point();
5268 if (mParentWindow != null) {
5269 // LocationInParentWindow indicates the offset to (0,0) of window, but what we need is
5270 // the offset to (0,0) of display.
5271 DisplayContent dc = this;
5272 do {
5273 final WindowState displayParent = dc.getParentWindow();
5274 location.x += displayParent.getFrameLw().left
5275 + (dc.getLocationInParentWindow().x * displayParent.mGlobalScale + 0.5f);
5276 location.y += displayParent.getFrameLw().top
5277 + (dc.getLocationInParentWindow().y * displayParent.mGlobalScale + 0.5f);
5278 dc = displayParent.getDisplayContent();
5279 } while (dc != null && dc.getParentWindow() != null);
5280 }
5281 return location;
5282 }
5283
5284 void notifyLocationInParentDisplayChanged() {
5285 forAllWindows(w -> {
5286 w.updateLocationInParentDisplayIfNeeded();
5287 }, false /* traverseTopToBottom */);
5288 }
5289
Tarandeep Singha6f35612019-01-11 19:50:46 -08005290 @VisibleForTesting
5291 SurfaceControl getWindowingLayer() {
chaviw8065f442019-11-18 13:20:58 -08005292 return mWindowContainers.getSurfaceControl();
Tarandeep Singha6f35612019-01-11 19:50:46 -08005293 }
5294
Vadim Caenf8474262019-08-12 17:52:01 +02005295 SurfaceControl getOverlayLayer() {
chaviw8065f442019-11-18 13:20:58 -08005296 return mOverlayContainers.getSurfaceControl();
Vadim Caenf8474262019-08-12 17:52:01 +02005297 }
5298
Tiger Huang04dc4cc2019-01-17 18:41:41 +08005299 /**
Adrian Roos4ffc8972019-02-07 20:45:11 +01005300 * Updates the display's system gesture exclusion.
5301 *
5302 * @return true, if the exclusion changed.
5303 */
5304 boolean updateSystemGestureExclusion() {
5305 if (mSystemGestureExclusionListeners.getRegisteredCallbackCount() == 0) {
5306 // No one's interested anyways.
5307 return false;
5308 }
5309
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005310 final Region systemGestureExclusion = Region.obtain();
5311 mSystemGestureExclusionWasRestricted = calculateSystemGestureExclusion(
5312 systemGestureExclusion, mSystemGestureExclusionUnrestricted);
Adrian Roos4ffc8972019-02-07 20:45:11 +01005313 try {
5314 if (mSystemGestureExclusion.equals(systemGestureExclusion)) {
5315 return false;
5316 }
5317 mSystemGestureExclusion.set(systemGestureExclusion);
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005318 final Region unrestrictedOrNull = mSystemGestureExclusionWasRestricted
5319 ? mSystemGestureExclusionUnrestricted : null;
Adrian Roos4ffc8972019-02-07 20:45:11 +01005320 for (int i = mSystemGestureExclusionListeners.beginBroadcast() - 1; i >= 0; --i) {
5321 try {
5322 mSystemGestureExclusionListeners.getBroadcastItem(i)
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005323 .onSystemGestureExclusionChanged(mDisplayId, systemGestureExclusion,
5324 unrestrictedOrNull);
Adrian Roos4ffc8972019-02-07 20:45:11 +01005325 } catch (RemoteException e) {
5326 Slog.e(TAG, "Failed to notify SystemGestureExclusionListener", e);
5327 }
5328 }
5329 mSystemGestureExclusionListeners.finishBroadcast();
5330 return true;
5331 } finally {
5332 systemGestureExclusion.recycle();
5333 }
5334 }
5335
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005336 /**
5337 * Calculates the system gesture exclusion.
5338 *
5339 * @param outExclusion will be set to the gesture exclusion region
5340 * @param outExclusionUnrestricted will be set to the gesture exclusion region without
5341 * any restrictions applied.
5342 * @return whether any restrictions were applied, i.e. outExclusion and outExclusionUnrestricted
5343 * differ.
5344 */
Adrian Roos4ffc8972019-02-07 20:45:11 +01005345 @VisibleForTesting
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005346 boolean calculateSystemGestureExclusion(Region outExclusion, @Nullable
5347 Region outExclusionUnrestricted) {
5348 outExclusion.setEmpty();
5349 if (outExclusionUnrestricted != null) {
5350 outExclusionUnrestricted.setEmpty();
5351 }
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005352 final Region unhandled = Region.obtain();
5353 unhandled.set(0, 0, mDisplayFrames.mDisplayWidth, mDisplayFrames.mDisplayHeight);
5354
Tiger Huang332793b2019-10-29 23:21:27 +08005355 final Rect leftEdge = mInsetsStateController.getSourceProvider(ITYPE_LEFT_GESTURES)
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005356 .getSource().getFrame();
Tiger Huang332793b2019-10-29 23:21:27 +08005357 final Rect rightEdge = mInsetsStateController.getSourceProvider(ITYPE_RIGHT_GESTURES)
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005358 .getSource().getFrame();
5359
Adrian Roos4ffc8972019-02-07 20:45:11 +01005360 final Region touchableRegion = Region.obtain();
5361 final Region local = Region.obtain();
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005362 final int[] remainingLeftRight =
5363 {mSystemGestureExclusionLimit, mSystemGestureExclusionLimit};
Adrian Roos4ffc8972019-02-07 20:45:11 +01005364
Adrian Roosb1063792019-06-28 12:10:51 +02005365 // Traverse all windows top down to assemble the gesture exclusion rects.
Adrian Roos4ffc8972019-02-07 20:45:11 +01005366 // For each window, we only take the rects that fall within its touchable region.
5367 forAllWindows(w -> {
5368 if (w.cantReceiveTouchInput() || !w.isVisible()
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005369 || (w.getAttrs().flags & FLAG_NOT_TOUCHABLE) != 0
5370 || unhandled.isEmpty()) {
Adrian Roos4ffc8972019-02-07 20:45:11 +01005371 return;
5372 }
Adrian Roos4ffc8972019-02-07 20:45:11 +01005373
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005374 // Get the touchable region of the window, and intersect with where the screen is still
5375 // touchable, i.e. touchable regions on top are not covering it yet.
Adrian Roosb1063792019-06-28 12:10:51 +02005376 w.getEffectiveTouchableRegion(touchableRegion);
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005377 touchableRegion.op(unhandled, Op.INTERSECT);
Adrian Roos4ffc8972019-02-07 20:45:11 +01005378
Adrian Roos019a52b2019-07-02 16:47:44 +02005379 if (w.isImplicitlyExcludingAllSystemGestures()) {
5380 local.set(touchableRegion);
5381 } else {
5382 rectListToRegion(w.getSystemGestureExclusion(), local);
Adrian Roos4ffc8972019-02-07 20:45:11 +01005383
Adrian Roos019a52b2019-07-02 16:47:44 +02005384 // Transform to display coordinates
5385 local.scale(w.mGlobalScale);
5386 final Rect frame = w.getWindowFrames().mFrame;
5387 local.translate(frame.left, frame.top);
Adrian Roos4ffc8972019-02-07 20:45:11 +01005388
Adrian Roos019a52b2019-07-02 16:47:44 +02005389 // A window can only exclude system gestures where it is actually touchable
5390 local.op(touchableRegion, Op.INTERSECT);
5391 }
Adrian Roos4ffc8972019-02-07 20:45:11 +01005392
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005393 // Apply restriction if necessary.
5394 if (needsGestureExclusionRestrictions(w, mLastDispatchedSystemUiVisibility)) {
5395
5396 // Processes the region along the left edge.
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005397 remainingLeftRight[0] = addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
5398 remainingLeftRight[0], w, EXCLUSION_LEFT);
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005399
5400 // Processes the region along the right edge.
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005401 remainingLeftRight[1] = addToGlobalAndConsumeLimit(local, outExclusion, rightEdge,
5402 remainingLeftRight[1], w, EXCLUSION_RIGHT);
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005403
5404 // Adds the middle (unrestricted area)
5405 final Region middle = Region.obtain(local);
5406 middle.op(leftEdge, Op.DIFFERENCE);
5407 middle.op(rightEdge, Op.DIFFERENCE);
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005408 outExclusion.op(middle, Op.UNION);
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005409 middle.recycle();
5410 } else {
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005411 boolean loggable = needsGestureExclusionRestrictions(w, 0 /* lastSysUiVis */);
5412 if (loggable) {
5413 addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
5414 Integer.MAX_VALUE, w, EXCLUSION_LEFT);
5415 addToGlobalAndConsumeLimit(local, outExclusion, rightEdge,
5416 Integer.MAX_VALUE, w, EXCLUSION_RIGHT);
5417 }
5418 outExclusion.op(local, Op.UNION);
5419 }
5420 if (outExclusionUnrestricted != null) {
5421 outExclusionUnrestricted.op(local, Op.UNION);
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005422 }
5423 unhandled.op(touchableRegion, Op.DIFFERENCE);
5424 }, true /* topToBottom */);
Adrian Roos4ffc8972019-02-07 20:45:11 +01005425 local.recycle();
5426 touchableRegion.recycle();
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005427 unhandled.recycle();
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005428 return remainingLeftRight[0] < mSystemGestureExclusionLimit
5429 || remainingLeftRight[1] < mSystemGestureExclusionLimit;
Adrian Roos4ffc8972019-02-07 20:45:11 +01005430 }
5431
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005432 /**
5433 * @return Whether gesture exclusion area should be restricted from the window depending on the
5434 * current SystemUI visibility flags.
5435 */
5436 private static boolean needsGestureExclusionRestrictions(WindowState win, int sysUiVisibility) {
5437 final int type = win.mAttrs.type;
5438 final int stickyHideNavFlags =
5439 SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
5440 final boolean stickyHideNav =
5441 (sysUiVisibility & stickyHideNavFlags) == stickyHideNavFlags;
wilsonshihe8321942019-10-18 18:39:46 +08005442 return !stickyHideNav && type != TYPE_INPUT_METHOD && type != TYPE_NOTIFICATION_SHADE
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005443 && win.getActivityType() != ACTIVITY_TYPE_HOME;
5444 }
5445
5446 /**
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005447 * @return Whether gesture exclusion area should be logged for the given window
5448 */
5449 static boolean logsGestureExclusionRestrictions(WindowState win) {
Adrian Roos1c2e9a12019-08-20 18:23:47 +02005450 if (win.mWmService.mConstants.mSystemGestureExclusionLogDebounceTimeoutMillis <= 0) {
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005451 return false;
5452 }
5453 final WindowManager.LayoutParams attrs = win.getAttrs();
5454 final int type = attrs.type;
5455 return type != TYPE_WALLPAPER
5456 && type != TYPE_APPLICATION_STARTING
5457 && type != TYPE_NAVIGATION_BAR
5458 && (attrs.flags & FLAG_NOT_TOUCHABLE) == 0
5459 && needsGestureExclusionRestrictions(win, 0 /* sysUiVisibility */)
5460 && win.getDisplayContent().mDisplayPolicy.hasSideGestures();
5461 }
5462
5463 /**
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005464 * Adds a local gesture exclusion area to the global area while applying a limit per edge.
5465 *
5466 * @param local The gesture exclusion area to add.
5467 * @param global The destination.
5468 * @param edge Only processes the part in that region.
5469 * @param limit How much limit in pixels we have.
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005470 * @param win The WindowState that is being processed
5471 * @param side The side that is being processed, either {@link WindowState#EXCLUSION_LEFT} or
5472 * {@link WindowState#EXCLUSION_RIGHT}
5473 * @return How much of the limit is remaining.
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005474 */
5475 private static int addToGlobalAndConsumeLimit(Region local, Region global, Rect edge,
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005476 int limit, WindowState win, int side) {
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005477 final Region r = Region.obtain(local);
5478 r.op(edge, Op.INTERSECT);
5479
5480 final int[] remaining = {limit};
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005481 final int[] requestedExclusion = {0};
Adrian Roos2351d5f2019-07-03 15:35:07 +02005482 forEachRectReverse(r, rect -> {
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005483 if (remaining[0] <= 0) {
5484 return;
5485 }
5486 final int height = rect.height();
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005487 requestedExclusion[0] += height;
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005488 if (height > remaining[0]) {
Adrian Roos2351d5f2019-07-03 15:35:07 +02005489 rect.top = rect.bottom - remaining[0];
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005490 }
5491 remaining[0] -= height;
5492 global.op(rect, Op.UNION);
5493 });
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005494
5495 final int grantedExclusion = limit - remaining[0];
5496 win.setLastExclusionHeights(side, requestedExclusion[0], grantedExclusion);
5497
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005498 r.recycle();
5499 return remaining[0];
5500 }
5501
Adrian Roos4ffc8972019-02-07 20:45:11 +01005502 void registerSystemGestureExclusionListener(ISystemGestureExclusionListener listener) {
5503 mSystemGestureExclusionListeners.register(listener);
5504 final boolean changed;
5505 if (mSystemGestureExclusionListeners.getRegisteredCallbackCount() == 1) {
5506 changed = updateSystemGestureExclusion();
5507 } else {
5508 changed = false;
5509 }
5510
5511 if (!changed) {
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005512 final Region unrestrictedOrNull = mSystemGestureExclusionWasRestricted
5513 ? mSystemGestureExclusionUnrestricted : null;
Adrian Roos4ffc8972019-02-07 20:45:11 +01005514 // If updateSystemGestureExclusion changed the exclusion, it will already have
5515 // notified the listener. Otherwise, we'll do it here.
5516 try {
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005517 listener.onSystemGestureExclusionChanged(mDisplayId, mSystemGestureExclusion,
5518 unrestrictedOrNull);
Adrian Roos4ffc8972019-02-07 20:45:11 +01005519 } catch (RemoteException e) {
5520 Slog.e(TAG, "Failed to notify SystemGestureExclusionListener during register", e);
5521 }
5522 }
5523 }
5524
5525 void unregisterSystemGestureExclusionListener(ISystemGestureExclusionListener listener) {
5526 mSystemGestureExclusionListeners.unregister(listener);
5527 }
5528
5529 /**
Tiger Huang04dc4cc2019-01-17 18:41:41 +08005530 * Create a portal window handle for input. This window transports any touch to the display
5531 * indicated by {@link InputWindowHandle#portalToDisplayId} if the touch hits this window.
5532 *
5533 * @param name The name of the portal window handle.
5534 * @return the new portal window handle.
5535 */
5536 private InputWindowHandle createPortalWindowHandle(String name) {
5537 // Let surface flinger to set the display ID of this input window handle because we don't
5538 // know which display the parent surface control is on.
5539 final InputWindowHandle portalWindowHandle = new InputWindowHandle(
Vishnu Nair18782162019-10-08 14:57:16 -07005540 null /* inputApplicationHandle */, INVALID_DISPLAY);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08005541 portalWindowHandle.name = name;
5542 portalWindowHandle.token = new Binder();
5543 portalWindowHandle.layoutParamsFlags =
5544 FLAG_SPLIT_TOUCH | FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL;
5545 getBounds(mTmpBounds);
5546 portalWindowHandle.touchableRegion.set(mTmpBounds);
5547 portalWindowHandle.scaleFactor = 1f;
5548 portalWindowHandle.ownerPid = Process.myPid();
5549 portalWindowHandle.ownerUid = Process.myUid();
5550 portalWindowHandle.portalToDisplayId = mDisplayId;
5551 return portalWindowHandle;
chaviwff2e7d82018-11-02 11:11:27 -07005552 }
Issei Suzukia5dbf522019-02-01 17:58:15 +01005553
5554 /**
5555 * @see IWindowManager#setForwardedInsets
5556 */
5557 public void setForwardedInsets(Insets insets) {
5558 if (insets == null) {
5559 insets = Insets.NONE;
5560 }
5561 if (mDisplayPolicy.getForwardedInsets().equals(insets)) {
5562 return;
5563 }
5564 mDisplayPolicy.setForwardedInsets(insets);
5565 setLayoutNeeded();
5566 mWmService.mWindowPlacerLocked.requestTraversal();
5567 }
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -05005568
5569 protected MetricsLogger getMetricsLogger() {
5570 if (mMetricsLogger == null) {
5571 mMetricsLogger = new MetricsLogger();
5572 }
5573 return mMetricsLogger;
5574 }
Louis Chang677921f2019-12-06 16:44:24 +08005575
5576 void onDisplayChanged() {
5577 // The window policy is responsible for stopping activities on the default display.
5578 final int displayId = mDisplay.getDisplayId();
5579 if (displayId != DEFAULT_DISPLAY) {
5580 final int displayState = mDisplay.getState();
5581 if (displayState == Display.STATE_OFF && mOffToken == null) {
5582 mOffToken = mAtmService.acquireSleepToken("Display-off", displayId);
5583 } else if (displayState == Display.STATE_ON && mOffToken != null) {
5584 mOffToken.release();
5585 mOffToken = null;
5586 }
5587 }
5588
5589 mDisplay.getRealSize(mTmpDisplaySize);
5590 setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y);
5591 updateDisplayInfo();
5592 mWmService.requestTraversal();
5593 }
5594
5595 void addStack(ActivityStack stack, int position) {
5596 setStackOnDisplay(stack, position);
5597 positionStackAt(stack, position);
5598 mAtmService.updateSleepIfNeededLocked();
5599 }
5600
5601 void onStackRemoved(ActivityStack stack) {
5602 if (ActivityTaskManagerDebugConfig.DEBUG_STACK) {
5603 Slog.v(TAG_STACK, "removeStack: detaching " + stack + " from displayId=" + mDisplayId);
5604 }
5605 if (mPreferredTopFocusableStack == stack) {
5606 mPreferredTopFocusableStack = null;
5607 }
5608 releaseSelfIfNeeded();
5609 mAtmService.updateSleepIfNeededLocked();
5610 onStackOrderChanged(stack);
5611 }
5612
5613 void positionStackAtTop(ActivityStack stack, boolean includingParents) {
5614 positionStackAtTop(stack, includingParents, null /* updateLastFocusedStackReason */);
5615 }
5616
5617 void positionStackAtTop(ActivityStack stack, boolean includingParents,
5618 String updateLastFocusedStackReason) {
5619 positionStackAt(stack, getStackCount(), includingParents, updateLastFocusedStackReason);
5620 }
5621
5622 void positionStackAtBottom(ActivityStack stack) {
5623 positionStackAtBottom(stack, null /* updateLastFocusedStackReason */);
5624 }
5625
5626 void positionStackAtBottom(ActivityStack stack, String updateLastFocusedStackReason) {
5627 positionStackAt(stack, 0, false /* includingParents */, updateLastFocusedStackReason);
5628 }
5629
5630 private void positionStackAt(ActivityStack stack, int position) {
5631 positionStackAt(stack, position, false /* includingParents */,
5632 null /* updateLastFocusedStackReason */);
5633 }
5634
5635 private void positionStackAt(ActivityStack stack, int position, boolean includingParents,
5636 String updateLastFocusedStackReason) {
5637 // TODO: Keep in sync with WindowContainer.positionChildAt(), once we change that to adjust
5638 // the position internally, also update the logic here
5639 final ActivityStack prevFocusedStack = updateLastFocusedStackReason != null
5640 ? getFocusedStack() : null;
5641 final boolean wasContained = getIndexOf(stack) >= 0;
5642 if (mSingleTaskInstance && getStackCount() == 1 && !wasContained) {
5643 throw new IllegalStateException(
5644 "positionStackAt: Can only have one task on display=" + this);
5645 }
5646
5647 // Since positionChildAt() is called during the creation process of pinned stacks,
5648 // ActivityStack#getStack() can be null.
5649 positionStackAt(position, stack, includingParents);
5650
5651 // The insert position may be adjusted to non-top when there is always-on-top stack. Since
5652 // the original position is preferred to be top, the stack should have higher priority when
5653 // we are looking for top focusable stack. The condition {@code wasContained} restricts the
5654 // preferred stack is set only when moving an existing stack to top instead of adding a new
5655 // stack that may be too early (e.g. in the middle of launching or reparenting).
5656 if (wasContained && position >= getStackCount() - 1 && stack.isFocusableAndVisible()) {
5657 mPreferredTopFocusableStack = stack;
5658 } else if (mPreferredTopFocusableStack == stack) {
5659 mPreferredTopFocusableStack = null;
5660 }
5661
5662 if (updateLastFocusedStackReason != null) {
5663 final ActivityStack currentFocusedStack = getFocusedStack();
5664 if (currentFocusedStack != prevFocusedStack) {
5665 mLastFocusedStack = prevFocusedStack;
Louis Chang149d5c82019-12-30 09:47:39 +08005666 EventLogTags.writeWmFocusedStack(mRootWindowContainer.mCurrentUser, mDisplayId,
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08005667 currentFocusedStack == null ? -1 : currentFocusedStack.getRootTaskId(),
5668 mLastFocusedStack == null ? -1 : mLastFocusedStack.getRootTaskId(),
Louis Chang677921f2019-12-06 16:44:24 +08005669 updateLastFocusedStackReason);
5670 }
5671 }
5672
5673 onStackOrderChanged(stack);
5674 }
5675
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08005676 ActivityStack getStack(int rootTaskId) {
Louis Chang677921f2019-12-06 16:44:24 +08005677 for (int i = getStackCount() - 1; i >= 0; --i) {
5678 final ActivityStack stack = getStackAt(i);
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08005679 if (stack.getRootTaskId() == rootTaskId) {
Louis Chang677921f2019-12-06 16:44:24 +08005680 return stack;
5681 }
5682 }
5683 return null;
5684 }
5685
5686 boolean alwaysCreateStack(int windowingMode, int activityType) {
5687 // Always create a stack for fullscreen, freeform, and split-screen-secondary windowing
5688 // modes so that we can manage visual ordering and return types correctly.
5689 return activityType == ACTIVITY_TYPE_STANDARD
5690 && (windowingMode == WINDOWING_MODE_FULLSCREEN
5691 || windowingMode == WINDOWING_MODE_FREEFORM
5692 || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
5693 }
5694
5695 /**
5696 * Returns an existing stack compatible with the windowing mode and activity type or creates one
5697 * if a compatible stack doesn't exist.
5698 * @see #getStack(int, int)
5699 * @see #createStack(int, int, boolean)
5700 */
5701 ActivityStack getOrCreateStack(int windowingMode, int activityType,
5702 boolean onTop) {
5703 if (!alwaysCreateStack(windowingMode, activityType)) {
5704 ActivityStack stack = getStack(windowingMode, activityType);
5705 if (stack != null) {
5706 return stack;
5707 }
5708 }
5709 return createStack(windowingMode, activityType, onTop);
5710 }
5711
5712 /**
5713 * Returns an existing stack compatible with the input params or creates one
5714 * if a compatible stack doesn't exist.
5715 * @see #getOrCreateStack(int, int, boolean)
5716 */
5717 ActivityStack getOrCreateStack(@Nullable ActivityRecord r,
5718 @Nullable ActivityOptions options, @Nullable Task candidateTask, int activityType,
5719 boolean onTop) {
5720 // First preference is the windowing mode in the activity options if set.
5721 int windowingMode = (options != null)
5722 ? options.getLaunchWindowingMode() : WINDOWING_MODE_UNDEFINED;
5723 // Validate that our desired windowingMode will work under the current conditions.
5724 // UNDEFINED windowing mode is a valid result and means that the new stack will inherit
5725 // it's display's windowing mode.
5726 windowingMode = validateWindowingMode(windowingMode, r, candidateTask, activityType);
5727 return getOrCreateStack(windowingMode, activityType, onTop);
5728 }
5729
5730 @VisibleForTesting
5731 int getNextStackId() {
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08005732 return mAtmService.mStackSupervisor.getNextTaskIdForUser();
Louis Chang677921f2019-12-06 16:44:24 +08005733 }
5734
Wale Ogunwale8f93b642019-12-26 12:10:52 -08005735 ActivityStack createStack(int windowingMode, int activityType, boolean onTop) {
5736 return createStack(windowingMode, activityType, onTop, null /*info*/, null /*intent*/);
5737 }
5738
Louis Chang677921f2019-12-06 16:44:24 +08005739 /**
5740 * Creates a stack matching the input windowing mode and activity type on this display.
5741 * @param windowingMode The windowing mode the stack should be created in. If
5742 * {@link WindowConfiguration#WINDOWING_MODE_UNDEFINED} then the stack will
5743 * inherit its parent's windowing mode.
5744 * @param activityType The activityType the stack should be created in. If
5745 * {@link WindowConfiguration#ACTIVITY_TYPE_UNDEFINED} then the stack will
5746 * be created in {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}.
5747 * @param onTop If true the stack will be created at the top of the display, else at the bottom.
5748 * @return The newly created stack.
5749 */
Wale Ogunwale8f93b642019-12-26 12:10:52 -08005750 ActivityStack createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info,
5751 Intent intent) {
Louis Chang677921f2019-12-06 16:44:24 +08005752 if (mSingleTaskInstance && getStackCount() > 0) {
5753 // Create stack on default display instead since this display can only contain 1 stack.
5754 // TODO: Kinda a hack, but better that having the decision at each call point. Hoping
5755 // this goes away once ActivityView is no longer using virtual displays.
Louis Chang149d5c82019-12-30 09:47:39 +08005756 return mRootWindowContainer.getDefaultDisplay().createStack(
Wale Ogunwale8f93b642019-12-26 12:10:52 -08005757 windowingMode, activityType, onTop, info, intent);
Louis Chang677921f2019-12-06 16:44:24 +08005758 }
5759
5760 if (activityType == ACTIVITY_TYPE_UNDEFINED) {
5761 // Can't have an undefined stack type yet...so re-map to standard. Anyone that wants
5762 // anything else should be passing it in anyways...
5763 activityType = ACTIVITY_TYPE_STANDARD;
5764 }
5765
5766 if (activityType != ACTIVITY_TYPE_STANDARD) {
5767 // For now there can be only one stack of a particular non-standard activity type on a
5768 // display. So, get that ignoring whatever windowing mode it is currently in.
5769 ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
5770 if (stack != null) {
5771 throw new IllegalArgumentException("Stack=" + stack + " of activityType="
5772 + activityType + " already on display=" + this + ". Can't have multiple.");
5773 }
5774 }
5775
5776 if (!isWindowingModeSupported(windowingMode, mAtmService.mSupportsMultiWindow,
5777 mAtmService.mSupportsSplitScreenMultiWindow,
5778 mAtmService.mSupportsFreeformWindowManagement,
5779 mAtmService.mSupportsPictureInPicture, activityType)) {
5780 throw new IllegalArgumentException("Can't create stack for unsupported windowingMode="
5781 + windowingMode);
5782 }
5783
5784 final int stackId = getNextStackId();
Wale Ogunwale8f93b642019-12-26 12:10:52 -08005785 return createStackUnchecked(windowingMode, activityType, stackId, onTop, info, intent);
Louis Chang677921f2019-12-06 16:44:24 +08005786 }
5787
5788 @VisibleForTesting
5789 ActivityStack createStackUnchecked(int windowingMode, int activityType,
Wale Ogunwale8f93b642019-12-26 12:10:52 -08005790 int stackId, boolean onTop, ActivityInfo info, Intent intent) {
Louis Chang677921f2019-12-06 16:44:24 +08005791 if (windowingMode == WINDOWING_MODE_PINNED && activityType != ACTIVITY_TYPE_STANDARD) {
5792 throw new IllegalArgumentException("Stack with windowing mode cannot with non standard "
5793 + "activity type.");
5794 }
Wale Ogunwale8f93b642019-12-26 12:10:52 -08005795 if (info == null) {
5796 info = new ActivityInfo();
5797 info.applicationInfo = new ApplicationInfo();
5798 }
5799
lumarkbde15132019-12-18 22:29:43 +08005800 final ActivityStack stack = new ActivityStack(this, stackId,
Wale Ogunwale8f93b642019-12-26 12:10:52 -08005801 mRootWindowContainer.mStackSupervisor, activityType, info, intent);
lumarkbde15132019-12-18 22:29:43 +08005802 addStack(stack, onTop ? POSITION_TOP : POSITION_BOTTOM);
5803 stack.setWindowingMode(windowingMode, false /* animate */, false /* showRecents */,
5804 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */,
5805 true /* creating */);
5806
5807 return stack;
Louis Chang677921f2019-12-06 16:44:24 +08005808 }
5809
5810 /**
5811 * Get the preferred focusable stack in priority. If the preferred stack does not exist, find a
5812 * focusable and visible stack from the top of stacks in this display.
5813 */
5814 ActivityStack getFocusedStack() {
5815 if (mPreferredTopFocusableStack != null) {
5816 return mPreferredTopFocusableStack;
5817 }
5818
5819 for (int i = getStackCount() - 1; i >= 0; --i) {
5820 final ActivityStack stack = getStackAt(i);
5821 if (stack.isFocusableAndVisible()) {
5822 return stack;
5823 }
5824 }
5825
5826 return null;
5827 }
5828
5829 ActivityStack getNextFocusableStack(ActivityStack currentFocus, boolean ignoreCurrent) {
5830 final int currentWindowingMode = currentFocus != null
5831 ? currentFocus.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
5832
5833 ActivityStack candidate = null;
5834 for (int i = getStackCount() - 1; i >= 0; --i) {
5835 final ActivityStack stack = getStackAt(i);
5836 if (ignoreCurrent && stack == currentFocus) {
5837 continue;
5838 }
5839 if (!stack.isFocusableAndVisible()) {
5840 continue;
5841 }
5842
5843 if (currentWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
5844 && candidate == null && stack.inSplitScreenPrimaryWindowingMode()) {
5845 // If the currently focused stack is in split-screen secondary we save off the
5846 // top primary split-screen stack as a candidate for focus because we might
5847 // prefer focus to move to an other stack to avoid primary split-screen stack
5848 // overlapping with a fullscreen stack when a fullscreen stack is higher in z
5849 // than the next split-screen stack. Assistant stack, I am looking at you...
5850 // We only move the focus to the primary-split screen stack if there isn't a
5851 // better alternative.
5852 candidate = stack;
5853 continue;
5854 }
5855 if (candidate != null && stack.inSplitScreenSecondaryWindowingMode()) {
5856 // Use the candidate stack since we are now at the secondary split-screen.
5857 return candidate;
5858 }
5859 return stack;
5860 }
5861 return candidate;
5862 }
5863
5864 ActivityRecord getResumedActivity() {
5865 final ActivityStack focusedStack = getFocusedStack();
5866 if (focusedStack == null) {
5867 return null;
5868 }
5869 // TODO(b/111541062): Move this into ActivityStack#getResumedActivity()
5870 // Check if the focused stack has the resumed activity
5871 ActivityRecord resumedActivity = focusedStack.getResumedActivity();
5872 if (resumedActivity == null || resumedActivity.app == null) {
5873 // If there is no registered resumed activity in the stack or it is not running -
5874 // try to use previously resumed one.
5875 resumedActivity = focusedStack.mPausingActivity;
5876 if (resumedActivity == null || resumedActivity.app == null) {
5877 // If previously resumed activity doesn't work either - find the topmost running
5878 // activity that can be focused.
5879 resumedActivity = focusedStack.topRunningActivity(true /* focusableOnly */);
5880 }
5881 }
5882 return resumedActivity;
5883 }
5884
5885 ActivityStack getLastFocusedStack() {
5886 return mLastFocusedStack;
5887 }
5888
5889 boolean allResumedActivitiesComplete() {
5890 for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
5891 final ActivityRecord r = getStackAt(stackNdx).getResumedActivity();
5892 if (r != null && !r.isState(RESUMED)) {
5893 return false;
5894 }
5895 }
5896 final ActivityStack currentFocusedStack = getFocusedStack();
5897 if (ActivityTaskManagerDebugConfig.DEBUG_STACK) {
5898 Slog.d(TAG_STACK, "allResumedActivitiesComplete: mLastFocusedStack changing from="
5899 + mLastFocusedStack + " to=" + currentFocusedStack);
5900 }
5901 mLastFocusedStack = currentFocusedStack;
5902 return true;
5903 }
5904
5905 /**
5906 * Pause all activities in either all of the stacks or just the back stacks. This is done before
5907 * resuming a new activity and to make sure that previously active activities are
5908 * paused in stacks that are no longer visible or in pinned windowing mode. This does not
5909 * pause activities in visible stacks, so if an activity is launched within the same stack/task,
5910 * then we should explicitly pause that stack's top activity.
5911 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
5912 * @param resuming The resuming activity.
5913 * @return {@code true} if any activity was paused as a result of this call.
5914 */
5915 boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming) {
5916 boolean someActivityPaused = false;
5917 for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
5918 final ActivityStack stack = getStackAt(stackNdx);
5919 final ActivityRecord resumedActivity = stack.getResumedActivity();
5920 if (resumedActivity != null
5921 && (stack.getVisibility(resuming) != STACK_VISIBILITY_VISIBLE
Evan Rosky226de132020-01-03 18:00:29 -08005922 || !stack.isTopActivityFocusable())) {
Louis Chang677921f2019-12-06 16:44:24 +08005923 if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack
5924 + " mResumedActivity=" + resumedActivity);
5925 someActivityPaused |= stack.startPausingLocked(userLeaving, false /* uiSleeping*/,
5926 resuming);
5927 }
5928 }
5929 return someActivityPaused;
5930 }
5931
5932 /**
5933 * Find task for putting the Activity in.
5934 */
5935 void findTaskLocked(final ActivityRecord r, final boolean isPreferredDisplay,
Louis Chang149d5c82019-12-30 09:47:39 +08005936 RootWindowContainer.FindTaskResult result) {
Louis Chang677921f2019-12-06 16:44:24 +08005937 mTmpFindTaskResult.clear();
5938 for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
5939 final ActivityStack stack = getStackAt(stackNdx);
5940 if (!r.hasCompatibleActivityType(stack)) {
5941 if (DEBUG_TASKS) {
5942 Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) " + stack);
5943 }
5944 continue;
5945 }
5946
5947 mTmpFindTaskResult.process(r, stack);
5948 // It is possible to have tasks in multiple stacks with the same root affinity, so
5949 // we should keep looking after finding an affinity match to see if there is a
5950 // better match in another stack. Also, task affinity isn't a good enough reason
5951 // to target a display which isn't the source of the intent, so skip any affinity
5952 // matches not on the specified display.
5953 if (mTmpFindTaskResult.mRecord != null) {
5954 if (mTmpFindTaskResult.mIdealMatch) {
5955 result.setTo(mTmpFindTaskResult);
5956 return;
5957 } else if (isPreferredDisplay) {
5958 // Note: since the traversing through the stacks is top down, the floating
5959 // tasks should always have lower priority than any affinity-matching tasks
5960 // in the fullscreen stacks
5961 result.setTo(mTmpFindTaskResult);
5962 }
5963 }
5964 }
5965 }
5966
5967 /**
5968 * Removes stacks in the input windowing modes from the system if they are of activity type
5969 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
5970 */
5971 void removeStacksInWindowingModes(int... windowingModes) {
5972 if (windowingModes == null || windowingModes.length == 0) {
5973 return;
5974 }
5975
5976 // Collect the stacks that are necessary to be removed instead of performing the removal
5977 // by looping mStacks, so that we don't miss any stacks after the stack size changed or
5978 // stacks reordered.
5979 final ArrayList<ActivityStack> stacks = new ArrayList<>();
5980 for (int j = windowingModes.length - 1; j >= 0; --j) {
5981 final int windowingMode = windowingModes[j];
5982 for (int i = getStackCount() - 1; i >= 0; --i) {
5983 final ActivityStack stack = getStackAt(i);
5984 if (!stack.isActivityTypeStandardOrUndefined()) {
5985 continue;
5986 }
5987 if (stack.getWindowingMode() != windowingMode) {
5988 continue;
5989 }
5990 stacks.add(stack);
5991 }
5992 }
5993
5994 for (int i = stacks.size() - 1; i >= 0; --i) {
Louis Chang149d5c82019-12-30 09:47:39 +08005995 mRootWindowContainer.mStackSupervisor.removeStack(stacks.get(i));
Louis Chang677921f2019-12-06 16:44:24 +08005996 }
5997 }
5998
5999 void removeStacksWithActivityTypes(int... activityTypes) {
6000 if (activityTypes == null || activityTypes.length == 0) {
6001 return;
6002 }
6003
6004 // Collect the stacks that are necessary to be removed instead of performing the removal
6005 // by looping mStacks, so that we don't miss any stacks after the stack size changed or
6006 // stacks reordered.
6007 final ArrayList<ActivityStack> stacks = new ArrayList<>();
6008 for (int j = activityTypes.length - 1; j >= 0; --j) {
6009 final int activityType = activityTypes[j];
6010 for (int i = getStackCount() - 1; i >= 0; --i) {
6011 final ActivityStack stack = getStackAt(i);
6012 if (stack.getActivityType() == activityType) {
6013 stacks.add(stack);
6014 }
6015 }
6016 }
6017
6018 for (int i = stacks.size() - 1; i >= 0; --i) {
Louis Chang149d5c82019-12-30 09:47:39 +08006019 mRootWindowContainer.mStackSupervisor.removeStack(stacks.get(i));
Louis Chang677921f2019-12-06 16:44:24 +08006020 }
6021 }
6022
6023 void onSplitScreenModeDismissed() {
6024 mAtmService.deferWindowLayout();
6025 try {
6026 // Adjust the windowing mode of any stack in secondary split-screen to fullscreen.
6027 for (int i = getStackCount() - 1; i >= 0; --i) {
6028 final ActivityStack otherStack = getStackAt(i);
6029 if (!otherStack.inSplitScreenSecondaryWindowingMode()) {
6030 continue;
6031 }
6032 otherStack.setWindowingMode(WINDOWING_MODE_UNDEFINED, false /* animate */,
6033 false /* showRecents */, false /* enteringSplitScreenMode */,
6034 true /* deferEnsuringVisibility */, false /* creating */);
6035 }
6036 } finally {
6037 final ActivityStack topFullscreenStack =
6038 getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN);
Wale Ogunwale734b8962020-01-21 12:17:42 -08006039 final ActivityStack homeStack = getRootHomeTask();
Louis Chang677921f2019-12-06 16:44:24 +08006040 if (topFullscreenStack != null && homeStack != null && !isTopStack(homeStack)) {
6041 // Whenever split-screen is dismissed we want the home stack directly behind the
6042 // current top fullscreen stack so it shows up when the top stack is finished.
6043 // TODO: Would be better to use ActivityDisplay.positionChildAt() for this, however
6044 // ActivityDisplay doesn't have a direct controller to WM side yet. We can switch
6045 // once we have that.
6046 homeStack.moveToFront("onSplitScreenModeDismissed");
6047 topFullscreenStack.moveToFront("onSplitScreenModeDismissed");
6048 }
6049 mAtmService.continueWindowLayout();
6050 }
6051 }
6052
6053 void onSplitScreenModeActivated() {
6054 mAtmService.deferWindowLayout();
6055 try {
6056 // Adjust the windowing mode of any affected by split-screen to split-screen secondary.
Wale Ogunwale734b8962020-01-21 12:17:42 -08006057 final ActivityStack splitScreenPrimaryStack = getRootSplitScreenPrimaryTask();
Louis Chang677921f2019-12-06 16:44:24 +08006058 for (int i = getStackCount() - 1; i >= 0; --i) {
6059 final ActivityStack otherStack = getStackAt(i);
6060 if (otherStack == splitScreenPrimaryStack
6061 || !otherStack.affectedBySplitScreenResize()) {
6062 continue;
6063 }
6064 otherStack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
6065 false /* animate */, false /* showRecents */,
6066 true /* enteringSplitScreenMode */, true /* deferEnsuringVisibility */,
6067 false /* creating */);
6068 }
6069 } finally {
6070 mAtmService.continueWindowLayout();
6071 }
6072 }
6073
6074 /**
6075 * Returns true if the {@param windowingMode} is supported based on other parameters passed in.
6076 * @param windowingMode The windowing mode we are checking support for.
6077 * @param supportsMultiWindow If we should consider support for multi-window mode in general.
6078 * @param supportsSplitScreen If we should consider support for split-screen multi-window.
6079 * @param supportsFreeform If we should consider support for freeform multi-window.
6080 * @param supportsPip If we should consider support for picture-in-picture mutli-window.
6081 * @param activityType The activity type under consideration.
6082 * @return true if the windowing mode is supported.
6083 */
6084 private boolean isWindowingModeSupported(int windowingMode, boolean supportsMultiWindow,
6085 boolean supportsSplitScreen, boolean supportsFreeform, boolean supportsPip,
6086 int activityType) {
6087
6088 if (windowingMode == WINDOWING_MODE_UNDEFINED
6089 || windowingMode == WINDOWING_MODE_FULLSCREEN) {
6090 return true;
6091 }
6092 if (!supportsMultiWindow) {
6093 return false;
6094 }
6095
Wale Ogunwale194435b2019-12-23 12:56:51 -08006096 if (windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
6097 return true;
6098 }
6099
Louis Chang677921f2019-12-06 16:44:24 +08006100 final int displayWindowingMode = getWindowingMode();
6101 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
6102 || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
6103 return supportsSplitScreen
6104 && WindowConfiguration.supportSplitScreenWindowingMode(activityType)
6105 // Freeform windows and split-screen windows don't mix well, so prevent
6106 // split windowing modes on freeform displays.
6107 && displayWindowingMode != WINDOWING_MODE_FREEFORM;
6108 }
6109
6110 if (!supportsFreeform && windowingMode == WINDOWING_MODE_FREEFORM) {
6111 return false;
6112 }
6113
6114 if (!supportsPip && windowingMode == WINDOWING_MODE_PINNED) {
6115 return false;
6116 }
6117 return true;
6118 }
6119
6120 /**
6121 * Resolves the windowing mode that an {@link ActivityRecord} would be in if started on this
6122 * display with the provided parameters.
6123 *
6124 * @param r The ActivityRecord in question.
6125 * @param options Options to start with.
6126 * @param task The task within-which the activity would start.
6127 * @param activityType The type of activity to start.
6128 * @return The resolved (not UNDEFINED) windowing-mode that the activity would be in.
6129 */
6130 int resolveWindowingMode(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
6131 @Nullable Task task, int activityType) {
6132
6133 // First preference if the windowing mode in the activity options if set.
6134 int windowingMode = (options != null)
6135 ? options.getLaunchWindowingMode() : WINDOWING_MODE_UNDEFINED;
6136
6137 // If windowing mode is unset, then next preference is the candidate task, then the
6138 // activity record.
6139 if (windowingMode == WINDOWING_MODE_UNDEFINED) {
6140 if (task != null) {
6141 windowingMode = task.getWindowingMode();
6142 }
6143 if (windowingMode == WINDOWING_MODE_UNDEFINED && r != null) {
6144 windowingMode = r.getWindowingMode();
6145 }
6146 if (windowingMode == WINDOWING_MODE_UNDEFINED) {
6147 // Use the display's windowing mode.
6148 windowingMode = getWindowingMode();
6149 }
6150 }
6151 windowingMode = validateWindowingMode(windowingMode, r, task, activityType);
6152 return windowingMode != WINDOWING_MODE_UNDEFINED
6153 ? windowingMode : WINDOWING_MODE_FULLSCREEN;
6154 }
6155
6156 /**
6157 * Check that the requested windowing-mode is appropriate for the specified task and/or activity
6158 * on this display.
6159 *
6160 * @param windowingMode The windowing-mode to validate.
6161 * @param r The {@link ActivityRecord} to check against.
6162 * @param task The {@link Task} to check against.
6163 * @param activityType An activity type.
6164 * @return The provided windowingMode or the closest valid mode which is appropriate.
6165 */
6166 int validateWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task,
6167 int activityType) {
6168 // Make sure the windowing mode we are trying to use makes sense for what is supported.
6169 boolean supportsMultiWindow = mAtmService.mSupportsMultiWindow;
6170 boolean supportsSplitScreen = mAtmService.mSupportsSplitScreenMultiWindow;
6171 boolean supportsFreeform = mAtmService.mSupportsFreeformWindowManagement;
6172 boolean supportsPip = mAtmService.mSupportsPictureInPicture;
6173 if (supportsMultiWindow) {
6174 if (task != null) {
6175 supportsMultiWindow = task.isResizeable();
6176 supportsSplitScreen = task.supportsSplitScreenWindowingMode();
6177 // TODO: Do we need to check for freeform and Pip support here?
6178 } else if (r != null) {
6179 supportsMultiWindow = r.isResizeable();
6180 supportsSplitScreen = r.supportsSplitScreenWindowingMode();
6181 supportsFreeform = r.supportsFreeform();
6182 supportsPip = r.supportsPictureInPicture();
6183 }
6184 }
6185
Wale Ogunwale734b8962020-01-21 12:17:42 -08006186 final boolean inSplitScreenMode = hasSplitScreenPrimaryTask();
Louis Chang677921f2019-12-06 16:44:24 +08006187 if (!inSplitScreenMode
6188 && windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY) {
6189 // Switch to the display's windowing mode if we are not in split-screen mode and we are
6190 // trying to launch in split-screen secondary.
6191 windowingMode = WINDOWING_MODE_UNDEFINED;
6192 } else if (inSplitScreenMode && (windowingMode == WINDOWING_MODE_FULLSCREEN
6193 || windowingMode == WINDOWING_MODE_UNDEFINED)
6194 && supportsSplitScreen) {
6195 windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
6196 }
6197
6198 if (windowingMode != WINDOWING_MODE_UNDEFINED
6199 && isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen,
6200 supportsFreeform, supportsPip, activityType)) {
6201 return windowingMode;
6202 }
6203 return WINDOWING_MODE_UNDEFINED;
6204 }
6205
6206 boolean isTopStack(ActivityStack stack) {
6207 return stack == getTopStack();
6208 }
6209
6210 boolean isTopNotPinnedStack(ActivityStack stack) {
6211 for (int i = getStackCount() - 1; i >= 0; --i) {
6212 final ActivityStack current = getStackAt(i);
6213 if (!current.inPinnedWindowingMode()) {
6214 return current == stack;
6215 }
6216 }
6217 return false;
6218 }
6219
6220 ActivityRecord topRunningActivity() {
6221 return topRunningActivity(false /* considerKeyguardState */);
6222 }
6223
6224 /**
6225 * Returns the top running activity in the focused stack. In the case the focused stack has no
6226 * such activity, the next focusable stack on this display is returned.
6227 *
6228 * @param considerKeyguardState Indicates whether the locked state should be considered. if
6229 * {@code true} and the keyguard is locked, only activities that
6230 * can be shown on top of the keyguard will be considered.
6231 * @return The top running activity. {@code null} if none is available.
6232 */
6233 ActivityRecord topRunningActivity(boolean considerKeyguardState) {
6234 ActivityRecord topRunning = null;
6235 final ActivityStack focusedStack = getFocusedStack();
6236 if (focusedStack != null) {
6237 topRunning = focusedStack.topRunningActivity();
6238 }
6239
6240 // Look in other focusable stacks.
6241 if (topRunning == null) {
6242 for (int i = getStackCount() - 1; i >= 0; --i) {
6243 final ActivityStack stack = getStackAt(i);
6244 // Only consider focusable stacks other than the current focused one.
Evan Rosky226de132020-01-03 18:00:29 -08006245 if (stack == focusedStack || !stack.isTopActivityFocusable()) {
Louis Chang677921f2019-12-06 16:44:24 +08006246 continue;
6247 }
6248 topRunning = stack.topRunningActivity();
6249 if (topRunning != null) {
6250 break;
6251 }
6252 }
6253 }
6254
6255 // This activity can be considered the top running activity if we are not considering
6256 // the locked state, the keyguard isn't locked, or we can show when locked.
6257 if (topRunning != null && considerKeyguardState
Louis Chang149d5c82019-12-30 09:47:39 +08006258 && mRootWindowContainer.mStackSupervisor.getKeyguardController()
Louis Chang677921f2019-12-06 16:44:24 +08006259 .isKeyguardLocked()
6260 && !topRunning.canShowWhenLocked()) {
6261 return null;
6262 }
6263
6264 return topRunning;
6265 }
6266
6267 boolean updateDisplayOverrideConfigurationLocked() {
6268 Configuration values = new Configuration();
6269 computeScreenConfiguration(values);
6270
6271 mAtmService.mH.sendMessage(PooledLambda.obtainMessage(
6272 ActivityManagerInternal::updateOomLevelsForDisplay, mAtmService.mAmInternal,
6273 mDisplayId));
6274
6275 Settings.System.clearConfiguration(values);
6276 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
6277 false /* deferResume */, mAtmService.mTmpUpdateConfigurationResult);
6278 return mAtmService.mTmpUpdateConfigurationResult.changes != 0;
6279 }
6280
6281 /**
6282 * Updates override configuration specific for the selected display. If no config is provided,
6283 * new one will be computed in WM based on current display info.
6284 */
6285 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
6286 ActivityRecord starting, boolean deferResume,
6287 ActivityTaskManagerService.UpdateConfigurationResult result) {
6288
6289 int changes = 0;
6290 boolean kept = true;
6291
6292 mAtmService.deferWindowLayout();
6293 try {
6294 if (values != null) {
6295 if (mDisplayId == DEFAULT_DISPLAY) {
6296 // Override configuration of the default display duplicates global config, so
6297 // we're calling global config update instead for default display. It will also
6298 // apply the correct override config.
6299 changes = mAtmService.updateGlobalConfigurationLocked(values,
6300 false /* initLocale */, false /* persistent */,
6301 UserHandle.USER_NULL /* userId */, deferResume);
6302 } else {
6303 changes = performDisplayOverrideConfigUpdate(values, deferResume);
6304 }
6305 }
6306
6307 kept = mAtmService.ensureConfigAndVisibilityAfterUpdate(starting, changes);
6308 } finally {
6309 mAtmService.continueWindowLayout();
6310 }
6311
6312 if (result != null) {
6313 result.changes = changes;
6314 result.activityRelaunched = !kept;
6315 }
6316 return kept;
6317 }
6318
6319 int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume) {
6320 mTempConfig.setTo(getRequestedOverrideConfiguration());
6321 final int changes = mTempConfig.updateFrom(values);
6322 if (changes != 0) {
6323 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
6324 + mTempConfig + " for displayId=" + mDisplayId);
6325 onRequestedOverrideConfigurationChanged(mTempConfig);
6326
6327 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
6328 if (isDensityChange && mDisplayId == DEFAULT_DISPLAY) {
6329 mAtmService.mAppWarnings.onDensityChanged();
6330
6331 // Post message to start process to avoid possible deadlock of calling into AMS with
6332 // the ATMS lock held.
6333 final Message msg = PooledLambda.obtainMessage(
6334 ActivityManagerInternal::killAllBackgroundProcessesExcept,
6335 mAtmService.mAmInternal, N,
6336 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
6337 mAtmService.mH.sendMessage(msg);
6338 }
6339 mWmService.mDisplayNotificationController.dispatchDisplayChanged(
6340 this, getConfiguration());
6341 }
6342 return changes;
6343 }
6344
6345 @Override
6346 public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
6347 final int currRotation =
6348 getRequestedOverrideConfiguration().windowConfiguration.getRotation();
6349 if (currRotation != ROTATION_UNDEFINED
6350 && currRotation != overrideConfiguration.windowConfiguration.getRotation()) {
6351 applyRotationLocked(currRotation,
6352 overrideConfiguration.windowConfiguration.getRotation());
6353 }
6354 mCurrentOverrideConfigurationChanges =
6355 getRequestedOverrideConfiguration().diff(overrideConfiguration);
6356 super.onRequestedOverrideConfigurationChanged(overrideConfiguration);
6357 mCurrentOverrideConfigurationChanges = 0;
6358 mWmService.setNewDisplayOverrideConfiguration(overrideConfiguration, this);
6359 mAtmService.addWindowLayoutReasons(
6360 ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED);
6361 }
6362
6363 /** Checks whether the given activity is in size compatibility mode and notifies the change. */
6364 void handleActivitySizeCompatModeIfNeeded(ActivityRecord r) {
6365 if (!r.isState(RESUMED) || r.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
6366 // The callback is only interested in the foreground changes of fullscreen activity.
6367 return;
6368 }
6369 if (!r.inSizeCompatMode()) {
6370 if (mLastCompatModeActivity != null) {
6371 mAtmService.getTaskChangeNotificationController()
6372 .notifySizeCompatModeActivityChanged(mDisplayId, null /* activityToken */);
6373 }
6374 mLastCompatModeActivity = null;
6375 return;
6376 }
6377 if (mLastCompatModeActivity == r) {
6378 return;
6379 }
6380 mLastCompatModeActivity = r;
6381 mAtmService.getTaskChangeNotificationController()
6382 .notifySizeCompatModeActivityChanged(mDisplayId, r.appToken);
6383 }
6384
6385 boolean isUidPresent(int uid) {
6386 final PooledPredicate p = PooledLambda.obtainPredicate(
6387 ActivityRecord::isUid, PooledLambda.__(ActivityRecord.class), uid);
6388 final boolean isUidPresent = mDisplayContent.getActivity(p) != null;
6389 p.recycle();
6390 return isUidPresent;
6391 }
6392
6393 /**
6394 * @see #mRemoved
6395 */
6396 boolean isRemoved() {
6397 return mRemoved;
6398 }
6399
6400 /**
6401 * @see #mRemoving
6402 */
6403 boolean isRemoving() {
6404 return mRemoving;
6405 }
6406
6407 void remove() {
6408 mRemoving = true;
6409 final boolean destroyContentOnRemoval = shouldDestroyContentOnRemove();
6410 ActivityStack lastReparentedStack = null;
6411 mPreferredTopFocusableStack = null;
6412
6413 // Stacks could be reparented from the removed display to other display. While
6414 // reparenting the last stack of the removed display, the remove display is ready to be
6415 // released (no more ActivityStack). But, we cannot release it at that moment or the
6416 // related WindowContainer will also be removed. So, we set display as removed after
6417 // reparenting stack finished.
Louis Chang149d5c82019-12-30 09:47:39 +08006418 final DisplayContent toDisplay = mRootWindowContainer.getDefaultDisplay();
6419 mRootWindowContainer.mStackSupervisor.beginDeferResume();
Louis Chang677921f2019-12-06 16:44:24 +08006420 try {
6421 int numStacks = getStackCount();
6422 // Keep the order from bottom to top.
6423 for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) {
6424 final ActivityStack stack = getStackAt(stackNdx);
6425 // Always finish non-standard type stacks.
6426 if (destroyContentOnRemoval || !stack.isActivityTypeStandardOrUndefined()) {
6427 stack.finishAllActivitiesImmediately();
6428 } else {
6429 // If default display is in split-window mode, set windowing mode of the stack
6430 // to split-screen secondary. Otherwise, set the windowing mode to undefined by
6431 // default to let stack inherited the windowing mode from the new display.
Wale Ogunwale734b8962020-01-21 12:17:42 -08006432 final int windowingMode = toDisplay.hasSplitScreenPrimaryTask()
Louis Chang677921f2019-12-06 16:44:24 +08006433 ? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
6434 : WINDOWING_MODE_UNDEFINED;
6435 stack.reparent(toDisplay, true /* onTop */);
6436 stack.setWindowingMode(windowingMode);
6437 lastReparentedStack = stack;
6438 }
6439 // Stacks may be removed from this display. Ensure each stack will be processed and
6440 // the loop will end.
6441 stackNdx -= numStacks - getStackCount();
6442 numStacks = getStackCount();
6443 }
6444 } finally {
Louis Chang149d5c82019-12-30 09:47:39 +08006445 mRootWindowContainer.mStackSupervisor.endDeferResume();
Louis Chang677921f2019-12-06 16:44:24 +08006446 }
6447 mRemoved = true;
6448
6449 // Only update focus/visibility for the last one because there may be many stacks are
6450 // reparented and the intermediate states are unnecessary.
6451 if (lastReparentedStack != null) {
6452 lastReparentedStack.postReparent();
6453 }
6454 releaseSelfIfNeeded();
6455
6456 if (!mAllSleepTokens.isEmpty()) {
Louis Chang149d5c82019-12-30 09:47:39 +08006457 mRootWindowContainer.mSleepTokens.removeAll(mAllSleepTokens);
Louis Chang677921f2019-12-06 16:44:24 +08006458 mAllSleepTokens.clear();
6459 mAtmService.updateSleepIfNeededLocked();
6460 }
6461 }
6462
6463 private void releaseSelfIfNeeded() {
6464 if (!mRemoved) {
6465 return;
6466 }
6467
6468 final ActivityStack stack = getStackCount() == 1 ? getStackAt(0) : null;
6469 if (stack != null && stack.isActivityTypeHome() && !stack.hasChild()) {
6470 // Release this display if an empty home stack is the only thing left.
6471 // Since it is the last stack, this display will be released along with the stack
6472 // removal.
6473 stack.removeIfPossible();
6474 } else if (getTopStack() == null) {
6475 removeIfPossible();
Louis Chang149d5c82019-12-30 09:47:39 +08006476 mRootWindowContainer.mStackSupervisor
Louis Chang677921f2019-12-06 16:44:24 +08006477 .getKeyguardController().onDisplayRemoved(mDisplayId);
6478 }
6479 }
6480
6481 /** Update and get all UIDs that are present on the display and have access to it. */
6482 IntArray getPresentUIDs() {
6483 mDisplayAccessUIDs.clear();
6484 final PooledConsumer c = PooledLambda.obtainConsumer(DisplayContent::addActivityUid,
6485 PooledLambda.__(ActivityRecord.class), mDisplayAccessUIDs);
6486 mDisplayContent.forAllActivities(c);
6487 c.recycle();
6488 return mDisplayAccessUIDs;
6489 }
6490
6491 private static void addActivityUid(ActivityRecord r, IntArray uids) {
6492 uids.add(r.getUid());
6493 }
6494
6495 @VisibleForTesting
6496 boolean shouldDestroyContentOnRemove() {
6497 return mDisplay.getRemoveMode() == REMOVE_MODE_DESTROY_CONTENT;
6498 }
6499
6500 boolean shouldSleep() {
6501 return (getStackCount() == 0 || !mAllSleepTokens.isEmpty())
6502 && (mAtmService.mRunningVoice == null);
6503 }
6504
6505 void setFocusedApp(ActivityRecord r, boolean moveFocusNow) {
6506 final ActivityRecord newFocus;
6507 final IBinder token = r.appToken;
6508 if (token == null) {
6509 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Clearing focused app, displayId=%d",
6510 mDisplayId);
6511 newFocus = null;
6512 } else {
6513 newFocus = mWmService.mRoot.getActivityRecord(token);
6514 if (newFocus == null) {
6515 Slog.w(TAG_WM, "Attempted to set focus to non-existing app token: " + token
6516 + ", displayId=" + mDisplayId);
6517 }
6518 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
6519 "Set focused app to: %s moveFocusNow=%b displayId=%d", newFocus,
6520 moveFocusNow, mDisplayId);
6521 }
6522
6523 final boolean changed = setFocusedApp(newFocus);
6524 if (moveFocusNow && changed) {
6525 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
6526 true /*updateInputWindows*/);
6527 }
6528 }
6529
6530 /**
6531 * @return the stack currently above the {@param stack}. Can be null if the {@param stack} is
6532 * already top-most.
6533 */
6534 ActivityStack getStackAbove(ActivityStack stack) {
6535 final int stackIndex = getIndexOf(stack) + 1;
6536 return (stackIndex < getStackCount()) ? getStackAt(stackIndex) : null;
6537 }
6538
6539 /**
6540 * Adjusts the {@param stack} behind the last visible stack in the display if necessary.
6541 * Generally used in conjunction with {@link #moveStackBehindStack}.
6542 */
6543 void moveStackBehindBottomMostVisibleStack(ActivityStack stack) {
6544 if (stack.shouldBeVisible(null)) {
6545 // Skip if the stack is already visible
6546 return;
6547 }
6548
6549 // Move the stack to the bottom to not affect the following visibility checks
6550 positionStackAtBottom(stack);
6551
6552 // Find the next position where the stack should be placed
6553 final int numStacks = getStackCount();
6554 for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) {
6555 final ActivityStack s = getStackAt(stackNdx);
6556 if (s == stack) {
6557 continue;
6558 }
6559 final int winMode = s.getWindowingMode();
6560 final boolean isValidWindowingMode = winMode == WINDOWING_MODE_FULLSCREEN
6561 || winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
6562 if (s.shouldBeVisible(null) && isValidWindowingMode) {
6563 // Move the provided stack to behind this stack
6564 positionStackAt(stack, Math.max(0, stackNdx - 1));
6565 break;
6566 }
6567 }
6568 }
6569
6570 /**
6571 * Moves the {@param stack} behind the given {@param behindStack} if possible. If
6572 * {@param behindStack} is not currently in the display, then then the stack is moved to the
6573 * back. Generally used in conjunction with {@link #moveStackBehindBottomMostVisibleStack}.
6574 */
6575 void moveStackBehindStack(ActivityStack stack, ActivityStack behindStack) {
6576 if (behindStack == null || behindStack == stack) {
6577 return;
6578 }
6579
6580 // Note that positionChildAt will first remove the given stack before inserting into the
6581 // list, so we need to adjust the insertion index to account for the removed index
6582 // TODO: Remove this logic when WindowContainer.positionChildAt() is updated to adjust the
6583 // position internally
6584 final int stackIndex = getIndexOf(stack);
6585 final int behindStackIndex = getIndexOf(behindStack);
6586 final int insertIndex = stackIndex <= behindStackIndex
6587 ? behindStackIndex - 1 : behindStackIndex;
6588 positionStackAt(stack, Math.max(0, insertIndex));
6589 }
6590
6591 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
6592 boolean preserveWindows, boolean notifyClients) {
6593 for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
6594 final ActivityStack stack = getStackAt(stackNdx);
6595 stack.ensureActivitiesVisible(starting, configChanges, preserveWindows,
6596 notifyClients);
6597 }
6598 }
6599
6600 void moveHomeStackToFront(String reason) {
Wale Ogunwale734b8962020-01-21 12:17:42 -08006601 final ActivityStack homeStack = getRootHomeTask();
Louis Chang677921f2019-12-06 16:44:24 +08006602 if (homeStack != null) {
6603 homeStack.moveToFront(reason);
6604 }
6605 }
6606
6607 /**
6608 * Moves the focusable home activity to top. If there is no such activity, the home stack will
6609 * still move to top.
6610 */
6611 void moveHomeActivityToTop(String reason) {
6612 final ActivityRecord top = getHomeActivity();
6613 if (top == null) {
6614 moveHomeStackToFront(reason);
6615 return;
6616 }
6617 top.moveFocusableActivityToTop(reason);
6618 }
6619
6620 @Nullable
6621 ActivityRecord getHomeActivity() {
Louis Chang149d5c82019-12-30 09:47:39 +08006622 return getHomeActivityForUser(mRootWindowContainer.mCurrentUser);
Louis Chang677921f2019-12-06 16:44:24 +08006623 }
6624
6625 @Nullable
6626 ActivityRecord getHomeActivityForUser(int userId) {
Wale Ogunwale734b8962020-01-21 12:17:42 -08006627 final ActivityStack homeStack = getRootHomeTask();
Louis Chang677921f2019-12-06 16:44:24 +08006628 if (homeStack == null) {
6629 return null;
6630 }
6631
6632 final PooledPredicate p = PooledLambda.obtainPredicate(
6633 DisplayContent::isHomeActivityForUser, PooledLambda.__(ActivityRecord.class),
6634 userId);
6635 final ActivityRecord r = homeStack.getActivity(p);
6636 p.recycle();
6637 return r;
6638 }
6639
6640 private static boolean isHomeActivityForUser(ActivityRecord r, int userId) {
6641 return r.isActivityTypeHome() && (userId == UserHandle.USER_ALL || r.mUserId == userId);
6642 }
6643
6644 boolean isSleeping() {
6645 return mSleeping;
6646 }
6647
6648 void setIsSleeping(boolean asleep) {
6649 mSleeping = asleep;
6650 }
6651
6652 /**
6653 * Adds a listener to be notified whenever the stack order in the display changes. Currently
6654 * only used by the {@link RecentsAnimation} to determine whether to interrupt and cancel the
6655 * current animation when the system state changes.
6656 */
6657 void registerStackOrderChangedListener(OnStackOrderChangedListener listener) {
6658 if (!mStackOrderChangedCallbacks.contains(listener)) {
6659 mStackOrderChangedCallbacks.add(listener);
6660 }
6661 }
6662
6663 /**
6664 * Removes a previously registered stack order change listener.
6665 */
6666 void unregisterStackOrderChangedListener(OnStackOrderChangedListener listener) {
6667 mStackOrderChangedCallbacks.remove(listener);
6668 }
6669
6670 /**
6671 * Notifies of a stack order change
6672 * @param stack The stack which triggered the order change
6673 */
6674 private void onStackOrderChanged(ActivityStack stack) {
6675 for (int i = mStackOrderChangedCallbacks.size() - 1; i >= 0; i--) {
6676 mStackOrderChangedCallbacks.get(i).onStackOrderChanged(stack);
6677 }
6678 }
6679
6680 void setDisplayToSingleTaskInstance() {
6681 final int childCount = getStackCount();
6682 if (childCount > 1) {
6683 throw new IllegalArgumentException("Display already has multiple stacks. display="
6684 + this);
6685 }
6686 if (childCount > 0) {
6687 final ActivityStack stack = getStackAt(0);
6688 if (stack.getChildCount() > 1) {
6689 throw new IllegalArgumentException("Display stack already has multiple tasks."
6690 + " display=" + this + " stack=" + stack);
6691 }
6692 }
6693
6694 mSingleTaskInstance = true;
6695 }
6696
6697 /** Returns true if the display can only contain one task */
6698 boolean isSingleTaskInstance() {
6699 return mSingleTaskInstance;
6700 }
6701
6702 @VisibleForTesting
6703 void removeAllTasks() {
6704 forAllTasks((t) -> { t.getStack().removeChild(t, "removeAllTasks"); });
6705 }
6706
6707 /**
6708 * Callback for when the order of the stacks in the display changes.
6709 */
6710 interface OnStackOrderChangedListener {
6711 void onStackOrderChanged(ActivityStack stack);
6712 }
6713
6714 public void dumpStacks(PrintWriter pw) {
6715 for (int i = getStackCount() - 1; i >= 0; --i) {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08006716 pw.print(getStackAt(i).getRootTaskId());
Louis Chang677921f2019-12-06 16:44:24 +08006717 if (i > 0) {
6718 pw.print(",");
6719 }
6720 }
6721 }
Charles Chen173ae782019-11-11 20:39:02 +08006722
6723 /**
6724 * Similar to {@link RootWindowContainer#isAnyNonToastWindowVisibleForUid(int)}, but
6725 * used for pid.
6726 */
6727 boolean isAnyNonToastWindowVisibleForPid(int pid) {
6728 final PooledPredicate p = PooledLambda.obtainPredicate(
6729 WindowState::isNonToastWindowVisibleForPid,
6730 PooledLambda.__(WindowState.class), pid);
6731
6732 final WindowState w = getWindow(p);
6733 p.recycle();
6734 return w != null;
6735 }
6736
6737 Context getDisplayUiContext() {
6738 return mDisplayPolicy.getSystemUiContext();
6739 }
Evan Rosky8d782e02019-10-14 15:43:53 -07006740
6741 class RemoteInsetsControlTarget implements InsetsControlTarget {
6742 private final IDisplayWindowInsetsController mRemoteInsetsController;
6743
6744 RemoteInsetsControlTarget(IDisplayWindowInsetsController controller) {
6745 mRemoteInsetsController = controller;
6746 }
6747
6748 void notifyInsetsChanged() {
6749 try {
6750 mRemoteInsetsController.insetsChanged(
6751 getInsetsStateController().getRawInsetsState());
6752 } catch (RemoteException e) {
6753 Slog.w(TAG, "Failed to deliver inset state change", e);
6754 }
6755 }
6756
6757 @Override
6758 public void notifyInsetsControlChanged() {
6759 final InsetsStateController stateController = getInsetsStateController();
6760 try {
6761 mRemoteInsetsController.insetsControlChanged(stateController.getRawInsetsState(),
6762 stateController.getControlsForDispatch(this));
6763 } catch (RemoteException e) {
6764 Slog.w(TAG, "Failed to deliver inset state change", e);
6765 }
6766 }
6767
6768 @Override
6769 public void showInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme) {
6770 try {
6771 mRemoteInsetsController.showInsets(types, fromIme);
6772 } catch (RemoteException e) {
6773 Slog.w(TAG, "Failed to deliver showInsets", e);
6774 }
6775 }
6776
6777 @Override
6778 public void hideInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme) {
6779 try {
6780 mRemoteInsetsController.hideInsets(types, fromIme);
6781 } catch (RemoteException e) {
6782 Slog.w(TAG, "Failed to deliver showInsets", e);
6783 }
6784 }
6785 }
Craig Mautner59c00972012-07-30 12:10:24 -07006786}