blob: 3acb127673e9793fab92145be74f85c61134637b [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
Wale Ogunwalef342f062020-01-27 07:34:13 -080019import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Galia Peycheva70b55712020-03-16 18:31:34 +010020import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
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;
Louis Chang677921f2019-12-06 16:44:24 +080024import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
25import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
Tarandeep Singh215929b2019-01-11 18:24:37 -080026import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale194435b2019-12-23 12:56:51 -080027import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
Evan Rosky688c8382020-04-03 17:27:08 -070028import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Louis Chang677921f2019-12-06 16:44:24 +080029import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
30import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwale51362492016-09-08 17:49:17 -070031import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
Tiger Huang86e6d072019-05-02 20:23:47 +080032import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
Wale Ogunwale687b4272017-07-27 02:56:23 -070033import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
34import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
Louis Chang677921f2019-12-06 16:44:24 +080035import static android.os.Build.VERSION_CODES.N;
Jorim Jaggi4981f152019-03-26 18:58:45 +010036import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
Adrian Roosbf3bc1b2019-06-18 16:13:53 +020037import static android.util.DisplayMetrics.DENSITY_DEFAULT;
Wale Ogunwale19e452e2016-10-12 12:36:29 -070038import static android.view.Display.DEFAULT_DISPLAY;
39import static android.view.Display.FLAG_PRIVATE;
Andrii Kuliandd989612019-02-21 12:13:28 -080040import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
Tiger Huang04dc4cc2019-01-17 18:41:41 +080041import static android.view.Display.INVALID_DISPLAY;
Louis Chang677921f2019-12-06 16:44:24 +080042import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
Tiger Huang332793b2019-10-29 23:21:27 +080043import static android.view.InsetsState.ITYPE_IME;
44import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
45import static android.view.InsetsState.ITYPE_RIGHT_GESTURES;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -070046import static android.view.Surface.ROTATION_0;
47import static android.view.Surface.ROTATION_180;
48import static android.view.Surface.ROTATION_270;
49import static android.view.Surface.ROTATION_90;
Wale Ogunwalef7cab102016-10-25 15:25:14 -070050import static android.view.View.GONE;
Adrian Roosbf3bc1b2019-06-18 16:13:53 +020051import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
52import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
Winson Chungc5fe7ff2019-02-19 14:49:25 -080053import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -080054import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
55import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
56import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070057import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Tiger Huang04dc4cc2019-01-17 18:41:41 +080058import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
Winson Chungc5fe7ff2019-02-19 14:49:25 -080059import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
chaviw8065f442019-11-18 13:20:58 -080060import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -070061import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Riddle Hsub2297ad2019-07-26 23:37:25 -060062import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Wale Ogunwale494009b82016-10-21 09:01:38 -070063import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
Wale Ogunwale3a931692016-11-02 16:49:48 -070064import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
65import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Adrian Roos5f2c9a12019-07-03 18:31:46 +020066import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
wilsonshihe8321942019-10-18 18:39:46 +080067import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
Wale Ogunwalef7cab102016-10-25 15:25:14 -070068import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
69import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
Svetoslav Ganovaa076532016-08-01 19:16:43 -070070import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
Wale Ogunwaleec731152016-09-08 20:18:57 -070071import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Wale Ogunwale3a256e62018-12-06 14:41:18 -080072import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
Wale Ogunwale3a256e62018-12-06 14:41:18 -080073import static android.view.WindowManager.TRANSIT_TASK_OPEN;
74import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
Tiger Huang51c5a1d2018-12-11 20:24:51 +080075
Adrian Roose99bc052017-11-20 17:55:31 +010076import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
77import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
78import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
79import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Louis Chang677921f2019-12-06 16:44:24 +080080import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
Louis Chang677921f2019-12-06 16:44:24 +080081import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
lumark588a3e82018-07-20 18:53:54 +080082import static com.android.server.wm.DisplayContentProto.APP_TRANSITION;
Louis Changa9350fe2019-04-25 17:14:20 +080083import static com.android.server.wm.DisplayContentProto.CLOSING_APPS;
Riddle Hsua4d6fa22018-08-11 00:50:39 +080084import static com.android.server.wm.DisplayContentProto.DISPLAY_FRAMES;
85import static com.android.server.wm.DisplayContentProto.DISPLAY_INFO;
Vishnu Nairdddc9f52020-03-09 09:37:27 -070086import static com.android.server.wm.DisplayContentProto.DISPLAY_READY;
Riddle Hsua4d6fa22018-08-11 00:50:39 +080087import static com.android.server.wm.DisplayContentProto.DPI;
Tiger Huang1e5b10a2018-07-30 20:19:51 +080088import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
Vadim Caena0fa9662020-01-27 15:00:01 +010089import static com.android.server.wm.DisplayContentProto.FOCUSED_ROOT_TASK_ID;
Riddle Hsua4d6fa22018-08-11 00:50:39 +080090import static com.android.server.wm.DisplayContentProto.ID;
Louis Changa9350fe2019-04-25 17:14:20 +080091import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
chaviw8065f442019-11-18 13:20:58 -080092import static com.android.server.wm.DisplayContentProto.OVERLAY_WINDOWS;
Vadim Caena0fa9662020-01-27 15:00:01 +010093import static com.android.server.wm.DisplayContentProto.RESUMED_ACTIVITY;
Adrian Roos22a20a82019-10-23 19:05:33 +020094import static com.android.server.wm.DisplayContentProto.ROOT_DISPLAY_AREA;
Riddle Hsua4d6fa22018-08-11 00:50:39 +080095import static com.android.server.wm.DisplayContentProto.ROTATION;
96import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
Vadim Caena0fa9662020-01-27 15:00:01 +010097import static com.android.server.wm.DisplayContentProto.SINGLE_TASK_INSTANCE;
Riddle Hsua4d6fa22018-08-11 00:50:39 +080098import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER;
Adrian Roosb125e0b2019-10-02 14:55:14 +020099import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
100import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS;
101import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
102import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
103import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
104import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
lumark9bca6b42019-10-17 18:35:22 +0800105import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
106import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
Vishnu Nairdddc9f52020-03-09 09:37:27 -0700107import static com.android.server.wm.WindowContainerChildProto.DISPLAY_CONTENT;
Wale Ogunwale10124582016-09-15 20:25:50 -0700108import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700109import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700110import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700111import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700112import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700113import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700114import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700115import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800116import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800117import static com.android.server.wm.WindowManagerService.H.REPORT_FOCUS_CHANGE;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800118import static com.android.server.wm.WindowManagerService.H.REPORT_HARD_KEYBOARD_STATUS_CHANGE;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800119import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
Evan Rosky73a7fe92019-11-18 18:28:01 -0800120import static com.android.server.wm.WindowManagerService.H.UPDATE_MULTI_WINDOW_STACKS;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700121import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700122import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
Andrii Kulian06d07d62017-03-14 11:11:47 -0700123import static com.android.server.wm.WindowManagerService.SEAMLESS_ROTATION_TIMEOUT_DURATION;
Louis Chang677921f2019-12-06 16:44:24 +0800124import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800125import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
126import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_REMOVING_FOCUS;
127import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_ASSIGN_LAYERS;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700128import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
Wale Ogunwale494009b82016-10-21 09:01:38 -0700129import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700130import static com.android.server.wm.WindowManagerService.dipToPixel;
Adrian Roos5f2c9a12019-07-03 18:31:46 +0200131import static com.android.server.wm.WindowState.EXCLUSION_LEFT;
132import static com.android.server.wm.WindowState.EXCLUSION_RIGHT;
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700133import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700134import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
Adrian Roos2351d5f2019-07-03 15:35:07 +0200135import static com.android.server.wm.utils.RegionUtils.forEachRectReverse;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100136import static com.android.server.wm.utils.RegionUtils.rectListToRegion;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700137
Riddle Hsuf53da812018-08-15 22:00:27 +0800138import android.annotation.IntDef;
Andrii Kulian3a507b52016-09-19 18:14:12 -0700139import android.annotation.NonNull;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200140import android.annotation.Nullable;
Louis Chang677921f2019-12-06 16:44:24 +0800141import android.app.ActivityManager;
142import android.app.ActivityManagerInternal;
Jorim Jaggicc57cb72020-04-09 14:54:13 +0200143import android.app.WindowConfiguration;
Charles Chen173ae782019-11-11 20:39:02 +0800144import android.content.Context;
Louis Chang677921f2019-12-06 16:44:24 +0800145import android.content.pm.ActivityInfo;
Riddle Hsuccf09402019-08-13 00:33:06 +0800146import android.content.pm.ActivityInfo.ScreenOrientation;
Andrii Kulian06d07d62017-03-14 11:11:47 -0700147import android.content.res.CompatibilityInfo;
Andrii Kulian441e4492016-09-29 15:25:00 -0700148import android.content.res.Configuration;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700149import android.graphics.Bitmap;
Issei Suzukia5dbf522019-02-01 17:58:15 +0100150import android.graphics.Insets;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700151import android.graphics.Matrix;
Tiger Huangd8ec9382019-04-18 14:35:09 -0700152import android.graphics.Point;
Craig Mautnerc00204b2013-03-05 15:02:14 -0800153import android.graphics.Rect;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700154import android.graphics.RectF;
Craig Mautner6601b7b2013-04-29 10:29:11 -0700155import android.graphics.Region;
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100156import android.graphics.Region.Op;
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700157import android.hardware.display.DisplayManagerInternal;
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500158import android.metrics.LogMaker;
Tiger Huang04dc4cc2019-01-17 18:41:41 +0800159import android.os.Binder;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700160import android.os.Debug;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700161import android.os.Handler;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700162import android.os.IBinder;
Louis Chang677921f2019-12-06 16:44:24 +0800163import android.os.Message;
Tiger Huang04dc4cc2019-01-17 18:41:41 +0800164import android.os.Process;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100165import android.os.RemoteCallbackList;
Wale Ogunwale494009b82016-10-21 09:01:38 -0700166import android.os.RemoteException;
167import android.os.SystemClock;
Jorim Jaggiffe128d2017-11-30 13:54:36 +0100168import android.os.Trace;
Riddle Hsuf53da812018-08-15 22:00:27 +0800169import android.os.UserHandle;
Louis Chang677921f2019-12-06 16:44:24 +0800170import android.provider.Settings;
Andrii Kulian4b6599e2018-01-15 17:24:08 -0800171import android.util.ArraySet;
Chong Zhang8e89b312015-09-09 15:09:30 -0700172import android.util.DisplayMetrics;
Louis Chang677921f2019-12-06 16:44:24 +0800173import android.util.IntArray;
shawnlin21e3f022020-01-21 16:36:13 +0800174import android.util.RotationUtils;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700175import android.util.Slog;
Evan Rosky22b6bbd2019-09-26 14:29:57 -0700176import android.util.SparseArray;
Riddle Hsub2297ad2019-07-26 23:37:25 -0600177import android.util.SparseBooleanArray;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700178import android.util.proto.ProtoOutputStream;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700179import android.view.Display;
Adrian Roos1cf585052018-01-03 18:43:27 +0100180import android.view.DisplayCutout;
Craig Mautner59c00972012-07-30 12:10:24 -0700181import android.view.DisplayInfo;
Riddle Hsua4d6fa22018-08-11 00:50:39 +0800182import android.view.Gravity;
Evan Rosky8d782e02019-10-14 15:43:53 -0700183import android.view.IDisplayWindowInsetsController;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100184import android.view.ISystemGestureExclusionListener;
Evan Rosky22b6bbd2019-09-26 14:29:57 -0700185import android.view.IWindow;
Arthur Hungbe5ce212018-09-13 18:41:56 +0800186import android.view.InputChannel;
Andrii Kulian06d07d62017-03-14 11:11:47 -0700187import android.view.InputDevice;
Tiger Huang04dc4cc2019-01-17 18:41:41 +0800188import android.view.InputWindowHandle;
Tiger Huang332793b2019-10-29 23:21:27 +0800189import android.view.InsetsState.InternalInsetsType;
Robert Carrb1579c82017-09-05 14:54:47 -0700190import android.view.MagnificationSpec;
Evan Rosky966759f2019-01-15 10:33:58 -0800191import android.view.RemoteAnimationDefinition;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700192import android.view.Surface;
193import android.view.SurfaceControl;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100194import android.view.SurfaceControl.Transaction;
Robert Carrb1579c82017-09-05 14:54:47 -0700195import android.view.SurfaceSession;
Tiger Huang7c610aa2018-10-27 00:01:01 +0800196import android.view.View;
Tiger Huang41ae5e82020-01-17 18:17:20 +0800197import android.view.ViewRootImpl;
Evan Rosky8d782e02019-10-14 15:43:53 -0700198import android.view.WindowInsets;
lumark588a3e82018-07-20 18:53:54 +0800199import android.view.WindowManager;
Evan Rosky39b6f232018-10-30 18:35:41 -0700200import android.view.WindowManagerPolicyConstants.PointerEventListener;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700201
Bryce Lee48f4b572017-04-10 10:54:15 -0700202import com.android.internal.annotations.VisibleForTesting;
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500203import com.android.internal.logging.MetricsLogger;
204import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800205import com.android.internal.util.ToBooleanFunction;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200206import com.android.internal.util.function.TriConsumer;
Winson Chungc5fe7ff2019-02-19 14:49:25 -0800207import com.android.internal.util.function.pooled.PooledConsumer;
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900208import com.android.internal.util.function.pooled.PooledFunction;
Winson Chungc5fe7ff2019-02-19 14:49:25 -0800209import com.android.internal.util.function.pooled.PooledLambda;
Louis Chang677921f2019-12-06 16:44:24 +0800210import com.android.internal.util.function.pooled.PooledPredicate;
Adrian Roose99bc052017-11-20 17:55:31 +0100211import com.android.server.policy.WindowManagerPolicy;
Adrian Roosb125e0b2019-10-02 14:55:14 +0200212import com.android.server.protolog.common.ProtoLog;
Issei Suzuki43190bd2018-08-20 17:28:41 +0200213import com.android.server.wm.utils.DisplayRotationUtil;
Adrian Roos2aa0fcd2018-02-19 18:07:49 +0100214import com.android.server.wm.utils.RotationCache;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100215import com.android.server.wm.utils.WmDisplayCutout;
Craig Mautner59c00972012-07-30 12:10:24 -0700216
217import java.io.PrintWriter;
Riddle Hsuf53da812018-08-15 22:00:27 +0800218import java.lang.annotation.Retention;
219import java.lang.annotation.RetentionPolicy;
Craig Mautner59c00972012-07-30 12:10:24 -0700220import java.util.ArrayList;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700221import java.util.Comparator;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700222import java.util.HashMap;
223import java.util.Iterator;
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700224import java.util.LinkedList;
Andrii Kulian3a507b52016-09-19 18:14:12 -0700225import java.util.List;
Adrian Roos1cf585052018-01-03 18:43:27 +0100226import java.util.Objects;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800227import java.util.function.Consumer;
228import java.util.function.Predicate;
Craig Mautner59c00972012-07-30 12:10:24 -0700229
Craig Mautner59c00972012-07-30 12:10:24 -0700230/**
231 * Utility class for keeping track of the WindowStates and other pertinent contents of a
232 * particular Display.
Craig Mautner59c00972012-07-30 12:10:24 -0700233 */
Riddle Hsuad256a12018-07-18 16:11:30 +0800234class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer>
Louis Chang2453d062019-11-19 22:30:48 +0800235 implements WindowManagerPolicy.DisplayContentInfo {
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700236 private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
Louis Chang677921f2019-12-06 16:44:24 +0800237 private static final String TAG_STACK = TAG + POSTFIX_STACK;
Craig Mautner59c00972012-07-30 12:10:24 -0700238
Riddle Hsuf53da812018-08-15 22:00:27 +0800239 /** The default scaling mode that scales content automatically. */
240 static final int FORCE_SCALING_MODE_AUTO = 0;
241 /** For {@link #setForcedScalingMode} to apply flag {@link Display#FLAG_SCALING_DISABLED}. */
242 static final int FORCE_SCALING_MODE_DISABLED = 1;
243
244 @IntDef(prefix = { "FORCE_SCALING_MODE_" }, value = {
245 FORCE_SCALING_MODE_AUTO,
246 FORCE_SCALING_MODE_DISABLED
247 })
248 @Retention(RetentionPolicy.SOURCE)
249 @interface ForceScalingMode {}
250
Louis Chang2453d062019-11-19 22:30:48 +0800251 ActivityTaskManagerService mAtmService;
Craig Mautner59c00972012-07-30 12:10:24 -0700252
Louis Chang2453d062019-11-19 22:30:48 +0800253 /** Unique identifier of this display. */
Louis Chang677921f2019-12-06 16:44:24 +0800254 final int mDisplayId;
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800255
chaviw8065f442019-11-18 13:20:58 -0800256 /**
257 * Most surfaces will be a child of this window. There are some special layers and windows
258 * which are always on top of others and omitted from Screen-Magnification, for example the
259 * strict mode flash or the magnification overlay itself. Those layers will be children of
260 * {@link #mOverlayContainers} where mWindowContainers contains everything else.
261 */
262 private final WindowContainers mWindowContainers =
263 new WindowContainers("mWindowContainers", mWmService);
264
265 // Contains some special windows which are always on top of others and omitted from
266 // Screen-Magnification, for example the WindowMagnification windows.
267 private final NonAppWindowContainers mOverlayContainers =
268 new NonAppWindowContainers("mOverlayContainers", mWmService);
269
270 /** The containers below are the only child containers {@link #mWindowContainers} can have. */
Adrian Roos22a20a82019-10-23 19:05:33 +0200271
Wale Ogunwale3a931692016-11-02 16:49:48 -0700272 // Contains all IME window containers. Note that the z-ordering of the IME windows will depend
273 // 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 -0800274 // window containers together and move them in-sync if/when needed. We use a subclass of
275 // WindowContainer which is omitted from screen magnification, as the IME is never magnified.
Adrian Roosefa40702020-01-08 17:58:45 +0100276 // TODO(display-area): is "no magnification" in the comment still true?
277 private final ImeContainer mImeWindowsContainers = new ImeContainer(mWmService);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700278
Adrian Roos22a20a82019-10-23 19:05:33 +0200279 private final DisplayArea.Root mRootDisplayArea = new DisplayArea.Root(mWmService);
280
Chris Lic5a937ce2020-04-29 23:43:52 -0700281 @VisibleForTesting
282 final DisplayAreaPolicy mDisplayAreaPolicy;
Adrian Roos22a20a82019-10-23 19:05:33 +0200283
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000284 private WindowState mTmpWindow;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800285 private WindowState mTmpWindow2;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800286 private boolean mUpdateImeTarget;
287 private boolean mTmpInitial;
Bryce Lee27cec322017-03-21 09:41:37 -0700288 private int mMaxUiWidth;
Craig Mautner59c00972012-07-30 12:10:24 -0700289
lumark588a3e82018-07-20 18:53:54 +0800290 final AppTransition mAppTransition;
291 final AppTransitionController mAppTransitionController;
292 boolean mSkipAppTransitionAnimation = false;
293
Garfield Tane8d84ab2019-10-11 09:49:40 -0700294 final ArraySet<ActivityRecord> mOpeningApps = new ArraySet<>();
295 final ArraySet<ActivityRecord> mClosingApps = new ArraySet<>();
Evan Rosky55bddd82020-01-29 13:07:18 -0800296 final ArraySet<WindowContainer> mChangingContainers = new ArraySet<>();
lumark588a3e82018-07-20 18:53:54 +0800297 final UnknownAppVisibilityController mUnknownAppVisibilityController;
lumark588a3e82018-07-20 18:53:54 +0800298
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -0500299 private MetricsLogger mMetricsLogger;
300
lumark588a3e82018-07-20 18:53:54 +0800301 /**
302 * List of clients without a transtiton animation that we notify once we are done
303 * transitioning since they won't be notified through the app window animator.
304 */
305 final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
306
Wale Ogunwale02319a62016-09-26 15:21:22 -0700307 // Mapping from a token IBinder to a WindowToken object on this display.
308 private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap();
309
Andrii Kuliancd097992017-03-23 18:31:59 -0700310 // Initial display metrics.
Craig Mautner59c00972012-07-30 12:10:24 -0700311 int mInitialDisplayWidth = 0;
312 int mInitialDisplayHeight = 0;
Dianne Hackborndde331c2012-08-03 14:01:57 -0700313 int mInitialDisplayDensity = 0;
Andrii Kuliancd097992017-03-23 18:31:59 -0700314
Adrian Roos1cf585052018-01-03 18:43:27 +0100315 DisplayCutout mInitialDisplayCutout;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100316 private final RotationCache<DisplayCutout, WmDisplayCutout> mDisplayCutoutCache
Adrian Roos2aa0fcd2018-02-19 18:07:49 +0100317 = new RotationCache<>(this::calculateDisplayCutoutForRotationUncached);
Adrian Roos1cf585052018-01-03 18:43:27 +0100318
Andrii Kuliancd097992017-03-23 18:31:59 -0700319 /**
320 * Overridden display size. Initialized with {@link #mInitialDisplayWidth}
321 * and {@link #mInitialDisplayHeight}, but can be set via shell command "adb shell wm size".
322 * @see WindowManagerService#setForcedDisplaySize(int, int, int)
323 */
Craig Mautner59c00972012-07-30 12:10:24 -0700324 int mBaseDisplayWidth = 0;
325 int mBaseDisplayHeight = 0;
Andrii Kuliancd097992017-03-23 18:31:59 -0700326 /**
327 * Overridden display density for current user. Initialized with {@link #mInitialDisplayDensity}
328 * but can be set from Settings or via shell command "adb shell wm density".
329 * @see WindowManagerService#setForcedDisplayDensityForUser(int, int, int)
330 */
Dianne Hackborndde331c2012-08-03 14:01:57 -0700331 int mBaseDisplayDensity = 0;
Riddle Hsuf53da812018-08-15 22:00:27 +0800332
333 /**
334 * Whether to disable display scaling. This can be set via shell command "adb shell wm scaling".
335 * @see WindowManagerService#setForcedDisplayScalingMode(int, int)
336 */
Jeff Brownd46747a2015-04-15 19:02:36 -0700337 boolean mDisplayScalingDisabled;
Louis Chang677921f2019-12-06 16:44:24 +0800338 final Display mDisplay;
Craig Mautner2d5618c2012-10-18 13:55:47 -0700339 private final DisplayInfo mDisplayInfo = new DisplayInfo();
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700340 private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800341 private final DisplayPolicy mDisplayPolicy;
Riddle Hsuccf09402019-08-13 00:33:06 +0800342 private final DisplayRotation mDisplayRotation;
Wale Ogunwale828ff7e2017-11-14 01:01:29 +0000343 DisplayFrames mDisplayFrames;
344
Adrian Roos4ffc8972019-02-07 20:45:11 +0100345 private final RemoteCallbackList<ISystemGestureExclusionListener>
346 mSystemGestureExclusionListeners = new RemoteCallbackList<>();
347 private final Region mSystemGestureExclusion = new Region();
Adrian Roos5f2c9a12019-07-03 18:31:46 +0200348 private boolean mSystemGestureExclusionWasRestricted = false;
349 private final Region mSystemGestureExclusionUnrestricted = new Region();
Adrian Roosbf3bc1b2019-06-18 16:13:53 +0200350 private int mSystemGestureExclusionLimit;
Adrian Roos4ffc8972019-02-07 20:45:11 +0100351
Andrii Kulian06d07d62017-03-14 11:11:47 -0700352 /**
353 * For default display it contains real metrics, empty for others.
chaviw619da692019-06-10 15:39:40 -0700354 * @see WindowManagerService#createWatermark()
Andrii Kulian06d07d62017-03-14 11:11:47 -0700355 */
356 final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
Tiger Huang7c610aa2018-10-27 00:01:01 +0800357
Mark Hong0db34112020-01-10 10:20:45 -0800358 /** @see #computeCompatSmallestWidth(boolean, int, int, int) */
Andrii Kulian06d07d62017-03-14 11:11:47 -0700359 private final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
Lucas Dupin1ead7fc2017-05-24 14:14:44 -0700360
Andrii Kulian06d07d62017-03-14 11:11:47 -0700361 /**
362 * Compat metrics computed based on {@link #mDisplayMetrics}.
363 * @see #updateDisplayAndOrientation(int)
364 */
365 private final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
366
367 /** The desired scaling factor for compatible apps. */
368 float mCompatibleScreenScale;
Craig Mautner59c00972012-07-30 12:10:24 -0700369
Riddle Hsu7f704b52019-12-10 23:10:45 +0800370 /** @see #getCurrentOverrideConfigurationChanges */
371 private int mCurrentOverrideConfigurationChanges;
372
Andrii Kulian8ee72852017-03-10 10:36:45 -0800373 /**
Tiger Huang86e6d072019-05-02 20:23:47 +0800374 * The maximum aspect ratio (longerSide/shorterSide) that is treated as close-to-square. The
375 * orientation requests from apps would be ignored if the display is close-to-square.
376 */
377 @VisibleForTesting
378 final float mCloseToSquareMaxAspectRatio;
379
380 /**
381 * If this is true, we would not rotate the display for apps. The rotation would be either the
382 * sensor rotation or the user rotation, controlled by
383 * {@link WindowManagerPolicy.UserRotationMode}.
384 */
385 private boolean mIgnoreRotationForApps;
386
387 /**
Lucas Dupin1ead7fc2017-05-24 14:14:44 -0700388 * Keep track of wallpaper visibility to notify changes.
389 */
390 private boolean mLastWallpaperVisible = false;
391
Andrii Kulian06d07d62017-03-14 11:11:47 -0700392 private Rect mBaseDisplayRect = new Rect();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700393
Craig Mautner39834192012-09-02 07:47:24 -0700394 // Accessed directly by all users.
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700395 private boolean mLayoutNeeded;
Craig Mautner76a71652012-09-03 23:23:58 -0700396 int pendingLayoutChanges;
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800397
Vishnu Nairba183352018-11-21 11:16:49 -0800398 /**
399 * Used to gate application window layout until we have sent the complete configuration.
400 * TODO: There are still scenarios where we may be out of sync with the client. Ideally
401 * we want to replace this flag with a mechanism that will confirm the configuration
402 * applied by the client is the one expected by the system server.
403 */
404 boolean mWaitingForConfig;
405
Andrii Kulian839def92016-11-02 10:58:58 -0700406 // TODO(multi-display): remove some of the usages.
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800407 @VisibleForTesting
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800408 boolean isDefaultDisplay;
Riddle Hsu5ce4bb32018-07-18 16:11:30 +0800409
Andrii Kulianf0379de2018-03-14 16:24:07 -0700410 /**
411 * Flag indicating whether WindowManager should override info for this display in
412 * DisplayManager.
413 */
414 boolean mShouldOverrideDisplayConfiguration = true;
Craig Mautner39834192012-09-02 07:47:24 -0700415
Craig Mautnerdc548482014-02-05 13:35:24 -0800416 /** Window tokens that are in the process of exiting, but still on screen for animations. */
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700417 final ArrayList<WindowToken> mExitingTokens = new ArrayList<>();
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800418
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700419 /** Detect user tapping outside of current focused task bounds .*/
Riddle Hsu2588ab02019-02-25 14:23:56 +0800420 @VisibleForTesting
421 final TaskTapPointerEventListener mTapDetector;
Craig Mautnercf910b02013-04-23 11:23:27 -0700422
Craig Mautner6601b7b2013-04-29 10:29:11 -0700423 /** Detect user tapping outside of current focused stack bounds .*/
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700424 private Region mTouchExcludeRegion = new Region();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700425
Craig Mautner6601b7b2013-04-29 10:29:11 -0700426 /** Save allocating when calculating rects */
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800427 private final Rect mTmpRect = new Rect();
428 private final Rect mTmpRect2 = new Rect();
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700429 private final RectF mTmpRectF = new RectF();
430 private final Matrix mTmpMatrix = new Matrix();
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800431 private final Region mTmpRegion = new Region();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700432
Bryce Leef3c6a472017-11-14 14:53:06 -0800433 /** Used for handing back size of display */
434 private final Rect mTmpBounds = new Rect();
435
Garfield Tan90b04282018-12-11 14:04:42 -0800436 private final Configuration mTmpConfiguration = new Configuration();
437
Craig Mautner95da1082014-02-24 17:54:35 -0800438 /** Remove this display when animation on it has completed. */
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700439 private boolean mDeferredRemoval;
Craig Mautner1bf2b872014-02-05 15:37:40 -0800440
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700441 final DockedStackDividerController mDividerControllerLocked;
Winson Chung655332c2016-10-31 13:14:28 -0700442 final PinnedStackController mPinnedStackControllerLocked;
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700443
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800444 final ArrayList<WindowState> mTapExcludedWindows = new ArrayList<>();
Andrii Kulian4b6599e2018-01-15 17:24:08 -0800445 /** A collection of windows that provide tap exclude regions inside of them. */
446 final ArraySet<WindowState> mTapExcludeProvidingWindows = new ArraySet<>();
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800447
Garfield Tane8d84ab2019-10-11 09:49:40 -0700448 private final LinkedList<ActivityRecord> mTmpUpdateAllDrawn = new LinkedList();
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700449
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700450 private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult =
451 new TaskForResizePointSearchResult();
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000452 private final ApplySurfaceChangesTransactionState mTmpApplySurfaceChangesTransactionState =
453 new ApplySurfaceChangesTransactionState();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700454
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700455 // True if this display is in the process of being removed. Used to determine if the removal of
456 // the display's direct children should be allowed.
457 private boolean mRemovingDisplay = false;
458
Bryce Leed1871262017-06-12 14:12:29 -0700459 // {@code false} if this display is in the processing of being created.
460 private boolean mDisplayReady = false;
461
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800462 WallpaperController mWallpaperController;
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700463
wilsonshihc32538e2018-11-07 17:27:34 +0800464 boolean mWallpaperMayChange = false;
465
Robert Carrb1579c82017-09-05 14:54:47 -0700466 private final SurfaceSession mSession = new SurfaceSession();
467
468 /**
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800469 * Window that is currently interacting with the user. This window is responsible for receiving
470 * key events and pointer events from the user.
471 */
472 WindowState mCurrentFocus = null;
473
474 /**
475 * The last focused window that we've notified the client that the focus is changed.
476 */
477 WindowState mLastFocus = null;
478
479 /**
480 * Windows that have lost input focus and are waiting for the new focus window to be displayed
481 * before they are told about this.
482 */
483 ArrayList<WindowState> mLosingFocus = new ArrayList<>();
484
485 /**
486 * The foreground app of this display. Windows below this app cannot be the focused window. If
487 * the user taps on the area outside of the task of the focused app, we will notify AM about the
488 * new task the user wants to interact with.
489 */
Garfield Tane8d84ab2019-10-11 09:49:40 -0700490 ActivityRecord mFocusedApp = null;
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800491
Riddle Hsu6f548e92020-01-13 13:34:09 +0800492 /**
493 * The launching activity which is using fixed rotation transformation.
494 *
495 * @see #handleTopActivityLaunchingInDifferentOrientation
Riddle Hsucbc5d272020-04-24 23:26:46 +0800496 * @see #setFixedRotationLaunchingApp
Riddle Hsud16620e2020-04-06 20:48:06 +0800497 * @see DisplayRotation#shouldRotateSeamlessly
Riddle Hsu6f548e92020-01-13 13:34:09 +0800498 */
499 ActivityRecord mFixedRotationLaunchingApp;
500
Vadim Caendca5b932020-04-23 18:26:50 +0200501 FixedRotationAnimationController mFixedRotationAnimationController;
502
Riddle Hsud4957432020-04-24 22:06:29 +0800503 final FixedRotationTransitionListener mFixedRotationTransitionListener =
504 new FixedRotationTransitionListener();
505
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800506 /** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
507 final ArrayList<WindowState> mWinAddedSinceNullFocus = new ArrayList<>();
508
509 /** Windows removed since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
510 final ArrayList<WindowState> mWinRemovedSinceNullFocus = new ArrayList<>();
511
Tiger Huang53c8eb82020-03-31 18:22:05 +0800512 /** Windows whose client's insets states are not up-to-date. */
513 final ArrayList<WindowState> mWinInsetsChanged = new ArrayList<>();
514
Vadim Caenb3715832019-08-13 17:06:38 +0200515 private ScreenRotationAnimation mScreenRotationAnimation;
516
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800517 /**
Adrian Roos5251b1d2018-03-23 18:57:43 +0100518 * Sequence number for the current layout pass.
519 */
520 int mLayoutSeq = 0;
521
Chavi Weingarten3a748552018-05-14 17:32:42 +0000522 /**
523 * Specifies the count to determine whether to defer updating the IME target until ready.
524 */
525 private int mDeferUpdateImeTargetCount;
526
Robert Carr24be9ab2018-04-30 17:54:53 -0700527 private MagnificationSpec mMagnificationSpec;
528
Arthur Hung95b38a92018-07-20 18:56:12 +0800529 private InputMonitor mInputMonitor;
530
Jorim Jaggif1292892018-09-10 11:58:13 +0200531 /** Caches the value whether told display manager that we have content. */
532 private boolean mLastHasContent;
533
Issei Suzuki43190bd2018-08-20 17:28:41 +0200534 private DisplayRotationUtil mRotationUtil = new DisplayRotationUtil();
535
lumark90120a82018-08-15 00:33:03 +0800536 /**
537 * The input method window for this display.
538 */
539 WindowState mInputMethodWindow;
540
lumarkff0ab692018-11-05 20:32:30 +0800541 /**
542 * This just indicates the window the input method is on top of, not
543 * necessarily the window its input is going to.
544 */
545 WindowState mInputMethodTarget;
546
Tiger Huangfdec32c2020-04-10 02:07:30 +0800547 /**
548 * The window which receives input from the input method. This is also a candidate of the
549 * input method control target.
550 */
551 WindowState mInputMethodInputTarget;
552
553 /**
554 * This controls the visibility and animation of the input method window.
555 */
Evan Rosky8d782e02019-10-14 15:43:53 -0700556 InsetsControlTarget mInputMethodControlTarget;
557
lumarkff0ab692018-11-05 20:32:30 +0800558 /** If true hold off on modifying the animation layer of mInputMethodTarget */
559 boolean mInputMethodTargetWaitingAnim;
560
Arthur Hungbe5ce212018-09-13 18:41:56 +0800561 private final PointerEventDispatcher mPointerEventDispatcher;
562
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200563 private final InsetsStateController mInsetsStateController;
Jorim Jaggi28620472019-01-02 23:21:49 +0100564 private final InsetsPolicy mInsetsPolicy;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200565
Tiger Huangd8ec9382019-04-18 14:35:09 -0700566 /** @see #getParentWindow() */
567 private WindowState mParentWindow;
568
569 private Point mLocationInParentWindow = new Point();
Tiger Huang04dc4cc2019-01-17 18:41:41 +0800570 private SurfaceControl mParentSurfaceControl;
571 private InputWindowHandle mPortalWindowHandle;
572
Tiger Huang7c610aa2018-10-27 00:01:01 +0800573 // Last systemUiVisibility we received from status bar.
574 private int mLastStatusBarVisibility = 0;
575 // Last systemUiVisibility we dispatched to windows.
576 private int mLastDispatchedSystemUiVisibility = 0;
577
Tiger Huang43b8fc22019-04-26 11:49:29 +0800578 /** Corner radius that windows should have in order to match the display. */
579 private final float mWindowCornerRadius;
580
Evan Rosky2ffddde2020-04-16 19:14:56 -0700581 final SparseArray<ShellRoot> mShellRoots = new SparseArray<>();
Evan Rosky8d782e02019-10-14 15:43:53 -0700582 RemoteInsetsControlTarget mRemoteInsetsControlTarget = null;
583 private final IBinder.DeathRecipient mRemoteInsetsDeath =
584 () -> {
585 synchronized (mWmService.mGlobalLock) {
586 mRemoteInsetsControlTarget = null;
587 }
588 };
Evan Rosky22b6bbd2019-09-26 14:29:57 -0700589
Louis Chang149d5c82019-12-30 09:47:39 +0800590 private RootWindowContainer mRootWindowContainer;
Louis Chang677921f2019-12-06 16:44:24 +0800591
Louis Chang677921f2019-12-06 16:44:24 +0800592 /** Array of all UIDs that are present on the display. */
593 private IntArray mDisplayAccessUIDs = new IntArray();
594
595 /** All tokens used to put activities on this stack to sleep (including mOffToken) */
596 final ArrayList<ActivityTaskManagerInternal.SleepToken> mAllSleepTokens = new ArrayList<>();
597 /** The token acquired by ActivityStackSupervisor to put stacks on the display to sleep */
598 ActivityTaskManagerInternal.SleepToken mOffToken;
599
600 private boolean mSleeping;
601
602 /** We started the process of removing the display from the system. */
603 private boolean mRemoving;
604
605 /**
606 * The display is removed from the system and we are just waiting for all activities on it to be
607 * finished before removing this object.
608 */
609 private boolean mRemoved;
610
611 /** The display can only contain one task. */
Andrii Kulian9ea12da2020-03-27 17:16:38 -0700612 boolean mSingleTaskInstance;
Louis Chang677921f2019-12-06 16:44:24 +0800613
614 /**
615 * Non-null if the last size compatibility mode activity is using non-native screen
616 * configuration. The activity is not able to put in multi-window mode, so it exists only one
617 * per display.
618 */
619 private ActivityRecord mLastCompatModeActivity;
620
Louis Chang677921f2019-12-06 16:44:24 +0800621 // Used in updating the display size
622 private Point mTmpDisplaySize = new Point();
623
624 // Used in updating override configurations
625 private final Configuration mTempConfig = new Configuration();
626
Tiger Huang57e2e1c2020-03-13 22:54:36 +0800627 // Used in performing layout
628 private boolean mTmpWindowsBehindIme;
629
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800630 private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
631 WindowStateAnimator winAnimator = w.mWinAnimator;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700632 final ActivityRecord activity = w.mActivityRecord;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800633 if (winAnimator.mDrawState == READY_TO_SHOW) {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700634 if (activity == null || activity.canShowWindows()) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800635 if (w.performShowLocked()) {
636 pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
637 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800638 mWmService.mWindowPlacerLocked.debugLayoutRepeats(
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800639 "updateWindowsAndWallpaperLocked 5", pendingLayoutChanges);
640 }
641 }
642 }
643 }
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800644 };
645
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800646 private final Consumer<WindowState> mScheduleToastTimeout = w -> {
647 final int lostFocusUid = mTmpWindow.mOwnerUid;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800648 final Handler handler = mWmService.mH;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800649 if (w.mAttrs.type == TYPE_TOAST && w.mOwnerUid == lostFocusUid) {
650 if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, w)) {
651 handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, w),
652 w.mAttrs.hideTimeoutMilliseconds);
653 }
654 }
655 };
656
657 private final ToBooleanFunction<WindowState> mFindFocusedWindow = w -> {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700658 final ActivityRecord focusedApp = mFocusedApp;
Adrian Roosb125e0b2019-10-02 14:55:14 +0200659 ProtoLog.v(WM_DEBUG_FOCUS, "Looking for focus: %s, flags=%d, canReceive=%b",
660 w, w.mAttrs.flags, w.canReceiveKeys());
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800661
662 if (!w.canReceiveKeys()) {
663 return false;
664 }
665
Garfield Tane8d84ab2019-10-11 09:49:40 -0700666 final ActivityRecord activity = w.mActivityRecord;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800667
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800668 if (focusedApp == null) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200669 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
670 "findFocusedWindow: focusedApp=null using new focus @ %s", w);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800671 mTmpWindow = w;
672 return true;
673 }
674
675 if (!focusedApp.windowsAreFocusable()) {
676 // Current focused app windows aren't focusable...
Adrian Roosb125e0b2019-10-02 14:55:14 +0200677 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: focusedApp windows not"
678 + " focusable using new focus @ %s", w);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800679 mTmpWindow = w;
680 return true;
681 }
682
683 // Descend through all of the app tokens and find the first that either matches
Garfield Tane8d84ab2019-10-11 09:49:40 -0700684 // win.mActivityRecord (return win) or mFocusedApp (return null).
685 if (activity != null && w.mAttrs.type != TYPE_APPLICATION_STARTING) {
686 if (focusedApp.compareTo(activity) > 0) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800687 // App stack below focused app stack. No focus for you!!!
Adrian Roosb125e0b2019-10-02 14:55:14 +0200688 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
689 "findFocusedWindow: Reached focused app=%s", focusedApp);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800690 mTmpWindow = null;
691 return true;
692 }
693 }
694
Adrian Roosb125e0b2019-10-02 14:55:14 +0200695 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: Found new focus @ %s", w);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800696 mTmpWindow = w;
697 return true;
698 };
699
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800700 private final Consumer<WindowState> mPerformLayout = w -> {
701 // Don't do layout of a window if it is not visible, or soon won't be visible, to avoid
702 // wasting time and funky changes while a window is animating away.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800703 final boolean gone = (mTmpWindow != null && mWmService.mPolicy.canBeHiddenByKeyguardLw(w))
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800704 || w.isGoneForLayoutLw();
705
706 if (DEBUG_LAYOUT && !w.mLayoutAttached) {
707 Slog.v(TAG, "1ST PASS " + w + ": gone=" + gone + " mHaveFrame=" + w.mHaveFrame
708 + " mLayoutAttached=" + w.mLayoutAttached
Jorim Jaggi381cd722019-03-27 17:33:02 +0100709 + " config reported=" + w.isLastConfigReportedToClient());
Garfield Tane8d84ab2019-10-11 09:49:40 -0700710 final ActivityRecord activity = w.mActivityRecord;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800711 if (gone) Slog.v(TAG, " GONE: mViewVisibility=" + w.mViewVisibility
Issei Suzukif2f6c912019-11-08 11:24:18 +0100712 + " mRelayoutCalled=" + w.mRelayoutCalled + " visible=" + w.mToken.isVisible()
Issei Suzuki1669ea42019-11-06 14:20:59 +0100713 + " visibleRequested=" + (activity != null && activity.mVisibleRequested)
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800714 + " parentHidden=" + w.isParentWindowHidden());
715 else Slog.v(TAG, " VIS: mViewVisibility=" + w.mViewVisibility
Issei Suzukif2f6c912019-11-08 11:24:18 +0100716 + " mRelayoutCalled=" + w.mRelayoutCalled + " visible=" + w.mToken.isVisible()
Issei Suzuki1669ea42019-11-06 14:20:59 +0100717 + " visibleRequested=" + (activity != null && activity.mVisibleRequested)
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800718 + " parentHidden=" + w.isParentWindowHidden());
719 }
720
Tiger Huang57e2e1c2020-03-13 22:54:36 +0800721 // Sets mBehindIme for each window. Windows behind IME can get IME insets.
Tiger Huang53c8eb82020-03-31 18:22:05 +0800722 if (w.mBehindIme != mTmpWindowsBehindIme) {
723 w.mBehindIme = mTmpWindowsBehindIme;
724 mWinInsetsChanged.add(w);
725 }
Tiger Huang57e2e1c2020-03-13 22:54:36 +0800726 if (w == mInputMethodWindow) {
727 mTmpWindowsBehindIme = true;
728 }
729
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800730 // If this view is GONE, then skip it -- keep the current frame, and let the caller know
731 // so they can ignore it if they want. (We do the normal layout for INVISIBLE windows,
732 // since that means "perform layout as normal, just don't display").
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100733 if ((!gone || !w.mHaveFrame || w.mLayoutNeeded) && !w.mLayoutAttached) {
734 if (mTmpInitial) {
735 w.resetContentChanged();
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800736 }
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100737 w.mLayoutNeeded = false;
738 w.prelayout();
739 final boolean firstLayout = !w.isLaidOut();
740 getDisplayPolicy().layoutWindowLw(w, null, mDisplayFrames);
741 w.mLayoutSeq = mLayoutSeq;
742
Riddle Hsuf64e1342019-12-05 17:38:41 +0800743 // If this is the first layout, we need to initialize the last frames and inset values,
744 // as otherwise we'd immediately cause an unnecessary resize.
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100745 if (firstLayout) {
Riddle Hsu12c05452020-01-09 00:39:52 +0800746 // The client may compute its actual requested size according to the first layout,
747 // so we still request the window to resize if the current frame is empty.
748 if (!w.getFrameLw().isEmpty()) {
749 w.updateLastFrames();
750 }
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100751 w.updateLastInsetValues();
Riddle Hsuf64e1342019-12-05 17:38:41 +0800752 w.updateLocationInParentDisplayIfNeeded();
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100753 }
754
Garfield Tane8d84ab2019-10-11 09:49:40 -0700755 if (w.mActivityRecord != null) {
756 w.mActivityRecord.layoutLetterbox(w);
Jorim Jaggi91d382a2019-03-27 17:00:48 +0100757 }
758
759 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrameLw()
760 + " mContainingFrame=" + w.getContainingFrame()
761 + " mDisplayFrame=" + w.getDisplayFrameLw());
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800762 }
763 };
764
765 private final Consumer<WindowState> mPerformLayoutAttached = w -> {
766 if (w.mLayoutAttached) {
767 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + w + " mHaveFrame=" + w.mHaveFrame
768 + " mViewVisibility=" + w.mViewVisibility
769 + " mRelayoutCalled=" + w.mRelayoutCalled);
770 // If this view is GONE, then skip it -- keep the current frame, and let the caller
771 // know so they can ignore it if they want. (We do the normal layout for INVISIBLE
772 // windows, since that means "perform layout as normal, just don't display").
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800773 if (mTmpWindow != null && mWmService.mPolicy.canBeHiddenByKeyguardLw(w)) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800774 return;
775 }
776 if ((w.mViewVisibility != GONE && w.mRelayoutCalled) || !w.mHaveFrame
777 || w.mLayoutNeeded) {
778 if (mTmpInitial) {
779 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
chaviw1454b392018-08-06 09:54:04 -0700780 w.resetContentChanged();
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800781 }
782 w.mLayoutNeeded = false;
783 w.prelayout();
Tiger Huang7c610aa2018-10-27 00:01:01 +0800784 getDisplayPolicy().layoutWindowLw(w, w.getParentWindow(), mDisplayFrames);
Adrian Roos5251b1d2018-03-23 18:57:43 +0100785 w.mLayoutSeq = mLayoutSeq;
chaviw492139a2018-07-16 16:07:35 -0700786 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrameLw()
chaviw553b0212018-07-12 13:37:01 -0700787 + " mContainingFrame=" + w.getContainingFrame()
788 + " mDisplayFrame=" + w.getDisplayFrameLw());
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800789 }
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800790 }
791 };
792
793 private final Predicate<WindowState> mComputeImeTargetPredicate = w -> {
794 if (DEBUG_INPUT_METHOD && mUpdateImeTarget) Slog.i(TAG_WM, "Checking window @" + w
795 + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
796 return w.canBeImeTarget();
797 };
798
799 private final Consumer<WindowState> mApplyPostLayoutPolicy =
Tiger Huang7c610aa2018-10-27 00:01:01 +0800800 w -> getDisplayPolicy().applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(),
lumarkff0ab692018-11-05 20:32:30 +0800801 mInputMethodTarget);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800802
803 private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800804 final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800805 final boolean obscuredChanged = w.mObscured !=
806 mTmpApplySurfaceChangesTransactionState.obscured;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800807 final RootWindowContainer root = mWmService.mRoot;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800808
809 // Update effect.
810 w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured;
Galia Peycheva056b3ee2019-06-26 14:05:12 +0200811
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800812 if (!mTmpApplySurfaceChangesTransactionState.obscured) {
813 final boolean isDisplayed = w.isDisplayedLw();
814
815 if (isDisplayed && w.isObscuringDisplay()) {
816 // This window completely covers everything behind it, so we want to leave all
817 // of them as undimmed (for performance reasons).
818 root.mObscuringWindow = w;
819 mTmpApplySurfaceChangesTransactionState.obscured = true;
820 }
821
Arthur Hungfbc8f412019-08-01 19:57:54 +0800822 final boolean displayHasContent = root.handleNotObscuredLocked(w,
823 mTmpApplySurfaceChangesTransactionState.obscured,
824 mTmpApplySurfaceChangesTransactionState.syswin);
825
826 if (!mTmpApplySurfaceChangesTransactionState.displayHasContent
827 && !getDisplayPolicy().isWindowExcludedFromContent(w)) {
828 mTmpApplySurfaceChangesTransactionState.displayHasContent |= displayHasContent;
829 }
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800830
831 if (w.mHasSurface && isDisplayed) {
832 final int type = w.mAttrs.type;
Santos Cordonc6a25522020-03-25 18:01:13 +0000833 if (type == TYPE_SYSTEM_DIALOG
834 || type == TYPE_SYSTEM_ERROR
835 || (type == TYPE_NOTIFICATION_SHADE
836 && mWmService.mPolicy.isKeyguardShowing())) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800837 mTmpApplySurfaceChangesTransactionState.syswin = true;
838 }
839 if (mTmpApplySurfaceChangesTransactionState.preferredRefreshRate == 0
840 && w.mAttrs.preferredRefreshRate != 0) {
841 mTmpApplySurfaceChangesTransactionState.preferredRefreshRate
842 = w.mAttrs.preferredRefreshRate;
843 }
Galia Peycheva056b3ee2019-06-26 14:05:12 +0200844
845 mTmpApplySurfaceChangesTransactionState.preferMinimalPostProcessing
846 |= w.mAttrs.preferMinimalPostProcessing;
847
Ady Abrahamf3e05312019-05-13 18:04:59 -0700848 final int preferredModeId = getDisplayPolicy().getRefreshRatePolicy()
849 .getPreferredModeId(w);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800850 if (mTmpApplySurfaceChangesTransactionState.preferredModeId == 0
Ady Abrahamf3e05312019-05-13 18:04:59 -0700851 && preferredModeId != 0) {
852 mTmpApplySurfaceChangesTransactionState.preferredModeId = preferredModeId;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800853 }
854 }
855 }
856
wilsonshihc32538e2018-11-07 17:27:34 +0800857 if (obscuredChanged && w.isVisibleLw() && mWallpaperController.isWallpaperTarget(w)) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800858 // This is the wallpaper target and its obscured state changed... make sure the
859 // current wallpaper's visibility has been updated accordingly.
860 mWallpaperController.updateWallpaperVisibility();
861 }
862
chaviw161ea3e2018-01-31 12:01:12 -0800863 w.handleWindowMovedIfNeeded();
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800864
865 final WindowStateAnimator winAnimator = w.mWinAnimator;
866
867 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
chaviw1454b392018-08-06 09:54:04 -0700868 w.resetContentChanged();
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800869
870 // Moved from updateWindowsAndWallpaperLocked().
871 if (w.mHasSurface) {
872 // Take care of the window being ready to display.
873 final boolean committed = winAnimator.commitFinishDrawingLocked();
874 if (isDefaultDisplay && committed) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800875 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
876 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
877 "First draw done in potential wallpaper target " + w);
wilsonshihc32538e2018-11-07 17:27:34 +0800878 mWallpaperMayChange = true;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800879 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
880 if (DEBUG_LAYOUT_REPEATS) {
881 surfacePlacer.debugLayoutRepeats(
882 "wallpaper and commitFinishDrawingLocked true",
883 pendingLayoutChanges);
884 }
885 }
886 }
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800887 }
888
Garfield Tane8d84ab2019-10-11 09:49:40 -0700889 final ActivityRecord activity = w.mActivityRecord;
890 if (activity != null) {
891 activity.updateLetterboxSurface(w);
892 final boolean updateAllDrawn = activity.updateDrawnWindowStates(w);
893 if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(activity)) {
894 mTmpUpdateAllDrawn.add(activity);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800895 }
896 }
897
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800898 if (!mLosingFocus.isEmpty() && w.isFocused() && w.isDisplayedLw()) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800899 mWmService.mH.obtainMessage(REPORT_LOSING_FOCUS, this).sendToTarget();
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800900 }
901
902 w.updateResizingWindowIfNeeded();
903 };
904
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800905 /**
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800906 * Create new {@link DisplayContent} instance, add itself to the root window container and
907 * initialize direct children.
Craig Mautner2d5618c2012-10-18 13:55:47 -0700908 * @param display May not be null.
Louis Chang149d5c82019-12-30 09:47:39 +0800909 * @param root {@link RootWindowContainer}
Craig Mautner2d5618c2012-10-18 13:55:47 -0700910 */
Louis Chang149d5c82019-12-30 09:47:39 +0800911 DisplayContent(Display display, RootWindowContainer root) {
Louis Chang677921f2019-12-06 16:44:24 +0800912 super(root.mWindowManager);
913 if (mWmService.mRoot.getDisplayContent(display.getDisplayId()) != null) {
Wale Ogunwale1666e312016-12-16 11:27:18 -0800914 throw new IllegalArgumentException("Display with ID=" + display.getDisplayId()
Louis Chang677921f2019-12-06 16:44:24 +0800915 + " already exists="
916 + mWmService.mRoot.getDisplayContent(display.getDisplayId())
Wale Ogunwale1666e312016-12-16 11:27:18 -0800917 + " new=" + display);
918 }
919
Louis Chang149d5c82019-12-30 09:47:39 +0800920 mRootWindowContainer = root;
Louis Chang2453d062019-11-19 22:30:48 +0800921 mAtmService = mWmService.mAtmService;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700922 mDisplay = display;
923 mDisplayId = display.getDisplayId();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800924 mWallpaperController = new WallpaperController(mWmService, this);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700925 display.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700926 display.getMetrics(mDisplayMetrics);
Adrian Roos1c2e9a12019-08-20 18:23:47 +0200927 mSystemGestureExclusionLimit = mWmService.mConstants.mSystemGestureExclusionLimitDp
Adrian Roosbf3bc1b2019-06-18 16:13:53 +0200928 * mDisplayMetrics.densityDpi / DENSITY_DEFAULT;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700929 isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100930 mDisplayFrames = new DisplayFrames(mDisplayId, mDisplayInfo,
931 calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700932 initializeDisplayBaseInfo();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700933
Louis Chang677921f2019-12-06 16:44:24 +0800934 mAppTransition = new AppTransition(mWmService.mContext, mWmService, this);
935 mAppTransition.registerListenerLocked(mWmService.mActivityManagerAppTransitionNotifier);
Riddle Hsud4957432020-04-24 22:06:29 +0800936 mAppTransition.registerListenerLocked(mFixedRotationTransitionListener);
Louis Chang677921f2019-12-06 16:44:24 +0800937 mAppTransitionController = new AppTransitionController(mWmService, this);
938 mUnknownAppVisibilityController = new UnknownAppVisibilityController(mWmService, this);
lumark588a3e82018-07-20 18:53:54 +0800939
Riddle Hsu2588ab02019-02-25 14:23:56 +0800940 final InputChannel inputChannel = mWmService.mInputManager.monitorInput(
941 "PointerEventDispatcher" + mDisplayId, mDisplayId);
942 mPointerEventDispatcher = new PointerEventDispatcher(inputChannel);
943
944 // Tap Listeners are supported for:
945 // 1. All physical displays (multi-display).
946 // 2. VirtualDisplays on VR, AA (and everything else).
947 mTapDetector = new TaskTapPointerEventListener(mWmService, this);
948 registerPointerEventListener(mTapDetector);
949 registerPointerEventListener(mWmService.mMousePositionTracker);
Winson Chungc5fe7ff2019-02-19 14:49:25 -0800950 if (mWmService.mAtmService.getRecentTasks() != null) {
951 registerPointerEventListener(
952 mWmService.mAtmService.getRecentTasks().getInputListener());
953 }
Riddle Hsu2588ab02019-02-25 14:23:56 +0800954
Louis Chang677921f2019-12-06 16:44:24 +0800955 mDisplayPolicy = new DisplayPolicy(mWmService, this);
956 mDisplayRotation = new DisplayRotation(mWmService, this);
957 mCloseToSquareMaxAspectRatio = mWmService.mContext.getResources().getFloat(
Tiger Huang86e6d072019-05-02 20:23:47 +0800958 com.android.internal.R.dimen.config_closeToSquareDisplayMaxAspectRatio);
Tiger Huang7c610aa2018-10-27 00:01:01 +0800959 if (isDefaultDisplay) {
960 // The policy may be invoked right after here, so it requires the necessary default
961 // fields of this display content.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800962 mWmService.mPolicy.setDefaultDisplay(this);
Tiger Huang7c610aa2018-10-27 00:01:01 +0800963 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800964 if (mWmService.mDisplayReady) {
Tiger Huang7c610aa2018-10-27 00:01:01 +0800965 mDisplayPolicy.onConfigurationChanged();
966 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800967 if (mWmService.mSystemReady) {
Tiger Huang7c610aa2018-10-27 00:01:01 +0800968 mDisplayPolicy.systemReady();
969 }
Tiger Huang43b8fc22019-04-26 11:49:29 +0800970 mWindowCornerRadius = mDisplayPolicy.getWindowCornerRadius();
Evan Rosky73a7fe92019-11-18 18:28:01 -0800971 mDividerControllerLocked = new DockedStackDividerController(this);
Louis Chang677921f2019-12-06 16:44:24 +0800972 mPinnedStackControllerLocked = new PinnedStackController(mWmService, this);
Tiger Huang7c610aa2018-10-27 00:01:01 +0800973
Chavi Weingarten6ef9cc62019-02-07 16:28:45 +0000974 final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(mSession)
975 .setOpaque(true)
976 .setContainerLayer();
Vadim Caen1812c762019-08-12 11:38:22 +0200977 mSurfaceControl = b.setName("Root").setContainerLayer().build();
Robert Carrb1579c82017-09-05 14:54:47 -0700978
Vadim Caen1812c762019-08-12 11:38:22 +0200979 getPendingTransaction()
980 .setLayer(mSurfaceControl, 0)
981 .setLayerStack(mSurfaceControl, mDisplayId)
chaviw8065f442019-11-18 13:20:58 -0800982 .show(mSurfaceControl);
Robert Carrf59b8dd2017-10-02 18:58:36 -0700983 getPendingTransaction().apply();
Robert Carrb1579c82017-09-05 14:54:47 -0700984
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700985 // These are the only direct children we should ever have and they are permanent.
chaviw8065f442019-11-18 13:20:58 -0800986 super.addChild(mWindowContainers, null);
987 super.addChild(mOverlayContainers, null);
988
Adrian Roos639ce072020-02-06 16:45:18 -0800989 mDisplayAreaPolicy = mWmService.mDisplayAreaPolicyProvider.instantiate(
Andrii Kulian44b3c562020-04-01 12:49:56 -0700990 mWmService, this, mRootDisplayArea, mImeWindowsContainers);
chaviw8065f442019-11-18 13:20:58 -0800991 mWindowContainers.addChildren();
992
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700993 // Sets the display content for the children.
994 onDisplayChanged(this);
Andrii Kulian367ff7f2017-01-25 19:45:34 -0800995
Garfield Tanfbd233a2019-12-26 12:39:25 -0800996 mInputMonitor = new InputMonitor(mWmService, this);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200997 mInsetsStateController = new InsetsStateController(this);
Jorim Jaggi28620472019-01-02 23:21:49 +0100998 mInsetsPolicy = new InsetsPolicy(mInsetsStateController, this);
Louis Chang677921f2019-12-06 16:44:24 +0800999
Garfield Tanfbd233a2019-12-26 12:39:25 -08001000 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Creating display=" + display);
Louis Chang677921f2019-12-06 16:44:24 +08001001
1002 mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this);
Bryce Leed1871262017-06-12 14:12:29 -07001003 }
1004
1005 boolean isReady() {
1006 // The display is ready when the system and the individual display are both ready.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001007 return mWmService.mDisplayReady && mDisplayReady;
Craig Mautner59c00972012-07-30 12:10:24 -07001008 }
1009
1010 int getDisplayId() {
1011 return mDisplayId;
1012 }
1013
Tiger Huang43b8fc22019-04-26 11:49:29 +08001014 float getWindowCornerRadius() {
1015 return mWindowCornerRadius;
1016 }
1017
Wale Ogunwale02319a62016-09-26 15:21:22 -07001018 WindowToken getWindowToken(IBinder binder) {
1019 return mTokenMap.get(binder);
1020 }
1021
Garfield Tane8d84ab2019-10-11 09:49:40 -07001022 ActivityRecord getActivityRecord(IBinder binder) {
Wale Ogunwale02319a62016-09-26 15:21:22 -07001023 final WindowToken token = getWindowToken(binder);
1024 if (token == null) {
1025 return null;
1026 }
Garfield Tane8d84ab2019-10-11 09:49:40 -07001027 return token.asActivityRecord();
Wale Ogunwale02319a62016-09-26 15:21:22 -07001028 }
1029
lumarkbde15132019-12-18 22:29:43 +08001030 void addWindowToken(IBinder binder, WindowToken token) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001031 final DisplayContent dc = mWmService.mRoot.getWindowTokenDisplay(token);
Wale Ogunwale02319a62016-09-26 15:21:22 -07001032 if (dc != null) {
1033 // We currently don't support adding a window token to the display if the display
1034 // already has the binder mapped to another token. If there is a use case for supporting
1035 // this moving forward we will either need to merge the WindowTokens some how or have
1036 // the binder map to a list of window tokens.
Wale Ogunwale2f569ed2017-05-08 09:15:49 -07001037 throw new IllegalArgumentException("Can't map token=" + token + " to display="
1038 + getName() + " already mapped to display=" + dc + " tokens=" + dc.mTokenMap);
Wale Ogunwale02319a62016-09-26 15:21:22 -07001039 }
Wale Ogunwale2f569ed2017-05-08 09:15:49 -07001040 if (binder == null) {
1041 throw new IllegalArgumentException("Can't map token=" + token + " to display="
1042 + getName() + " binder is null");
1043 }
1044 if (token == null) {
1045 throw new IllegalArgumentException("Can't map null token to display="
1046 + getName() + " binder=" + binder);
1047 }
1048
Wale Ogunwale02319a62016-09-26 15:21:22 -07001049 mTokenMap.put(binder, token);
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001050
Garfield Tane8d84ab2019-10-11 09:49:40 -07001051 if (token.asActivityRecord() == null) {
lumarkbde15132019-12-18 22:29:43 +08001052 // Set displayContent for non-app token to prevent same token will add twice after
1053 // onDisplayChanged.
1054 // TODO: Check if it's fine that super.onDisplayChanged of WindowToken
1055 // (WindowsContainer#onDisplayChanged) may skipped when token.mDisplayContent assigned.
1056 token.mDisplayContent = this;
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001057 // Add non-app token to container hierarchy on the display. App tokens are added through
1058 // the parent container managing them (e.g. Tasks).
Wale Ogunwale3a931692016-11-02 16:49:48 -07001059 switch (token.windowType) {
Wale Ogunwale3a931692016-11-02 16:49:48 -07001060 case TYPE_INPUT_METHOD:
1061 case TYPE_INPUT_METHOD_DIALOG:
1062 mImeWindowsContainers.addChild(token);
1063 break;
chaviw8065f442019-11-18 13:20:58 -08001064 case TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY:
Adrian Roos22a20a82019-10-23 19:05:33 +02001065 // TODO(display-area): Migrate to DisplayArea
chaviw8065f442019-11-18 13:20:58 -08001066 mOverlayContainers.addChild(token);
1067 break;
Wale Ogunwale3a931692016-11-02 16:49:48 -07001068 default:
Adrian Roos22a20a82019-10-23 19:05:33 +02001069 mDisplayAreaPolicy.addWindow(token);
Wale Ogunwale3a931692016-11-02 16:49:48 -07001070 break;
1071 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001072 }
Wale Ogunwale02319a62016-09-26 15:21:22 -07001073 }
1074
1075 WindowToken removeWindowToken(IBinder binder) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001076 final WindowToken token = mTokenMap.remove(binder);
Garfield Tane8d84ab2019-10-11 09:49:40 -07001077 if (token != null && token.asActivityRecord() == null) {
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -08001078 token.setExiting();
1079 }
1080 return token;
1081 }
1082
Evan Rosky22b6bbd2019-09-26 14:29:57 -07001083 SurfaceControl addShellRoot(@NonNull IWindow client, int windowType) {
1084 ShellRoot root = mShellRoots.get(windowType);
1085 if (root != null) {
1086 if (root.getClient() == client) {
1087 return root.getSurfaceControl();
1088 }
1089 root.clear();
1090 mShellRoots.remove(windowType);
1091 }
1092 root = new ShellRoot(client, this, windowType);
1093 SurfaceControl rootLeash = root.getSurfaceControl();
1094 if (rootLeash == null) {
1095 // Root didn't finish initializing, so don't add it.
1096 root.clear();
1097 return null;
1098 }
1099 mShellRoots.put(windowType, root);
Jorim Jaggiee540702020-04-02 21:40:52 +02001100 SurfaceControl out = new SurfaceControl(rootLeash);
Evan Rosky22b6bbd2019-09-26 14:29:57 -07001101 return out;
1102 }
1103
1104 void removeShellRoot(int windowType) {
1105 ShellRoot root = mShellRoots.get(windowType);
1106 if (root == null) {
1107 return;
1108 }
1109 root.clear();
1110 mShellRoots.remove(windowType);
1111 }
1112
Evan Rosky8d782e02019-10-14 15:43:53 -07001113 void setRemoteInsetsController(IDisplayWindowInsetsController controller) {
1114 if (mRemoteInsetsControlTarget != null) {
1115 mRemoteInsetsControlTarget.mRemoteInsetsController.asBinder().unlinkToDeath(
1116 mRemoteInsetsDeath, 0);
1117 mRemoteInsetsControlTarget = null;
1118 }
1119 if (controller != null) {
1120 try {
1121 controller.asBinder().linkToDeath(mRemoteInsetsDeath, 0);
1122 mRemoteInsetsControlTarget = new RemoteInsetsControlTarget(controller);
1123 } catch (RemoteException e) {
1124 return;
1125 }
1126 }
1127 }
1128
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -08001129 /** Changes the display the input window token is housed on to this one. */
1130 void reParentWindowToken(WindowToken token) {
1131 final DisplayContent prevDc = token.getDisplayContent();
1132 if (prevDc == this) {
1133 return;
1134 }
Riddle Hsu85bd04b2018-11-17 00:34:36 +08001135 if (prevDc != null) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07001136 if (prevDc.mTokenMap.remove(token.token) != null && token.asActivityRecord() == null) {
Riddle Hsu85bd04b2018-11-17 00:34:36 +08001137 // Removed the token from the map, but made sure it's not an app token before
1138 // removing from parent.
1139 token.getParent().removeChild(token);
1140 }
lumark280cb212019-09-09 09:47:22 +08001141 if (token.hasChild(prevDc.mLastFocus)) {
1142 // If the reparent window token contains previous display's last focus window, means
1143 // it will end up to gain window focus on the target display, so it should not be
1144 // notified that it lost focus from the previous display.
Riddle Hsu85bd04b2018-11-17 00:34:36 +08001145 prevDc.mLastFocus = null;
1146 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001147 }
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -08001148
1149 addWindowToken(token.token, token);
RyanlwLin925e8222019-08-30 15:08:48 +08001150
1151 if (mWmService.mAccessibilityController != null) {
1152 final int prevDisplayId = prevDc != null ? prevDc.getDisplayId() : INVALID_DISPLAY;
1153 mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(prevDisplayId,
1154 getDisplayId());
1155 }
Wale Ogunwale02319a62016-09-26 15:21:22 -07001156 }
1157
Wale Ogunwaleac2561e2016-11-01 15:43:46 -07001158 void removeAppToken(IBinder binder) {
1159 final WindowToken token = removeWindowToken(binder);
1160 if (token == null) {
1161 Slog.w(TAG_WM, "removeAppToken: Attempted to remove non-existing token: " + binder);
1162 return;
1163 }
1164
Garfield Tane8d84ab2019-10-11 09:49:40 -07001165 final ActivityRecord activity = token.asActivityRecord();
Wale Ogunwaleac2561e2016-11-01 15:43:46 -07001166
Garfield Tane8d84ab2019-10-11 09:49:40 -07001167 if (activity == null) {
Wale Ogunwaleac2561e2016-11-01 15:43:46 -07001168 Slog.w(TAG_WM, "Attempted to remove non-App token: " + binder + " token=" + token);
1169 return;
1170 }
1171
Garfield Tane8d84ab2019-10-11 09:49:40 -07001172 activity.onRemovedFromDisplay();
Wale Ogunwaleac2561e2016-11-01 15:43:46 -07001173 }
1174
Riddle Hsuad256a12018-07-18 16:11:30 +08001175 @Override
1176 public Display getDisplay() {
Craig Mautnerb47bbc32012-08-22 17:41:48 -07001177 return mDisplay;
1178 }
1179
Craig Mautner59c00972012-07-30 12:10:24 -07001180 DisplayInfo getDisplayInfo() {
1181 return mDisplayInfo;
1182 }
1183
Wale Ogunwale231b06e2015-09-16 12:03:09 -07001184 DisplayMetrics getDisplayMetrics() {
1185 return mDisplayMetrics;
1186 }
1187
Riddle Hsu5ce4bb32018-07-18 16:11:30 +08001188 DisplayPolicy getDisplayPolicy() {
1189 return mDisplayPolicy;
1190 }
1191
Riddle Hsuad256a12018-07-18 16:11:30 +08001192 @Override
1193 public DisplayRotation getDisplayRotation() {
1194 return mDisplayRotation;
1195 }
1196
Jorim Jaggi9b4f4202020-01-28 17:05:06 +01001197 void setInsetProvider(@InternalInsetsType int type, WindowState win,
1198 @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider){
1199 setInsetProvider(type, win, frameProvider, null /* imeFrameProvider */);
1200 }
1201
Jorim Jaggif96c90a2018-09-26 16:55:15 +02001202 /**
1203 * Marks a window as providing insets for the rest of the windows in the system.
1204 *
1205 * @param type The type of inset this window provides.
1206 * @param win The window.
1207 * @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
1208 * the window should be taken.
Jorim Jaggi9b4f4202020-01-28 17:05:06 +01001209 * @param imeFrameProvider Function to compute the frame when dispatching insets to the IME, or
1210 * {@code null} if the normal frame should be taken.
Jorim Jaggif96c90a2018-09-26 16:55:15 +02001211 */
Tiger Huang332793b2019-10-29 23:21:27 +08001212 void setInsetProvider(@InternalInsetsType int type, WindowState win,
Jorim Jaggi9b4f4202020-01-28 17:05:06 +01001213 @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider,
1214 @Nullable TriConsumer<DisplayFrames, WindowState, Rect> imeFrameProvider) {
1215 mInsetsStateController.getSourceProvider(type).setWindow(win, frameProvider,
1216 imeFrameProvider);
Jorim Jaggif96c90a2018-09-26 16:55:15 +02001217 }
1218
1219 InsetsStateController getInsetsStateController() {
1220 return mInsetsStateController;
1221 }
1222
Jorim Jaggi28620472019-01-02 23:21:49 +01001223 InsetsPolicy getInsetsPolicy() {
1224 return mInsetsPolicy;
1225 }
1226
Riddle Hsuccf09402019-08-13 00:33:06 +08001227 @Surface.Rotation
Andrii Kulian8ee72852017-03-10 10:36:45 -08001228 int getRotation() {
Riddle Hsuccf09402019-08-13 00:33:06 +08001229 return mDisplayRotation.getRotation();
Andrii Kulian8ee72852017-03-10 10:36:45 -08001230 }
1231
Riddle Hsuccf09402019-08-13 00:33:06 +08001232 @ScreenOrientation
Andrii Kulian8ee72852017-03-10 10:36:45 -08001233 int getLastOrientation() {
Riddle Hsuccf09402019-08-13 00:33:06 +08001234 return mDisplayRotation.getLastOrientation();
Andrii Kulian8ee72852017-03-10 10:36:45 -08001235 }
1236
Evan Rosky966759f2019-01-15 10:33:58 -08001237 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
1238 mAppTransitionController.registerRemoteAnimations(definition);
1239 }
1240
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07001241 void reconfigureDisplayLocked() {
1242 if (!isReady()) {
1243 return;
1244 }
1245 configureDisplayPolicy();
1246 setLayoutNeeded();
1247
Riddle Hsuccf09402019-08-13 00:33:06 +08001248 boolean configChanged = updateOrientation();
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07001249 final Configuration currentDisplayConfig = getConfiguration();
1250 mTmpConfiguration.setTo(currentDisplayConfig);
1251 computeScreenConfiguration(mTmpConfiguration);
1252 configChanged |= currentDisplayConfig.diff(mTmpConfiguration) != 0;
1253
1254 if (configChanged) {
1255 mWaitingForConfig = true;
Riddle Hsud16620e2020-04-06 20:48:06 +08001256 mWmService.startFreezingDisplay(0 /* exitAnim */, 0 /* enterAnim */, this);
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07001257 sendNewConfiguration();
1258 }
1259
1260 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Riddle Hsu4e611772018-10-31 18:58:28 +08001261 }
1262
Shivam Agrawal1d3db652019-07-01 15:26:11 -07001263 void sendNewConfiguration() {
Louis Chang2453d062019-11-19 22:30:48 +08001264 if (!isReady()) {
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07001265 return;
1266 }
Evan Rosky69cace42019-09-20 16:28:13 -07001267 if (mDisplayRotation.isWaitingForRemoteRotation()) {
1268 return;
1269 }
Riddle Hsu6f548e92020-01-13 13:34:09 +08001270
Louis Chang677921f2019-12-06 16:44:24 +08001271 final boolean configUpdated = updateDisplayOverrideConfigurationLocked();
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07001272 if (configUpdated) {
1273 return;
1274 }
Riddle Hsub40f9662020-04-25 01:58:23 +08001275
1276 // The display configuration doesn't change. If there is a launching transformed app, that
1277 // means its request to change display configuration has been discarded, then it should
1278 // respect to the current configuration of display.
1279 clearFixedRotationLaunchingApp();
1280
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07001281 // Something changed (E.g. device rotation), but no configuration update is needed.
1282 // E.g. changing device rotation by 180 degrees. Go ahead and perform surface placement to
1283 // unfreeze the display since we froze it when the rotation was updated in
1284 // DisplayContent#updateRotationUnchecked.
1285 if (mWaitingForConfig) {
1286 mWaitingForConfig = false;
1287 mWmService.mLastFinishedFreezeSource = "config-unchanged";
1288 setLayoutNeeded();
1289 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Shivam Agrawal1d3db652019-07-01 15:26:11 -07001290 }
1291 }
1292
Garfield Tan90b04282018-12-11 14:04:42 -08001293 @Override
1294 boolean onDescendantOrientationChanged(IBinder freezeDisplayToken,
1295 ConfigurationContainer requestingContainer) {
Riddle Hsuccf09402019-08-13 00:33:06 +08001296 final Configuration config = updateOrientation(
1297 getRequestedOverrideConfiguration(), freezeDisplayToken, false /* forceUpdate */);
Garfield Tan49dae102019-02-04 09:51:59 -08001298 // If display rotation class tells us that it doesn't consider app requested orientation,
1299 // this display won't rotate just because of an app changes its requested orientation. Thus
1300 // it indicates that this display chooses not to handle this request.
1301 final boolean handled = getDisplayRotation().respectAppRequestedOrientation();
Garfield Tan90b04282018-12-11 14:04:42 -08001302 if (config == null) {
1303 return handled;
1304 }
1305
1306 if (handled && requestingContainer instanceof ActivityRecord) {
1307 final ActivityRecord activityRecord = (ActivityRecord) requestingContainer;
Louis Chang677921f2019-12-06 16:44:24 +08001308 final boolean kept = updateDisplayOverrideConfigurationLocked(config, activityRecord,
1309 false /* deferResume */, null /* result */);
Garfield Tan90b04282018-12-11 14:04:42 -08001310 activityRecord.frozenBeforeDestroy = true;
1311 if (!kept) {
Louis Chang149d5c82019-12-30 09:47:39 +08001312 mRootWindowContainer.resumeFocusedStacksTopActivities();
Garfield Tan90b04282018-12-11 14:04:42 -08001313 }
1314 } else {
1315 // We have a new configuration to push so we need to update ATMS for now.
1316 // TODO: Clean up display configuration push between ATMS and WMS after unification.
Louis Chang677921f2019-12-06 16:44:24 +08001317 updateDisplayOverrideConfigurationLocked(config, null /* starting */,
1318 false /* deferResume */, null);
Garfield Tan90b04282018-12-11 14:04:42 -08001319 }
1320 return handled;
1321 }
1322
Garfield Tan49dae102019-02-04 09:51:59 -08001323 @Override
1324 boolean handlesOrientationChangeFromDescendant() {
1325 return getDisplayRotation().respectAppRequestedOrientation();
1326 }
1327
Riddle Hsu4e611772018-10-31 18:58:28 +08001328 /**
1329 * Determine the new desired orientation of this display.
1330 *
Riddle Hsuccf09402019-08-13 00:33:06 +08001331 * @see #getOrientation()
1332 * @return {@code true} if the orientation is changed and the caller should call
1333 * {@link #sendNewConfiguration} if the method returns {@code true}.
Riddle Hsu4e611772018-10-31 18:58:28 +08001334 */
Riddle Hsuccf09402019-08-13 00:33:06 +08001335 boolean updateOrientation() {
Riddle Hsu6f548e92020-01-13 13:34:09 +08001336 return updateOrientation(false /* forceUpdate */);
Riddle Hsu4e611772018-10-31 18:58:28 +08001337 }
1338
Garfield Tan90b04282018-12-11 14:04:42 -08001339 /**
Riddle Hsuccf09402019-08-13 00:33:06 +08001340 * Update orientation of the display, returning a non-null new Configuration if it has
Garfield Tan90b04282018-12-11 14:04:42 -08001341 * changed from the current orientation. If a non-null configuration is returned, someone must
1342 * call {@link WindowManagerService#setNewDisplayOverrideConfiguration(Configuration,
1343 * DisplayContent)} to tell the window manager it can unfreeze the screen. This will typically
Riddle Hsuccf09402019-08-13 00:33:06 +08001344 * be done by calling {@link #sendNewConfiguration}.
1345 *
1346 * @param currentConfig The current requested override configuration (it is usually set from
1347 * the last {@link #sendNewConfiguration}) of the display. It is used to
1348 * check if the configuration container has the latest state.
1349 * @param freezeDisplayToken Freeze the app window token if the orientation is changed.
1350 * @param forceUpdate See {@link DisplayRotation#updateRotationUnchecked(boolean)}
Garfield Tan90b04282018-12-11 14:04:42 -08001351 */
Riddle Hsuccf09402019-08-13 00:33:06 +08001352 Configuration updateOrientation(Configuration currentConfig, IBinder freezeDisplayToken,
1353 boolean forceUpdate) {
Garfield Tan90b04282018-12-11 14:04:42 -08001354 if (!mDisplayReady) {
1355 return null;
1356 }
1357
1358 Configuration config = null;
Riddle Hsu6f548e92020-01-13 13:34:09 +08001359 if (updateOrientation(forceUpdate)) {
Garfield Tan90b04282018-12-11 14:04:42 -08001360 // If we changed the orientation but mOrientationChangeComplete is already true,
1361 // we used seamless rotation, and we don't need to freeze the screen.
1362 if (freezeDisplayToken != null && !mWmService.mRoot.mOrientationChangeComplete) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07001363 final ActivityRecord activity = getActivityRecord(freezeDisplayToken);
1364 if (activity != null) {
1365 activity.startFreezingScreen();
Garfield Tan90b04282018-12-11 14:04:42 -08001366 }
1367 }
1368 config = new Configuration();
1369 computeScreenConfiguration(config);
1370 } else if (currentConfig != null) {
1371 // No obvious action we need to take, but if our current state mismatches the
1372 // activity manager's, update it, disregarding font scale, which should remain set
1373 // to the value of the previous configuration.
1374 // Here we're calling Configuration#unset() instead of setToDefaults() because we
1375 // need to keep override configs clear of non-empty values (e.g. fontSize).
1376 mTmpConfiguration.unset();
1377 mTmpConfiguration.updateFrom(currentConfig);
1378 computeScreenConfiguration(mTmpConfiguration);
1379 if (currentConfig.diff(mTmpConfiguration) != 0) {
1380 mWaitingForConfig = true;
1381 setLayoutNeeded();
Riddle Hsuccf09402019-08-13 00:33:06 +08001382 mDisplayRotation.prepareNormalRotationAnimation();
Garfield Tan90b04282018-12-11 14:04:42 -08001383 config = new Configuration(mTmpConfiguration);
1384 }
1385 }
1386
1387 return config;
1388 }
1389
Riddle Hsu6f548e92020-01-13 13:34:09 +08001390 private boolean updateOrientation(boolean forceUpdate) {
1391 final int orientation = getOrientation();
1392 // The last orientation source is valid only after getOrientation.
1393 final WindowContainer orientationSource = getLastOrientationSource();
1394 final ActivityRecord r =
1395 orientationSource != null ? orientationSource.asActivityRecord() : null;
Riddle Hsudb94bfd2020-05-13 01:50:17 +08001396 if (r != null) {
Garfield Tanafa0de82020-03-03 16:07:07 -08001397 final Task task = r.getTask();
Riddle Hsudb94bfd2020-05-13 01:50:17 +08001398 if (task != null && orientation != task.mLastReportedRequestedOrientation) {
1399 task.mLastReportedRequestedOrientation = orientation;
1400 mAtmService.getTaskChangeNotificationController()
1401 .notifyTaskRequestedOrientationChanged(task.mTaskId, orientation);
1402 }
1403 // Currently there is no use case from non-activity.
1404 if (handleTopActivityLaunchingInDifferentOrientation(r, true /* checkOpening */)) {
1405 // Display orientation should be deferred until the top fixed rotation is finished.
1406 return false;
1407 }
Riddle Hsu6f548e92020-01-13 13:34:09 +08001408 }
1409 return mDisplayRotation.updateOrientation(orientation, forceUpdate);
1410 }
1411
Riddle Hsueae6ef3e2020-05-13 01:07:33 +08001412 /**
1413 * Returns a valid rotation if the activity can use different orientation than the display.
1414 * Otherwise {@link #ROTATION_UNDEFINED}.
1415 */
Riddle Hsu6f548e92020-01-13 13:34:09 +08001416 @Surface.Rotation
Riddle Hsueae6ef3e2020-05-13 01:07:33 +08001417 int rotationForActivityInDifferentOrientation(@NonNull ActivityRecord r) {
Riddle Hsu6f548e92020-01-13 13:34:09 +08001418 if (!mWmService.mIsFixedRotationTransformEnabled) {
Riddle Hsueae6ef3e2020-05-13 01:07:33 +08001419 return ROTATION_UNDEFINED;
Riddle Hsu6f548e92020-01-13 13:34:09 +08001420 }
1421 if (r.inMultiWindowMode()
1422 || r.getRequestedConfigurationOrientation() == getConfiguration().orientation) {
Riddle Hsueae6ef3e2020-05-13 01:07:33 +08001423 return ROTATION_UNDEFINED;
Riddle Hsu6f548e92020-01-13 13:34:09 +08001424 }
1425 final int currentRotation = getRotation();
1426 final int rotation = mDisplayRotation.rotationForOrientation(r.getRequestedOrientation(),
1427 currentRotation);
1428 if (rotation == currentRotation) {
Riddle Hsueae6ef3e2020-05-13 01:07:33 +08001429 return ROTATION_UNDEFINED;
Riddle Hsu6f548e92020-01-13 13:34:09 +08001430 }
1431 return rotation;
1432 }
1433
1434 /**
1435 * We need to keep display rotation fixed for a while when the activity in different orientation
1436 * is launching until the launch animation is done to avoid showing the previous activity
1437 * inadvertently in a wrong orientation.
1438 *
Riddle Hsudb94bfd2020-05-13 01:50:17 +08001439 * @param r The launching activity which may change display orientation.
1440 * @param checkOpening Whether to check if the activity is animating by transition. Set to
1441 * {@code true} if the caller is not sure whether the activity is launching.
Riddle Hsu6f548e92020-01-13 13:34:09 +08001442 * @return {@code true} if the fixed rotation is started.
1443 */
Riddle Hsudb94bfd2020-05-13 01:50:17 +08001444 boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
1445 boolean checkOpening) {
Riddle Hsu6f548e92020-01-13 13:34:09 +08001446 if (!mWmService.mIsFixedRotationTransformEnabled) {
1447 return false;
1448 }
1449 if (r.isFinishingFixedRotationTransform()) {
1450 return false;
1451 }
1452 if (r.hasFixedRotationTransform()) {
1453 // It has been set and not yet finished.
1454 return true;
1455 }
Riddle Hsudb94bfd2020-05-13 01:50:17 +08001456 if (checkOpening) {
1457 if (!mAppTransition.isTransitionSet() && !mOpeningApps.contains(r)) {
1458 // Apply normal rotation animation in case of the activity set different requested
1459 // orientation without activity switch.
1460 return false;
1461 }
1462 } else if (r != topRunningActivity()) {
1463 // If the transition has not started yet, the activity must be the top.
Riddle Hsu6f548e92020-01-13 13:34:09 +08001464 return false;
1465 }
1466 final int rotation = rotationForActivityInDifferentOrientation(r);
Riddle Hsueae6ef3e2020-05-13 01:07:33 +08001467 if (rotation == ROTATION_UNDEFINED) {
Riddle Hsu6f548e92020-01-13 13:34:09 +08001468 return false;
1469 }
1470 if (!r.getParent().matchParentBounds()) {
1471 // Because the fixed rotated configuration applies to activity directly, if its parent
1472 // has it own policy for bounds, the activity bounds based on parent is unknown.
1473 return false;
1474 }
1475
Riddle Hsucbc5d272020-04-24 23:26:46 +08001476 setFixedRotationLaunchingApp(r, rotation);
1477 return true;
1478 }
1479
1480 /**
1481 * Sets the provided record to {@link mFixedRotationLaunchingApp} if possible to apply fixed
1482 * rotation transform to it and indicate that the display may be rotated after it is launched.
1483 */
1484 void setFixedRotationLaunchingApp(@NonNull ActivityRecord r, @Surface.Rotation int rotation) {
Riddle Hsud4957432020-04-24 22:06:29 +08001485 final WindowToken prevRotatedLaunchingApp = mFixedRotationLaunchingApp;
1486 if (prevRotatedLaunchingApp != null
1487 && prevRotatedLaunchingApp.getWindowConfiguration().getRotation() == rotation
1488 // It is animating so we can expect there will have a transition callback.
1489 && prevRotatedLaunchingApp.isAnimating(TRANSITION | PARENTS)) {
1490 // It may be the case that multiple activities launch consecutively. Because their
1491 // rotation are the same, the transformed state can be shared to avoid duplicating
1492 // the heavy operations. This also benefits that the states of multiple activities
1493 // are handled together.
1494 r.linkFixedRotationTransform(prevRotatedLaunchingApp);
Riddle Hsucbc5d272020-04-24 23:26:46 +08001495 return;
Riddle Hsud4957432020-04-24 22:06:29 +08001496 }
1497
Riddle Hsucbc5d272020-04-24 23:26:46 +08001498 if (!r.hasFixedRotationTransform()) {
1499 startFixedRotationTransform(r, rotation);
1500 }
Riddle Hsud4957432020-04-24 22:06:29 +08001501 mFixedRotationLaunchingApp = r;
1502 if (prevRotatedLaunchingApp != null) {
1503 prevRotatedLaunchingApp.finishFixedRotationTransform();
1504 }
Riddle Hsu6f548e92020-01-13 13:34:09 +08001505 }
1506
Riddle Hsud4957432020-04-24 22:06:29 +08001507 /**
1508 * Continue updating the orientation change of display if it was deferred by a top activity
1509 * launched in a different orientation.
1510 */
1511 void continueUpdateOrientationForDiffOrienLaunchingApp() {
1512 if (mFixedRotationLaunchingApp == null) {
1513 return;
Riddle Hsu6f548e92020-01-13 13:34:09 +08001514 }
Riddle Hsu06aeb062020-03-24 23:38:40 +08001515 // Update directly because the app which will change the orientation of display is ready.
1516 if (mDisplayRotation.updateOrientation(getOrientation(), false /* forceUpdate */)) {
Riddle Hsu6f548e92020-01-13 13:34:09 +08001517 sendNewConfiguration();
Riddle Hsud4957432020-04-24 22:06:29 +08001518 return;
Riddle Hsu6f548e92020-01-13 13:34:09 +08001519 }
Riddle Hsu742313e2020-05-05 17:20:32 +08001520 if (mDisplayRotation.isWaitingForRemoteRotation()) {
1521 // There is pending rotation change to apply.
1522 return;
1523 }
Riddle Hsub40f9662020-04-25 01:58:23 +08001524 // The orientation of display is not changed.
1525 clearFixedRotationLaunchingApp();
1526 }
1527
1528 /**
1529 * Clears the {@link mFixedRotationLaunchingApp} without applying rotation to display. It is
1530 * used when the display won't rotate (e.g. the orientation from sensor has updated again before
1531 * applying rotation to display) but the launching app has been transformed. So the record need
1532 * to be cleared and restored to stop using seamless rotation and rotated configuration.
1533 */
1534 private void clearFixedRotationLaunchingApp() {
1535 if (mFixedRotationLaunchingApp == null) {
1536 return;
1537 }
Riddle Hsud4957432020-04-24 22:06:29 +08001538 mFixedRotationLaunchingApp.finishFixedRotationTransform();
Riddle Hsud16620e2020-04-06 20:48:06 +08001539 mFixedRotationLaunchingApp = null;
Riddle Hsu6f548e92020-01-13 13:34:09 +08001540 }
1541
1542 private void startFixedRotationTransform(WindowToken token, int rotation) {
Vadim Caendca5b932020-04-23 18:26:50 +02001543 if (mFixedRotationAnimationController == null) {
1544 mFixedRotationAnimationController = new FixedRotationAnimationController(
1545 this);
1546 }
1547 mFixedRotationAnimationController.hide(rotation);
Riddle Hsu6f548e92020-01-13 13:34:09 +08001548 mTmpConfiguration.unset();
1549 final DisplayInfo info = computeScreenConfiguration(mTmpConfiguration, rotation);
1550 final WmDisplayCutout cutout = calculateDisplayCutoutForRotation(rotation);
1551 final DisplayFrames displayFrames = new DisplayFrames(mDisplayId, info, cutout);
1552 token.applyFixedRotationTransform(info, displayFrames, mTmpConfiguration);
1553 }
1554
Riddle Hsu5ce4bb32018-07-18 16:11:30 +08001555 /**
Vadim Caena0fa9662020-01-27 15:00:01 +01001556 * If the provided {@link ActivityRecord} can be displayed in an orientation different from the
1557 * display's, it will be rotated to match its requested orientation.
1558 *
1559 * @see #rotationForActivityInDifferentOrientation(ActivityRecord).
1560 * @see WindowToken#applyFixedRotationTransform(DisplayInfo, DisplayFrames, Configuration)
1561 */
1562 void rotateInDifferentOrientationIfNeeded(ActivityRecord activityRecord) {
1563 int rotation = rotationForActivityInDifferentOrientation(activityRecord);
Riddle Hsueae6ef3e2020-05-13 01:07:33 +08001564 if (rotation != ROTATION_UNDEFINED) {
Vadim Caena0fa9662020-01-27 15:00:01 +01001565 startFixedRotationTransform(activityRecord, rotation);
1566 }
1567 }
1568
Vadim Caendca5b932020-04-23 18:26:50 +02001569 void finishFixedRotationAnimation() {
1570 if (mFixedRotationAnimationController != null
1571 && mFixedRotationAnimationController.show()) {
1572 mFixedRotationAnimationController = null;
1573 }
1574 }
1575
Vadim Caena0fa9662020-01-27 15:00:01 +01001576 /**
Andrii Kulian06d07d62017-03-14 11:11:47 -07001577 * Update rotation of the display.
1578 *
Andrii Kulian6cdcfe42018-05-23 17:59:43 -07001579 * @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
Riddle Hsuccf09402019-08-13 00:33:06 +08001580 * {@link #sendNewConfiguration} TO UNFREEZE THE SCREEN.
Andrii Kulian06d07d62017-03-14 11:11:47 -07001581 */
Robert Carrae606b42018-02-15 15:36:23 -08001582 boolean updateRotationUnchecked() {
Riddle Hsuccf09402019-08-13 00:33:06 +08001583 return mDisplayRotation.updateRotationUnchecked(false /* forceUpdate */);
Evan Roskye747c3e2018-10-30 20:06:41 -07001584 }
1585
1586 /**
1587 * Applies the rotation transaction. This must be called after {@link #updateRotationUnchecked}
1588 * (if it returned {@code true}) to actually finish the rotation.
1589 *
1590 * @param oldRotation the rotation we are coming from.
1591 * @param rotation the rotation to apply.
1592 */
Riddle Hsu06aeb062020-03-24 23:38:40 +08001593 private void applyRotation(final int oldRotation, final int rotation) {
Riddle Hsuccf09402019-08-13 00:33:06 +08001594 mDisplayRotation.applyCurrentRotation(rotation);
1595 final boolean rotateSeamlessly = mDisplayRotation.isRotatingSeamlessly();
Riddle Hsuccf09402019-08-13 00:33:06 +08001596 final Transaction transaction = getPendingTransaction();
Vadim Caenb3715832019-08-13 17:06:38 +02001597 ScreenRotationAnimation screenRotationAnimation = rotateSeamlessly
1598 ? null : getRotationAnimation();
Andrii Kulian06d07d62017-03-14 11:11:47 -07001599 // We need to update our screen size information to match the new rotation. If the rotation
1600 // has actually changed then this method will return true and, according to the comment at
1601 // the top of the method, the caller is obligated to call computeNewConfigurationLocked().
1602 // By updating the Display info here it will be available to
1603 // #computeScreenConfiguration() later.
Tiger Huanga817b1f2019-05-09 20:04:17 +08001604 updateDisplayAndOrientation(getConfiguration().uiMode, null /* outConfig */);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001605
Robert Carrae606b42018-02-15 15:36:23 -08001606 // NOTE: We disable the rotation in the emulator because
1607 // it doesn't support hardware OpenGL emulation yet.
Vadim Caenba4fd6c2019-08-05 16:45:46 +02001608 if (screenRotationAnimation != null && screenRotationAnimation.hasScreenshot()) {
Riddle Hsuccf09402019-08-13 00:33:06 +08001609 screenRotationAnimation.setRotation(transaction, rotation);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001610 }
1611
Vishnu Nair83537a72018-07-19 21:27:48 -07001612 forAllWindows(w -> {
Riddle Hsuccf09402019-08-13 00:33:06 +08001613 w.seamlesslyRotateIfAllowed(transaction, oldRotation, rotation, rotateSeamlessly);
Vishnu Nair83537a72018-07-19 21:27:48 -07001614 }, true /* traverseTopToBottom */);
1615
Riddle Hsuccf09402019-08-13 00:33:06 +08001616 mWmService.mDisplayManagerInternal.performTraversal(transaction);
Robert Carrae606b42018-02-15 15:36:23 -08001617 scheduleAnimation();
1618
Andrii Kulian06d07d62017-03-14 11:11:47 -07001619 forAllWindows(w -> {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001620 if (w.mHasSurface && !rotateSeamlessly) {
Adrian Roosb125e0b2019-10-02 14:55:14 +02001621 ProtoLog.v(WM_DEBUG_ORIENTATION, "Set mOrientationChanging of %s", w);
Bryce Lee8c3cf382017-07-06 19:47:10 -07001622 w.setOrientationChanging(true);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001623 mWmService.mRoot.mOrientationChangeComplete = false;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001624 w.mLastFreezeDuration = 0;
1625 }
1626 w.mReportOrientationChanged = true;
1627 }, true /* traverseTopToBottom */);
1628
1629 if (rotateSeamlessly) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001630 mWmService.mH.sendNewMessageDelayed(WindowManagerService.H.SEAMLESS_ROTATION_TIMEOUT,
Riddle Hsu654a6f92018-07-13 22:59:36 +08001631 this, SEAMLESS_ROTATION_TIMEOUT_DURATION);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001632 }
1633
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001634 for (int i = mWmService.mRotationWatchers.size() - 1; i >= 0; i--) {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001635 final WindowManagerService.RotationWatcher rotationWatcher
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001636 = mWmService.mRotationWatchers.get(i);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001637 if (rotationWatcher.mDisplayId == mDisplayId) {
1638 try {
1639 rotationWatcher.mWatcher.onRotationChanged(rotation);
1640 } catch (RemoteException e) {
1641 // Ignore
1642 }
1643 }
1644 }
1645
chaviwafc54cf2020-05-05 09:54:53 -07001646 if (mWmService.mAccessibilityController != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001647 mWmService.mAccessibilityController.onRotationChangedLocked(this);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001648 }
Andrii Kulian06d07d62017-03-14 11:11:47 -07001649 }
1650
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00001651 void configureDisplayPolicy() {
Riddle Hsu5ce4bb32018-07-18 16:11:30 +08001652 final int width = mBaseDisplayWidth;
1653 final int height = mBaseDisplayHeight;
1654 final int shortSize;
1655 final int longSize;
1656 if (width > height) {
1657 shortSize = height;
1658 longSize = width;
1659 } else {
1660 shortSize = width;
1661 longSize = height;
1662 }
1663
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02001664 final int shortSizeDp = shortSize * DENSITY_DEFAULT / mBaseDisplayDensity;
1665 final int longSizeDp = longSize * DENSITY_DEFAULT / mBaseDisplayDensity;
Riddle Hsu5ce4bb32018-07-18 16:11:30 +08001666
Winson Chung4723b4e2019-03-25 16:49:36 -07001667 mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors();
Tiger Huang3d2b8982019-01-29 22:56:48 +08001668 mDisplayRotation.configure(width, height, shortSizeDp, longSizeDp);
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00001669
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001670 mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
1671 calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
Tiger Huang86e6d072019-05-02 20:23:47 +08001672
1673 // Not much of use to rotate the display for apps since it's close to square.
1674 mIgnoreRotationForApps = isNonDecorDisplayCloseToSquare(Surface.ROTATION_0, width, height);
1675 }
1676
Riddle Hsue47501b2020-02-18 12:45:41 +08001677 /** @return {@code true} if the orientation requested from application will be ignored. */
1678 boolean ignoreRotationForApps() {
1679 return mIgnoreRotationForApps;
1680 }
1681
Tiger Huang86e6d072019-05-02 20:23:47 +08001682 private boolean isNonDecorDisplayCloseToSquare(int rotation, int width, int height) {
1683 final DisplayCutout displayCutout =
1684 calculateDisplayCutoutForRotation(rotation).getDisplayCutout();
1685 final int uiMode = mWmService.mPolicy.getUiMode();
1686 final int w = mDisplayPolicy.getNonDecorDisplayWidth(
1687 width, height, rotation, uiMode, displayCutout);
1688 final int h = mDisplayPolicy.getNonDecorDisplayHeight(
1689 width, height, rotation, uiMode, displayCutout);
1690 final float aspectRatio = Math.max(w, h) / (float) Math.min(w, h);
1691 return aspectRatio <= mCloseToSquareMaxAspectRatio;
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00001692 }
1693
Andrii Kulian06d07d62017-03-14 11:11:47 -07001694 /**
1695 * Update {@link #mDisplayInfo} and other internal variables when display is rotated or config
1696 * changed.
1697 * Do not call if {@link WindowManagerService#mDisplayReady} == false.
1698 */
Tiger Huanga817b1f2019-05-09 20:04:17 +08001699 private DisplayInfo updateDisplayAndOrientation(int uiMode, Configuration outConfig) {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001700 // Use the effective "visual" dimensions based on current rotation
Riddle Hsuccf09402019-08-13 00:33:06 +08001701 final int rotation = getRotation();
1702 final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
Garfield Tan4bb83472019-01-16 14:37:04 -08001703 final int dw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
1704 final int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001705
1706 // Update application display metrics.
Riddle Hsuccf09402019-08-13 00:33:06 +08001707 final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001708 final DisplayCutout displayCutout = wmDisplayCutout.getDisplayCutout();
1709
Riddle Hsuccf09402019-08-13 00:33:06 +08001710 final int appWidth = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001711 displayCutout);
Riddle Hsuccf09402019-08-13 00:33:06 +08001712 final int appHeight = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
Tiger Huang7c610aa2018-10-27 00:01:01 +08001713 displayCutout);
Riddle Hsuccf09402019-08-13 00:33:06 +08001714 mDisplayInfo.rotation = rotation;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001715 mDisplayInfo.logicalWidth = dw;
1716 mDisplayInfo.logicalHeight = dh;
1717 mDisplayInfo.logicalDensityDpi = mBaseDisplayDensity;
1718 mDisplayInfo.appWidth = appWidth;
1719 mDisplayInfo.appHeight = appHeight;
1720 if (isDefaultDisplay) {
1721 mDisplayInfo.getLogicalMetrics(mRealDisplayMetrics,
1722 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
1723 }
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001724 mDisplayInfo.displayCutout = displayCutout.isEmpty() ? null : displayCutout;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001725 mDisplayInfo.getAppMetrics(mDisplayMetrics);
1726 if (mDisplayScalingDisabled) {
1727 mDisplayInfo.flags |= Display.FLAG_SCALING_DISABLED;
1728 } else {
1729 mDisplayInfo.flags &= ~Display.FLAG_SCALING_DISABLED;
1730 }
1731
Tiger Huanga817b1f2019-05-09 20:04:17 +08001732 computeSizeRangesAndScreenLayout(mDisplayInfo, rotated, uiMode, dw, dh,
1733 mDisplayMetrics.density, outConfig);
1734
Andrii Kulianf0379de2018-03-14 16:24:07 -07001735 // We usually set the override info in DisplayManager so that we get consistent display
1736 // metrics values when displays are changing and don't send out new values until WM is aware
1737 // of them. However, we don't do this for displays that serve as containers for ActivityView
1738 // because we don't want letter-/pillar-boxing during resize.
1739 final DisplayInfo overrideDisplayInfo = mShouldOverrideDisplayConfiguration
1740 ? mDisplayInfo : null;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001741 mWmService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(mDisplayId,
Andrii Kulianf0379de2018-03-14 16:24:07 -07001742 overrideDisplayInfo);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001743
1744 mBaseDisplayRect.set(0, 0, dw, dh);
1745
1746 if (isDefaultDisplay) {
1747 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(mDisplayMetrics,
1748 mCompatDisplayMetrics);
1749 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001750
Andrii Kulian06d07d62017-03-14 11:11:47 -07001751 return mDisplayInfo;
1752 }
1753
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001754 WmDisplayCutout calculateDisplayCutoutForRotation(int rotation) {
Adrian Roos2aa0fcd2018-02-19 18:07:49 +01001755 return mDisplayCutoutCache.getOrCompute(mInitialDisplayCutout, rotation);
1756 }
1757
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001758 private WmDisplayCutout calculateDisplayCutoutForRotationUncached(
Adrian Roos2aa0fcd2018-02-19 18:07:49 +01001759 DisplayCutout cutout, int rotation) {
Adrian Roos24264212018-02-19 16:26:15 +01001760 if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) {
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001761 return WmDisplayCutout.NO_CUTOUT;
Adrian Roos1cf585052018-01-03 18:43:27 +01001762 }
shawnlin21e3f022020-01-21 16:36:13 +08001763 final Insets waterfallInsets =
1764 RotationUtils.rotateInsets(cutout.getWaterfallInsets(), rotation);
Adrian Roos11c25582018-02-19 18:06:36 +01001765 if (rotation == ROTATION_0) {
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01001766 return WmDisplayCutout.computeSafeInsets(
1767 cutout, mInitialDisplayWidth, mInitialDisplayHeight);
Adrian Roos24264212018-02-19 16:26:15 +01001768 }
Adrian Roosbed538e2018-02-21 17:50:07 +01001769 final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
Issei Suzuki43190bd2018-08-20 17:28:41 +02001770 final Rect[] newBounds = mRotationUtil.getRotatedBounds(
shawnlin21e3f022020-01-21 16:36:13 +08001771 cutout.getBoundingRectsAll(),
Issei Suzuki43190bd2018-08-20 17:28:41 +02001772 rotation, mInitialDisplayWidth, mInitialDisplayHeight);
shawnlin21e3f022020-01-21 16:36:13 +08001773 return WmDisplayCutout.computeSafeInsets(
1774 DisplayCutout.fromBoundsAndWaterfall(newBounds, waterfallInsets),
Adrian Roos24264212018-02-19 16:26:15 +01001775 rotated ? mInitialDisplayHeight : mInitialDisplayWidth,
1776 rotated ? mInitialDisplayWidth : mInitialDisplayHeight);
Adrian Roos1cf585052018-01-03 18:43:27 +01001777 }
1778
Andrii Kulian06d07d62017-03-14 11:11:47 -07001779 /**
Riddle Hsu6f548e92020-01-13 13:34:09 +08001780 * Compute display info and configuration according to the given rotation without changing
1781 * current display.
1782 */
1783 DisplayInfo computeScreenConfiguration(Configuration outConfig, int rotation) {
1784 final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
1785 final int dw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
1786 final int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
1787 outConfig.windowConfiguration.getBounds().set(0, 0, dw, dh);
1788
1789 final int uiMode = getConfiguration().uiMode;
1790 final DisplayCutout displayCutout =
1791 calculateDisplayCutoutForRotation(rotation).getDisplayCutout();
1792 computeScreenAppConfiguration(outConfig, dw, dh, rotation, uiMode, displayCutout);
1793
1794 final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
1795 displayInfo.rotation = rotation;
1796 displayInfo.logicalWidth = dw;
1797 displayInfo.logicalHeight = dh;
1798 final Rect appBounds = outConfig.windowConfiguration.getAppBounds();
1799 displayInfo.appWidth = appBounds.width();
1800 displayInfo.appHeight = appBounds.height();
1801 displayInfo.displayCutout = displayCutout.isEmpty() ? null : displayCutout;
1802 computeSizeRangesAndScreenLayout(displayInfo, rotated, uiMode, dw, dh,
1803 mDisplayMetrics.density, outConfig);
1804 return displayInfo;
1805 }
1806
1807 /** Compute configuration related to application without changing current display. */
1808 private void computeScreenAppConfiguration(Configuration outConfig, int dw, int dh,
1809 int rotation, int uiMode, DisplayCutout displayCutout) {
1810 final int appWidth = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
1811 displayCutout);
1812 final int appHeight = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
1813 displayCutout);
1814 mDisplayPolicy.getNonDecorInsetsLw(rotation, dw, dh, displayCutout, mTmpRect);
1815 final int leftInset = mTmpRect.left;
1816 final int topInset = mTmpRect.top;
1817 // AppBounds at the root level should mirror the app screen size.
1818 outConfig.windowConfiguration.setAppBounds(leftInset /* left */, topInset /* top */,
1819 leftInset + appWidth /* right */, topInset + appHeight /* bottom */);
1820 outConfig.windowConfiguration.setRotation(rotation);
1821 outConfig.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
1822
1823 final float density = mDisplayMetrics.density;
1824 outConfig.screenWidthDp = (int) (mDisplayPolicy.getConfigDisplayWidth(dw, dh, rotation,
1825 uiMode, displayCutout) / density);
1826 outConfig.screenHeightDp = (int) (mDisplayPolicy.getConfigDisplayHeight(dw, dh, rotation,
1827 uiMode, displayCutout) / density);
1828 outConfig.compatScreenWidthDp = (int) (outConfig.screenWidthDp / mCompatibleScreenScale);
1829 outConfig.compatScreenHeightDp = (int) (outConfig.screenHeightDp / mCompatibleScreenScale);
1830
1831 final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
1832 outConfig.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, uiMode, dw,
Mark Hong0db34112020-01-10 10:20:45 -08001833 dh);
Riddle Hsu6f548e92020-01-13 13:34:09 +08001834 }
1835
1836 /**
Andrii Kulian06d07d62017-03-14 11:11:47 -07001837 * Compute display configuration based on display properties and policy settings.
1838 * Do not call if mDisplayReady == false.
1839 */
1840 void computeScreenConfiguration(Configuration config) {
Tiger Huanga817b1f2019-05-09 20:04:17 +08001841 final DisplayInfo displayInfo = updateDisplayAndOrientation(config.uiMode, config);
Evan Roskye747c3e2018-10-30 20:06:41 -07001842 calculateBounds(displayInfo, mTmpBounds);
1843 config.windowConfiguration.setBounds(mTmpBounds);
Riddle Hsu6f548e92020-01-13 13:34:09 +08001844 config.windowConfiguration.setWindowingMode(getWindowingMode());
1845 config.windowConfiguration.setDisplayWindowingMode(getWindowingMode());
Andrii Kulian06d07d62017-03-14 11:11:47 -07001846
1847 final int dw = displayInfo.logicalWidth;
1848 final int dh = displayInfo.logicalHeight;
Riddle Hsu6f548e92020-01-13 13:34:09 +08001849 computeScreenAppConfiguration(config, dw, dh, displayInfo.rotation, config.uiMode,
1850 displayInfo.displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001851
Andrii Kulian06d07d62017-03-14 11:11:47 -07001852 config.screenLayout = (config.screenLayout & ~Configuration.SCREENLAYOUT_ROUND_MASK)
1853 | ((displayInfo.flags & Display.FLAG_ROUND) != 0
1854 ? Configuration.SCREENLAYOUT_ROUND_YES
1855 : Configuration.SCREENLAYOUT_ROUND_NO);
1856
Andrii Kulian06d07d62017-03-14 11:11:47 -07001857 config.densityDpi = displayInfo.logicalDensityDpi;
1858
1859 config.colorMode =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001860 ((displayInfo.isHdr() && mWmService.hasHdrSupport())
Andrii Kulian06d07d62017-03-14 11:11:47 -07001861 ? Configuration.COLOR_MODE_HDR_YES
1862 : Configuration.COLOR_MODE_HDR_NO)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001863 | (displayInfo.isWideColorGamut() && mWmService.hasWideColorGamutSupport()
Andrii Kulian06d07d62017-03-14 11:11:47 -07001864 ? Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_YES
1865 : Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_NO);
1866
1867 // Update the configuration based on available input devices, lid switch,
1868 // and platform configuration.
1869 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
1870 config.keyboard = Configuration.KEYBOARD_NOKEYS;
1871 config.navigation = Configuration.NAVIGATION_NONAV;
1872
1873 int keyboardPresence = 0;
1874 int navigationPresence = 0;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001875 final InputDevice[] devices = mWmService.mInputManager.getInputDevices();
Andrii Kulian06d07d62017-03-14 11:11:47 -07001876 final int len = devices != null ? devices.length : 0;
1877 for (int i = 0; i < len; i++) {
1878 InputDevice device = devices[i];
Arthur Hung82bbfc32018-11-29 20:24:51 +08001879 // Ignore virtual input device.
1880 if (device.isVirtual()) {
1881 continue;
1882 }
Andrii Kulian06d07d62017-03-14 11:11:47 -07001883
Arthur Hung82bbfc32018-11-29 20:24:51 +08001884 // Check if input device can dispatch events to current display.
1885 // If display type is virtual, will follow the default display.
1886 if (!mWmService.mInputManager.canDispatchToDisplay(device.getId(),
1887 displayInfo.type == Display.TYPE_VIRTUAL ? DEFAULT_DISPLAY : mDisplayId)) {
1888 continue;
1889 }
Andrii Kulian06d07d62017-03-14 11:11:47 -07001890
Arthur Hung82bbfc32018-11-29 20:24:51 +08001891 final int sources = device.getSources();
1892 final int presenceFlag = device.isExternal()
1893 ? WindowManagerPolicy.PRESENCE_EXTERNAL : WindowManagerPolicy.PRESENCE_INTERNAL;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001894
Arthur Hung82bbfc32018-11-29 20:24:51 +08001895 if (mWmService.mIsTouchDevice) {
1896 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) == InputDevice.SOURCE_TOUCHSCREEN) {
1897 config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001898 }
Arthur Hung82bbfc32018-11-29 20:24:51 +08001899 } else {
1900 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
1901 }
1902
1903 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
1904 config.navigation = Configuration.NAVIGATION_TRACKBALL;
1905 navigationPresence |= presenceFlag;
1906 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
1907 && config.navigation == Configuration.NAVIGATION_NONAV) {
1908 config.navigation = Configuration.NAVIGATION_DPAD;
1909 navigationPresence |= presenceFlag;
1910 }
1911
1912 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
1913 config.keyboard = Configuration.KEYBOARD_QWERTY;
1914 keyboardPresence |= presenceFlag;
Andrii Kulian06d07d62017-03-14 11:11:47 -07001915 }
1916 }
1917
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001918 if (config.navigation == Configuration.NAVIGATION_NONAV && mWmService.mHasPermanentDpad) {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001919 config.navigation = Configuration.NAVIGATION_DPAD;
1920 navigationPresence |= WindowManagerPolicy.PRESENCE_INTERNAL;
1921 }
1922
1923 // Determine whether a hard keyboard is available and enabled.
1924 // TODO(multi-display): Should the hardware keyboard be tied to a display or to a device?
1925 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001926 if (hardKeyboardAvailable != mWmService.mHardKeyboardAvailable) {
1927 mWmService.mHardKeyboardAvailable = hardKeyboardAvailable;
1928 mWmService.mH.removeMessages(REPORT_HARD_KEYBOARD_STATUS_CHANGE);
1929 mWmService.mH.sendEmptyMessage(REPORT_HARD_KEYBOARD_STATUS_CHANGE);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001930 }
1931
Winson Chung4723b4e2019-03-25 16:49:36 -07001932 mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors();
Tiger Huang7c610aa2018-10-27 00:01:01 +08001933
Andrii Kulian06d07d62017-03-14 11:11:47 -07001934 // Let the policy update hidden states.
1935 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
1936 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
1937 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001938 mWmService.mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001939 }
1940
Mark Hong0db34112020-01-10 10:20:45 -08001941 private int computeCompatSmallestWidth(boolean rotated, int uiMode, int dw, int dh) {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001942 mTmpDisplayMetrics.setTo(mDisplayMetrics);
1943 final DisplayMetrics tmpDm = mTmpDisplayMetrics;
1944 final int unrotDw, unrotDh;
1945 if (rotated) {
1946 unrotDw = dh;
1947 unrotDh = dw;
1948 } else {
1949 unrotDw = dw;
1950 unrotDh = dh;
1951 }
Mark Hong0db34112020-01-10 10:20:45 -08001952 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw,
1953 unrotDh);
1954 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh,
1955 unrotDw);
1956 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw,
1957 unrotDh);
1958 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh,
1959 unrotDw);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001960 return sw;
1961 }
1962
1963 private int reduceCompatConfigWidthSize(int curSize, int rotation, int uiMode,
Mark Hong0db34112020-01-10 10:20:45 -08001964 DisplayMetrics dm, int dw, int dh) {
1965 final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(
1966 rotation).getDisplayCutout();
Tiger Huang7c610aa2018-10-27 00:01:01 +08001967 dm.noncompatWidthPixels = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
1968 displayCutout);
1969 dm.noncompatHeightPixels = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
1970 displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07001971 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
1972 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
1973 if (curSize == 0 || size < curSize) {
1974 curSize = size;
1975 }
1976 return curSize;
1977 }
1978
Tiger Huang7c610aa2018-10-27 00:01:01 +08001979 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
1980 int uiMode, int dw, int dh, float density, Configuration outConfig) {
Andrii Kulian06d07d62017-03-14 11:11:47 -07001981
1982 // We need to determine the smallest width that will occur under normal
1983 // operation. To this, start with the base screen size and compute the
1984 // width under the different possible rotations. We need to un-rotate
1985 // the current screen dimensions before doing this.
1986 int unrotDw, unrotDh;
1987 if (rotated) {
1988 unrotDw = dh;
1989 unrotDh = dw;
1990 } else {
1991 unrotDw = dw;
1992 unrotDh = dh;
1993 }
1994 displayInfo.smallestNominalAppWidth = 1<<30;
1995 displayInfo.smallestNominalAppHeight = 1<<30;
1996 displayInfo.largestNominalAppWidth = 0;
1997 displayInfo.largestNominalAppHeight = 0;
Tiger Huang7c610aa2018-10-27 00:01:01 +08001998 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, uiMode, unrotDw, unrotDh);
1999 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, uiMode, unrotDh, unrotDw);
2000 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, uiMode, unrotDw, unrotDh);
2001 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, uiMode, unrotDh, unrotDw);
Tiger Huanga817b1f2019-05-09 20:04:17 +08002002
2003 if (outConfig == null) {
2004 return;
2005 }
Andrii Kulian06d07d62017-03-14 11:11:47 -07002006 int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
Mark Hong0db34112020-01-10 10:20:45 -08002007 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode);
2008 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode);
2009 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode);
2010 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode);
Andrii Kulian06d07d62017-03-14 11:11:47 -07002011 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
2012 outConfig.screenLayout = sl;
2013 }
2014
2015 private int reduceConfigLayout(int curLayout, int rotation, float density, int dw, int dh,
Mark Hong0db34112020-01-10 10:20:45 -08002016 int uiMode) {
2017 // Get the display cutout at this rotation.
2018 final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(
2019 rotation).getDisplayCutout();
2020
Andrii Kulian06d07d62017-03-14 11:11:47 -07002021 // Get the app screen size at this rotation.
Tiger Huang7c610aa2018-10-27 00:01:01 +08002022 int w = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayCutout);
2023 int h = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07002024
2025 // Compute the screen layout size class for this rotation.
2026 int longSize = w;
2027 int shortSize = h;
2028 if (longSize < shortSize) {
2029 int tmp = longSize;
2030 longSize = shortSize;
2031 shortSize = tmp;
2032 }
2033 longSize = (int)(longSize/density);
2034 shortSize = (int)(shortSize/density);
2035 return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
2036 }
2037
Tiger Huang7c610aa2018-10-27 00:01:01 +08002038 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation,
Andrii Kulian06d07d62017-03-14 11:11:47 -07002039 int uiMode, int dw, int dh) {
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01002040 final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(
2041 rotation).getDisplayCutout();
Tiger Huang7c610aa2018-10-27 00:01:01 +08002042 final int width = mDisplayPolicy.getConfigDisplayWidth(dw, dh, rotation, uiMode,
2043 displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07002044 if (width < displayInfo.smallestNominalAppWidth) {
2045 displayInfo.smallestNominalAppWidth = width;
2046 }
2047 if (width > displayInfo.largestNominalAppWidth) {
2048 displayInfo.largestNominalAppWidth = width;
2049 }
Tiger Huang7c610aa2018-10-27 00:01:01 +08002050 final int height = mDisplayPolicy.getConfigDisplayHeight(dw, dh, rotation, uiMode,
2051 displayCutout);
Andrii Kulian06d07d62017-03-14 11:11:47 -07002052 if (height < displayInfo.smallestNominalAppHeight) {
2053 displayInfo.smallestNominalAppHeight = height;
2054 }
2055 if (height > displayInfo.largestNominalAppHeight) {
2056 displayInfo.largestNominalAppHeight = height;
2057 }
2058 }
2059
Riddle Hsua4d6fa22018-08-11 00:50:39 +08002060 /**
2061 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
2062 * theme attribute) on devices that feature a physical options menu key attempt to position
2063 * their menu panel window along the edge of the screen nearest the physical menu key.
2064 * This lowers the travel distance between invoking the menu panel and selecting
2065 * a menu option.
2066 *
2067 * This method helps control where that menu is placed. Its current implementation makes
2068 * assumptions about the menu key and its relationship to the screen based on whether
2069 * the device's natural orientation is portrait (width < height) or landscape.
2070 *
2071 * The menu key is assumed to be located along the bottom edge of natural-portrait
2072 * devices and along the right edge of natural-landscape devices. If these assumptions
2073 * do not hold for the target device, this method should be changed to reflect that.
2074 *
2075 * @return A {@link Gravity} value for placing the options menu window.
2076 */
2077 int getPreferredOptionsPanelGravity() {
2078 final int rotation = getRotation();
2079 if (mInitialDisplayWidth < mInitialDisplayHeight) {
2080 // On devices with a natural orientation of portrait.
2081 switch (rotation) {
2082 default:
2083 case Surface.ROTATION_0:
2084 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
2085 case Surface.ROTATION_90:
2086 return Gravity.RIGHT | Gravity.BOTTOM;
2087 case Surface.ROTATION_180:
2088 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
2089 case Surface.ROTATION_270:
2090 return Gravity.START | Gravity.BOTTOM;
2091 }
2092 }
2093
2094 // On devices with a natural orientation of landscape.
2095 switch (rotation) {
2096 default:
2097 case Surface.ROTATION_0:
2098 return Gravity.RIGHT | Gravity.BOTTOM;
2099 case Surface.ROTATION_90:
2100 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
2101 case Surface.ROTATION_180:
2102 return Gravity.START | Gravity.BOTTOM;
2103 case Surface.ROTATION_270:
2104 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
2105 }
2106 }
2107
Jorim Jaggi61f39a72015-10-29 16:54:18 +01002108 DockedStackDividerController getDockedDividerController() {
2109 return mDividerControllerLocked;
2110 }
2111
Winson Chung655332c2016-10-31 13:14:28 -07002112 PinnedStackController getPinnedStackController() {
2113 return mPinnedStackControllerLocked;
2114 }
2115
Jeff Browna506a6e2013-06-04 00:02:38 -07002116 /**
2117 * Returns true if the specified UID has access to this display.
2118 */
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07002119 boolean hasAccess(int uid) {
Jeff Browna506a6e2013-06-04 00:02:38 -07002120 return mDisplay.hasAccess(uid);
2121 }
2122
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07002123 boolean isPrivate() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002124 return (mDisplay.getFlags() & FLAG_PRIVATE) != 0;
keunyounga446bf02013-06-21 19:07:57 -07002125 }
2126
Wale Ogunwaleb62139d2017-09-20 15:37:35 -07002127 /**
Wale Ogunwaleb62139d2017-09-20 15:37:35 -07002128 * Returns the topmost stack on the display that is compatible with the input windowing mode and
2129 * activity type. Null is no compatible stack on the display.
2130 */
Louis Changdc077272019-11-12 16:52:56 +08002131 ActivityStack getStack(int windowingMode, int activityType) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002132 for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2133 final ActivityStack stack = getTaskDisplayAreaAt(tdaNdx)
2134 .getStack(windowingMode, activityType);
2135 if (stack != null) {
2136 return stack;
2137 }
2138 }
2139 return null;
2140 }
2141
2142 protected int getTaskDisplayAreaCount() {
Andrii Kulian44b3c562020-04-01 12:49:56 -07002143 return mDisplayAreaPolicy.getTaskDisplayAreaCount();
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002144 }
2145
2146 protected TaskDisplayArea getTaskDisplayAreaAt(int index) {
Andrii Kulian44b3c562020-04-01 12:49:56 -07002147 return mDisplayAreaPolicy.getTaskDisplayAreaAt(index);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002148 }
2149
2150 ActivityStack getStack(int rootTaskId) {
2151 for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2152 final ActivityStack stack = getTaskDisplayAreaAt(tdaNdx).getStack(rootTaskId);
2153 if (stack != null) {
2154 return stack;
2155 }
2156 }
2157 return null;
Wale Ogunwaleb62139d2017-09-20 15:37:35 -07002158 }
2159
Louis Chang2453d062019-11-19 22:30:48 +08002160 protected int getStackCount() {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002161 int totalStackCount = 0;
2162 for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) {
2163 totalStackCount += getTaskDisplayAreaAt(i).getStackCount();
2164 }
2165 return totalStackCount;
Louis Chang2453d062019-11-19 22:30:48 +08002166 }
2167
Kazuki Takise148d00a2018-05-31 15:32:19 +09002168 @VisibleForTesting
Louis Changdc077272019-11-12 16:52:56 +08002169 ActivityStack getTopStack() {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002170 for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) {
2171 final ActivityStack stack = getTaskDisplayAreaAt(i).getTopStack();
2172 if (stack != null) {
2173 return stack;
2174 }
2175 }
2176 return null;
Bryce Lee48f4b572017-04-10 10:54:15 -07002177 }
2178
Riddle Hsu7f704b52019-12-10 23:10:45 +08002179 /**
2180 * The value is only valid in the scope {@link #onRequestedOverrideConfigurationChanged} of the
2181 * changing hierarchy and the {@link #onConfigurationChanged} of its children.
2182 *
2183 * @return The current changes ({@link android.content.pm.ActivityInfo.Config}) of requested
2184 * override configuration.
2185 */
2186 int getCurrentOverrideConfigurationChanges() {
2187 return mCurrentOverrideConfigurationChanges;
2188 }
2189
2190 @Override
Wale Ogunwale98d62312017-07-12 09:24:56 -07002191 public void onConfigurationChanged(Configuration newParentConfig) {
Louis Chang677921f2019-12-06 16:44:24 +08002192 // update resources before cascade so that docked/pinned stacks use the correct info
2193 preOnConfigurationChanged();
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -05002194 final int lastOrientation = getConfiguration().orientation;
Andrii Kulian441e4492016-09-29 15:25:00 -07002195 super.onConfigurationChanged(newParentConfig);
Tiger Huang7c610aa2018-10-27 00:01:01 +08002196 if (mDisplayPolicy != null) {
2197 mDisplayPolicy.onConfigurationChanged();
2198 }
Andrii Kulian441e4492016-09-29 15:25:00 -07002199
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -05002200 if (lastOrientation != getConfiguration().orientation) {
2201 getMetricsLogger().write(
2202 new LogMaker(MetricsEvent.ACTION_PHONE_ORIENTATION_CHANGED)
chaviw8065f442019-11-18 13:20:58 -08002203 .setSubtype(getConfiguration().orientation)
2204 .addTaggedData(MetricsEvent.FIELD_DISPLAY_ID, getDisplayId()));
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -05002205 }
2206
Winson Chungd1674cd2020-03-11 22:26:56 -07002207 if (mPinnedStackControllerLocked != null) {
Evan Roskye747c3e2018-10-30 20:06:41 -07002208 mPinnedStackControllerLocked.onDisplayInfoChanged(getDisplayInfo());
2209 }
Evan Roskye747c3e2018-10-30 20:06:41 -07002210 }
2211
2212 /**
2213 * Updates the resources used by docked/pinned controllers. This needs to be called at the
2214 * beginning of a configuration update cascade since the metrics from these resources are used
Louis Chang677921f2019-12-06 16:44:24 +08002215 * for bounds calculations.
Evan Roskye747c3e2018-10-30 20:06:41 -07002216 */
2217 void preOnConfigurationChanged() {
Bryce Leef3c6a472017-11-14 14:53:06 -08002218 final PinnedStackController pinnedStackController = getPinnedStackController();
2219
2220 if (pinnedStackController != null) {
2221 getPinnedStackController().onConfigurationChanged();
2222 }
Andrii Kulian441e4492016-09-29 15:25:00 -07002223 }
Andrii Kulian3a507b52016-09-19 18:14:12 -07002224
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07002225 @Override
2226 boolean fillsParent() {
2227 return true;
2228 }
2229
2230 @Override
2231 boolean isVisible() {
2232 return true;
2233 }
2234
2235 @Override
Wale Ogunwale9adfe572016-09-08 20:43:58 -07002236 void onAppTransitionDone() {
Wale Ogunwale10124582016-09-15 20:25:50 -07002237 super.onAppTransitionDone();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002238 mWmService.mWindowsChanged = true;
Wale Ogunwale9adfe572016-09-08 20:43:58 -07002239 }
2240
Yunfan Chen7daa6ac2018-11-29 18:16:44 -08002241 @Override
2242 public void setWindowingMode(int windowingMode) {
2243 super.setWindowingMode(windowingMode);
2244 super.setDisplayWindowingMode(windowingMode);
2245 }
2246
2247 @Override
2248 void setDisplayWindowingMode(int windowingMode) {
2249 setWindowingMode(windowingMode);
2250 }
2251
Wale Ogunwale3c1170d2016-12-02 14:44:52 -08002252 boolean forAllImeWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
Adrian Roosefa40702020-01-08 17:58:45 +01002253 return mImeWindowsContainers.forAllWindowForce(callback, traverseTopToBottom);
Wale Ogunwale3c1170d2016-12-02 14:44:52 -08002254 }
2255
Riddle Hsuccf09402019-08-13 00:33:06 +08002256 /**
2257 * In the general case, the orientation is computed from the above app windows first. If none of
2258 * the above app windows specify orientation, the orientation is computed from the child window
Riddle Hsu6f548e92020-01-13 13:34:09 +08002259 * container, e.g. {@link ActivityRecord#getOrientation(int)}.
Riddle Hsuccf09402019-08-13 00:33:06 +08002260 */
Vadim Caenfc14c662020-01-20 16:00:31 +01002261 @ScreenOrientation
Wale Ogunwale399c8692017-05-08 14:22:42 -07002262 @Override
2263 int getOrientation() {
Riddle Hsu6f548e92020-01-13 13:34:09 +08002264 mLastOrientationSource = null;
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07002265
Tiger Huang86e6d072019-05-02 20:23:47 +08002266 if (mIgnoreRotationForApps) {
2267 return SCREEN_ORIENTATION_USER;
2268 }
2269
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002270 if (mWmService.mDisplayFrozen) {
Riddle Hsu6f548e92020-01-13 13:34:09 +08002271 if (mWmService.mPolicy.isKeyguardLocked()) {
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07002272 // Use the last orientation the while the display is frozen with the keyguard
2273 // locked. This could be the keyguard forced orientation or from a SHOW_WHEN_LOCKED
2274 // window. We don't want to check the show when locked window directly though as
2275 // things aren't stable while the display is frozen, for example the window could be
2276 // momentarily unavailable due to activity relaunch.
Adrian Roosb125e0b2019-10-02 14:55:14 +02002277 ProtoLog.v(WM_DEBUG_ORIENTATION,
2278 "Display id=%d is frozen while keyguard locked, return %d",
chaviw8065f442019-11-18 13:20:58 -08002279 mDisplayId, getLastOrientation());
Riddle Hsuccf09402019-08-13 00:33:06 +08002280 return getLastOrientation();
Wale Ogunwale51362492016-09-08 17:49:17 -07002281 }
Adrian Roos0384f122020-01-10 19:39:43 +01002282 }
Riddle Hsu6f548e92020-01-13 13:34:09 +08002283 final int rootOrientation = mRootDisplayArea.getOrientation();
2284 mLastOrientationSource = mRootDisplayArea.getLastOrientationSource();
2285 return rootOrientation;
Wale Ogunwale51362492016-09-08 17:49:17 -07002286 }
2287
Craig Mautner46ac6fa2013-08-01 10:06:34 -07002288 void updateDisplayInfo() {
Andrii Kuliancd097992017-03-23 18:31:59 -07002289 // Check if display metrics changed and update base values if needed.
2290 updateBaseDisplayMetricsIfNeeded();
2291
Craig Mautner722285e2012-09-07 13:55:58 -07002292 mDisplay.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -07002293 mDisplay.getMetrics(mDisplayMetrics);
Andrii Kuliancd097992017-03-23 18:31:59 -07002294
Garfield Tan2f145f22018-11-01 15:27:03 -07002295 onDisplayChanged(this);
Craig Mautner722285e2012-09-07 13:55:58 -07002296 }
2297
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02002298 @Override
2299 void onDisplayChanged(DisplayContent dc) {
2300 super.onDisplayChanged(dc);
2301 updateSystemGestureExclusionLimit();
2302 }
2303
2304 void updateSystemGestureExclusionLimit() {
Adrian Roos1c2e9a12019-08-20 18:23:47 +02002305 mSystemGestureExclusionLimit = mWmService.mConstants.mSystemGestureExclusionLimitDp
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02002306 * mDisplayMetrics.densityDpi / DENSITY_DEFAULT;
2307 updateSystemGestureExclusion();
2308 }
2309
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -07002310 void initializeDisplayBaseInfo() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002311 final DisplayManagerInternal displayManagerInternal = mWmService.mDisplayManagerInternal;
Wale Ogunwaleb699ce02016-07-18 12:05:30 -07002312 if (displayManagerInternal != null) {
2313 // Bootstrap the default logical display from the display manager.
2314 final DisplayInfo newDisplayInfo = displayManagerInternal.getDisplayInfo(mDisplayId);
2315 if (newDisplayInfo != null) {
2316 mDisplayInfo.copyFrom(newDisplayInfo);
2317 }
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -07002318 }
Wale Ogunwaleb699ce02016-07-18 12:05:30 -07002319
Andrii Kuliancd097992017-03-23 18:31:59 -07002320 updateBaseDisplayMetrics(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight,
2321 mDisplayInfo.logicalDensityDpi);
2322 mInitialDisplayWidth = mDisplayInfo.logicalWidth;
2323 mInitialDisplayHeight = mDisplayInfo.logicalHeight;
2324 mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi;
Adrian Roos1cf585052018-01-03 18:43:27 +01002325 mInitialDisplayCutout = mDisplayInfo.displayCutout;
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -07002326 }
2327
Andrii Kuliancd097992017-03-23 18:31:59 -07002328 /**
2329 * If display metrics changed, overrides are not set and it's not just a rotation - update base
2330 * values.
2331 */
2332 private void updateBaseDisplayMetricsIfNeeded() {
2333 // Get real display metrics without overrides from WM.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002334 mWmService.mDisplayManagerInternal.getNonOverrideDisplayInfo(mDisplayId, mDisplayInfo);
Andrii Kuliancd097992017-03-23 18:31:59 -07002335 final int orientation = mDisplayInfo.rotation;
2336 final boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
2337 final int newWidth = rotated ? mDisplayInfo.logicalHeight : mDisplayInfo.logicalWidth;
2338 final int newHeight = rotated ? mDisplayInfo.logicalWidth : mDisplayInfo.logicalHeight;
2339 final int newDensity = mDisplayInfo.logicalDensityDpi;
Adrian Roos1cf585052018-01-03 18:43:27 +01002340 final DisplayCutout newCutout = mDisplayInfo.displayCutout;
Andrii Kuliancd097992017-03-23 18:31:59 -07002341
2342 final boolean displayMetricsChanged = mInitialDisplayWidth != newWidth
2343 || mInitialDisplayHeight != newHeight
Adrian Roos1cf585052018-01-03 18:43:27 +01002344 || mInitialDisplayDensity != mDisplayInfo.logicalDensityDpi
2345 || !Objects.equals(mInitialDisplayCutout, newCutout);
Andrii Kuliancd097992017-03-23 18:31:59 -07002346
2347 if (displayMetricsChanged) {
2348 // Check if display size or density is forced.
2349 final boolean isDisplaySizeForced = mBaseDisplayWidth != mInitialDisplayWidth
2350 || mBaseDisplayHeight != mInitialDisplayHeight;
2351 final boolean isDisplayDensityForced = mBaseDisplayDensity != mInitialDisplayDensity;
2352
2353 // If there is an override set for base values - use it, otherwise use new values.
2354 updateBaseDisplayMetrics(isDisplaySizeForced ? mBaseDisplayWidth : newWidth,
2355 isDisplaySizeForced ? mBaseDisplayHeight : newHeight,
2356 isDisplayDensityForced ? mBaseDisplayDensity : newDensity);
2357
2358 // Real display metrics changed, so we should also update initial values.
2359 mInitialDisplayWidth = newWidth;
2360 mInitialDisplayHeight = newHeight;
2361 mInitialDisplayDensity = newDensity;
Adrian Roos1cf585052018-01-03 18:43:27 +01002362 mInitialDisplayCutout = newCutout;
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07002363 reconfigureDisplayLocked();
Andrii Kuliancd097992017-03-23 18:31:59 -07002364 }
2365 }
2366
Bryce Lee27cec322017-03-21 09:41:37 -07002367 /** Sets the maximum width the screen resolution can be */
2368 void setMaxUiWidth(int width) {
2369 if (DEBUG_DISPLAY) {
2370 Slog.v(TAG_WM, "Setting max ui width:" + width + " on display:" + getDisplayId());
2371 }
2372
2373 mMaxUiWidth = width;
2374
2375 // Update existing metrics.
2376 updateBaseDisplayMetrics(mBaseDisplayWidth, mBaseDisplayHeight, mBaseDisplayDensity);
2377 }
2378
2379 /** Update base (override) display metrics. */
2380 void updateBaseDisplayMetrics(int baseWidth, int baseHeight, int baseDensity) {
2381 mBaseDisplayWidth = baseWidth;
2382 mBaseDisplayHeight = baseHeight;
2383 mBaseDisplayDensity = baseDensity;
2384
2385 if (mMaxUiWidth > 0 && mBaseDisplayWidth > mMaxUiWidth) {
2386 mBaseDisplayHeight = (mMaxUiWidth * mBaseDisplayHeight) / mBaseDisplayWidth;
2387 mBaseDisplayDensity = (mMaxUiWidth * mBaseDisplayDensity) / mBaseDisplayWidth;
2388 mBaseDisplayWidth = mMaxUiWidth;
2389
2390 if (DEBUG_DISPLAY) {
2391 Slog.v(TAG_WM, "Applying config restraints:" + mBaseDisplayWidth + "x"
2392 + mBaseDisplayHeight + " at density:" + mBaseDisplayDensity
2393 + " on display:" + getDisplayId());
2394 }
2395 }
2396
2397 mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
Bryce Leef3c6a472017-11-14 14:53:06 -08002398
2399 updateBounds();
Bryce Lee27cec322017-03-21 09:41:37 -07002400 }
2401
Riddle Hsuf53da812018-08-15 22:00:27 +08002402 /**
2403 * Forces this display to use the specified density.
2404 *
2405 * @param density The density in DPI to use. If the value equals to initial density, the setting
2406 * will be cleared.
2407 * @param userId The target user to apply. Only meaningful when this is default display. If the
2408 * user id is {@link UserHandle#USER_CURRENT}, it means to apply current settings
2409 * so only need to configure display.
2410 */
2411 void setForcedDensity(int density, int userId) {
Riddle Hsuf53da812018-08-15 22:00:27 +08002412 final boolean updateCurrent = userId == UserHandle.USER_CURRENT;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002413 if (mWmService.mCurrentUserId == userId || updateCurrent) {
Riddle Hsuf53da812018-08-15 22:00:27 +08002414 mBaseDisplayDensity = density;
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07002415 reconfigureDisplayLocked();
Riddle Hsuf53da812018-08-15 22:00:27 +08002416 }
2417 if (updateCurrent) {
2418 // We are applying existing settings so no need to save it again.
2419 return;
2420 }
2421
2422 if (density == mInitialDisplayDensity) {
2423 density = 0;
2424 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002425 mWmService.mDisplayWindowSettings.setForcedDensity(this, density, userId);
Riddle Hsuf53da812018-08-15 22:00:27 +08002426 }
2427
2428 /** @param mode {@link #FORCE_SCALING_MODE_AUTO} or {@link #FORCE_SCALING_MODE_DISABLED}. */
2429 void setForcedScalingMode(@ForceScalingMode int mode) {
2430 if (mode != FORCE_SCALING_MODE_DISABLED) {
2431 mode = FORCE_SCALING_MODE_AUTO;
2432 }
2433
2434 mDisplayScalingDisabled = (mode != FORCE_SCALING_MODE_AUTO);
2435 Slog.i(TAG_WM, "Using display scaling mode: " + (mDisplayScalingDisabled ? "off" : "auto"));
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07002436 reconfigureDisplayLocked();
Riddle Hsuf53da812018-08-15 22:00:27 +08002437
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002438 mWmService.mDisplayWindowSettings.setForcedScalingMode(this, mode);
Riddle Hsuf53da812018-08-15 22:00:27 +08002439 }
2440
2441 /** If the given width and height equal to initial size, the setting will be cleared. */
2442 void setForcedSize(int width, int height) {
2443 final boolean clear = mInitialDisplayWidth == width && mInitialDisplayHeight == height;
2444 if (!clear) {
2445 // Set some sort of reasonable bounds on the size of the display that we will try
2446 // to emulate.
2447 final int minSize = 200;
2448 final int maxScale = 2;
2449 width = Math.min(Math.max(width, minSize), mInitialDisplayWidth * maxScale);
2450 height = Math.min(Math.max(height, minSize), mInitialDisplayHeight * maxScale);
2451 }
2452
2453 Slog.i(TAG_WM, "Using new display size: " + width + "x" + height);
2454 updateBaseDisplayMetrics(width, height, mBaseDisplayDensity);
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07002455 reconfigureDisplayLocked();
Riddle Hsuf53da812018-08-15 22:00:27 +08002456
2457 if (clear) {
2458 width = height = 0;
2459 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002460 mWmService.mDisplayWindowSettings.setForcedSize(this, width, height);
Riddle Hsuf53da812018-08-15 22:00:27 +08002461 }
2462
Wale Ogunwaledb506192017-12-08 10:57:32 -08002463 void getStableRect(Rect out) {
2464 out.set(mDisplayFrames.mStable);
Chong Zhangf66db432016-01-13 10:39:51 -08002465 }
2466
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002467 /**
2468 * Get the default display area on the display dedicated to app windows. This one should be used
2469 * only as a fallback location for activity launches when no target display area is specified,
2470 * or for cases when multi-instance is not supported yet (like Split-screen, PiP or Recents).
2471 */
2472 TaskDisplayArea getDefaultTaskDisplayArea() {
Andrii Kulian44b3c562020-04-01 12:49:56 -07002473 return mDisplayAreaPolicy.getTaskDisplayAreaAt(0);
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07002474 }
Andrii Kulian839def92016-11-02 10:58:58 -07002475
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002476 @Override
2477 protected void addChild(DisplayChildWindowContainer child,
2478 Comparator<DisplayChildWindowContainer> comparator) {
2479 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
2480 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -07002481
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002482 @Override
2483 protected void addChild(DisplayChildWindowContainer child, int index) {
2484 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
2485 }
2486
2487 @Override
2488 protected void removeChild(DisplayChildWindowContainer child) {
Wale Ogunwale601a3f02016-10-17 08:39:39 -07002489 // Only allow removal of direct children from this display if the display is in the process
2490 // of been removed.
2491 if (mRemovingDisplay) {
2492 super.removeChild(child);
2493 return;
2494 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002495 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
Craig Mautnerbdc748af2013-12-02 14:08:25 -08002496 }
2497
Adrian Roosefa40702020-01-08 17:58:45 +01002498 void positionDisplayAt(int position, boolean includingParents) {
2499 getParent().positionChildAt(position, this, includingParents);
2500 }
2501
Andrii Kuliand2765632016-12-12 22:26:34 -08002502 @Override
2503 void positionChildAt(int position, DisplayChildWindowContainer child, boolean includingParents) {
2504 // Children of the display are statically ordered, so the real intention here is to perform
2505 // the operation on the display and not the static direct children.
Adrian Roosefa40702020-01-08 17:58:45 +01002506 positionDisplayAt(position, includingParents);
Andrii Kuliand2765632016-12-12 22:26:34 -08002507 }
2508
Garfield Tan4f71c5a2018-10-10 10:12:02 -07002509 /**
Winson Chungc5fe7ff2019-02-19 14:49:25 -08002510 * Returns true if the input point is within an app window.
2511 */
2512 boolean pointWithinAppWindow(int x, int y) {
2513 final int[] targetWindowType = {-1};
Wale Ogunwalef5f3f1b2019-11-12 09:47:30 -08002514 final PooledConsumer fn = PooledLambda.obtainConsumer((w, nonArg) -> {
Winson Chungc5fe7ff2019-02-19 14:49:25 -08002515 if (targetWindowType[0] != -1) {
2516 return;
2517 }
2518
2519 if (w.isOnScreen() && w.isVisibleLw() && w.getFrameLw().contains(x, y)) {
2520 targetWindowType[0] = w.mAttrs.type;
2521 return;
2522 }
2523 }, PooledLambda.__(WindowState.class), mTmpRect);
2524 forAllWindows(fn, true /* traverseTopToBottom */);
Wale Ogunwalef5f3f1b2019-11-12 09:47:30 -08002525 fn.recycle();
Winson Chungc5fe7ff2019-02-19 14:49:25 -08002526 return FIRST_APPLICATION_WINDOW <= targetWindowType[0]
chaviw8065f442019-11-18 13:20:58 -08002527 && targetWindowType[0] <= LAST_APPLICATION_WINDOW;
Winson Chungc5fe7ff2019-02-19 14:49:25 -08002528 }
2529
2530 /**
Chong Zhangd8ceb852015-11-11 14:53:41 -08002531 * Find the task whose outside touch area (for resizing) (x, y) falls within.
Chong Zhang9184ec62015-09-24 12:32:21 -07002532 * Returns null if the touch doesn't fall into a resizing area.
Chong Zhang8e89b312015-09-09 15:09:30 -07002533 */
Wale Ogunwale15ead902016-09-02 14:30:11 -07002534 Task findTaskForResizePoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002535 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002536 return mTmpTaskForResizePointSearchResult.process(getDefaultTaskDisplayArea(), x, y, delta);
Chong Zhang8e89b312015-09-09 15:09:30 -07002537 }
2538
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002539 void updateTouchExcludeRegion() {
2540 final Task focusedTask = (mFocusedApp != null ? mFocusedApp.getTask() : null);
David Stevensee9e2772017-02-09 16:30:27 -08002541 if (focusedTask == null) {
2542 mTouchExcludeRegion.setEmpty();
2543 } else {
2544 mTouchExcludeRegion.set(mBaseDisplayRect);
2545 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002546 mTmpRect.setEmpty();
David Stevensee9e2772017-02-09 16:30:27 -08002547 mTmpRect2.setEmpty();
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002548
2549 final PooledConsumer c = PooledLambda.obtainConsumer(
2550 DisplayContent::processTaskForTouchExcludeRegion, this,
2551 PooledLambda.__(Task.class), focusedTask, delta);
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002552 forAllTasks(c);
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002553 c.recycle();
2554
David Stevensee9e2772017-02-09 16:30:27 -08002555 // If we removed the focused task above, add it back and only leave its
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002556 // outside touch area in the exclusion. TapDetector is not interested in
David Stevensee9e2772017-02-09 16:30:27 -08002557 // any touch inside the focused task itself.
2558 if (!mTmpRect2.isEmpty()) {
2559 mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION);
2560 }
Chong Zhangd8ceb852015-11-11 14:53:41 -08002561 }
lumark90120a82018-08-15 00:33:03 +08002562 if (mInputMethodWindow != null && mInputMethodWindow.isVisibleLw()) {
Filip Gruszczynski912d9192015-12-01 16:14:04 -08002563 // If the input method is visible and the user is typing, we don't want these touch
2564 // events to be intercepted and used to change focus. This would likely cause a
2565 // disappearance of the input method.
lumark90120a82018-08-15 00:33:03 +08002566 mInputMethodWindow.getTouchableRegion(mTmpRegion);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002567 mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
Filip Gruszczynski912d9192015-12-01 16:14:04 -08002568 }
Filip Gruszczynskiecf67222015-12-11 15:16:36 -08002569 for (int i = mTapExcludedWindows.size() - 1; i >= 0; i--) {
Andrii Kulian4b6599e2018-01-15 17:24:08 -08002570 final WindowState win = mTapExcludedWindows.get(i);
arthurhunga28da952020-04-29 17:45:53 +08002571 if (!win.isVisibleLw()) {
2572 continue;
2573 }
Filip Gruszczynskiecf67222015-12-11 15:16:36 -08002574 win.getTouchableRegion(mTmpRegion);
2575 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
2576 }
Tiger Huang04dc4cc2019-01-17 18:41:41 +08002577 amendWindowTapExcludeRegion(mTouchExcludeRegion);
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002578 // TODO(multi-display): Support docked stacks on secondary displays & task containers.
2579 if (mDisplayId == DEFAULT_DISPLAY
2580 && getDefaultTaskDisplayArea().isSplitScreenModeActivated()) {
Jorim Jaggid47e7e12016-03-01 09:57:38 +01002581 mDividerControllerLocked.getTouchRegion(mTmpRect);
Jorim Jaggi7f19cb82016-03-25 19:37:44 -07002582 mTmpRegion.set(mTmpRect);
Jorim Jaggid47e7e12016-03-01 09:57:38 +01002583 mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
2584 }
Riddle Hsu2588ab02019-02-25 14:23:56 +08002585 mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
Craig Mautner6601b7b2013-04-29 10:29:11 -07002586 }
2587
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002588 private void processTaskForTouchExcludeRegion(Task task, Task focusedTask, int delta) {
2589 final ActivityRecord topVisibleActivity = task.getTopVisibleActivity();
2590
2591 if (topVisibleActivity == null || !topVisibleActivity.hasContentToDisplay()) {
2592 return;
2593 }
2594
2595 // Exclusion region is the region that TapDetector doesn't care about.
2596 // Here we want to remove all non-focused tasks from the exclusion region.
2597 // We also remove the outside touch area for resizing for all freeform
2598 // tasks (including the focused).
2599 // We save the focused task region once we find it, and add it back at the end.
Evan Rosky73a7fe92019-11-18 18:28:01 -08002600 // If the task is home stack and it is resizable and visible (top of its root task), we want
2601 // to exclude the docked stack from touch so we need the entire screen area and not just a
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002602 // small portion which the home stack currently is resized to.
Louis Changa009c762020-02-26 11:21:31 +08002603 if (task.isActivityTypeHome() && task.isVisible() && task.isResizeable()) {
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002604 mDisplayContent.getBounds(mTmpRect);
2605 } else {
2606 task.getDimBounds(mTmpRect);
2607 }
2608
2609 if (task == focusedTask) {
2610 // Add the focused task rect back into the exclude region once we are done
2611 // processing stacks.
Evan Rosky73a7fe92019-11-18 18:28:01 -08002612 // NOTE: this *looks* like a no-op, but this usage of mTmpRect2 is expected by
2613 // updateTouchExcludeRegion.
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002614 mTmpRect2.set(mTmpRect);
2615 }
2616
2617 final boolean isFreeformed = task.inFreeformWindowingMode();
2618 if (task != focusedTask || isFreeformed) {
2619 if (isFreeformed) {
2620 // If the task is freeformed, enlarge the area to account for outside
2621 // touch area for resize.
2622 mTmpRect.inset(-delta, -delta);
2623 // Intersect with display content rect. If we have system decor (status bar/
2624 // navigation bar), we want to exclude that from the tap detection.
2625 // Otherwise, if the app is partially placed under some system button (eg.
2626 // Recents, Home), pressing that button would cause a full series of
2627 // unwanted transfer focus/resume/pause, before we could go home.
2628 mTmpRect.intersect(mDisplayFrames.mContent);
2629 }
2630 mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
2631 }
2632 }
2633
Tiger Huang04dc4cc2019-01-17 18:41:41 +08002634 /**
2635 * Union the region with all the tap exclude region provided by windows on this display.
2636 *
2637 * @param inOutRegion The region to be amended.
2638 */
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09002639 private void amendWindowTapExcludeRegion(Region inOutRegion) {
chaviwaa0d74e2019-12-26 14:13:40 -08002640 final Region region = Region.obtain();
Tiger Huang04dc4cc2019-01-17 18:41:41 +08002641 for (int i = mTapExcludeProvidingWindows.size() - 1; i >= 0; i--) {
2642 final WindowState win = mTapExcludeProvidingWindows.valueAt(i);
chaviwaa0d74e2019-12-26 14:13:40 -08002643 win.getTapExcludeRegion(region);
2644 inOutRegion.op(region, Op.UNION);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08002645 }
chaviwaa0d74e2019-12-26 14:13:40 -08002646 region.recycle();
Tiger Huang04dc4cc2019-01-17 18:41:41 +08002647 }
2648
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002649 @Override
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07002650 void switchUser(int userId) {
2651 super.switchUser(userId);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002652 mWmService.mWindowsChanged = true;
Winson Chungda20fec2019-04-10 12:19:59 -07002653 mDisplayPolicy.switchUser();
Craig Mautner858d8a62013-04-23 17:08:34 -07002654 }
2655
Wale Ogunwale10124582016-09-15 20:25:50 -07002656 @Override
2657 void removeIfPossible() {
lumark9bca6b42019-10-17 18:35:22 +08002658 if (isAnimating(TRANSITION | PARENTS)) {
Wale Ogunwale10124582016-09-15 20:25:50 -07002659 mDeferredRemoval = true;
2660 return;
Craig Mautner2eb15342013-08-07 13:13:35 -07002661 }
Wale Ogunwale10124582016-09-15 20:25:50 -07002662 removeImmediately();
Craig Mautner2eb15342013-08-07 13:13:35 -07002663 }
2664
Wale Ogunwale10124582016-09-15 20:25:50 -07002665 @Override
2666 void removeImmediately() {
Wale Ogunwale601a3f02016-10-17 08:39:39 -07002667 mRemovingDisplay = true;
2668 try {
Jackal Guoc43a0a62019-04-23 09:15:14 +08002669 if (mParentWindow != null) {
2670 mParentWindow.removeEmbeddedDisplayContent(this);
2671 }
lumark588a3e82018-07-20 18:53:54 +08002672 // Clear all transitions & screen frozen states when removing display.
2673 mOpeningApps.clear();
2674 mClosingApps.clear();
Evan Rosky55bddd82020-01-29 13:07:18 -08002675 mChangingContainers.clear();
lumark588a3e82018-07-20 18:53:54 +08002676 mUnknownAppVisibilityController.clear();
2677 mAppTransition.removeAppTransitionTimeoutCallbacks();
2678 handleAnimatingStoppedAndTransition();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002679 mWmService.stopFreezingDisplayLocked();
Wale Ogunwale601a3f02016-10-17 08:39:39 -07002680 super.removeImmediately();
2681 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
Riddle Hsu2588ab02019-02-25 14:23:56 +08002682 mPointerEventDispatcher.dispose();
Vadim Caenb3715832019-08-13 17:06:38 +02002683 setRotationAnimation(null);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002684 mWmService.mAnimator.removeDisplayLocked(mDisplayId);
Jorim Jaggiae962e62018-12-27 17:23:48 +01002685 mInputMonitor.onDisplayRemoved();
Louis Chang677921f2019-12-06 16:44:24 +08002686 mWmService.mDisplayNotificationController.dispatchDisplayRemoved(this);
Wale Ogunwale601a3f02016-10-17 08:39:39 -07002687 } finally {
Riddle Hsu4e611772018-10-31 18:58:28 +08002688 mDisplayReady = false;
Wale Ogunwale601a3f02016-10-17 08:39:39 -07002689 mRemovingDisplay = false;
Craig Mautner95da1082014-02-24 17:54:35 -08002690 }
Robert Carr679ccb02018-08-08 15:32:35 -07002691
chaviwb9c44aa2020-02-19 16:00:08 -08002692 // Apply the pending transaction here since we may not be able to reach the DisplayContent
2693 // on the next traversal if it's removed from RootWindowContainer child list.
2694 getPendingTransaction().apply();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002695 mWmService.mWindowPlacerLocked.requestTraversal();
Craig Mautner95da1082014-02-24 17:54:35 -08002696 }
2697
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002698 /** Returns true if a removal action is still being deferred. */
Wale Ogunwale10124582016-09-15 20:25:50 -07002699 @Override
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002700 boolean checkCompleteDeferredRemoval() {
Riddle Hsu793442c52019-11-05 01:04:55 +08002701 boolean stillDeferringRemoval = false;
2702
2703 for (int i = getChildCount() - 1; i >= 0; --i) {
2704 final DisplayChildWindowContainer child = getChildAt(i);
2705 stillDeferringRemoval |= child.checkCompleteDeferredRemoval();
2706 if (getChildCount() == 0) {
2707 // If this display is pending to be removed because it contains an activity with
2708 // {@link ActivityRecord#mIsExiting} is true, this display may be removed when
2709 // completing the removal of the last activity from
2710 // {@link ActivityRecord#checkCompleteDeferredRemoval}.
2711 return false;
2712 }
2713 }
Wale Ogunwale10124582016-09-15 20:25:50 -07002714
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002715 if (!stillDeferringRemoval && mDeferredRemoval) {
Wale Ogunwale10124582016-09-15 20:25:50 -07002716 removeImmediately();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002717 return false;
Craig Mautner95da1082014-02-24 17:54:35 -08002718 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002719 return true;
Craig Mautner95da1082014-02-24 17:54:35 -08002720 }
2721
Andrii Kulian0214ed92017-05-16 13:44:05 -07002722 /** @return 'true' if removal of this display content is deferred due to active animation. */
2723 boolean isRemovalDeferred() {
2724 return mDeferredRemoval;
2725 }
2726
Wale Ogunwale10124582016-09-15 20:25:50 -07002727 void adjustForImeIfNeeded() {
lumark90120a82018-08-15 00:33:03 +08002728 final WindowState imeWin = mInputMethodWindow;
Evan Roskyaf9f27c2020-02-18 18:58:35 +00002729 final boolean imeVisible = imeWin != null && imeWin.isVisibleLw()
2730 && imeWin.isDisplayedLw();
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00002731 final int imeHeight = mDisplayFrames.getInputMethodWindowVisibleHeight();
Winson Chung655332c2016-10-31 13:14:28 -07002732 mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);
Wale Ogunwale10124582016-09-15 20:25:50 -07002733 }
2734
2735 void prepareFreezingTaskBounds() {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002736 for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2737 getTaskDisplayAreaAt(tdaNdx).prepareFreezingTaskBounds();
Wale Ogunwale10124582016-09-15 20:25:50 -07002738 }
2739 }
2740
Wale Ogunwale94744212015-09-21 19:01:47 -07002741 void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
Bryce Leef3c6a472017-11-14 14:53:06 -08002742 getBounds(mTmpRect, newRotation);
Evan Rosky39b6f232018-10-30 18:35:41 -07002743 rotateBounds(mTmpRect, oldRotation, newRotation, bounds);
2744 }
Andrii Kulian4dfb9c42016-10-11 20:06:27 -07002745
Evan Rosky39b6f232018-10-30 18:35:41 -07002746 void rotateBounds(Rect parentBounds, int oldRotation, int newRotation, Rect bounds) {
Andrii Kulian4dfb9c42016-10-11 20:06:27 -07002747 // Compute a transform matrix to undo the coordinate space transformation,
2748 // and present the window at the same physical position it previously occupied.
2749 final int deltaRotation = deltaRotation(newRotation, oldRotation);
Evan Rosky39b6f232018-10-30 18:35:41 -07002750 createRotationMatrix(
2751 deltaRotation, parentBounds.width(), parentBounds.height(), mTmpMatrix);
Andrii Kulian4dfb9c42016-10-11 20:06:27 -07002752
2753 mTmpRectF.set(bounds);
2754 mTmpMatrix.mapRect(mTmpRectF);
2755 mTmpRectF.round(bounds);
Wale Ogunwale94744212015-09-21 19:01:47 -07002756 }
2757
Wale Ogunwale4a02d812015-02-12 23:01:38 -08002758 static int deltaRotation(int oldRotation, int newRotation) {
2759 int delta = newRotation - oldRotation;
2760 if (delta < 0) delta += 4;
2761 return delta;
2762 }
2763
Vadim Caenb3715832019-08-13 17:06:38 +02002764 public void setRotationAnimation(ScreenRotationAnimation screenRotationAnimation) {
2765 if (mScreenRotationAnimation != null) {
2766 mScreenRotationAnimation.kill();
2767 }
2768 mScreenRotationAnimation = screenRotationAnimation;
2769 }
2770
2771 public ScreenRotationAnimation getRotationAnimation() {
2772 return mScreenRotationAnimation;
2773 }
2774
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002775 private static void createRotationMatrix(int rotation, float displayWidth, float displayHeight,
Andrii Kulian4dfb9c42016-10-11 20:06:27 -07002776 Matrix outMatrix) {
2777 // For rotations without Z-ordering we don't need the target rectangle's position.
2778 createRotationMatrix(rotation, 0 /* rectLeft */, 0 /* rectTop */, displayWidth,
2779 displayHeight, outMatrix);
2780 }
2781
2782 static void createRotationMatrix(int rotation, float rectLeft, float rectTop,
2783 float displayWidth, float displayHeight, Matrix outMatrix) {
2784 switch (rotation) {
2785 case ROTATION_0:
2786 outMatrix.reset();
2787 break;
2788 case ROTATION_270:
2789 outMatrix.setRotate(270, 0, 0);
2790 outMatrix.postTranslate(0, displayHeight);
2791 outMatrix.postTranslate(rectTop, 0);
2792 break;
2793 case ROTATION_180:
2794 outMatrix.reset();
2795 break;
2796 case ROTATION_90:
2797 outMatrix.setRotate(90, 0, 0);
2798 outMatrix.postTranslate(displayWidth, 0);
2799 outMatrix.postTranslate(-rectTop, rectLeft);
2800 break;
2801 }
2802 }
2803
Louis Chang677921f2019-12-06 16:44:24 +08002804 public void dumpDebug(ProtoOutputStream proto, long fieldId,
2805 @WindowTraceLogLevel int logLevel) {
Nataniel Borges023ecb52019-01-16 14:15:43 -08002806 // Critical log level logs only visible elements to mitigate performance overheard
2807 if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
2808 return;
2809 }
2810
Steven Timotiusaf03df62017-07-18 16:56:43 -07002811 final long token = proto.start(fieldId);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002812 super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
Wale Ogunwalef342f062020-01-27 07:34:13 -08002813
Steven Timotiusaf03df62017-07-18 16:56:43 -07002814 proto.write(ID, mDisplayId);
Adrian Roos22a20a82019-10-23 19:05:33 +02002815 mRootDisplayArea.dumpDebug(proto, ROOT_DISPLAY_AREA, logLevel);
chaviw8065f442019-11-18 13:20:58 -08002816 for (int i = mOverlayContainers.getChildCount() - 1; i >= 0; --i) {
2817 final WindowToken windowToken = mOverlayContainers.getChildAt(i);
2818 windowToken.dumpDebug(proto, OVERLAY_WINDOWS, logLevel);
2819 }
Steven Timotiusaf03df62017-07-18 16:56:43 -07002820 proto.write(DPI, mBaseDisplayDensity);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002821 mDisplayInfo.dumpDebug(proto, DISPLAY_INFO);
Riddle Hsuccf09402019-08-13 00:33:06 +08002822 proto.write(ROTATION, getRotation());
Vadim Caenb3715832019-08-13 17:06:38 +02002823 final ScreenRotationAnimation screenRotationAnimation = getRotationAnimation();
Steven Timotiusf2d68892017-08-28 17:00:01 -07002824 if (screenRotationAnimation != null) {
Jeffrey Huangcb782852019-12-05 11:28:11 -08002825 screenRotationAnimation.dumpDebug(proto, SCREEN_ROTATION_ANIMATION);
Steven Timotiusf2d68892017-08-28 17:00:01 -07002826 }
Jeffrey Huangcb782852019-12-05 11:28:11 -08002827 mDisplayFrames.dumpDebug(proto, DISPLAY_FRAMES);
2828 mAppTransition.dumpDebug(proto, APP_TRANSITION);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002829 if (mFocusedApp != null) {
2830 mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
2831 }
Jorim Jaggi1112fed2019-04-15 13:32:14 +02002832 for (int i = mOpeningApps.size() - 1; i >= 0; i--) {
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08002833 mOpeningApps.valueAt(i).writeIdentifierToProto(proto, OPENING_APPS);
Jorim Jaggi1112fed2019-04-15 13:32:14 +02002834 }
2835 for (int i = mClosingApps.size() - 1; i >= 0; i--) {
Wale Ogunwaleda8b8272018-11-29 19:37:37 -08002836 mClosingApps.valueAt(i).writeIdentifierToProto(proto, CLOSING_APPS);
Jorim Jaggi1112fed2019-04-15 13:32:14 +02002837 }
Wale Ogunwalef342f062020-01-27 07:34:13 -08002838
2839 proto.write(SINGLE_TASK_INSTANCE, mSingleTaskInstance);
2840 final ActivityStack focusedStack = getFocusedStack();
2841 if (focusedStack != null) {
2842 proto.write(FOCUSED_ROOT_TASK_ID, focusedStack.getRootTaskId());
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002843 final ActivityRecord focusedActivity = focusedStack.getDisplayArea()
2844 .getFocusedActivity();
Wale Ogunwalef342f062020-01-27 07:34:13 -08002845 if (focusedActivity != null) {
2846 focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
2847 }
2848 } else {
2849 proto.write(FOCUSED_ROOT_TASK_ID, INVALID_TASK_ID);
2850 }
Vishnu Nairdddc9f52020-03-09 09:37:27 -07002851 proto.write(DISPLAY_READY, isReady());
Wale Ogunwalef342f062020-01-27 07:34:13 -08002852
Steven Timotiusaf03df62017-07-18 16:56:43 -07002853 proto.end(token);
2854 }
2855
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002856 @Override
Vishnu Nairdddc9f52020-03-09 09:37:27 -07002857 long getProtoFieldId() {
2858 return DISPLAY_CONTENT;
2859 }
2860
2861 @Override
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002862 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
2863 super.dump(pw, prefix, dumpAll);
Louis Chang677921f2019-12-06 16:44:24 +08002864 pw.print(prefix);
2865 pw.println("Display: mDisplayId=" + mDisplayId + " stacks=" + getStackCount() + (
2866 mSingleTaskInstance ? " mSingleTaskInstance" : ""));
Craig Mautnera91f9e22012-09-14 16:22:08 -07002867 final String subPrefix = " " + prefix;
2868 pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x");
chaviw8065f442019-11-18 13:20:58 -08002869 pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
2870 pw.print("dpi");
2871 if (mInitialDisplayWidth != mBaseDisplayWidth
2872 || mInitialDisplayHeight != mBaseDisplayHeight
2873 || mInitialDisplayDensity != mBaseDisplayDensity) {
2874 pw.print(" base=");
2875 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
2876 pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
2877 }
2878 if (mDisplayScalingDisabled) {
2879 pw.println(" noscale");
2880 }
2881 pw.print(" cur=");
2882 pw.print(mDisplayInfo.logicalWidth);
2883 pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
2884 pw.print(" app=");
2885 pw.print(mDisplayInfo.appWidth);
2886 pw.print("x"); pw.print(mDisplayInfo.appHeight);
2887 pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
2888 pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
2889 pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
2890 pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
2891 pw.print(subPrefix + "deferred=" + mDeferredRemoval
2892 + " mLayoutNeeded=" + mLayoutNeeded);
2893 pw.println(" mTouchExcludeRegion=" + mTouchExcludeRegion);
Wale Ogunwaleb429e682016-01-06 12:36:34 -08002894
Craig Mautnerdc548482014-02-05 13:35:24 -08002895 pw.println();
Adrian Roos5251b1d2018-03-23 18:57:43 +01002896 pw.print(prefix); pw.print("mLayoutSeq="); pw.println(mLayoutSeq);
2897
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002898 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
2899 if (mLastFocus != mCurrentFocus) {
2900 pw.print(" mLastFocus="); pw.println(mLastFocus);
2901 }
2902 if (mLosingFocus.size() > 0) {
2903 pw.println();
2904 pw.println(" Windows losing focus:");
2905 for (int i = mLosingFocus.size() - 1; i >= 0; i--) {
2906 final WindowState w = mLosingFocus.get(i);
2907 pw.print(" Losing #"); pw.print(i); pw.print(' ');
2908 pw.print(w);
2909 if (dumpAll) {
2910 pw.println(":");
2911 w.dump(pw, " ", true);
2912 } else {
2913 pw.println();
2914 }
2915 }
2916 }
2917 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
Tiger Huang7c610aa2018-10-27 00:01:01 +08002918 if (mLastStatusBarVisibility != 0) {
2919 pw.print(" mLastStatusBarVisibility=0x");
2920 pw.println(Integer.toHexString(mLastStatusBarVisibility));
2921 }
Riddle Hsub40f9662020-04-25 01:58:23 +08002922 if (mFixedRotationLaunchingApp != null) {
2923 pw.println(" mFixedRotationLaunchingApp=" + mFixedRotationLaunchingApp);
2924 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +08002925
Adrian Roos5251b1d2018-03-23 18:57:43 +01002926 pw.println();
wilsonshihc32538e2018-11-07 17:27:34 +08002927 mWallpaperController.dump(pw, " ");
2928
2929 pw.println();
Adrian Roos4ffc8972019-02-07 20:45:11 +01002930 pw.print("mSystemGestureExclusion=");
2931 if (mSystemGestureExclusionListeners.getRegisteredCallbackCount() > 0) {
2932 pw.println(mSystemGestureExclusion);
2933 } else {
2934 pw.println("<no lstnrs>");
2935 }
2936
2937 pw.println();
Andrii Kulianf9df4a82020-03-31 12:09:27 -07002938 pw.println(prefix + "Task display areas in top down Z order:");
2939 for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
2940 getTaskDisplayAreaAt(tdaNdx).dump(pw, prefix + " ", dumpAll);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002941 }
Wale Ogunwaleb429e682016-01-06 12:36:34 -08002942
Craig Mautnerdc548482014-02-05 13:35:24 -08002943 pw.println();
2944 if (!mExitingTokens.isEmpty()) {
Craig Mautnerde4ef022013-04-07 19:01:33 -07002945 pw.println();
2946 pw.println(" Exiting tokens:");
Wale Ogunwaleb429e682016-01-06 12:36:34 -08002947 for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002948 final WindowToken token = mExitingTokens.get(i);
Craig Mautnerde4ef022013-04-07 19:01:33 -07002949 pw.print(" Exiting #"); pw.print(i);
2950 pw.print(' '); pw.print(token);
2951 pw.println(':');
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002952 token.dump(pw, " ", dumpAll);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08002953 }
Craig Mautnerde4ef022013-04-07 19:01:33 -07002954 }
Robert Carrf59b8dd2017-10-02 18:58:36 -07002955
Vadim Caenb3715832019-08-13 17:06:38 +02002956 final ScreenRotationAnimation rotationAnimation = getRotationAnimation();
2957 if (rotationAnimation != null) {
2958 pw.print(subPrefix);
2959 pw.println(" mScreenRotationAnimation:");
2960 rotationAnimation.printTo(" ", pw);
2961 } else if (dumpAll) {
2962 pw.print(subPrefix);
2963 pw.println(" no ScreenRotationAnimation ");
2964 }
2965
Jorim Jaggi31f71702016-05-04 16:43:04 -07002966 pw.println();
Wale Ogunwale61911492017-10-11 08:50:50 -07002967
2968 // Dump stack references
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002969 final ActivityStack homeStack = getDefaultTaskDisplayArea().getRootHomeTask();
Wale Ogunwale61911492017-10-11 08:50:50 -07002970 if (homeStack != null) {
2971 pw.println(prefix + "homeStack=" + homeStack.getName());
2972 }
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002973 final ActivityStack pinnedStack = getDefaultTaskDisplayArea().getRootPinnedTask();
Wale Ogunwale61911492017-10-11 08:50:50 -07002974 if (pinnedStack != null) {
2975 pw.println(prefix + "pinnedStack=" + pinnedStack.getName());
2976 }
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002977 final ActivityStack splitScreenPrimaryStack = getDefaultTaskDisplayArea()
2978 .getRootSplitScreenPrimaryTask();
Wale Ogunwale61911492017-10-11 08:50:50 -07002979 if (splitScreenPrimaryStack != null) {
2980 pw.println(prefix + "splitScreenPrimaryStack=" + splitScreenPrimaryStack.getName());
2981 }
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07002982 // TODO: Support recents on non-default task containers
2983 final ActivityStack recentsStack = getDefaultTaskDisplayArea().getStack(
2984 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS);
Louis Chang677921f2019-12-06 16:44:24 +08002985 if (recentsStack != null) {
2986 pw.println(prefix + "recentsStack=" + recentsStack.getName());
2987 }
Galia Peycheva70b55712020-03-16 18:31:34 +01002988 final ActivityStack dreamStack =
2989 getStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_DREAM);
2990 if (dreamStack != null) {
2991 pw.println(prefix + "dreamStack=" + dreamStack.getName());
2992 }
Wale Ogunwale61911492017-10-11 08:50:50 -07002993
2994 pw.println();
Jorim Jaggiad5d2842016-11-01 18:22:53 -07002995 mPinnedStackControllerLocked.dump(prefix, pw);
Wale Ogunwalec69694a2016-10-18 13:51:15 -07002996
Wale Ogunwale828ff7e2017-11-14 01:01:29 +00002997 pw.println();
2998 mDisplayFrames.dump(prefix, pw);
Arthur Hung95b38a92018-07-20 18:56:12 +08002999 pw.println();
Riddle Hsu5ce4bb32018-07-18 16:11:30 +08003000 mDisplayPolicy.dump(prefix, pw);
3001 pw.println();
Riddle Hsuad256a12018-07-18 16:11:30 +08003002 mDisplayRotation.dump(prefix, pw);
3003 pw.println();
Arthur Hung95b38a92018-07-20 18:56:12 +08003004 mInputMonitor.dump(pw, " ");
Jorim Jaggif96c90a2018-09-26 16:55:15 +02003005 pw.println();
3006 mInsetsStateController.dump(prefix, pw);
Craig Mautner59c00972012-07-30 12:10:24 -07003007 }
Craig Mautnere0a38842013-12-16 16:14:02 -08003008
3009 @Override
3010 public String toString() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07003011 return "Display " + mDisplayId + " info=" + mDisplayInfo + " stacks=" + mChildren;
Wale Ogunwale9adfe572016-09-08 20:43:58 -07003012 }
3013
3014 String getName() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07003015 return "Display " + mDisplayId + " name=\"" + mDisplayInfo.name + "\"";
Craig Mautnere0a38842013-12-16 16:14:02 -08003016 }
Filip Gruszczynski466f3212015-09-21 17:57:57 -07003017
Wale Ogunwale9adfe572016-09-08 20:43:58 -07003018 /** Find the visible, touch-deliverable window under the given point */
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003019 WindowState getTouchableWinAtPointLocked(float xf, float yf) {
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003020 final int x = (int) xf;
3021 final int y = (int) yf;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003022 final WindowState touchedWin = getWindow(w -> {
3023 final int flags = w.mAttrs.flags;
3024 if (!w.isVisibleLw()) {
3025 return false;
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003026 }
3027 if ((flags & FLAG_NOT_TOUCHABLE) != 0) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003028 return false;
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003029 }
3030
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003031 w.getVisibleBounds(mTmpRect);
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003032 if (!mTmpRect.contains(x, y)) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003033 return false;
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003034 }
3035
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003036 w.getTouchableRegion(mTmpRegion);
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003037
3038 final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003039 return mTmpRegion.contains(x, y) || touchFlags == 0;
3040 });
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -08003041
3042 return touchedWin;
3043 }
Jorim Jaggi6626f542016-08-22 13:08:44 -07003044
Svetoslav Ganovaa076532016-08-01 19:16:43 -07003045 boolean canAddToastWindowForUid(int uid) {
3046 // We allow one toast window per UID being shown at a time.
Svet Ganovdaca8ee2017-01-21 17:40:40 -08003047 // Also if the app is focused adding more than one toast at
3048 // a time for better backwards compatibility.
3049 final WindowState focusedWindowForUid = getWindow(w ->
3050 w.mOwnerUid == uid && w.isFocused());
3051 if (focusedWindowForUid != null) {
3052 return true;
3053 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003054 final WindowState win = getWindow(w ->
3055 w.mAttrs.type == TYPE_TOAST && w.mOwnerUid == uid && !w.mPermanentlyHidden
chaviw8065f442019-11-18 13:20:58 -08003056 && !w.mWindowRemovalAllowed);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003057 return win == null;
Svetoslav Ganovaa076532016-08-01 19:16:43 -07003058 }
3059
Wale Ogunwale19e452e2016-10-12 12:36:29 -07003060 void scheduleToastWindowsTimeoutIfNeededLocked(WindowState oldFocus, WindowState newFocus) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -07003061 if (oldFocus == null || (newFocus != null && newFocus.mOwnerUid == oldFocus.mOwnerUid)) {
3062 return;
3063 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003064
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003065 // Used to communicate the old focus to the callback method.
3066 mTmpWindow = oldFocus;
3067
3068 forAllWindows(mScheduleToastTimeout, false /* traverseTopToBottom */);
Svetoslav Ganovaa076532016-08-01 19:16:43 -07003069 }
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07003070
Louis Changa9350fe2019-04-25 17:14:20 +08003071 /**
3072 * Looking for the focused window on this display if the top focused display hasn't been
3073 * found yet (topFocusedDisplayId is INVALID_DISPLAY) or per-display focused was allowed.
3074 *
3075 * @param topFocusedDisplayId Id of the top focused display.
3076 * @return The focused window or null if there isn't any or no need to seek.
3077 */
3078 WindowState findFocusedWindowIfNeeded(int topFocusedDisplayId) {
3079 return (mWmService.mPerDisplayFocusEnabled || topFocusedDisplayId == INVALID_DISPLAY)
3080 ? findFocusedWindow() : null;
Tiger Huang51c5a1d2018-12-11 20:24:51 +08003081 }
3082
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07003083 WindowState findFocusedWindow() {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003084 mTmpWindow = null;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07003085
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003086 forAllWindows(mFindFocusedWindow, true /* traverseTopToBottom */);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003087
3088 if (mTmpWindow == null) {
Adrian Roosb125e0b2019-10-02 14:55:14 +02003089 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: No focusable windows.");
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003090 return null;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07003091 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003092 return mTmpWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07003093 }
3094
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003095 /**
3096 * Update the focused window and make some adjustments if the focus has changed.
3097 *
3098 * @param mode Indicates the situation we are in. Possible modes are:
3099 * {@link WindowManagerService#UPDATE_FOCUS_NORMAL},
3100 * {@link WindowManagerService#UPDATE_FOCUS_PLACING_SURFACES},
3101 * {@link WindowManagerService#UPDATE_FOCUS_WILL_PLACE_SURFACES},
3102 * {@link WindowManagerService#UPDATE_FOCUS_REMOVING_FOCUS}
3103 * @param updateInputWindows Whether to sync the window information to the input module.
Louis Changa9350fe2019-04-25 17:14:20 +08003104 * @param topFocusedDisplayId Display id of current top focused display.
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003105 * @return {@code true} if the focused window has changed.
3106 */
Louis Changa9350fe2019-04-25 17:14:20 +08003107 boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows,
3108 int topFocusedDisplayId) {
3109 WindowState newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003110 if (mCurrentFocus == newFocus) {
3111 return false;
3112 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003113 boolean imWindowChanged = false;
Tiger Huang51c5a1d2018-12-11 20:24:51 +08003114 final WindowState imWindow = mInputMethodWindow;
3115 if (imWindow != null) {
3116 final WindowState prevTarget = mInputMethodTarget;
3117 final WindowState newTarget = computeImeTarget(true /* updateImeTarget*/);
3118 imWindowChanged = prevTarget != newTarget;
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003119
Tiger Huang51c5a1d2018-12-11 20:24:51 +08003120 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
3121 && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES) {
3122 assignWindowLayers(false /* setLayoutNeeded */);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003123 }
3124 }
3125
3126 if (imWindowChanged) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003127 mWmService.mWindowsChanged = true;
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003128 setLayoutNeeded();
Louis Changa9350fe2019-04-25 17:14:20 +08003129 newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
Tiger Huang51c5a1d2018-12-11 20:24:51 +08003130 }
3131 if (mCurrentFocus != newFocus) {
3132 mWmService.mH.obtainMessage(REPORT_FOCUS_CHANGE, this).sendToTarget();
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003133 }
3134
Adrian Roosb125e0b2019-10-02 14:55:14 +02003135 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Changing focus from %s to %s displayId=%d Callers=%s",
chaviw8065f442019-11-18 13:20:58 -08003136 mCurrentFocus, newFocus, getDisplayId(), Debug.getCallers(4));
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003137 final WindowState oldFocus = mCurrentFocus;
3138 mCurrentFocus = newFocus;
3139 mLosingFocus.remove(newFocus);
3140
3141 if (newFocus != null) {
3142 mWinAddedSinceNullFocus.clear();
3143 mWinRemovedSinceNullFocus.clear();
3144
3145 if (newFocus.canReceiveKeys()) {
3146 // Displaying a window implicitly causes dispatching to be unpaused.
3147 // This is to protect against bugs if someone pauses dispatching but
3148 // forgets to resume.
3149 newFocus.mToken.paused = false;
3150 }
3151 }
3152
Vishnu Nairf6ef1c72020-01-23 16:28:33 -08003153 onWindowFocusChanged(oldFocus, newFocus);
3154
Tiger Huang7c610aa2018-10-27 00:01:01 +08003155 int focusChanged = getDisplayPolicy().focusChangedLw(oldFocus, newFocus);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003156
3157 if (imWindowChanged && oldFocus != mInputMethodWindow) {
3158 // Focus of the input method window changed. Perform layout if needed.
3159 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
3160 performLayout(true /*initial*/, updateInputWindows);
3161 focusChanged &= ~FINISH_LAYOUT_REDO_LAYOUT;
3162 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
3163 // Client will do the layout, but we need to assign layers
3164 // for handleNewWindowLocked() below.
3165 assignWindowLayers(false /* setLayoutNeeded */);
3166 }
3167 }
3168
3169 if ((focusChanged & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
3170 // The change in focus caused us to need to do a layout. Okay.
3171 setLayoutNeeded();
3172 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
3173 performLayout(true /*initial*/, updateInputWindows);
3174 } else if (mode == UPDATE_FOCUS_REMOVING_FOCUS) {
Riddle Hsu72d6dc32020-03-25 22:58:00 +08003175 mWmService.mRoot.performSurfacePlacement();
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003176 }
3177 }
3178
3179 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
3180 // If we defer assigning layers, then the caller is responsible for doing this part.
3181 getInputMonitor().setInputFocusLw(newFocus, updateInputWindows);
3182 }
3183
3184 adjustForImeIfNeeded();
3185
3186 // We may need to schedule some toast windows to be removed. The toasts for an app that
3187 // does not have input focus are removed within a timeout to prevent apps to redress
3188 // other apps' UI.
3189 scheduleToastWindowsTimeoutIfNeededLocked(oldFocus, newFocus);
3190
3191 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
3192 pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
3193 }
3194 return true;
3195 }
3196
Vishnu Nairf6ef1c72020-01-23 16:28:33 -08003197 private static void onWindowFocusChanged(WindowState oldFocus, WindowState newFocus) {
3198 final Task focusedTask = newFocus != null ? newFocus.getTask() : null;
3199 final Task unfocusedTask = oldFocus != null ? oldFocus.getTask() : null;
3200 if (focusedTask == unfocusedTask) {
3201 return;
3202 }
3203 if (focusedTask != null) {
3204 focusedTask.onWindowFocusChanged(true /* hasFocus */);
3205 }
3206 if (unfocusedTask != null) {
3207 unfocusedTask.onWindowFocusChanged(false /* hasFocus */);
3208 }
3209 }
3210
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003211 /**
3212 * Set the new focused app to this display.
3213 *
Garfield Tane8d84ab2019-10-11 09:49:40 -07003214 * @param newFocus the new focused {@link ActivityRecord}.
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003215 * @return true if the focused app is changed.
3216 */
Garfield Tane8d84ab2019-10-11 09:49:40 -07003217 boolean setFocusedApp(ActivityRecord newFocus) {
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003218 if (newFocus != null) {
3219 final DisplayContent appDisplay = newFocus.getDisplayContent();
3220 if (appDisplay != this) {
3221 throw new IllegalStateException(newFocus + " is not on " + getName()
3222 + " but " + ((appDisplay != null) ? appDisplay.getName() : "none"));
3223 }
3224 }
3225 if (mFocusedApp == newFocus) {
3226 return false;
3227 }
3228 mFocusedApp = newFocus;
3229 getInputMonitor().setFocusedAppLw(newFocus);
3230 updateTouchExcludeRegion();
3231 return true;
3232 }
3233
Wale Ogunwalec69694a2016-10-18 13:51:15 -07003234 /** Updates the layer assignment of windows on this display. */
3235 void assignWindowLayers(boolean setLayoutNeeded) {
Jorim Jaggi4981f152019-03-26 18:58:45 +01003236 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers");
Robert Carrf59b8dd2017-10-02 18:58:36 -07003237 assignChildLayers(getPendingTransaction());
Wale Ogunwalec69694a2016-10-18 13:51:15 -07003238 if (setLayoutNeeded) {
3239 setLayoutNeeded();
3240 }
Robert Carrb1579c82017-09-05 14:54:47 -07003241
Robert Carrf59b8dd2017-10-02 18:58:36 -07003242 // We accumlate the layer changes in-to "getPendingTransaction()" but we defer
Robert Carrb1579c82017-09-05 14:54:47 -07003243 // the application of this transaction until the animation pass triggers
3244 // prepareSurfaces. This allows us to synchronize Z-ordering changes with
3245 // the hiding and showing of surfaces.
3246 scheduleAnimation();
Jorim Jaggi4981f152019-03-26 18:58:45 +01003247 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
Wale Ogunwalec69694a2016-10-18 13:51:15 -07003248 }
3249
Wale Ogunwale1666e312016-12-16 11:27:18 -08003250 // TODO: This should probably be called any time a visual change is made to the hierarchy like
3251 // moving containers or resizing them. Need to investigate the best way to have it automatically
3252 // happen so we don't run into issues with programmers forgetting to do it.
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003253 void layoutAndAssignWindowLayersIfNeeded() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003254 mWmService.mWindowsChanged = true;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003255 setLayoutNeeded();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003256
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003257 if (!mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003258 false /*updateInputWindows*/)) {
3259 assignWindowLayers(false /* setLayoutNeeded */);
3260 }
3261
Arthur Hung95b38a92018-07-20 18:56:12 +08003262 mInputMonitor.setUpdateInputWindowsNeededLw();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003263 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Arthur Hung95b38a92018-07-20 18:56:12 +08003264 mInputMonitor.updateInputWindowsLw(false /*force*/);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003265 }
3266
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003267 /** Returns true if a leaked surface was destroyed */
3268 boolean destroyLeakedSurfaces() {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003269 // Used to indicate that a surface was leaked.
3270 mTmpWindow = null;
3271 forAllWindows(w -> {
3272 final WindowStateAnimator wsa = w.mWinAnimator;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003273 if (wsa.mSurfaceController == null) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003274 return;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003275 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003276 if (!mWmService.mSessions.contains(wsa.mSession)) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003277 Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003278 + w + " surface=" + wsa.mSurfaceController
3279 + " token=" + w.mToken
3280 + " pid=" + w.mSession.mPid
3281 + " uid=" + w.mSession.mUid);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003282 wsa.destroySurface();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003283 mWmService.mForceRemoves.add(w);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003284 mTmpWindow = w;
Issei Suzukid4ee1cc2019-11-08 13:20:14 +01003285 } else if (w.mActivityRecord != null && !w.mActivityRecord.isClientVisible()) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003286 Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003287 + w + " surface=" + wsa.mSurfaceController
Garfield Tane8d84ab2019-10-11 09:49:40 -07003288 + " token=" + w.mActivityRecord);
Adrian Roosb125e0b2019-10-02 14:55:14 +02003289 ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE LEAK DESTROY: %s", w);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003290 wsa.destroySurface();
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003291 mTmpWindow = w;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003292 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003293 }, false /* traverseTopToBottom */);
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003294
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003295 return mTmpWindow != null;
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003296 }
3297
Riddle Hsuccf09402019-08-13 00:33:06 +08003298 boolean hasAlertWindowSurfaces() {
3299 for (int i = mWmService.mSessions.size() - 1; i >= 0; --i) {
3300 if (mWmService.mSessions.valueAt(i).hasAlertWindowSurfaces(this)) {
3301 return true;
3302 }
3303 }
3304 return false;
3305 }
3306
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003307 /**
lumark90120a82018-08-15 00:33:03 +08003308 * Set input method window for the display.
3309 * @param win Set when window added or Null when destroyed.
3310 */
3311 void setInputMethodWindowLocked(WindowState win) {
3312 mInputMethodWindow = win;
lumark70865a82018-09-17 16:56:26 +08003313 // Update display configuration for IME process.
3314 if (mInputMethodWindow != null) {
3315 final int imePid = mInputMethodWindow.mSession.mPid;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003316 mWmService.mAtmInternal.onImeWindowSetOnDisplay(imePid,
lumark70865a82018-09-17 16:56:26 +08003317 mInputMethodWindow.getDisplayId());
3318 }
Tiger Huang332793b2019-10-29 23:21:27 +08003319 mInsetsStateController.getSourceProvider(ITYPE_IME).setWindow(win,
Jorim Jaggi9b4f4202020-01-28 17:05:06 +01003320 null /* frameProvider */, null /* imeFrameProvider */);
Tiger Huangaa3b19d2020-02-14 21:26:00 +08003321 computeImeTarget(true /* updateImeTarget */);
Tiger Huangfdec32c2020-04-10 02:07:30 +08003322 updateImeControlTarget();
lumark90120a82018-08-15 00:33:03 +08003323 }
3324
3325 /**
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003326 * Determine and return the window that should be the IME target.
3327 * @param updateImeTarget If true the system IME target will be updated to match what we found.
3328 * @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 +00003329 */
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003330 WindowState computeImeTarget(boolean updateImeTarget) {
lumark90120a82018-08-15 00:33:03 +08003331 if (mInputMethodWindow == null) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003332 // There isn't an IME so there shouldn't be a target...That was easy!
3333 if (updateImeTarget) {
3334 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from "
lumarkff0ab692018-11-05 20:32:30 +08003335 + mInputMethodTarget + " to null since mInputMethodWindow is null");
3336 setInputMethodTarget(null, mInputMethodTargetWaitingAnim);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003337 }
3338 return null;
3339 }
3340
lumarkff0ab692018-11-05 20:32:30 +08003341 final WindowState curTarget = mInputMethodTarget;
Chavi Weingarten3a748552018-05-14 17:32:42 +00003342 if (!canUpdateImeTarget()) {
3343 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Defer updating IME target");
3344 return curTarget;
3345 }
3346
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003347 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
3348 // same display. Or even when the current IME/target are not on the same screen as the next
3349 // IME/target. For now only look for input windows on the main screen.
Wale Ogunwale8e44f6c2017-03-09 15:25:10 -08003350 mUpdateImeTarget = updateImeTarget;
3351 WindowState target = getWindow(mComputeImeTargetPredicate);
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003352
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003353
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003354 // Yet more tricksyness! If this window is a "starting" window, we do actually want
3355 // to be on top of it, but it is not -really- where input will go. So look down below
3356 // for a real window to target...
3357 if (target != null && target.mAttrs.type == TYPE_APPLICATION_STARTING) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003358 final ActivityRecord activity = target.mActivityRecord;
3359 if (activity != null) {
3360 final WindowState betterTarget = activity.getImeTargetBelowWindow(target);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003361 if (betterTarget != null) {
3362 target = betterTarget;
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003363 }
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003364 }
3365 }
3366
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003367 if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM,
lumarkff0ab692018-11-05 20:32:30 +08003368 "Proposed new IME target: " + target + " for display: " + getDisplayId());
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003369
chaviw1c13ad32018-06-12 16:44:23 -07003370 // Now, a special case -- if the last target's window is in the process of exiting, but
Tarandeep Singh2d0aca42019-03-28 14:08:58 -07003371 // not removed, keep on the last target to avoid IME flicker.
chaviw1c13ad32018-06-12 16:44:23 -07003372 if (curTarget != null && !curTarget.mRemoved && curTarget.isDisplayedLw()
Tarandeep Singh2d0aca42019-03-28 14:08:58 -07003373 && curTarget.isClosing()) {
3374 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Not changing target till current window is"
3375 + " closing and not removed");
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003376 return curTarget;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003377 }
3378
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003379 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target=" + target
3380 + " updateImeTarget=" + updateImeTarget);
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003381
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003382 if (target == null) {
3383 if (updateImeTarget) {
3384 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget
3385 + " to null." + (SHOW_STACK_CRAWLS ? " Callers="
3386 + Debug.getCallers(4) : ""));
lumarkff0ab692018-11-05 20:32:30 +08003387 setInputMethodTarget(null, mInputMethodTargetWaitingAnim);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003388 }
3389
3390 return null;
3391 }
3392
3393 if (updateImeTarget) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003394 ActivityRecord activity = curTarget == null ? null : curTarget.mActivityRecord;
3395 if (activity != null) {
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003396
3397 // Now some fun for dealing with window animations that modify the Z order. We need
3398 // to look at all windows below the current target that are in this app, finding the
3399 // highest visible one in layering.
3400 WindowState highestTarget = null;
lumark5341d1c2019-12-14 01:54:02 +08003401 if (activity.isAnimating(PARENTS | TRANSITION)) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003402 highestTarget = activity.getHighestAnimLayerWindow(curTarget);
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003403 }
3404
3405 if (highestTarget != null) {
lumark9bca6b42019-10-17 18:35:22 +08003406 if (DEBUG_INPUT_METHOD) {
3407 Slog.v(TAG_WM, mAppTransition + " " + highestTarget + " animating="
3408 + highestTarget.isAnimating(TRANSITION | PARENTS));
3409 }
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003410
lumark588a3e82018-07-20 18:53:54 +08003411 if (mAppTransition.isTransitionSet()) {
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003412 // If we are currently setting up for an animation, hold everything until we
3413 // can find out what will happen.
Jorim Jaggib0fc8172017-11-23 17:04:08 +00003414 setInputMethodTarget(highestTarget, true);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003415 return highestTarget;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003416 }
3417 }
3418 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003419
3420 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
3421 + target + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
Jorim Jaggib0fc8172017-11-23 17:04:08 +00003422 setInputMethodTarget(target, false);
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07003423 }
3424
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003425 return target;
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003426 }
3427
lumarkff0ab692018-11-05 20:32:30 +08003428 /**
3429 * Calling {@link #computeImeTarget(boolean)} to update the input method target window in
3430 * the candidate app window token if needed.
3431 */
Garfield Tane8d84ab2019-10-11 09:49:40 -07003432 void computeImeTargetIfNeeded(ActivityRecord candidate) {
3433 if (mInputMethodTarget != null && mInputMethodTarget.mActivityRecord == candidate) {
lumarkff0ab692018-11-05 20:32:30 +08003434 computeImeTarget(true /* updateImeTarget */);
3435 }
3436 }
3437
Jorim Jaggicc57cb72020-04-09 14:54:13 +02003438 private boolean isImeControlledByApp() {
3439 return mInputMethodTarget != null && !WindowConfiguration.isSplitScreenWindowingMode(
3440 mInputMethodTarget.getWindowingMode());
3441 }
3442
Evan Rosky8d782e02019-10-14 15:43:53 -07003443 boolean isImeAttachedToApp() {
Jorim Jaggicc57cb72020-04-09 14:54:13 +02003444 return isImeControlledByApp()
3445 && mInputMethodTarget.mActivityRecord != null
Evan Rosky8d782e02019-10-14 15:43:53 -07003446 && mInputMethodTarget.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
3447 // An activity with override bounds should be letterboxed inside its parent bounds,
3448 // so it doesn't fill the screen.
Jorim Jaggicc57cb72020-04-09 14:54:13 +02003449 && mInputMethodTarget.mActivityRecord.matchParentBounds();
Tarandeep Singh1e5b1a82020-01-24 16:03:05 -08003450 }
3451
3452 /**
3453 * Finds the window which can host IME if IME target cannot host it.
3454 * e.g. IME target cannot host IME when it's display has a parent display OR when display
3455 * doesn't support IME/system decorations.
3456 *
3457 * @param target current IME target.
3458 * @return {@link WindowState} that can host IME.
Tarandeep Singh1e5b1a82020-01-24 16:03:05 -08003459 */
3460 WindowState getImeHostOrFallback(WindowState target) {
3461 if (target != null && target.getDisplayContent().canShowIme()) {
3462 return target;
3463 }
Jorim Jaggi001b3412020-02-17 17:52:06 +01003464 return getImeFallback();
3465 }
3466
3467 WindowState getImeFallback() {
Tarandeep Singh1e5b1a82020-01-24 16:03:05 -08003468
3469 // host is in non-default display that doesn't support system decor, default to
3470 // default display's StatusBar to control IME.
3471 // TODO: (b/148234093)find a better host OR control IME animation/visibility directly
3472 // because it won't work when statusbar isn't available.
3473 return mWmService.getDefaultDisplayContentLocked().getDisplayPolicy().getStatusBar();
3474 }
3475
3476 boolean canShowIme() {
3477 if (isUntrustedVirtualDisplay()) {
3478 return false;
3479 }
3480 return mWmService.mDisplayWindowSettings.shouldShowImeLocked(this)
3481 || mWmService.mForceDesktopModeOnExternalDisplays;
3482 }
3483
Jorim Jaggib0fc8172017-11-23 17:04:08 +00003484 private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) {
lumarkff0ab692018-11-05 20:32:30 +08003485 if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003486 return;
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003487 }
3488
lumarkff0ab692018-11-05 20:32:30 +08003489 mInputMethodTarget = target;
3490 mInputMethodTargetWaitingAnim = targetWaitingAnim;
Jorim Jaggi62ea2cf2020-04-16 00:22:28 +02003491 assignWindowLayers(true /* setLayoutNeeded */);
Tarandeep Singha6f35612019-01-11 19:50:46 -08003492 updateImeParent();
Tiger Huangfdec32c2020-04-10 02:07:30 +08003493 updateImeControlTarget();
Tarandeep Singha6f35612019-01-11 19:50:46 -08003494 }
3495
Tarandeep Singha6590182020-01-24 16:05:18 -08003496 /**
Tiger Huangfdec32c2020-04-10 02:07:30 +08003497 * The IME input target is the window which receives input from IME. It is also a candidate
3498 * which controls the visibility and animation of the input method window.
Tarandeep Singha6590182020-01-24 16:05:18 -08003499 */
Tiger Huangfdec32c2020-04-10 02:07:30 +08003500 void setInputMethodInputTarget(WindowState target) {
3501 if (mInputMethodInputTarget != target) {
3502 mInputMethodInputTarget = target;
3503 updateImeControlTarget();
3504 }
3505 }
3506
3507 private void updateImeControlTarget() {
Jorim Jaggicc57cb72020-04-09 14:54:13 +02003508 mInputMethodControlTarget = computeImeControlTarget();
Tarandeep Singha6590182020-01-24 16:05:18 -08003509 mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget);
3510 }
3511
Tarandeep Singha6f35612019-01-11 19:50:46 -08003512 private void updateImeParent() {
Adrian Roos329cbd02020-04-14 15:42:41 +02003513 final SurfaceControl newParent = computeImeParent();
Tarandeep Singha6f35612019-01-11 19:50:46 -08003514 if (newParent != null) {
Tiger Huanged6794e2019-05-07 20:07:59 +08003515 getPendingTransaction().reparent(mImeWindowsContainers.mSurfaceControl, newParent);
Tarandeep Singha6f35612019-01-11 19:50:46 -08003516 scheduleAnimation();
3517 }
3518 }
3519
3520 /**
Jorim Jaggicc57cb72020-04-09 14:54:13 +02003521 * Computes the window where we hand IME control to.
3522 */
3523 @VisibleForTesting
3524 InsetsControlTarget computeImeControlTarget() {
3525 if (!isImeControlledByApp() && mRemoteInsetsControlTarget != null) {
3526 return mRemoteInsetsControlTarget;
3527 } else {
3528 // Otherwise, we just use the ime target as received from IME.
3529 return mInputMethodInputTarget;
3530 }
3531 }
3532
3533 /**
Tarandeep Singha6f35612019-01-11 19:50:46 -08003534 * Computes the window the IME should be attached to.
3535 */
3536 @VisibleForTesting
3537 SurfaceControl computeImeParent() {
Adrian Roos329cbd02020-04-14 15:42:41 +02003538 // Force attaching IME to the display when magnifying, or it would be magnified with
3539 // target app together.
3540 final boolean allowAttachToApp = (mMagnificationSpec == null);
Tarandeep Singha6f35612019-01-11 19:50:46 -08003541
3542 // Attach it to app if the target is part of an app and such app is covering the entire
3543 // screen. If it's not covering the entire screen the IME might extend beyond the apps
3544 // bounds.
Adrian Roos329cbd02020-04-14 15:42:41 +02003545 if (allowAttachToApp && isImeAttachedToApp()) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003546 return mInputMethodTarget.mActivityRecord.getSurfaceControl();
Tarandeep Singha6f35612019-01-11 19:50:46 -08003547 }
3548
Adrian Roos329cbd02020-04-14 15:42:41 +02003549 // Otherwise, we just attach it to where the display area policy put it.
3550 return mImeWindowsContainers.getParent().getSurfaceControl();
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003551 }
3552
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07003553 void setLayoutNeeded() {
3554 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "setLayoutNeeded: callers=" + Debug.getCallers(3));
3555 mLayoutNeeded = true;
3556 }
3557
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003558 private void clearLayoutNeeded() {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07003559 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "clearLayoutNeeded: callers=" + Debug.getCallers(3));
3560 mLayoutNeeded = false;
3561 }
3562
3563 boolean isLayoutNeeded() {
3564 return mLayoutNeeded;
3565 }
3566
Wale Ogunwale02319a62016-09-26 15:21:22 -07003567 void dumpTokens(PrintWriter pw, boolean dumpAll) {
3568 if (mTokenMap.isEmpty()) {
3569 return;
3570 }
3571 pw.println(" Display #" + mDisplayId);
3572 final Iterator<WindowToken> it = mTokenMap.values().iterator();
3573 while (it.hasNext()) {
3574 final WindowToken token = it.next();
3575 pw.print(" ");
3576 pw.print(token);
3577 if (dumpAll) {
3578 pw.println(':');
Jorim Jaggif5f9e122017-10-24 18:21:09 +02003579 token.dump(pw, " ", dumpAll);
Wale Ogunwale02319a62016-09-26 15:21:22 -07003580 } else {
3581 pw.println();
3582 }
3583 }
lumark588a3e82018-07-20 18:53:54 +08003584
Evan Rosky55bddd82020-01-29 13:07:18 -08003585 if (!mOpeningApps.isEmpty() || !mClosingApps.isEmpty() || !mChangingContainers.isEmpty()) {
lumark588a3e82018-07-20 18:53:54 +08003586 pw.println();
3587 if (mOpeningApps.size() > 0) {
3588 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
3589 }
3590 if (mClosingApps.size() > 0) {
3591 pw.print(" mClosingApps="); pw.println(mClosingApps);
3592 }
Evan Rosky55bddd82020-01-29 13:07:18 -08003593 if (mChangingContainers.size() > 0) {
3594 pw.print(" mChangingApps="); pw.println(mChangingContainers);
Evan Rosky2289ba12018-11-19 18:28:18 -08003595 }
lumark588a3e82018-07-20 18:53:54 +08003596 }
3597
3598 mUnknownAppVisibilityController.dump(pw, " ");
Wale Ogunwale02319a62016-09-26 15:21:22 -07003599 }
3600
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07003601 void dumpWindowAnimators(PrintWriter pw, String subPrefix) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003602 final int[] index = new int[1];
3603 forAllWindows(w -> {
3604 final WindowStateAnimator wAnim = w.mWinAnimator;
3605 pw.println(subPrefix + "Window #" + index[0] + ": " + wAnim);
3606 index[0] = index[0] + 1;
3607 }, false /* traverseTopToBottom */);
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07003608 }
3609
Jorim Jaggife762342016-10-13 14:33:27 +02003610 /**
3611 * Starts the Keyguard exit animation on all windows that don't belong to an app token.
3612 */
Issei Suzuki5609ccb2019-06-13 15:04:08 +02003613 void startKeyguardExitOnNonAppWindows(boolean onWallpaper, boolean goingToShade,
3614 boolean subtle) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003615 final WindowManagerPolicy policy = mWmService.mPolicy;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003616 forAllWindows(w -> {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003617 if (w.mActivityRecord == null && policy.canBeHiddenByKeyguardLw(w)
Jorim Jaggic6ae42a2017-05-08 23:42:02 +02003618 && w.wouldBeVisibleIfPolicyIgnored() && !w.isVisible()) {
Issei Suzuki5609ccb2019-06-13 15:04:08 +02003619 w.startAnimation(policy.createHiddenByKeyguardExit(
3620 onWallpaper, goingToShade, subtle));
Jorim Jaggife762342016-10-13 14:33:27 +02003621 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003622 }, true /* traverseTopToBottom */);
Evan Rosky0ad8d2c2020-03-16 12:09:58 -07003623 for (int i = mShellRoots.size() - 1; i >= 0; --i) {
3624 mShellRoots.valueAt(i).startAnimation(policy.createHiddenByKeyguardExit(
3625 onWallpaper, goingToShade, subtle));
3626 }
Jorim Jaggife762342016-10-13 14:33:27 +02003627 }
3628
Riddle Hsub2297ad2019-07-26 23:37:25 -06003629 /** @return {@code true} if there is window to wait before enabling the screen. */
3630 boolean shouldWaitForSystemDecorWindowsOnBoot() {
3631 if (!isDefaultDisplay && !supportsSystemDecorations()) {
3632 // Nothing to wait because the secondary display doesn't support system decorations,
3633 // there is no wallpaper, keyguard (status bar) or application (home) window to show
3634 // during booting.
3635 return false;
3636 }
Wale Ogunwale494009b82016-10-21 09:01:38 -07003637
Riddle Hsub2297ad2019-07-26 23:37:25 -06003638 final SparseBooleanArray drawnWindowTypes = new SparseBooleanArray();
3639 // Presuppose keyguard is drawn because if its window isn't attached, we don't know if it
3640 // wants to be shown or hidden, then it should not delay enabling the screen.
wilsonshihe8321942019-10-18 18:39:46 +08003641 drawnWindowTypes.put(TYPE_NOTIFICATION_SHADE, true);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003642
Riddle Hsub2297ad2019-07-26 23:37:25 -06003643 final WindowState visibleNotDrawnWindow = getWindow(w -> {
Lais Andrade57283fb2020-04-21 18:58:15 +00003644 boolean isVisible = w.mViewVisibility == View.VISIBLE && !w.mObscured;
3645 boolean hasDrawn = w.isDrawnLw() && w.hasDrawnLw();
3646 if (isVisible && !hasDrawn) {
Wale Ogunwale494009b82016-10-21 09:01:38 -07003647 return true;
3648 }
Lais Andrade57283fb2020-04-21 18:58:15 +00003649 if (hasDrawn) {
3650 switch (w.mAttrs.type) {
3651 case TYPE_BOOT_PROGRESS:
3652 case TYPE_BASE_APPLICATION:
3653 case TYPE_WALLPAPER:
3654 drawnWindowTypes.put(w.mAttrs.type, true);
3655 break;
3656 case TYPE_NOTIFICATION_SHADE:
3657 drawnWindowTypes.put(TYPE_NOTIFICATION_SHADE,
3658 mWmService.mPolicy.isKeyguardDrawnLw());
3659 break;
Wale Ogunwale494009b82016-10-21 09:01:38 -07003660 }
3661 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003662 return false;
3663 });
3664
Riddle Hsub2297ad2019-07-26 23:37:25 -06003665 if (visibleNotDrawnWindow != null) {
3666 // Wait for the visible window to be drawn.
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003667 return true;
Wale Ogunwale494009b82016-10-21 09:01:38 -07003668 }
3669
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003670 // if the wallpaper service is disabled on the device, we're never going to have
3671 // wallpaper, don't bother waiting for it
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003672 boolean wallpaperEnabled = mWmService.mContext.getResources().getBoolean(
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003673 com.android.internal.R.bool.config_enableWallpaperService)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003674 && mWmService.mContext.getResources().getBoolean(
chaviw8065f442019-11-18 13:20:58 -08003675 com.android.internal.R.bool.config_checkWallpaperAtBoot)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003676 && !mWmService.mOnlyCore;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003677
Riddle Hsub2297ad2019-07-26 23:37:25 -06003678 final boolean haveBootMsg = drawnWindowTypes.get(TYPE_BOOT_PROGRESS);
3679 final boolean haveApp = drawnWindowTypes.get(TYPE_BASE_APPLICATION);
3680 final boolean haveWallpaper = drawnWindowTypes.get(TYPE_WALLPAPER);
wilsonshihe8321942019-10-18 18:39:46 +08003681 final boolean haveKeyguard = drawnWindowTypes.get(TYPE_NOTIFICATION_SHADE);
Riddle Hsub2297ad2019-07-26 23:37:25 -06003682
Adrian Roosb125e0b2019-10-02 14:55:14 +02003683 ProtoLog.i(WM_DEBUG_SCREEN_ON,
Riddle Hsub2297ad2019-07-26 23:37:25 -06003684 "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b "
3685 + "wallEnabled=%b haveKeyguard=%b",
3686 mWmService.mSystemBooted, mWmService.mShowingBootMessages, haveBootMsg,
3687 haveApp, haveWallpaper, wallpaperEnabled, haveKeyguard);
Wale Ogunwale494009b82016-10-21 09:01:38 -07003688
3689 // If we are turning on the screen to show the boot message, don't do it until the boot
3690 // message is actually displayed.
Riddle Hsub2297ad2019-07-26 23:37:25 -06003691 if (!mWmService.mSystemBooted && !haveBootMsg) {
Wale Ogunwale494009b82016-10-21 09:01:38 -07003692 return true;
3693 }
3694
3695 // If we are turning on the screen after the boot is completed normally, don't do so until
3696 // we have the application and wallpaper.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003697 if (mWmService.mSystemBooted
Riddle Hsub2297ad2019-07-26 23:37:25 -06003698 && ((!haveApp && !haveKeyguard) || (wallpaperEnabled && !haveWallpaper))) {
Wale Ogunwale494009b82016-10-21 09:01:38 -07003699 return true;
3700 }
3701
3702 return false;
3703 }
3704
Jorim Jaggi8f520872018-08-14 17:00:20 +02003705 void updateWindowsForAnimator() {
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003706 forAllWindows(mUpdateWindowsForAnimator, true /* traverseTopToBottom */);
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07003707 }
3708
Yohei Yukawa41f89c32018-09-19 14:30:04 -07003709 boolean isInputMethodClientFocus(int uid, int pid) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003710 final WindowState imFocus = computeImeTarget(false /* updateImeTarget */);
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003711 if (imFocus == null) {
3712 return false;
3713 }
3714
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003715 if (DEBUG_INPUT_METHOD) {
3716 Slog.i(TAG_WM, "Desired input method target: " + imFocus);
Tiger Huang1e5b10a2018-07-30 20:19:51 +08003717 Slog.i(TAG_WM, "Current focus: " + mCurrentFocus + " displayId=" + mDisplayId);
3718 Slog.i(TAG_WM, "Last focus: " + mLastFocus + " displayId=" + mDisplayId);
Jorim Jaggiffa5a9d2016-11-23 16:59:19 +00003719 }
3720
Wale Ogunwale494009b82016-10-21 09:01:38 -07003721 if (DEBUG_INPUT_METHOD) {
Yohei Yukawa41f89c32018-09-19 14:30:04 -07003722 Slog.i(TAG_WM, "IM target uid/pid: " + imFocus.mSession.mUid
3723 + "/" + imFocus.mSession.mPid);
3724 Slog.i(TAG_WM, "Requesting client uid/pid: " + uid + "/" + pid);
Wale Ogunwale494009b82016-10-21 09:01:38 -07003725 }
3726
Yohei Yukawa41f89c32018-09-19 14:30:04 -07003727 return imFocus.mSession.mUid == uid && imFocus.mSession.mPid == pid;
Wale Ogunwale494009b82016-10-21 09:01:38 -07003728 }
3729
3730 boolean hasSecureWindowOnScreen() {
Winson Chung0026f652020-05-08 11:35:11 -07003731 final WindowState win = getWindow(w -> w.isOnScreen() && mWmService.isSecureLocked(w));
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003732 return win != null;
Wale Ogunwale494009b82016-10-21 09:01:38 -07003733 }
3734
Jorim Jaggi956ca412019-01-07 14:49:14 +01003735 void hideTransientBars() {
3736 // TODO(b/118118435): Remove this after migration
3737 final int transientFlags = View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
3738 statusBarVisibilityChanged(mLastStatusBarVisibility & ~transientFlags);
3739
3740 getInsetsPolicy().hideTransient();
3741 }
3742
Tiger Huang7c610aa2018-10-27 00:01:01 +08003743 void statusBarVisibilityChanged(int visibility) {
3744 mLastStatusBarVisibility = visibility;
3745 visibility = getDisplayPolicy().adjustSystemUiVisibilityLw(visibility);
3746 updateStatusBarVisibilityLocked(visibility);
3747 }
3748
3749 private boolean updateStatusBarVisibilityLocked(int visibility) {
3750 if (mLastDispatchedSystemUiVisibility == visibility) {
3751 return false;
3752 }
3753 final int globalDiff = (visibility ^ mLastDispatchedSystemUiVisibility)
3754 // We are only interested in differences of one of the
3755 // clearable flags...
3756 & View.SYSTEM_UI_CLEARABLE_FLAGS
3757 // ...if it has actually been cleared.
3758 & ~visibility;
3759
3760 mLastDispatchedSystemUiVisibility = visibility;
3761 if (isDefaultDisplay) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003762 mWmService.mInputManager.setSystemUiVisibility(visibility);
Tiger Huang7c610aa2018-10-27 00:01:01 +08003763 }
3764 updateSystemUiVisibility(visibility, globalDiff);
3765 return true;
3766 }
3767
Wale Ogunwale494009b82016-10-21 09:01:38 -07003768 void updateSystemUiVisibility(int visibility, int globalDiff) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003769 forAllWindows(w -> {
Wale Ogunwale494009b82016-10-21 09:01:38 -07003770 try {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003771 final int curValue = w.mSystemUiVisibility;
3772 final int diff = (curValue ^ visibility) & globalDiff;
3773 final int newValue = (curValue & ~diff) | (visibility & diff);
Wale Ogunwale494009b82016-10-21 09:01:38 -07003774 if (newValue != curValue) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003775 w.mSeq++;
3776 w.mSystemUiVisibility = newValue;
Wale Ogunwale494009b82016-10-21 09:01:38 -07003777 }
Tiger Huang41ae5e82020-01-17 18:17:20 +08003778 if ((newValue != curValue || w.mAttrs.hasSystemUiListeners)
3779 && ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003780 w.mClient.dispatchSystemUiVisibilityChanged(w.mSeq,
Wale Ogunwale494009b82016-10-21 09:01:38 -07003781 visibility, newValue, diff);
3782 }
3783 } catch (RemoteException e) {
3784 // so sorry
3785 }
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003786 }, true /* traverseTopToBottom */);
Wale Ogunwale494009b82016-10-21 09:01:38 -07003787 }
3788
Tiger Huang7c610aa2018-10-27 00:01:01 +08003789 void reevaluateStatusBarVisibility() {
3790 int visibility = getDisplayPolicy().adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
3791 if (updateStatusBarVisibilityLocked(visibility)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003792 mWmService.mWindowPlacerLocked.requestTraversal();
Tiger Huang7c610aa2018-10-27 00:01:01 +08003793 }
3794 }
3795
Wale Ogunwale494009b82016-10-21 09:01:38 -07003796 void onWindowFreezeTimeout() {
3797 Slog.w(TAG_WM, "Window freeze timeout expired.");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003798 mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003799
3800 forAllWindows(w -> {
Bryce Lee8c3cf382017-07-06 19:47:10 -07003801 if (!w.getOrientationChanging()) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003802 return;
Wale Ogunwale494009b82016-10-21 09:01:38 -07003803 }
Robert Carr9c1c3a02017-08-08 12:59:01 -07003804 w.orientationChangeTimedOut();
Wale Ogunwale494009b82016-10-21 09:01:38 -07003805 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003806 - mWmService.mDisplayFreezeTime);
Wale Ogunwale494009b82016-10-21 09:01:38 -07003807 Slog.w(TAG_WM, "Force clearing orientation change: " + w);
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003808 }, true /* traverseTopToBottom */);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003809 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale494009b82016-10-21 09:01:38 -07003810 }
3811
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003812 // TODO: Super crazy long method that should be broken down...
Riddle Hsu72d6dc32020-03-25 22:58:00 +08003813 void applySurfaceChangesTransaction() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003814 final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003815
3816 mTmpUpdateAllDrawn.clear();
3817
3818 int repeats = 0;
3819 do {
3820 repeats++;
3821 if (repeats > 6) {
3822 Slog.w(TAG, "Animation repeat aborted after too many iterations");
3823 clearLayoutNeeded();
3824 break;
3825 }
3826
3827 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("On entry to LockedInner",
3828 pendingLayoutChanges);
3829
wilsonshihc32538e2018-11-07 17:27:34 +08003830 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
3831 mWallpaperController.adjustWallpaperWindows();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003832 }
3833
Riddle Hsu654a6f92018-07-13 22:59:36 +08003834 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003835 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Riddle Hsuccf09402019-08-13 00:33:06 +08003836 if (updateOrientation()) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003837 setLayoutNeeded();
Shivam Agrawal6472e0e2019-07-03 16:27:49 -07003838 sendNewConfiguration();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003839 }
3840 }
3841
3842 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
3843 setLayoutNeeded();
3844 }
3845
3846 // FIRST LOOP: Perform a layout, if needed.
3847 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
3848 performLayout(repeats == 1, false /* updateInputWindows */);
3849 } else {
3850 Slog.w(TAG, "Layout repeat skipped after too many iterations");
3851 }
3852
3853 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think it is animating.
3854 pendingLayoutChanges = 0;
3855
Jorim Jaggi4981f152019-03-26 18:58:45 +01003856 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy");
3857 try {
3858 mDisplayPolicy.beginPostLayoutPolicyLw();
3859 forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */);
3860 pendingLayoutChanges |= mDisplayPolicy.finishPostLayoutPolicyLw();
3861 } finally {
3862 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
3863 }
Tiger Huang7c610aa2018-10-27 00:01:01 +08003864 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
3865 "after finishPostLayoutPolicyLw", pendingLayoutChanges);
chaviw8065f442019-11-18 13:20:58 -08003866 mInsetsStateController.onPostLayout();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003867 } while (pendingLayoutChanges != 0);
3868
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003869 mTmpApplySurfaceChangesTransactionState.reset();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003870
Jorim Jaggi4981f152019-03-26 18:58:45 +01003871 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyWindowSurfaceChanges");
3872 try {
3873 forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
3874 } finally {
3875 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
3876 }
Jorim Jaggi6b0f8462018-01-05 17:23:47 +01003877 prepareSurfaces();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003878
Tiger Huangaa3b19d2020-02-14 21:26:00 +08003879 // This should be called after the insets have been dispatched to clients and we have
3880 // committed finish drawing windows.
3881 mInsetsStateController.getImeSourceProvider().checkShowImePostLayout();
3882
Jorim Jaggif1292892018-09-10 11:58:13 +02003883 mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003884 mWmService.mDisplayManagerInternal.setDisplayProperties(mDisplayId,
Jorim Jaggif1292892018-09-10 11:58:13 +02003885 mLastHasContent,
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003886 mTmpApplySurfaceChangesTransactionState.preferredRefreshRate,
3887 mTmpApplySurfaceChangesTransactionState.preferredModeId,
Galia Peycheva056b3ee2019-06-26 14:05:12 +02003888 mTmpApplySurfaceChangesTransactionState.preferMinimalPostProcessing,
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003889 true /* inTraversal, must call performTraversalInTrans... below */);
3890
Lucas Dupin1ead7fc2017-05-24 14:14:44 -07003891 final boolean wallpaperVisible = mWallpaperController.isWallpaperVisible();
3892 if (wallpaperVisible != mLastWallpaperVisible) {
3893 mLastWallpaperVisible = wallpaperVisible;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003894 mWmService.mWallpaperVisibilityListeners.notifyWallpaperVisibilityChanged(this);
Lucas Dupin1ead7fc2017-05-24 14:14:44 -07003895 }
3896
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003897 while (!mTmpUpdateAllDrawn.isEmpty()) {
Garfield Tane8d84ab2019-10-11 09:49:40 -07003898 final ActivityRecord activity = mTmpUpdateAllDrawn.removeLast();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003899 // See if any windows have been drawn, so they (and others associated with them)
3900 // can now be shown.
Garfield Tane8d84ab2019-10-11 09:49:40 -07003901 activity.updateAllDrawn();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003902 }
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003903 }
3904
Bryce Leef3c6a472017-11-14 14:53:06 -08003905 private void updateBounds() {
Evan Rosky39b6f232018-10-30 18:35:41 -07003906 calculateBounds(mDisplayInfo, mTmpBounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08003907 setBounds(mTmpBounds);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08003908 if (mPortalWindowHandle != null && mParentSurfaceControl != null) {
3909 mPortalWindowHandle.touchableRegion.getBounds(mTmpRect);
3910 if (!mTmpBounds.equals(mTmpRect)) {
3911 mPortalWindowHandle.touchableRegion.set(mTmpBounds);
Tiger Huanged6794e2019-05-07 20:07:59 +08003912 getPendingTransaction().setInputWindowInfo(
3913 mParentSurfaceControl, mPortalWindowHandle);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08003914 }
3915 }
Bryce Leef3c6a472017-11-14 14:53:06 -08003916 }
3917
3918 // Determines the current display bounds based on the current state
Evan Rosky39b6f232018-10-30 18:35:41 -07003919 private void calculateBounds(DisplayInfo displayInfo, Rect out) {
Bryce Leef3c6a472017-11-14 14:53:06 -08003920 // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
Evan Rosky39b6f232018-10-30 18:35:41 -07003921 final int rotation = displayInfo.rotation;
3922 boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
Bryce Leef3c6a472017-11-14 14:53:06 -08003923 final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
3924 final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
Evan Rosky39b6f232018-10-30 18:35:41 -07003925 int width = displayInfo.logicalWidth;
Bryce Leef3c6a472017-11-14 14:53:06 -08003926 int left = (physWidth - width) / 2;
Evan Rosky39b6f232018-10-30 18:35:41 -07003927 int height = displayInfo.logicalHeight;
Bryce Leef3c6a472017-11-14 14:53:06 -08003928 int top = (physHeight - height) / 2;
3929 out.set(left, top, left + width, top + height);
3930 }
3931
Bryce Leef3c6a472017-11-14 14:53:06 -08003932 private void getBounds(Rect out, int orientation) {
3933 getBounds(out);
3934
3935 // Rotate the Rect if needed.
3936 final int currentRotation = mDisplayInfo.rotation;
3937 final int rotationDelta = deltaRotation(currentRotation, orientation);
3938 if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
3939 createRotationMatrix(rotationDelta, mBaseDisplayWidth, mBaseDisplayHeight, mTmpMatrix);
3940 mTmpRectF.set(out);
3941 mTmpMatrix.mapRect(mTmpRectF);
3942 mTmpRectF.round(out);
3943 }
3944 }
3945
Evan Roskyaf9f27c2020-02-18 18:58:35 +00003946 /** @return the orientation of the display when it's rotation is ROTATION_0. */
Evan Rosky730f6e82018-12-03 17:40:11 -08003947 int getNaturalOrientation() {
3948 return mBaseDisplayWidth < mBaseDisplayHeight
3949 ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
3950 }
3951
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003952 void performLayout(boolean initial, boolean updateInputWindows) {
Jorim Jaggi4981f152019-03-26 18:58:45 +01003953 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performLayout");
3954 try {
3955 performLayoutNoTrace(initial, updateInputWindows);
3956 } finally {
3957 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
3958 }
3959 }
3960
3961 private void performLayoutNoTrace(boolean initial, boolean updateInputWindows) {
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003962 if (!isLayoutNeeded()) {
3963 return;
3964 }
3965 clearLayoutNeeded();
3966
3967 final int dw = mDisplayInfo.logicalWidth;
3968 final int dh = mDisplayInfo.logicalHeight;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003969 if (DEBUG_LAYOUT) {
3970 Slog.v(TAG, "-------------------------------------");
Jorim Jaggi4981f152019-03-26 18:58:45 +01003971 Slog.v(TAG, "performLayout: needed=" + isLayoutNeeded() + " dw=" + dw
3972 + " dh=" + dh);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003973 }
3974
Adrian Roos6a4fa0e2018-03-05 19:50:16 +01003975 mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
3976 calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
Jorim Jaggi4981f152019-03-26 18:58:45 +01003977 // TODO: Not sure if we really need to set the rotation here since we are updating from
3978 // the display info above...
Riddle Hsuccf09402019-08-13 00:33:06 +08003979 mDisplayFrames.mRotation = getRotation();
Tiger Huang7c610aa2018-10-27 00:01:01 +08003980 mDisplayPolicy.beginLayoutLw(mDisplayFrames, getConfiguration().uiMode);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003981
Adrian Roos5251b1d2018-03-23 18:57:43 +01003982 int seq = mLayoutSeq + 1;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003983 if (seq < 0) seq = 0;
Adrian Roos5251b1d2018-03-23 18:57:43 +01003984 mLayoutSeq = seq;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003985
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003986 // Used to indicate that we have processed the dream window and all additional windows are
3987 // behind it.
3988 mTmpWindow = null;
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003989 mTmpInitial = initial;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003990
Tiger Huang57e2e1c2020-03-13 22:54:36 +08003991 // Used to indicate that we have processed the IME window.
3992 mTmpWindowsBehindIme = false;
3993
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003994 // First perform layout of any root windows (not attached to another window).
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003995 forAllWindows(mPerformLayout, true /* traverseTopToBottom */);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07003996
Wale Ogunwale6213caa2016-12-02 16:47:15 +00003997 // Used to indicate that we have processed the dream window and all additional attached
3998 // windows are behind it.
Wale Ogunwale1e129a42016-11-21 13:03:47 -08003999 mTmpWindow2 = mTmpWindow;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004000 mTmpWindow = null;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07004001
4002 // Now perform layout of attached windows, which usually depend on the position of the
4003 // window they are attached to. XXX does not deal with windows that are attached to windows
4004 // that are themselves attached.
Wale Ogunwale1e129a42016-11-21 13:03:47 -08004005 forAllWindows(mPerformLayoutAttached, true /* traverseTopToBottom */);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07004006
4007 // Window frames may have changed. Tell the input dispatcher about it.
Arthur Hung95b38a92018-07-20 18:56:12 +08004008 mInputMonitor.layoutInputConsumers(dw, dh);
4009 mInputMonitor.setUpdateInputWindowsNeededLw();
Wale Ogunwalef7cab102016-10-25 15:25:14 -07004010 if (updateInputWindows) {
Arthur Hung95b38a92018-07-20 18:56:12 +08004011 mInputMonitor.updateInputWindowsLw(false /*force*/);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07004012 }
4013
Evan Rosky73a7fe92019-11-18 18:28:01 -08004014 mWmService.mH.sendEmptyMessage(UPDATE_MULTI_WINDOW_STACKS);
Wale Ogunwalef7cab102016-10-25 15:25:14 -07004015 }
4016
4017 /**
4018 * Takes a snapshot of the display. In landscape mode this grabs the whole screen.
4019 * In portrait mode, it grabs the full screenshot.
4020 *
Wale Ogunwalef7cab102016-10-25 15:25:14 -07004021 * @param config of the output bitmap
Wale Ogunwalef7cab102016-10-25 15:25:14 -07004022 */
chaviw0315a1a2018-03-05 15:28:35 -08004023 Bitmap screenshotDisplayLocked(Bitmap.Config config) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004024 if (!mWmService.mPolicy.isScreenOn()) {
chaviw0315a1a2018-03-05 15:28:35 -08004025 if (DEBUG_SCREENSHOT) {
4026 Slog.i(TAG_WM, "Attempted to take screenshot while display was off.");
Wale Ogunwalef7cab102016-10-25 15:25:14 -07004027 }
chaviw0315a1a2018-03-05 15:28:35 -08004028 return null;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07004029 }
chaviwfbe47df2017-11-10 16:14:49 -08004030
chaviw0315a1a2018-03-05 15:28:35 -08004031 int dw = mDisplayInfo.logicalWidth;
4032 int dh = mDisplayInfo.logicalHeight;
chaviwfbe47df2017-11-10 16:14:49 -08004033
chaviw0315a1a2018-03-05 15:28:35 -08004034 if (dw <= 0 || dh <= 0) {
4035 return null;
4036 }
chaviwfbe47df2017-11-10 16:14:49 -08004037
chaviw0315a1a2018-03-05 15:28:35 -08004038 final Rect frame = new Rect(0, 0, dw, dh);
chaviwfbe47df2017-11-10 16:14:49 -08004039
chaviw0315a1a2018-03-05 15:28:35 -08004040 // The screenshot API does not apply the current screen rotation.
4041 int rot = mDisplay.getRotation();
chaviwfbe47df2017-11-10 16:14:49 -08004042
chaviw0315a1a2018-03-05 15:28:35 -08004043 if (rot == ROTATION_90 || rot == ROTATION_270) {
4044 rot = (rot == ROTATION_90) ? ROTATION_270 : ROTATION_90;
4045 }
chaviwfbe47df2017-11-10 16:14:49 -08004046
chaviw0315a1a2018-03-05 15:28:35 -08004047 // SurfaceFlinger is not aware of orientation, so convert our logical
4048 // crop to SurfaceFlinger's portrait orientation.
4049 convertCropForSurfaceFlinger(frame, rot, dw, dh);
4050
4051 final ScreenRotationAnimation screenRotationAnimation =
Vadim Caenb3715832019-08-13 17:06:38 +02004052 mWmService.mRoot.getDisplayContent(DEFAULT_DISPLAY).getRotationAnimation();
chaviw0315a1a2018-03-05 15:28:35 -08004053 final boolean inRotation = screenRotationAnimation != null &&
4054 screenRotationAnimation.isAnimating();
4055 if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG_WM, "Taking screenshot while rotating");
4056
4057 // TODO(b/68392460): We should screenshot Task controls directly
4058 // but it's difficult at the moment as the Task doesn't have the
4059 // correct size set.
chaviw08520a02018-09-10 16:44:56 -07004060 final Bitmap bitmap = SurfaceControl.screenshot(frame, dw, dh, inRotation, rot);
chaviw0315a1a2018-03-05 15:28:35 -08004061 if (bitmap == null) {
4062 Slog.w(TAG_WM, "Failed to take screenshot");
4063 return null;
4064 }
4065
4066 // Create a copy of the screenshot that is immutable and backed in ashmem.
4067 // This greatly reduces the overhead of passing the bitmap between processes.
4068 final Bitmap ret = bitmap.createAshmemBitmap(config);
4069 bitmap.recycle();
4070 return ret;
Wale Ogunwalef7cab102016-10-25 15:25:14 -07004071 }
4072
4073 // TODO: Can this use createRotationMatrix()?
4074 private static void convertCropForSurfaceFlinger(Rect crop, int rot, int dw, int dh) {
4075 if (rot == Surface.ROTATION_90) {
4076 final int tmp = crop.top;
4077 crop.top = dw - crop.right;
4078 crop.right = crop.bottom;
4079 crop.bottom = dw - crop.left;
4080 crop.left = tmp;
4081 } else if (rot == Surface.ROTATION_180) {
4082 int tmp = crop.top;
4083 crop.top = dh - crop.bottom;
4084 crop.bottom = dh - tmp;
4085 tmp = crop.right;
4086 crop.right = dw - crop.left;
4087 crop.left = dw - tmp;
4088 } else if (rot == Surface.ROTATION_270) {
4089 final int tmp = crop.top;
4090 crop.top = crop.left;
4091 crop.left = dh - crop.bottom;
4092 crop.bottom = crop.right;
4093 crop.right = dh - tmp;
4094 }
4095 }
4096
Wale Ogunwale1666e312016-12-16 11:27:18 -08004097 void setExitingTokensHasVisible(boolean hasVisible) {
4098 for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
4099 mExitingTokens.get(i).hasVisible = hasVisible;
4100 }
4101
4102 // Initialize state of exiting applications.
Andrii Kulianf9df4a82020-03-31 12:09:27 -07004103 for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) {
4104 getTaskDisplayAreaAt(i).setExitingTokensHasVisible(hasVisible);
4105 }
Wale Ogunwale1666e312016-12-16 11:27:18 -08004106 }
4107
4108 void removeExistingTokensIfPossible() {
4109 for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
4110 final WindowToken token = mExitingTokens.get(i);
4111 if (!token.hasVisible) {
4112 mExitingTokens.remove(i);
4113 }
4114 }
4115
4116 // Time to remove any exiting applications?
Andrii Kulianf9df4a82020-03-31 12:09:27 -07004117 for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) {
4118 getTaskDisplayAreaAt(i).removeExistingAppTokensIfPossible();
4119 }
Wale Ogunwale1666e312016-12-16 11:27:18 -08004120 }
4121
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07004122 @Override
4123 void onDescendantOverrideConfigurationChanged() {
4124 setLayoutNeeded();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004125 mWmService.requestTraversal();
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07004126 }
4127
David Stevens9440dc82017-03-16 19:00:20 -07004128 boolean okToDisplay() {
lumark3b8bbc82019-12-02 16:22:08 +08004129 return okToDisplay(false);
4130 }
4131
4132 boolean okToDisplay(boolean ignoreFrozen) {
David Stevens9440dc82017-03-16 19:00:20 -07004133 if (mDisplayId == DEFAULT_DISPLAY) {
lumark3b8bbc82019-12-02 16:22:08 +08004134 return (!mWmService.mDisplayFrozen || ignoreFrozen)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004135 && mWmService.mDisplayEnabled && mWmService.mPolicy.isScreenOn();
David Stevens9440dc82017-03-16 19:00:20 -07004136 }
4137 return mDisplayInfo.state == Display.STATE_ON;
4138 }
4139
4140 boolean okToAnimate() {
lumark3b8bbc82019-12-02 16:22:08 +08004141 return okToAnimate(false);
4142 }
4143
4144 boolean okToAnimate(boolean ignoreFrozen) {
4145 return okToDisplay(ignoreFrozen) &&
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004146 (mDisplayId != DEFAULT_DISPLAY || mWmService.mPolicy.okToAnimate());
David Stevens9440dc82017-03-16 19:00:20 -07004147 }
4148
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07004149 static final class TaskForResizePointSearchResult {
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09004150 private Task taskForResize;
4151 private int x;
4152 private int y;
4153 private int delta;
4154 private Rect mTmpRect = new Rect();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07004155
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09004156 Task process(WindowContainer root, int x, int y, int delta) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07004157 taskForResize = null;
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09004158 this.x = x;
4159 this.y = y;
4160 this.delta = delta;
4161 mTmpRect.setEmpty();
4162
4163 final PooledFunction f = PooledLambda.obtainFunction(
4164 TaskForResizePointSearchResult::processTask, this, PooledLambda.__(Task.class));
4165 root.forAllTasks(f);
4166 f.recycle();
4167
4168 return taskForResize;
4169 }
4170
4171 private boolean processTask(Task task) {
4172 if (!task.getStack().getWindowConfiguration().canResizeTask()) {
4173 return true;
4174 }
4175
4176 if (task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
4177 return true;
4178 }
4179
Winson Chunga1f869d2020-03-21 23:02:48 -07004180 if (task.isOrganized()) {
4181 return true;
4182 }
4183
Wale Ogunwale85fb19a2019-12-05 10:41:05 +09004184 // We need to use the task's dim bounds (which is derived from the visible bounds of
4185 // its apps windows) for any touch-related tests. Can't use the task's original
4186 // bounds because it might be adjusted to fit the content frame. One example is when
4187 // the task is put to top-left quadrant, the actual visible area would not start at
4188 // (0,0) after it's adjusted for the status bar.
4189 task.getDimBounds(mTmpRect);
4190 mTmpRect.inset(-delta, -delta);
4191 if (mTmpRect.contains(x, y)) {
4192 mTmpRect.inset(delta, delta);
4193
4194 if (!mTmpRect.contains(x, y)) {
4195 taskForResize = task;
4196 return true;
4197 }
4198 // User touched inside the task. No need to look further,
4199 // focus transfer will be handled in ACTION_UP.
4200 return true;
4201 }
4202
4203 return false;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07004204 }
4205 }
Robert Carr3b716242016-08-16 16:02:21 -07004206
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004207 private static final class ApplySurfaceChangesTransactionState {
4208 boolean displayHasContent;
4209 boolean obscured;
4210 boolean syswin;
Galia Peycheva056b3ee2019-06-26 14:05:12 +02004211 boolean preferMinimalPostProcessing;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004212 float preferredRefreshRate;
4213 int preferredModeId;
4214
4215 void reset() {
4216 displayHasContent = false;
4217 obscured = false;
4218 syswin = false;
Galia Peycheva056b3ee2019-06-26 14:05:12 +02004219 preferMinimalPostProcessing = false;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004220 preferredRefreshRate = 0;
4221 preferredModeId = 0;
4222 }
4223 }
4224
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004225 /**
4226 * Base class for any direct child window container of {@link #DisplayContent} need to inherit
4227 * from. This is mainly a pass through class that allows {@link #DisplayContent} to have
4228 * homogeneous children type which is currently required by sub-classes of
4229 * {@link WindowContainer} class.
4230 */
4231 static class DisplayChildWindowContainer<E extends WindowContainer> extends WindowContainer<E> {
4232
Jorim Jaggiffe128d2017-11-30 13:54:36 +01004233 DisplayChildWindowContainer(WindowManagerService service) {
4234 super(service);
Adrian Roos0384f122020-01-10 19:39:43 +01004235 // TODO(display-area): move to ConfigurationContainer?
4236 mOrientation = SCREEN_ORIENTATION_UNSET;
Jorim Jaggiffe128d2017-11-30 13:54:36 +01004237 }
4238
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004239 @Override
4240 boolean fillsParent() {
4241 return true;
4242 }
4243
4244 @Override
4245 boolean isVisible() {
4246 return true;
Robert Carr3b716242016-08-16 16:02:21 -07004247 }
4248 }
4249
chaviw8065f442019-11-18 13:20:58 -08004250 private class WindowContainers extends DisplayChildWindowContainer<WindowContainer> {
4251 private final String mName;
4252
4253 WindowContainers(String name, WindowManagerService service) {
4254 super(service);
4255 mName = name;
4256 }
4257
4258 @Override
4259 void assignChildLayers(SurfaceControl.Transaction t) {
Adrian Roosefa40702020-01-08 17:58:45 +01004260 mImeWindowsContainers.setNeedsLayer();
Adrian Roos22a20a82019-10-23 19:05:33 +02004261
4262 mRootDisplayArea.assignLayer(t, 0);
chaviw8065f442019-11-18 13:20:58 -08004263
4264 final WindowState imeTarget = mInputMethodTarget;
chaviw8065f442019-11-18 13:20:58 -08004265 // In the case where we have an IME target that is not in split-screen mode IME
4266 // assignment is easy. We just need the IME to go directly above the target. This way
4267 // children of the target will naturally go above the IME and everyone is happy.
4268 //
4269 // In the case of split-screen windowing mode, we need to elevate the IME above the
4270 // docked divider while keeping the app itself below the docked divider, so instead
4271 // we use relative layering of the IME targets child windows, and place the IME in
4272 // the non-app layer (see {@link AboveAppWindowContainers#assignChildLayers}).
4273 //
4274 // In the case the IME target is animating, the animation Z order may be different
4275 // than the WindowContainer Z order, so it's difficult to be sure we have the correct
4276 // IME target. In this case we just layer the IME over all transitions by placing it
4277 // in the above applications layer.
4278 //
4279 // In the case where we have no IME target we assign it where its base layer would
4280 // place it in the AboveAppWindowContainers.
4281 //
4282 // Keep IME window in mAboveAppWindowsContainers as long as app's starting window
4283 // exists so it get's layered above the starting window.
4284 if (imeTarget != null && !(imeTarget.mActivityRecord != null
4285 && imeTarget.mActivityRecord.hasStartingWindow()) && (
Robert Carr599d83c2020-01-24 14:45:14 -08004286 !(imeTarget.inMultiWindowMode()
chaviw8065f442019-11-18 13:20:58 -08004287 || imeTarget.mToken.isAppTransitioning()) && (
4288 imeTarget.getSurfaceControl() != null))) {
4289 mImeWindowsContainers.assignRelativeLayer(t, imeTarget.getSurfaceControl(),
4290 // TODO: We need to use an extra level on the app surface to ensure
4291 // this is always above SurfaceView but always below attached window.
4292 1);
chaviw8065f442019-11-18 13:20:58 -08004293 }
4294
4295 // Above we have assigned layers to our children, now we ask them to assign
4296 // layers to their children.
Adrian Roos22a20a82019-10-23 19:05:33 +02004297 mRootDisplayArea.assignChildLayers(t);
chaviw8065f442019-11-18 13:20:58 -08004298 }
4299
4300 @Override
4301 String getName() {
4302 return mName;
4303 }
4304
4305 void addChildren() {
Adrian Roos22a20a82019-10-23 19:05:33 +02004306 addChild(mRootDisplayArea, 0);
4307 mDisplayAreaPolicy.attachDisplayAreas();
chaviw8065f442019-11-18 13:20:58 -08004308 }
4309
chaviw8065f442019-11-18 13:20:58 -08004310 @Override
4311 void positionChildAt(int position, WindowContainer child, boolean includingParents) {
4312 // Children of the WindowContainers are statically ordered, so the real intention here
4313 // is to perform the operation on the display and not the static direct children.
4314 getParent().positionChildAt(position, this, includingParents);
4315 }
4316 }
4317
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004318 /**
4319 * Window container class that contains all containers on this display that are not related to
4320 * Apps. E.g. status bar.
4321 */
Robert Carree4d4b92017-11-22 12:21:46 -08004322 private class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
Wale Ogunwale3a931692016-11-02 16:49:48 -07004323 /**
4324 * Compares two child window tokens returns -1 if the first is lesser than the second in
4325 * terms of z-order and 1 otherwise.
4326 */
Wale Ogunwale1e129a42016-11-21 13:03:47 -08004327 private final Comparator<WindowToken> mWindowComparator = (token1, token2) ->
Wale Ogunwale3a931692016-11-02 16:49:48 -07004328 // Tokens with higher base layer are z-ordered on-top.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004329 mWmService.mPolicy.getWindowLayerFromTypeLw(token1.windowType,
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08004330 token1.mOwnerCanManageAppTokens)
chaviw8065f442019-11-18 13:20:58 -08004331 < mWmService.mPolicy.getWindowLayerFromTypeLw(token2.windowType,
Wale Ogunwale5cd907d2017-01-26 14:14:08 -08004332 token2.mOwnerCanManageAppTokens) ? -1 : 1;
Wale Ogunwale19e452e2016-10-12 12:36:29 -07004333
Wale Ogunwale3a931692016-11-02 16:49:48 -07004334 private final String mName;
chaviwf29223e2018-01-31 13:23:51 -08004335 private final Dimmer mDimmer = new Dimmer(this);
4336 private final Rect mTmpDimBoundsRect = new Rect();
4337
Jorim Jaggiffe128d2017-11-30 13:54:36 +01004338 NonAppWindowContainers(String name, WindowManagerService service) {
4339 super(service);
Wale Ogunwale3a931692016-11-02 16:49:48 -07004340 mName = name;
4341 }
4342
Wale Ogunwaledfbeed72019-11-20 08:57:39 -08004343 @Override
4344 boolean hasActivity() {
4345 // I am a non-app-window-container :P
4346 return false;
4347 }
4348
Wale Ogunwale3a931692016-11-02 16:49:48 -07004349 void addChild(WindowToken token) {
4350 addChild(token, mWindowComparator);
4351 }
4352
4353 @Override
Adrian Roos0384f122020-01-10 19:39:43 +01004354 int getOrientation(int candidate) {
Adrian Roos22a20a82019-10-23 19:05:33 +02004355 ProtoLog.w(WM_DEBUG_ORIENTATION, "NonAppWindowContainer cannot set orientation: %s",
4356 this);
4357 return SCREEN_ORIENTATION_UNSET;
Wale Ogunwale6213caa2016-12-02 16:47:15 +00004358 }
4359
4360 @Override
Wale Ogunwale3a931692016-11-02 16:49:48 -07004361 String getName() {
4362 return mName;
4363 }
chaviwf29223e2018-01-31 13:23:51 -08004364
4365 @Override
4366 Dimmer getDimmer() {
4367 return mDimmer;
4368 }
4369
4370 @Override
4371 void prepareSurfaces() {
4372 mDimmer.resetDimStates();
4373 super.prepareSurfaces();
4374 getBounds(mTmpDimBoundsRect);
4375
4376 if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
4377 scheduleAnimation();
4378 }
4379 }
Arthur Hung96986462020-03-10 18:34:56 +08004380
4381 @Override
4382 boolean shouldMagnify() {
4383 // Omitted from Screen-Magnification
4384 return false;
4385 }
Robert Carr3b716242016-08-16 16:02:21 -07004386 }
Jorim Jaggi6a7a8592017-01-12 00:44:33 +01004387
Adrian Roosefa40702020-01-08 17:58:45 +01004388 /**
4389 * Container for IME windows.
4390 *
4391 * This has some special behaviors:
4392 * - layers assignment is ignored except if setNeedsLayer() has been called before (and no
4393 * layer has been assigned since), to facilitate assigning the layer from the IME target, or
4394 * fall back if there is no target.
4395 * - the container doesn't always participate in window traversal, according to
4396 * {@link #skipImeWindowsDuringTraversal()}
4397 */
Adrian Roos22a20a82019-10-23 19:05:33 +02004398 private static class ImeContainer extends DisplayArea.Tokens {
Adrian Roosefa40702020-01-08 17:58:45 +01004399 boolean mNeedsLayer = false;
4400
4401 ImeContainer(WindowManagerService wms) {
Adrian Roos22a20a82019-10-23 19:05:33 +02004402 super(wms, Type.ABOVE_TASKS, "ImeContainer");
Adrian Roosefa40702020-01-08 17:58:45 +01004403 }
4404
4405 public void setNeedsLayer() {
4406 mNeedsLayer = true;
4407 }
4408
4409 @Override
Adrian Roos0384f122020-01-10 19:39:43 +01004410 int getOrientation(int candidate) {
4411 // IME does not participate in orientation.
4412 return candidate;
4413 }
4414
4415 @Override
Adrian Roosefa40702020-01-08 17:58:45 +01004416 boolean forAllWindows(ToBooleanFunction<WindowState> callback,
4417 boolean traverseTopToBottom) {
4418 final DisplayContent dc = mDisplayContent;
4419 if (skipImeWindowsDuringTraversal(dc)) {
4420 return false;
4421 }
4422 return super.forAllWindows(callback, traverseTopToBottom);
4423 }
4424
4425 private boolean skipImeWindowsDuringTraversal(DisplayContent dc) {
4426 // We skip IME windows so they're processed just above their target, except
4427 // in split-screen mode where we process the IME containers above the docked divider.
Andrii Kulian9ea12da2020-03-27 17:16:38 -07004428 return dc.mInputMethodTarget != null
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -07004429 && !dc.getDefaultTaskDisplayArea().isSplitScreenModeActivated();
Adrian Roosefa40702020-01-08 17:58:45 +01004430 }
4431
4432 /** Like {@link #forAllWindows}, but ignores {@link #skipImeWindowsDuringTraversal} */
4433 boolean forAllWindowForce(ToBooleanFunction<WindowState> callback,
4434 boolean traverseTopToBottom) {
4435 return super.forAllWindows(callback, traverseTopToBottom);
4436 }
4437
4438 @Override
4439 void assignLayer(Transaction t, int layer) {
4440 if (!mNeedsLayer) {
4441 return;
4442 }
4443 super.assignLayer(t, layer);
4444 mNeedsLayer = false;
4445 }
4446
4447 @Override
4448 void assignRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
4449 if (!mNeedsLayer) {
4450 return;
4451 }
4452 super.assignRelativeLayer(t, relativeTo, layer);
4453 mNeedsLayer = false;
4454 }
4455 }
4456
Robert Carrb1579c82017-09-05 14:54:47 -07004457 @Override
4458 SurfaceSession getSession() {
4459 return mSession;
4460 }
4461
4462 @Override
4463 SurfaceControl.Builder makeChildSurface(WindowContainer child) {
Robert Carrf59b8dd2017-10-02 18:58:36 -07004464 SurfaceSession s = child != null ? child.getSession() : getSession();
Chavi Weingarten6ef9cc62019-02-07 16:28:45 +00004465 final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(s).setContainerLayer();
Robert Carrf59b8dd2017-10-02 18:58:36 -07004466 if (child == null) {
4467 return b;
4468 }
4469
Robert Carree4d4b92017-11-22 12:21:46 -08004470 return b.setName(child.getName())
chaviw8065f442019-11-18 13:20:58 -08004471 .setParent(mSurfaceControl);
Robert Carrb1579c82017-09-05 14:54:47 -07004472 }
4473
4474 /**
4475 * The makeSurface variants are for use by the window-container
4476 * hierarchy. makeOverlay here is a function for various non windowing
4477 * overlays like the ScreenRotation screenshot, the Strict Mode Flash
4478 * and other potpourii.
4479 */
4480 SurfaceControl.Builder makeOverlay() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004481 return mWmService.makeSurfaceBuilder(mSession)
chaviw8065f442019-11-18 13:20:58 -08004482 .setParent(mOverlayContainers.getSurfaceControl());
Robert Carrb1579c82017-09-05 14:54:47 -07004483 }
4484
Daichi Hironoa1fb9be2017-12-18 17:02:54 +09004485 /**
chaviw8065f442019-11-18 13:20:58 -08004486 * Reparents the given surface to {@link #mOverlayContainers}' SurfaceControl.
Daichi Hironoa1fb9be2017-12-18 17:02:54 +09004487 */
4488 void reparentToOverlay(Transaction transaction, SurfaceControl surface) {
chaviw8065f442019-11-18 13:20:58 -08004489 transaction.reparent(surface, mOverlayContainers.getSurfaceControl());
Daichi Hironoa1fb9be2017-12-18 17:02:54 +09004490 }
4491
Robert Carrb1579c82017-09-05 14:54:47 -07004492 void applyMagnificationSpec(MagnificationSpec spec) {
Robert Carr24be9ab2018-04-30 17:54:53 -07004493 if (spec.scale != 1.0) {
4494 mMagnificationSpec = spec;
4495 } else {
4496 mMagnificationSpec = null;
4497 }
Jackal Guo818c3f12019-03-08 18:00:39 +08004498 // Re-parent IME's SurfaceControl when MagnificationSpec changed.
4499 updateImeParent();
Robert Carr24be9ab2018-04-30 17:54:53 -07004500
Robert Carr7603dea2019-07-17 13:16:21 -07004501 if (spec.scale != 1.0) {
4502 applyMagnificationSpec(getPendingTransaction(), spec);
4503 } else {
4504 clearMagnificationSpec(getPendingTransaction());
4505 }
Robert Carrf59b8dd2017-10-02 18:58:36 -07004506 getPendingTransaction().apply();
Robert Carrb1579c82017-09-05 14:54:47 -07004507 }
4508
Robert Carr24be9ab2018-04-30 17:54:53 -07004509 void reapplyMagnificationSpec() {
4510 if (mMagnificationSpec != null) {
4511 applyMagnificationSpec(getPendingTransaction(), mMagnificationSpec);
4512 }
4513 }
4514
Robert Carrb1579c82017-09-05 14:54:47 -07004515 @Override
Wale Ogunwalec17418e2019-10-13 23:00:40 +02004516 void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
Robert Carrb1579c82017-09-05 14:54:47 -07004517 // Since we are the top of the SurfaceControl hierarchy here
4518 // we create the root surfaces explicitly rather than chaining
Riddle Hsu3a4bb612019-01-31 00:02:22 +08004519 // up as the default implementation in onParentChanged does. So we
Robert Carrb1579c82017-09-05 14:54:47 -07004520 // explicitly do NOT call super here.
Garfield Tanfbd233a2019-12-26 12:39:25 -08004521
4522 if (!isReady()) {
4523 // TODO(b/62541591): evaluate whether this is the best spot to declare the
4524 // {@link DisplayContent} ready for use.
4525 mDisplayReady = true;
4526
4527 mWmService.mAnimator.addDisplayLocked(mDisplayId);
4528
4529 if (mWmService.mDisplayManagerInternal != null) {
4530 mWmService.mDisplayManagerInternal
4531 .setDisplayInfoOverrideFromWindowManager(mDisplayId, getDisplayInfo());
4532 configureDisplayPolicy();
4533 }
4534
4535 reconfigureDisplayLocked();
4536 onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration());
4537 mWmService.mDisplayNotificationController.dispatchDisplayAdded(this);
4538 }
Robert Carrb1579c82017-09-05 14:54:47 -07004539 }
4540
4541 @Override
4542 void assignChildLayers(SurfaceControl.Transaction t) {
chaviw8065f442019-11-18 13:20:58 -08004543 mWindowContainers.assignLayer(t, 0);
4544 mOverlayContainers.assignLayer(t, 1);
Robert Carrb1579c82017-09-05 14:54:47 -07004545
chaviw8065f442019-11-18 13:20:58 -08004546 mWindowContainers.assignChildLayers(t);
4547 mOverlayContainers.assignChildLayers(t);
Robert Carrb1579c82017-09-05 14:54:47 -07004548 }
4549
4550 /**
4551 * Here we satisfy an unfortunate special case of the IME in split-screen mode. Imagine
4552 * that the IME target is one of the docked applications. We'd like the docked divider to be
4553 * above both of the applications, and we'd like the IME to be above the docked divider.
4554 * However we need child windows of the applications to be above the IME (Text drag handles).
4555 * This is a non-strictly hierarcical layering and we need to break out of the Z ordering
4556 * somehow. We do this by relatively ordering children of the target to the IME in cooperation
Tiger Huang7c610aa2018-10-27 00:01:01 +08004557 * with {@link WindowState#assignLayer}
Robert Carrb1579c82017-09-05 14:54:47 -07004558 */
4559 void assignRelativeLayerForImeTargetChild(SurfaceControl.Transaction t, WindowContainer child) {
Adrian Roosefa40702020-01-08 17:58:45 +01004560 mImeWindowsContainers.setNeedsLayer();
Robert Carrbb5de662018-04-26 13:29:51 -07004561 child.assignRelativeLayer(t, mImeWindowsContainers.getSurfaceControl(), 1);
Robert Carrb1579c82017-09-05 14:54:47 -07004562 }
4563
4564 @Override
Jorim Jaggi9af095b2017-12-12 17:18:57 +01004565 void prepareSurfaces() {
Jorim Jaggi4981f152019-03-26 18:58:45 +01004566 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareSurfaces");
4567 try {
Tiger Huanged6794e2019-05-07 20:07:59 +08004568 final Transaction transaction = getPendingTransaction();
Jorim Jaggi4981f152019-03-26 18:58:45 +01004569 super.prepareSurfaces();
Tiger Huanged6794e2019-05-07 20:07:59 +08004570
4571 // TODO: Once we totally eliminate global transaction we will pass transaction in here
4572 // rather than merging to global.
4573 SurfaceControl.mergeToGlobalTransaction(transaction);
Jorim Jaggi4981f152019-03-26 18:58:45 +01004574 } finally {
4575 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
4576 }
Jorim Jaggi9af095b2017-12-12 17:18:57 +01004577 }
Robert Carr2f8aa392018-01-31 14:46:51 -08004578
Jorim Jaggibe418292018-03-26 16:14:12 +02004579 void assignStackOrdering() {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07004580 for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) {
4581 getTaskDisplayAreaAt(i).assignStackOrdering(getPendingTransaction());
4582 }
Robert Carr2f8aa392018-01-31 14:46:51 -08004583 }
Chavi Weingarten3a748552018-05-14 17:32:42 +00004584
4585 /**
4586 * Increment the deferral count to determine whether to update the IME target.
4587 */
4588 void deferUpdateImeTarget() {
4589 mDeferUpdateImeTargetCount++;
4590 }
4591
4592 /**
4593 * Decrement the deferral count to determine whether to update the IME target. If the count
4594 * reaches 0, a new ime target will get computed.
4595 */
4596 void continueUpdateImeTarget() {
4597 if (mDeferUpdateImeTargetCount == 0) {
4598 return;
4599 }
4600
4601 mDeferUpdateImeTargetCount--;
4602 if (mDeferUpdateImeTargetCount == 0) {
4603 computeImeTarget(true /* updateImeTarget */);
4604 }
4605 }
4606
4607 /**
4608 * @return Whether a new IME target should be computed.
4609 */
4610 private boolean canUpdateImeTarget() {
4611 return mDeferUpdateImeTargetCount == 0;
4612 }
Arthur Hung95b38a92018-07-20 18:56:12 +08004613
4614 InputMonitor getInputMonitor() {
4615 return mInputMonitor;
4616 }
Jorim Jaggif1292892018-09-10 11:58:13 +02004617
4618 /**
4619 * @return Cached value whether we told display manager that we have content.
4620 */
4621 boolean getLastHasContent() {
4622 return mLastHasContent;
4623 }
Arthur Hungbe5ce212018-09-13 18:41:56 +08004624
4625 void registerPointerEventListener(@NonNull PointerEventListener listener) {
Riddle Hsu2588ab02019-02-25 14:23:56 +08004626 mPointerEventDispatcher.registerInputEventListener(listener);
Arthur Hungbe5ce212018-09-13 18:41:56 +08004627 }
4628
4629 void unregisterPointerEventListener(@NonNull PointerEventListener listener) {
Riddle Hsu2588ab02019-02-25 14:23:56 +08004630 mPointerEventDispatcher.unregisterInputEventListener(listener);
Arthur Hungbe5ce212018-09-13 18:41:56 +08004631 }
lumark588a3e82018-07-20 18:53:54 +08004632
4633 void prepareAppTransition(@WindowManager.TransitionType int transit,
Wale Ogunwale3a256e62018-12-06 14:41:18 -08004634 boolean alwaysKeepCurrent) {
4635 prepareAppTransition(transit, alwaysKeepCurrent, 0 /* flags */, false /* forceOverride */);
4636 }
4637
4638 void prepareAppTransition(@WindowManager.TransitionType int transit,
lumark588a3e82018-07-20 18:53:54 +08004639 boolean alwaysKeepCurrent, @WindowManager.TransitionFlags int flags,
4640 boolean forceOverride) {
4641 final boolean prepared = mAppTransition.prepareAppTransitionLocked(
4642 transit, alwaysKeepCurrent, flags, forceOverride);
4643 if (prepared && okToAnimate()) {
4644 mSkipAppTransitionAnimation = false;
4645 }
4646 }
4647
4648 void executeAppTransition() {
4649 if (mAppTransition.isTransitionSet()) {
Adrian Roosb125e0b2019-10-02 14:55:14 +02004650 ProtoLog.w(WM_DEBUG_APP_TRANSITIONS,
4651 "Execute app transition: %s, displayId: %d Callers=%s",
chaviw8065f442019-11-18 13:20:58 -08004652 mAppTransition, mDisplayId, Debug.getCallers(5));
lumark588a3e82018-07-20 18:53:54 +08004653 mAppTransition.setReady();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004654 mWmService.mWindowPlacerLocked.requestTraversal();
lumark588a3e82018-07-20 18:53:54 +08004655 }
4656 }
4657
4658 /**
4659 * Update pendingLayoutChanges after app transition has finished.
4660 */
4661 void handleAnimatingStoppedAndTransition() {
4662 int changes = 0;
4663
4664 mAppTransition.setIdle();
4665
4666 for (int i = mNoAnimationNotifyOnTransitionFinished.size() - 1; i >= 0; i--) {
4667 final IBinder token = mNoAnimationNotifyOnTransitionFinished.get(i);
4668 mAppTransition.notifyAppTransitionFinishedLocked(token);
4669 }
4670 mNoAnimationNotifyOnTransitionFinished.clear();
4671
4672 mWallpaperController.hideDeferredWallpapersIfNeeded();
4673
4674 onAppTransitionDone();
4675
4676 changes |= FINISH_LAYOUT_REDO_LAYOUT;
4677 if (DEBUG_WALLPAPER_LIGHT) {
4678 Slog.v(TAG_WM, "Wallpaper layer changed: assigning layers + relayout");
4679 }
4680 computeImeTarget(true /* updateImeTarget */);
wilsonshihc32538e2018-11-07 17:27:34 +08004681 mWallpaperMayChange = true;
lumark588a3e82018-07-20 18:53:54 +08004682 // Since the window list has been rebuilt, focus might have to be recomputed since the
4683 // actual order of windows might have changed again.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004684 mWmService.mFocusMayChange = true;
lumark588a3e82018-07-20 18:53:54 +08004685
4686 pendingLayoutChanges |= changes;
4687 }
Andrii Kulian15cfb422018-11-07 13:38:49 -08004688
Wale Ogunwale3a256e62018-12-06 14:41:18 -08004689 /** Check if pending app transition is for activity / task launch. */
4690 boolean isNextTransitionForward() {
4691 final int transit = mAppTransition.getAppTransition();
4692 return transit == TRANSIT_ACTIVITY_OPEN
4693 || transit == TRANSIT_TASK_OPEN
4694 || transit == TRANSIT_TASK_TO_FRONT;
4695 }
4696
Andrii Kulian15cfb422018-11-07 13:38:49 -08004697 /**
4698 * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
4699 */
4700 boolean supportsSystemDecorations() {
Arthur Hung879a8ab2019-03-13 19:51:10 +08004701 return (mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(this)
Andrii Kuliandd989612019-02-21 12:13:28 -08004702 || (mDisplay.getFlags() & FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0
Chilun891aed22019-05-02 18:08:47 +08004703 || (mWmService.mForceDesktopModeOnExternalDisplays && !isUntrustedVirtualDisplay()))
Arthur Hung879a8ab2019-03-13 19:51:10 +08004704 // VR virtual display will be used to run and render 2D app within a VR experience.
4705 && mDisplayId != mWmService.mVr2dDisplayId;
Andrii Kulian15cfb422018-11-07 13:38:49 -08004706 }
chaviwff2e7d82018-11-02 11:11:27 -07004707
Tiger Huang04dc4cc2019-01-17 18:41:41 +08004708 /**
Chilun891aed22019-05-02 18:08:47 +08004709 * @return {@code true} if the display is non-system created virtual display.
4710 */
4711 boolean isUntrustedVirtualDisplay() {
4712 return mDisplay.getType() == Display.TYPE_VIRTUAL
4713 && mDisplay.getOwnerUid() != Process.SYSTEM_UID;
4714 }
4715
4716 /**
chaviw8065f442019-11-18 13:20:58 -08004717 * Re-parent the DisplayContent's top surface, {@link #mSurfaceControl} to the specified
4718 * SurfaceControl.
chaviwff2e7d82018-11-02 11:11:27 -07004719 *
Tiger Huangd8ec9382019-04-18 14:35:09 -07004720 * @param win The window which owns the SurfaceControl. This indicates the z-order of the
4721 * windows of this display against the windows on the parent display.
Tiger Huang04dc4cc2019-01-17 18:41:41 +08004722 * @param sc The new SurfaceControl, where the DisplayContent's surfaces will be re-parented to.
chaviwff2e7d82018-11-02 11:11:27 -07004723 */
Tiger Huangd8ec9382019-04-18 14:35:09 -07004724 void reparentDisplayContent(WindowState win, SurfaceControl sc) {
4725 mParentWindow = win;
Jackal Guoc43a0a62019-04-23 09:15:14 +08004726 mParentWindow.addEmbeddedDisplayContent(this);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08004727 mParentSurfaceControl = sc;
4728 if (mPortalWindowHandle == null) {
4729 mPortalWindowHandle = createPortalWindowHandle(sc.toString());
4730 }
Tiger Huanged6794e2019-05-07 20:07:59 +08004731 getPendingTransaction().setInputWindowInfo(sc, mPortalWindowHandle)
Vadim Caen1812c762019-08-12 11:38:22 +02004732 .reparent(mSurfaceControl, sc);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08004733 }
4734
Tiger Huangd8ec9382019-04-18 14:35:09 -07004735 /**
4736 * Get the window which owns the surface that this DisplayContent is re-parented to.
4737 *
4738 * @return the parent window.
4739 */
4740 WindowState getParentWindow() {
4741 return mParentWindow;
4742 }
4743
4744 /**
4745 * Update the location of this display in the parent window. This enables windows in this
4746 * display to compute the global transformation matrix.
4747 *
4748 * @param win The parent window of this display.
4749 * @param x The x coordinate in the parent window.
4750 * @param y The y coordinate in the parent window.
4751 */
4752 void updateLocation(WindowState win, int x, int y) {
4753 if (mParentWindow != win) {
4754 throw new IllegalArgumentException(
4755 "The given window is not the parent window of this display.");
4756 }
Jackal Guoc43a0a62019-04-23 09:15:14 +08004757 if (!mLocationInParentWindow.equals(x, y)) {
4758 mLocationInParentWindow.set(x, y);
Tiger Huangd8ec9382019-04-18 14:35:09 -07004759 if (mWmService.mAccessibilityController != null) {
Jacky Kaof93252b2019-07-18 15:19:52 +08004760 mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(mDisplayId);
Tiger Huangd8ec9382019-04-18 14:35:09 -07004761 }
Jackal Guoc43a0a62019-04-23 09:15:14 +08004762 notifyLocationInParentDisplayChanged();
Tiger Huangd8ec9382019-04-18 14:35:09 -07004763 }
4764 }
4765
4766 Point getLocationInParentWindow() {
4767 return mLocationInParentWindow;
4768 }
4769
Jackal Guoc43a0a62019-04-23 09:15:14 +08004770 Point getLocationInParentDisplay() {
4771 final Point location = new Point();
4772 if (mParentWindow != null) {
4773 // LocationInParentWindow indicates the offset to (0,0) of window, but what we need is
4774 // the offset to (0,0) of display.
4775 DisplayContent dc = this;
4776 do {
4777 final WindowState displayParent = dc.getParentWindow();
4778 location.x += displayParent.getFrameLw().left
4779 + (dc.getLocationInParentWindow().x * displayParent.mGlobalScale + 0.5f);
4780 location.y += displayParent.getFrameLw().top
4781 + (dc.getLocationInParentWindow().y * displayParent.mGlobalScale + 0.5f);
4782 dc = displayParent.getDisplayContent();
4783 } while (dc != null && dc.getParentWindow() != null);
4784 }
4785 return location;
4786 }
4787
4788 void notifyLocationInParentDisplayChanged() {
4789 forAllWindows(w -> {
4790 w.updateLocationInParentDisplayIfNeeded();
4791 }, false /* traverseTopToBottom */);
4792 }
4793
Tarandeep Singha6f35612019-01-11 19:50:46 -08004794 @VisibleForTesting
4795 SurfaceControl getWindowingLayer() {
chaviw8065f442019-11-18 13:20:58 -08004796 return mWindowContainers.getSurfaceControl();
Tarandeep Singha6f35612019-01-11 19:50:46 -08004797 }
4798
Adrian Roos329cbd02020-04-14 15:42:41 +02004799 @VisibleForTesting
4800 WindowContainer<?> getImeContainer() {
4801 return mImeWindowsContainers;
4802 }
4803
Vadim Caenf8474262019-08-12 17:52:01 +02004804 SurfaceControl getOverlayLayer() {
chaviw8065f442019-11-18 13:20:58 -08004805 return mOverlayContainers.getSurfaceControl();
Vadim Caenf8474262019-08-12 17:52:01 +02004806 }
4807
Tiger Huang04dc4cc2019-01-17 18:41:41 +08004808 /**
Adrian Roos4ffc8972019-02-07 20:45:11 +01004809 * Updates the display's system gesture exclusion.
4810 *
4811 * @return true, if the exclusion changed.
4812 */
4813 boolean updateSystemGestureExclusion() {
4814 if (mSystemGestureExclusionListeners.getRegisteredCallbackCount() == 0) {
4815 // No one's interested anyways.
4816 return false;
4817 }
4818
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004819 final Region systemGestureExclusion = Region.obtain();
4820 mSystemGestureExclusionWasRestricted = calculateSystemGestureExclusion(
4821 systemGestureExclusion, mSystemGestureExclusionUnrestricted);
Adrian Roos4ffc8972019-02-07 20:45:11 +01004822 try {
4823 if (mSystemGestureExclusion.equals(systemGestureExclusion)) {
4824 return false;
4825 }
4826 mSystemGestureExclusion.set(systemGestureExclusion);
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004827 final Region unrestrictedOrNull = mSystemGestureExclusionWasRestricted
4828 ? mSystemGestureExclusionUnrestricted : null;
Adrian Roos4ffc8972019-02-07 20:45:11 +01004829 for (int i = mSystemGestureExclusionListeners.beginBroadcast() - 1; i >= 0; --i) {
4830 try {
4831 mSystemGestureExclusionListeners.getBroadcastItem(i)
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004832 .onSystemGestureExclusionChanged(mDisplayId, systemGestureExclusion,
4833 unrestrictedOrNull);
Adrian Roos4ffc8972019-02-07 20:45:11 +01004834 } catch (RemoteException e) {
4835 Slog.e(TAG, "Failed to notify SystemGestureExclusionListener", e);
4836 }
4837 }
4838 mSystemGestureExclusionListeners.finishBroadcast();
4839 return true;
4840 } finally {
4841 systemGestureExclusion.recycle();
4842 }
4843 }
4844
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004845 /**
4846 * Calculates the system gesture exclusion.
4847 *
4848 * @param outExclusion will be set to the gesture exclusion region
4849 * @param outExclusionUnrestricted will be set to the gesture exclusion region without
4850 * any restrictions applied.
4851 * @return whether any restrictions were applied, i.e. outExclusion and outExclusionUnrestricted
4852 * differ.
4853 */
Adrian Roos4ffc8972019-02-07 20:45:11 +01004854 @VisibleForTesting
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004855 boolean calculateSystemGestureExclusion(Region outExclusion, @Nullable
4856 Region outExclusionUnrestricted) {
4857 outExclusion.setEmpty();
4858 if (outExclusionUnrestricted != null) {
4859 outExclusionUnrestricted.setEmpty();
4860 }
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004861 final Region unhandled = Region.obtain();
4862 unhandled.set(0, 0, mDisplayFrames.mDisplayWidth, mDisplayFrames.mDisplayHeight);
4863
Tiger Huang332793b2019-10-29 23:21:27 +08004864 final Rect leftEdge = mInsetsStateController.getSourceProvider(ITYPE_LEFT_GESTURES)
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004865 .getSource().getFrame();
Tiger Huang332793b2019-10-29 23:21:27 +08004866 final Rect rightEdge = mInsetsStateController.getSourceProvider(ITYPE_RIGHT_GESTURES)
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004867 .getSource().getFrame();
4868
Adrian Roos4ffc8972019-02-07 20:45:11 +01004869 final Region touchableRegion = Region.obtain();
4870 final Region local = Region.obtain();
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004871 final int[] remainingLeftRight =
4872 {mSystemGestureExclusionLimit, mSystemGestureExclusionLimit};
Adrian Roos4ffc8972019-02-07 20:45:11 +01004873
Adrian Roosb1063792019-06-28 12:10:51 +02004874 // Traverse all windows top down to assemble the gesture exclusion rects.
Adrian Roos4ffc8972019-02-07 20:45:11 +01004875 // For each window, we only take the rects that fall within its touchable region.
4876 forAllWindows(w -> {
4877 if (w.cantReceiveTouchInput() || !w.isVisible()
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004878 || (w.getAttrs().flags & FLAG_NOT_TOUCHABLE) != 0
4879 || unhandled.isEmpty()) {
Adrian Roos4ffc8972019-02-07 20:45:11 +01004880 return;
4881 }
Adrian Roos4ffc8972019-02-07 20:45:11 +01004882
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004883 // Get the touchable region of the window, and intersect with where the screen is still
4884 // touchable, i.e. touchable regions on top are not covering it yet.
Adrian Roosb1063792019-06-28 12:10:51 +02004885 w.getEffectiveTouchableRegion(touchableRegion);
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004886 touchableRegion.op(unhandled, Op.INTERSECT);
Adrian Roos4ffc8972019-02-07 20:45:11 +01004887
Adrian Roos019a52b2019-07-02 16:47:44 +02004888 if (w.isImplicitlyExcludingAllSystemGestures()) {
4889 local.set(touchableRegion);
4890 } else {
4891 rectListToRegion(w.getSystemGestureExclusion(), local);
Adrian Roos4ffc8972019-02-07 20:45:11 +01004892
Adrian Roos019a52b2019-07-02 16:47:44 +02004893 // Transform to display coordinates
4894 local.scale(w.mGlobalScale);
4895 final Rect frame = w.getWindowFrames().mFrame;
4896 local.translate(frame.left, frame.top);
Adrian Roos4ffc8972019-02-07 20:45:11 +01004897
Adrian Roos019a52b2019-07-02 16:47:44 +02004898 // A window can only exclude system gestures where it is actually touchable
4899 local.op(touchableRegion, Op.INTERSECT);
4900 }
Adrian Roos4ffc8972019-02-07 20:45:11 +01004901
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004902 // Apply restriction if necessary.
4903 if (needsGestureExclusionRestrictions(w, mLastDispatchedSystemUiVisibility)) {
4904
4905 // Processes the region along the left edge.
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004906 remainingLeftRight[0] = addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
4907 remainingLeftRight[0], w, EXCLUSION_LEFT);
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004908
4909 // Processes the region along the right edge.
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004910 remainingLeftRight[1] = addToGlobalAndConsumeLimit(local, outExclusion, rightEdge,
4911 remainingLeftRight[1], w, EXCLUSION_RIGHT);
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004912
4913 // Adds the middle (unrestricted area)
4914 final Region middle = Region.obtain(local);
4915 middle.op(leftEdge, Op.DIFFERENCE);
4916 middle.op(rightEdge, Op.DIFFERENCE);
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004917 outExclusion.op(middle, Op.UNION);
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004918 middle.recycle();
4919 } else {
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004920 boolean loggable = needsGestureExclusionRestrictions(w, 0 /* lastSysUiVis */);
4921 if (loggable) {
4922 addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
4923 Integer.MAX_VALUE, w, EXCLUSION_LEFT);
4924 addToGlobalAndConsumeLimit(local, outExclusion, rightEdge,
4925 Integer.MAX_VALUE, w, EXCLUSION_RIGHT);
4926 }
4927 outExclusion.op(local, Op.UNION);
4928 }
4929 if (outExclusionUnrestricted != null) {
4930 outExclusionUnrestricted.op(local, Op.UNION);
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004931 }
4932 unhandled.op(touchableRegion, Op.DIFFERENCE);
4933 }, true /* topToBottom */);
Adrian Roos4ffc8972019-02-07 20:45:11 +01004934 local.recycle();
4935 touchableRegion.recycle();
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004936 unhandled.recycle();
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004937 return remainingLeftRight[0] < mSystemGestureExclusionLimit
4938 || remainingLeftRight[1] < mSystemGestureExclusionLimit;
Adrian Roos4ffc8972019-02-07 20:45:11 +01004939 }
4940
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004941 /**
4942 * @return Whether gesture exclusion area should be restricted from the window depending on the
4943 * current SystemUI visibility flags.
4944 */
4945 private static boolean needsGestureExclusionRestrictions(WindowState win, int sysUiVisibility) {
4946 final int type = win.mAttrs.type;
4947 final int stickyHideNavFlags =
4948 SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
4949 final boolean stickyHideNav =
4950 (sysUiVisibility & stickyHideNavFlags) == stickyHideNavFlags;
wilsonshihe8321942019-10-18 18:39:46 +08004951 return !stickyHideNav && type != TYPE_INPUT_METHOD && type != TYPE_NOTIFICATION_SHADE
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004952 && win.getActivityType() != ACTIVITY_TYPE_HOME;
4953 }
4954
4955 /**
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004956 * @return Whether gesture exclusion area should be logged for the given window
4957 */
4958 static boolean logsGestureExclusionRestrictions(WindowState win) {
Adrian Roos1c2e9a12019-08-20 18:23:47 +02004959 if (win.mWmService.mConstants.mSystemGestureExclusionLogDebounceTimeoutMillis <= 0) {
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004960 return false;
4961 }
4962 final WindowManager.LayoutParams attrs = win.getAttrs();
4963 final int type = attrs.type;
4964 return type != TYPE_WALLPAPER
4965 && type != TYPE_APPLICATION_STARTING
4966 && type != TYPE_NAVIGATION_BAR
4967 && (attrs.flags & FLAG_NOT_TOUCHABLE) == 0
4968 && needsGestureExclusionRestrictions(win, 0 /* sysUiVisibility */)
4969 && win.getDisplayContent().mDisplayPolicy.hasSideGestures();
4970 }
4971
4972 /**
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004973 * Adds a local gesture exclusion area to the global area while applying a limit per edge.
4974 *
4975 * @param local The gesture exclusion area to add.
4976 * @param global The destination.
4977 * @param edge Only processes the part in that region.
4978 * @param limit How much limit in pixels we have.
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004979 * @param win The WindowState that is being processed
4980 * @param side The side that is being processed, either {@link WindowState#EXCLUSION_LEFT} or
4981 * {@link WindowState#EXCLUSION_RIGHT}
4982 * @return How much of the limit is remaining.
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004983 */
4984 private static int addToGlobalAndConsumeLimit(Region local, Region global, Rect edge,
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004985 int limit, WindowState win, int side) {
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004986 final Region r = Region.obtain(local);
4987 r.op(edge, Op.INTERSECT);
4988
4989 final int[] remaining = {limit};
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004990 final int[] requestedExclusion = {0};
Adrian Roos2351d5f2019-07-03 15:35:07 +02004991 forEachRectReverse(r, rect -> {
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004992 if (remaining[0] <= 0) {
4993 return;
4994 }
4995 final int height = rect.height();
Adrian Roos5f2c9a12019-07-03 18:31:46 +02004996 requestedExclusion[0] += height;
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004997 if (height > remaining[0]) {
Adrian Roos2351d5f2019-07-03 15:35:07 +02004998 rect.top = rect.bottom - remaining[0];
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02004999 }
5000 remaining[0] -= height;
5001 global.op(rect, Op.UNION);
5002 });
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005003
5004 final int grantedExclusion = limit - remaining[0];
5005 win.setLastExclusionHeights(side, requestedExclusion[0], grantedExclusion);
5006
Adrian Roosbf3bc1b2019-06-18 16:13:53 +02005007 r.recycle();
5008 return remaining[0];
5009 }
5010
Adrian Roos4ffc8972019-02-07 20:45:11 +01005011 void registerSystemGestureExclusionListener(ISystemGestureExclusionListener listener) {
5012 mSystemGestureExclusionListeners.register(listener);
5013 final boolean changed;
5014 if (mSystemGestureExclusionListeners.getRegisteredCallbackCount() == 1) {
5015 changed = updateSystemGestureExclusion();
5016 } else {
5017 changed = false;
5018 }
5019
5020 if (!changed) {
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005021 final Region unrestrictedOrNull = mSystemGestureExclusionWasRestricted
5022 ? mSystemGestureExclusionUnrestricted : null;
Adrian Roos4ffc8972019-02-07 20:45:11 +01005023 // If updateSystemGestureExclusion changed the exclusion, it will already have
5024 // notified the listener. Otherwise, we'll do it here.
5025 try {
Adrian Roos5f2c9a12019-07-03 18:31:46 +02005026 listener.onSystemGestureExclusionChanged(mDisplayId, mSystemGestureExclusion,
5027 unrestrictedOrNull);
Adrian Roos4ffc8972019-02-07 20:45:11 +01005028 } catch (RemoteException e) {
5029 Slog.e(TAG, "Failed to notify SystemGestureExclusionListener during register", e);
5030 }
5031 }
5032 }
5033
5034 void unregisterSystemGestureExclusionListener(ISystemGestureExclusionListener listener) {
5035 mSystemGestureExclusionListeners.unregister(listener);
5036 }
5037
5038 /**
Tiger Huang04dc4cc2019-01-17 18:41:41 +08005039 * Create a portal window handle for input. This window transports any touch to the display
5040 * indicated by {@link InputWindowHandle#portalToDisplayId} if the touch hits this window.
5041 *
5042 * @param name The name of the portal window handle.
5043 * @return the new portal window handle.
5044 */
5045 private InputWindowHandle createPortalWindowHandle(String name) {
5046 // Let surface flinger to set the display ID of this input window handle because we don't
5047 // know which display the parent surface control is on.
5048 final InputWindowHandle portalWindowHandle = new InputWindowHandle(
Vishnu Nair18782162019-10-08 14:57:16 -07005049 null /* inputApplicationHandle */, INVALID_DISPLAY);
Tiger Huang04dc4cc2019-01-17 18:41:41 +08005050 portalWindowHandle.name = name;
5051 portalWindowHandle.token = new Binder();
5052 portalWindowHandle.layoutParamsFlags =
5053 FLAG_SPLIT_TOUCH | FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL;
5054 getBounds(mTmpBounds);
5055 portalWindowHandle.touchableRegion.set(mTmpBounds);
5056 portalWindowHandle.scaleFactor = 1f;
5057 portalWindowHandle.ownerPid = Process.myPid();
5058 portalWindowHandle.ownerUid = Process.myUid();
5059 portalWindowHandle.portalToDisplayId = mDisplayId;
5060 return portalWindowHandle;
chaviwff2e7d82018-11-02 11:11:27 -07005061 }
Issei Suzukia5dbf522019-02-01 17:58:15 +01005062
5063 /**
5064 * @see IWindowManager#setForwardedInsets
5065 */
5066 public void setForwardedInsets(Insets insets) {
5067 if (insets == null) {
5068 insets = Insets.NONE;
5069 }
5070 if (mDisplayPolicy.getForwardedInsets().equals(insets)) {
5071 return;
5072 }
5073 mDisplayPolicy.setForwardedInsets(insets);
5074 setLayoutNeeded();
5075 mWmService.mWindowPlacerLocked.requestTraversal();
5076 }
Susi Kharraz-Post9893b8c2019-02-12 14:21:29 -05005077
5078 protected MetricsLogger getMetricsLogger() {
5079 if (mMetricsLogger == null) {
5080 mMetricsLogger = new MetricsLogger();
5081 }
5082 return mMetricsLogger;
5083 }
Louis Chang677921f2019-12-06 16:44:24 +08005084
5085 void onDisplayChanged() {
Jorim Jaggi7c579cd2020-03-25 18:42:49 +01005086 mDisplay.getRealSize(mTmpDisplaySize);
5087 setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y);
5088 updateDisplayInfo();
5089
Louis Chang677921f2019-12-06 16:44:24 +08005090 // The window policy is responsible for stopping activities on the default display.
5091 final int displayId = mDisplay.getDisplayId();
5092 if (displayId != DEFAULT_DISPLAY) {
5093 final int displayState = mDisplay.getState();
5094 if (displayState == Display.STATE_OFF && mOffToken == null) {
5095 mOffToken = mAtmService.acquireSleepToken("Display-off", displayId);
5096 } else if (displayState == Display.STATE_ON && mOffToken != null) {
5097 mOffToken.release();
5098 mOffToken = null;
5099 }
5100 }
Louis Chang677921f2019-12-06 16:44:24 +08005101 mWmService.requestTraversal();
5102 }
5103
Wale Ogunwale0d465192020-01-23 19:14:44 -08005104 static boolean alwaysCreateStack(int windowingMode, int activityType) {
Louis Chang677921f2019-12-06 16:44:24 +08005105 // Always create a stack for fullscreen, freeform, and split-screen-secondary windowing
5106 // modes so that we can manage visual ordering and return types correctly.
5107 return activityType == ACTIVITY_TYPE_STANDARD
5108 && (windowingMode == WINDOWING_MODE_FULLSCREEN
5109 || windowingMode == WINDOWING_MODE_FREEFORM
Evan Rosky688c8382020-04-03 17:27:08 -07005110 || windowingMode == WINDOWING_MODE_PINNED
Robert Carrcb1dde62020-02-06 13:53:46 -08005111 || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
5112 || windowingMode == WINDOWING_MODE_MULTI_WINDOW);
Louis Chang677921f2019-12-06 16:44:24 +08005113 }
5114
Andrii Kulianf9df4a82020-03-31 12:09:27 -07005115 @Nullable
Louis Chang677921f2019-12-06 16:44:24 +08005116 ActivityStack getFocusedStack() {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07005117 for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) {
5118 final ActivityStack stack = getTaskDisplayAreaAt(i).getFocusedStack();
5119 if (stack != null) {
5120 return stack;
5121 }
5122 }
5123 return null;
Louis Chang677921f2019-12-06 16:44:24 +08005124 }
5125
5126 /**
5127 * Removes stacks in the input windowing modes from the system if they are of activity type
5128 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
5129 */
5130 void removeStacksInWindowingModes(int... windowingModes) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07005131 for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) {
5132 getTaskDisplayAreaAt(i).removeStacksInWindowingModes(windowingModes);
5133 }
Louis Chang677921f2019-12-06 16:44:24 +08005134 }
5135
5136 void removeStacksWithActivityTypes(int... activityTypes) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07005137 for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) {
5138 getTaskDisplayAreaAt(i).removeStacksWithActivityTypes(activityTypes);
5139 }
Louis Chang677921f2019-12-06 16:44:24 +08005140 }
5141
5142 ActivityRecord topRunningActivity() {
5143 return topRunningActivity(false /* considerKeyguardState */);
5144 }
5145
5146 /**
5147 * Returns the top running activity in the focused stack. In the case the focused stack has no
5148 * such activity, the next focusable stack on this display is returned.
5149 *
5150 * @param considerKeyguardState Indicates whether the locked state should be considered. if
5151 * {@code true} and the keyguard is locked, only activities that
5152 * can be shown on top of the keyguard will be considered.
5153 * @return The top running activity. {@code null} if none is available.
5154 */
5155 ActivityRecord topRunningActivity(boolean considerKeyguardState) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07005156 for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) {
5157 final ActivityRecord activity = getTaskDisplayAreaAt(i)
5158 .topRunningActivity(considerKeyguardState);
5159 if (activity != null) {
5160 return activity;
5161 }
5162 }
5163 return null;
Louis Chang677921f2019-12-06 16:44:24 +08005164 }
5165
5166 boolean updateDisplayOverrideConfigurationLocked() {
5167 Configuration values = new Configuration();
5168 computeScreenConfiguration(values);
5169
5170 mAtmService.mH.sendMessage(PooledLambda.obtainMessage(
5171 ActivityManagerInternal::updateOomLevelsForDisplay, mAtmService.mAmInternal,
5172 mDisplayId));
5173
5174 Settings.System.clearConfiguration(values);
5175 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
5176 false /* deferResume */, mAtmService.mTmpUpdateConfigurationResult);
5177 return mAtmService.mTmpUpdateConfigurationResult.changes != 0;
5178 }
5179
5180 /**
5181 * Updates override configuration specific for the selected display. If no config is provided,
5182 * new one will be computed in WM based on current display info.
5183 */
5184 boolean updateDisplayOverrideConfigurationLocked(Configuration values,
5185 ActivityRecord starting, boolean deferResume,
5186 ActivityTaskManagerService.UpdateConfigurationResult result) {
5187
5188 int changes = 0;
5189 boolean kept = true;
5190
5191 mAtmService.deferWindowLayout();
5192 try {
5193 if (values != null) {
5194 if (mDisplayId == DEFAULT_DISPLAY) {
5195 // Override configuration of the default display duplicates global config, so
5196 // we're calling global config update instead for default display. It will also
5197 // apply the correct override config.
5198 changes = mAtmService.updateGlobalConfigurationLocked(values,
5199 false /* initLocale */, false /* persistent */,
5200 UserHandle.USER_NULL /* userId */, deferResume);
5201 } else {
5202 changes = performDisplayOverrideConfigUpdate(values, deferResume);
5203 }
5204 }
5205
5206 kept = mAtmService.ensureConfigAndVisibilityAfterUpdate(starting, changes);
5207 } finally {
5208 mAtmService.continueWindowLayout();
5209 }
5210
5211 if (result != null) {
5212 result.changes = changes;
5213 result.activityRelaunched = !kept;
5214 }
5215 return kept;
5216 }
5217
5218 int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume) {
5219 mTempConfig.setTo(getRequestedOverrideConfiguration());
5220 final int changes = mTempConfig.updateFrom(values);
5221 if (changes != 0) {
5222 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
5223 + mTempConfig + " for displayId=" + mDisplayId);
5224 onRequestedOverrideConfigurationChanged(mTempConfig);
5225
5226 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
5227 if (isDensityChange && mDisplayId == DEFAULT_DISPLAY) {
5228 mAtmService.mAppWarnings.onDensityChanged();
5229
5230 // Post message to start process to avoid possible deadlock of calling into AMS with
5231 // the ATMS lock held.
5232 final Message msg = PooledLambda.obtainMessage(
5233 ActivityManagerInternal::killAllBackgroundProcessesExcept,
5234 mAtmService.mAmInternal, N,
5235 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
5236 mAtmService.mH.sendMessage(msg);
5237 }
5238 mWmService.mDisplayNotificationController.dispatchDisplayChanged(
5239 this, getConfiguration());
5240 }
5241 return changes;
5242 }
5243
5244 @Override
5245 public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
Riddle Hsu06aeb062020-03-24 23:38:40 +08005246 final Configuration currOverrideConfig = getRequestedOverrideConfiguration();
5247 final int currRotation = currOverrideConfig.windowConfiguration.getRotation();
5248 final int overrideRotation = overrideConfiguration.windowConfiguration.getRotation();
5249 if (currRotation != ROTATION_UNDEFINED && currRotation != overrideRotation) {
Riddle Hsud4957432020-04-24 22:06:29 +08005250 applyRotationAndFinishFixedRotation(currRotation, overrideRotation);
Louis Chang677921f2019-12-06 16:44:24 +08005251 }
Riddle Hsu06aeb062020-03-24 23:38:40 +08005252 mCurrentOverrideConfigurationChanges = currOverrideConfig.diff(overrideConfiguration);
Louis Chang677921f2019-12-06 16:44:24 +08005253 super.onRequestedOverrideConfigurationChanged(overrideConfiguration);
5254 mCurrentOverrideConfigurationChanges = 0;
5255 mWmService.setNewDisplayOverrideConfiguration(overrideConfiguration, this);
5256 mAtmService.addWindowLayoutReasons(
5257 ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED);
5258 }
5259
Riddle Hsufc246d12020-03-20 18:28:11 +08005260 /**
5261 * If the launching rotated activity ({@link #mFixedRotationLaunchingApp}) is null, it simply
5262 * applies the rotation to display. Otherwise because the activity has shown as rotated, the
5263 * fixed rotation transform also needs to be cleared to make sure the rotated activity fits
5264 * the display naturally.
5265 */
Riddle Hsud4957432020-04-24 22:06:29 +08005266 private void applyRotationAndFinishFixedRotation(int oldRotation, int newRotation) {
Riddle Hsu3691c1f2020-05-05 21:27:04 +08005267 final WindowToken rotatedLaunchingApp = mFixedRotationLaunchingApp;
5268 if (rotatedLaunchingApp == null) {
Riddle Hsufc246d12020-03-20 18:28:11 +08005269 applyRotation(oldRotation, newRotation);
5270 return;
5271 }
5272
Riddle Hsu3691c1f2020-05-05 21:27:04 +08005273 rotatedLaunchingApp.finishFixedRotationTransform(
Riddle Hsufc246d12020-03-20 18:28:11 +08005274 () -> applyRotation(oldRotation, newRotation));
5275 mFixedRotationLaunchingApp = null;
5276 }
5277
Louis Chang677921f2019-12-06 16:44:24 +08005278 /** Checks whether the given activity is in size compatibility mode and notifies the change. */
5279 void handleActivitySizeCompatModeIfNeeded(ActivityRecord r) {
5280 if (!r.isState(RESUMED) || r.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
5281 // The callback is only interested in the foreground changes of fullscreen activity.
5282 return;
5283 }
5284 if (!r.inSizeCompatMode()) {
5285 if (mLastCompatModeActivity != null) {
5286 mAtmService.getTaskChangeNotificationController()
5287 .notifySizeCompatModeActivityChanged(mDisplayId, null /* activityToken */);
5288 }
5289 mLastCompatModeActivity = null;
5290 return;
5291 }
5292 if (mLastCompatModeActivity == r) {
5293 return;
5294 }
5295 mLastCompatModeActivity = r;
5296 mAtmService.getTaskChangeNotificationController()
5297 .notifySizeCompatModeActivityChanged(mDisplayId, r.appToken);
5298 }
5299
5300 boolean isUidPresent(int uid) {
5301 final PooledPredicate p = PooledLambda.obtainPredicate(
5302 ActivityRecord::isUid, PooledLambda.__(ActivityRecord.class), uid);
5303 final boolean isUidPresent = mDisplayContent.getActivity(p) != null;
5304 p.recycle();
5305 return isUidPresent;
5306 }
5307
5308 /**
5309 * @see #mRemoved
5310 */
5311 boolean isRemoved() {
5312 return mRemoved;
5313 }
5314
5315 /**
5316 * @see #mRemoving
5317 */
5318 boolean isRemoving() {
5319 return mRemoving;
5320 }
5321
5322 void remove() {
5323 mRemoving = true;
Louis Chang677921f2019-12-06 16:44:24 +08005324 ActivityStack lastReparentedStack = null;
Louis Chang677921f2019-12-06 16:44:24 +08005325
Louis Chang149d5c82019-12-30 09:47:39 +08005326 mRootWindowContainer.mStackSupervisor.beginDeferResume();
Louis Chang677921f2019-12-06 16:44:24 +08005327 try {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07005328 int numTaskContainers = getTaskDisplayAreaCount();
5329 for (int tdaNdx = 0; tdaNdx < numTaskContainers; tdaNdx++) {
5330 final ActivityStack lastReparentedStackFromArea = getTaskDisplayAreaAt(tdaNdx)
5331 .remove();
5332 if (lastReparentedStackFromArea != null) {
5333 lastReparentedStack = lastReparentedStackFromArea;
Louis Chang677921f2019-12-06 16:44:24 +08005334 }
Louis Chang677921f2019-12-06 16:44:24 +08005335 }
5336 } finally {
Louis Chang149d5c82019-12-30 09:47:39 +08005337 mRootWindowContainer.mStackSupervisor.endDeferResume();
Louis Chang677921f2019-12-06 16:44:24 +08005338 }
5339 mRemoved = true;
5340
5341 // Only update focus/visibility for the last one because there may be many stacks are
5342 // reparented and the intermediate states are unnecessary.
5343 if (lastReparentedStack != null) {
5344 lastReparentedStack.postReparent();
5345 }
5346 releaseSelfIfNeeded();
Mehdi Alizadehf2b28e92019-12-05 20:13:49 -08005347 mDisplayPolicy.release();
Louis Chang677921f2019-12-06 16:44:24 +08005348
5349 if (!mAllSleepTokens.isEmpty()) {
Louis Chang149d5c82019-12-30 09:47:39 +08005350 mRootWindowContainer.mSleepTokens.removeAll(mAllSleepTokens);
Louis Chang677921f2019-12-06 16:44:24 +08005351 mAllSleepTokens.clear();
5352 mAtmService.updateSleepIfNeededLocked();
5353 }
5354 }
5355
Andrii Kulian9ea12da2020-03-27 17:16:38 -07005356 void releaseSelfIfNeeded() {
Louis Chang677921f2019-12-06 16:44:24 +08005357 if (!mRemoved) {
5358 return;
5359 }
5360
Andrii Kulianf9df4a82020-03-31 12:09:27 -07005361 // Check if all task display areas have only the empty home stacks left.
5362 boolean onlyEmptyHomeStacksLeft = true;
5363 for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
5364 final TaskDisplayArea taskDisplayArea = getTaskDisplayAreaAt(tdaNdx);
5365 if (taskDisplayArea.getStackCount() != 1) {
5366 onlyEmptyHomeStacksLeft = false;
5367 break;
5368 }
5369 final ActivityStack stack = taskDisplayArea.getStackAt(0);
5370 if (!stack.isActivityTypeHome() || stack.hasChild()) {
5371 onlyEmptyHomeStacksLeft = false;
5372 break;
5373 }
5374 }
5375 if (onlyEmptyHomeStacksLeft) {
5376 // Release this display if only empty home stack(s) are left. This display will be
5377 // released along with the stack(s) removal.
5378 for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
5379 final ActivityStack s = getTaskDisplayAreaAt(tdaNdx).getStackAt(0);
5380 s.removeIfPossible();
5381 }
Louis Chang677921f2019-12-06 16:44:24 +08005382 } else if (getTopStack() == null) {
5383 removeIfPossible();
Louis Chang149d5c82019-12-30 09:47:39 +08005384 mRootWindowContainer.mStackSupervisor
Louis Chang677921f2019-12-06 16:44:24 +08005385 .getKeyguardController().onDisplayRemoved(mDisplayId);
5386 }
5387 }
5388
5389 /** Update and get all UIDs that are present on the display and have access to it. */
5390 IntArray getPresentUIDs() {
5391 mDisplayAccessUIDs.clear();
5392 final PooledConsumer c = PooledLambda.obtainConsumer(DisplayContent::addActivityUid,
5393 PooledLambda.__(ActivityRecord.class), mDisplayAccessUIDs);
5394 mDisplayContent.forAllActivities(c);
5395 c.recycle();
5396 return mDisplayAccessUIDs;
5397 }
5398
5399 private static void addActivityUid(ActivityRecord r, IntArray uids) {
5400 uids.add(r.getUid());
5401 }
5402
5403 @VisibleForTesting
5404 boolean shouldDestroyContentOnRemove() {
5405 return mDisplay.getRemoveMode() == REMOVE_MODE_DESTROY_CONTENT;
5406 }
5407
5408 boolean shouldSleep() {
5409 return (getStackCount() == 0 || !mAllSleepTokens.isEmpty())
5410 && (mAtmService.mRunningVoice == null);
5411 }
5412
5413 void setFocusedApp(ActivityRecord r, boolean moveFocusNow) {
5414 final ActivityRecord newFocus;
5415 final IBinder token = r.appToken;
5416 if (token == null) {
5417 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Clearing focused app, displayId=%d",
5418 mDisplayId);
5419 newFocus = null;
5420 } else {
5421 newFocus = mWmService.mRoot.getActivityRecord(token);
5422 if (newFocus == null) {
5423 Slog.w(TAG_WM, "Attempted to set focus to non-existing app token: " + token
5424 + ", displayId=" + mDisplayId);
5425 }
5426 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
5427 "Set focused app to: %s moveFocusNow=%b displayId=%d", newFocus,
5428 moveFocusNow, mDisplayId);
5429 }
5430
5431 final boolean changed = setFocusedApp(newFocus);
5432 if (moveFocusNow && changed) {
5433 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
5434 true /*updateInputWindows*/);
5435 }
5436 }
5437
Louis Chang677921f2019-12-06 16:44:24 +08005438 void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
5439 boolean preserveWindows, boolean notifyClients) {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07005440 for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) {
5441 getTaskDisplayAreaAt(i).ensureActivitiesVisible(starting, configChanges,
5442 preserveWindows, notifyClients);
Louis Chang677921f2019-12-06 16:44:24 +08005443 }
5444 }
5445
Louis Chang677921f2019-12-06 16:44:24 +08005446 boolean isSleeping() {
5447 return mSleeping;
5448 }
5449
5450 void setIsSleeping(boolean asleep) {
5451 mSleeping = asleep;
5452 }
5453
Louis Chang677921f2019-12-06 16:44:24 +08005454 void setDisplayToSingleTaskInstance() {
Andrii Kulianf9df4a82020-03-31 12:09:27 -07005455 final int taskDisplayAreaCount = getTaskDisplayAreaCount();
5456 if (taskDisplayAreaCount > 1) {
5457 throw new IllegalArgumentException(
5458 "Display already has multiple task display areas. display=" + this);
5459 }
5460 final int stackCount = getDefaultTaskDisplayArea().getStackCount();
5461 if (stackCount > 1) {
Louis Chang677921f2019-12-06 16:44:24 +08005462 throw new IllegalArgumentException("Display already has multiple stacks. display="
5463 + this);
5464 }
Andrii Kulianf9df4a82020-03-31 12:09:27 -07005465 if (stackCount > 0) {
5466 final ActivityStack stack = getDefaultTaskDisplayArea().getStackAt(0);
Louis Chang677921f2019-12-06 16:44:24 +08005467 if (stack.getChildCount() > 1) {
5468 throw new IllegalArgumentException("Display stack already has multiple tasks."
5469 + " display=" + this + " stack=" + stack);
5470 }
5471 }
5472
5473 mSingleTaskInstance = true;
5474 }
5475
5476 /** Returns true if the display can only contain one task */
5477 boolean isSingleTaskInstance() {
5478 return mSingleTaskInstance;
5479 }
5480
5481 @VisibleForTesting
5482 void removeAllTasks() {
5483 forAllTasks((t) -> { t.getStack().removeChild(t, "removeAllTasks"); });
5484 }
5485
5486 /**
Charles Chen173ae782019-11-11 20:39:02 +08005487 * Similar to {@link RootWindowContainer#isAnyNonToastWindowVisibleForUid(int)}, but
5488 * used for pid.
5489 */
5490 boolean isAnyNonToastWindowVisibleForPid(int pid) {
5491 final PooledPredicate p = PooledLambda.obtainPredicate(
5492 WindowState::isNonToastWindowVisibleForPid,
5493 PooledLambda.__(WindowState.class), pid);
5494
5495 final WindowState w = getWindow(p);
5496 p.recycle();
5497 return w != null;
5498 }
5499
5500 Context getDisplayUiContext() {
5501 return mDisplayPolicy.getSystemUiContext();
5502 }
Evan Rosky8d782e02019-10-14 15:43:53 -07005503
chaviw945f7302020-02-24 14:35:33 -08005504 Point getDisplayPosition() {
5505 return mWmService.mDisplayManagerInternal.getDisplayPosition(getDisplayId());
5506 }
5507
Mark Renoufa9279292020-04-17 12:22:50 -04005508 /**
5509 * Locates the appropriate target window for scroll capture. The search progresses top to
5510 * bottom.
5511 * If {@code searchBehind} is non-null, the search will only consider windows behind this one.
5512 * If a valid taskId is specified, the target window must belong to the given task.
5513 *
5514 * @param searchBehind a window used to filter the search to windows behind it, or null to begin
5515 * the search at the top window of the display
5516 * @param taskId specifies the id of a task the result must belong to or
5517 * {@link android.app.ActivityTaskManager#INVALID_TASK_ID INVALID_TASK_ID}
5518 * to match any window
5519 * @return the located window or null if none could be found matching criteria
5520 */
5521 @Nullable
5522 WindowState findScrollCaptureTargetWindow(@Nullable WindowState searchBehind, int taskId) {
5523 return getWindow(new Predicate<WindowState>() {
5524 boolean behindTopWindow = (searchBehind == null); // optional filter
5525 @Override
5526 public boolean test(WindowState nextWindow) {
5527 // Skip through all windows until we pass topWindow (if specified)
5528 if (!behindTopWindow) {
5529 if (nextWindow == searchBehind) {
5530 behindTopWindow = true;
5531 }
5532 return false; /* continue */
5533 }
5534 if (taskId != INVALID_TASK_ID) {
5535 Task task = nextWindow.getTask();
5536 if (task == null || !task.isTaskId(taskId)) {
5537 return false; /* continue */
5538 }
5539 }
5540 if (!nextWindow.canReceiveKeys()) {
5541 return false; /* continue */
5542 }
5543 return true; /* stop */
5544 }
5545 });
5546 }
5547
Riddle Hsud4957432020-04-24 22:06:29 +08005548 /** The entry for proceeding to handle {@link #mFixedRotationLaunchingApp}. */
5549 class FixedRotationTransitionListener extends WindowManagerInternal.AppTransitionListener {
5550
Riddle Hsucbc5d272020-04-24 23:26:46 +08005551 /**
5552 * The animating activity which shows the recents task list. It is set between
5553 * {@link RecentsAnimationController#initialize} and
Riddle Hsu70a920c2020-05-05 17:20:32 +08005554 * {@link RecentsAnimationController#cleanupAnimation}.
Riddle Hsucbc5d272020-04-24 23:26:46 +08005555 */
5556 private ActivityRecord mAnimatingRecents;
5557
5558 /**
5559 * If the recents activity has a fixed orientation which is different from the current top
5560 * activity, it will be rotated before being shown so we avoid a screen rotation animation
5561 * when showing the Recents view.
5562 */
5563 void onStartRecentsAnimation(@NonNull ActivityRecord r) {
5564 mAnimatingRecents = r;
5565 rotateInDifferentOrientationIfNeeded(r);
5566 if (r.hasFixedRotationTransform()) {
5567 // Set the record so we can recognize it to continue to update display orientation
5568 // if the recents activity becomes the top later.
5569 setFixedRotationLaunchingApp(r, r.getWindowConfiguration().getRotation());
5570 }
5571 }
5572
5573 /**
5574 * If {@link #mAnimatingRecents} still has fixed rotation, it should be moved to top so we
5575 * don't clear {@link #mFixedRotationLaunchingApp} that will be handled by transition.
5576 */
Riddle Hsu70a920c2020-05-05 17:20:32 +08005577 void onFinishRecentsAnimation(boolean moveRecentsToBack) {
Riddle Hsucbc5d272020-04-24 23:26:46 +08005578 final ActivityRecord animatingRecents = mAnimatingRecents;
5579 mAnimatingRecents = null;
Riddle Hsu70a920c2020-05-05 17:20:32 +08005580 if (!moveRecentsToBack) {
5581 // The recents activity will be the top, such as staying at recents list or
5582 // returning to home (if home and recents are the same activity).
5583 return;
5584 }
5585
5586 if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp) {
5587 // Because it won't affect display orientation, just finish the transform.
5588 animatingRecents.finishFixedRotationTransform();
Riddle Hsucbc5d272020-04-24 23:26:46 +08005589 mFixedRotationLaunchingApp = null;
Riddle Hsu70a920c2020-05-05 17:20:32 +08005590 } else {
5591 // If there is already a launching activity that is not the recents, before its
5592 // transition is completed, the recents animation may be started. So if the recents
5593 // activity won't be the top, the display orientation should be updated according
5594 // to the current top activity.
5595 continueUpdateOrientationForDiffOrienLaunchingApp();
Riddle Hsucbc5d272020-04-24 23:26:46 +08005596 }
5597 }
5598
Riddle Hsud4957432020-04-24 22:06:29 +08005599 @Override
5600 public void onAppTransitionFinishedLocked(IBinder token) {
5601 final ActivityRecord r = getActivityRecord(token);
Riddle Hsucbc5d272020-04-24 23:26:46 +08005602 // Ignore the animating recents so the fixed rotation transform won't be switched twice
5603 // by finishing the recents animation and moving it to top. That also avoids flickering
5604 // due to wait for previous activity to be paused if it supports PiP that ignores the
5605 // effect of resume-while-pausing.
5606 if (r == null || r == mAnimatingRecents) {
Riddle Hsud4957432020-04-24 22:06:29 +08005607 return;
5608 }
5609 if (mFixedRotationLaunchingApp != null
5610 && mFixedRotationLaunchingApp.hasFixedRotationTransform(r)) {
5611 continueUpdateOrientationForDiffOrienLaunchingApp();
5612 } else {
5613 r.finishFixedRotationTransform();
5614 }
5615 }
5616
5617 @Override
5618 public void onAppTransitionCancelledLocked(int transit) {
5619 continueUpdateOrientationForDiffOrienLaunchingApp();
5620 }
5621
5622 @Override
5623 public void onAppTransitionTimeoutLocked() {
5624 continueUpdateOrientationForDiffOrienLaunchingApp();
5625 }
5626 }
5627
Evan Rosky8d782e02019-10-14 15:43:53 -07005628 class RemoteInsetsControlTarget implements InsetsControlTarget {
5629 private final IDisplayWindowInsetsController mRemoteInsetsController;
5630
5631 RemoteInsetsControlTarget(IDisplayWindowInsetsController controller) {
5632 mRemoteInsetsController = controller;
5633 }
5634
5635 void notifyInsetsChanged() {
5636 try {
5637 mRemoteInsetsController.insetsChanged(
5638 getInsetsStateController().getRawInsetsState());
5639 } catch (RemoteException e) {
5640 Slog.w(TAG, "Failed to deliver inset state change", e);
5641 }
5642 }
5643
5644 @Override
5645 public void notifyInsetsControlChanged() {
5646 final InsetsStateController stateController = getInsetsStateController();
5647 try {
5648 mRemoteInsetsController.insetsControlChanged(stateController.getRawInsetsState(),
5649 stateController.getControlsForDispatch(this));
5650 } catch (RemoteException e) {
5651 Slog.w(TAG, "Failed to deliver inset state change", e);
5652 }
5653 }
5654
5655 @Override
5656 public void showInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme) {
5657 try {
5658 mRemoteInsetsController.showInsets(types, fromIme);
5659 } catch (RemoteException e) {
5660 Slog.w(TAG, "Failed to deliver showInsets", e);
5661 }
5662 }
5663
5664 @Override
5665 public void hideInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme) {
5666 try {
5667 mRemoteInsetsController.hideInsets(types, fromIme);
5668 } catch (RemoteException e) {
5669 Slog.w(TAG, "Failed to deliver showInsets", e);
5670 }
5671 }
Yunfan Chenb83940c2020-04-06 16:43:09 +09005672
5673 @Override
5674 public boolean isClientControlled() {
5675 return false;
5676 }
Evan Rosky8d782e02019-10-14 15:43:53 -07005677 }
Charles Chen2622d3e2020-04-15 14:28:13 +08005678
5679 /**
5680 * Returns the number of window tokens without surface on this display. A {@link WindowToken}
5681 * won't have its {@link SurfaceControl} until a window is added to a {@link WindowToken}.
5682 * The purpose of this method is to accumulate non-window containing {@link WindowToken}s and
5683 * limit the usage if the count exceeds a number.
5684 *
5685 * @param callingUid app calling uid
5686 * @return the number of window tokens without surface on this display
5687 * @see WindowToken#addWindow(WindowState)
5688 */
5689 int getWindowTokensWithoutSurfaceCount(int callingUid) {
5690 List<WindowToken> tokens = new ArrayList<>(mTokenMap.values());
5691 int count = 0;
5692 for (int i = tokens.size() - 1; i >= 0; i--) {
5693 final WindowToken token = tokens.get(i);
5694 if (callingUid != token.getOwnerUid()) {
5695 continue;
5696 }
5697 // Skip if token is an Activity
5698 if (token.asActivityRecord() != null) {
5699 continue;
5700 }
5701 if (token.mSurfaceControl != null) {
5702 continue;
5703 }
5704 count++;
5705 }
5706 return count;
5707 }
Craig Mautner59c00972012-07-30 12:10:24 -07005708}