blob: 31e8bbdab71cfb7c6d99460e9c686a84cfa9bbe6 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Winson Chungbb348802017-01-30 12:01:45 -080019import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Riddle Hsuaec55442019-03-12 17:25:35 +080020import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
Ruben Brunkf53497c2017-03-27 20:26:17 -070021import static android.app.ActivityManager.TaskDescription.ATTR_TASKDESCRIPTION_PREFIX;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080022import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
23import static android.app.ActivityOptions.ANIM_CUSTOM;
24import static android.app.ActivityOptions.ANIM_NONE;
25import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
26import static android.app.ActivityOptions.ANIM_REMOTE_ANIMATION;
27import static android.app.ActivityOptions.ANIM_SCALE_UP;
Ruben Brunkf53497c2017-03-27 20:26:17 -070028import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080029import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
30import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP;
31import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
32import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
Louis Chang477e93e2019-04-24 18:35:20 +080033import static android.app.ActivityOptions.ANIM_UNDEFINED;
Riddle Hsu16567132018-08-16 21:37:47 +080034import static android.app.ActivityTaskManager.INVALID_STACK_ID;
Vishnu Nair9ba31652018-11-13 14:34:05 -080035import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Winson Chung59fda9e2017-01-20 16:14:51 -080036import static android.app.AppOpsManager.MODE_ALLOWED;
Winson Chungf4ac0632017-03-17 12:34:12 -070037import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
Vishnu Nair132ee832018-09-28 15:00:05 -070038import static android.app.WaitResult.INVALID_DELAY;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070039import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
40import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
41import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070042import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Riddle Hsu74826262019-04-17 14:57:42 +080043import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070044import static android.app.WindowConfiguration.activityTypeToString;
Ruben Brunkf53497c2017-03-27 20:26:17 -070045import static android.content.Intent.ACTION_MAIN;
46import static android.content.Intent.CATEGORY_HOME;
47import static android.content.Intent.CATEGORY_LAUNCHER;
Chilun2ef71f72018-11-16 17:57:15 +080048import static android.content.Intent.CATEGORY_SECONDARY_HOME;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080049import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
Bryce Leeb7c9b802017-05-02 14:20:24 -070050import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY;
Andrii Kulian21713ac2016-10-12 22:05:05 -070051import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
52import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
53import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
54import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
Zak Cohen90e7116742017-01-29 12:59:23 -080055import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
Wale Ogunwale822e5122017-07-26 06:02:24 -070056import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
Jorim Jaggi02886a82016-12-06 09:10:06 -080057import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080058import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
59import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
Issei Suzuki74e1eb22018-12-20 17:42:52 +010060import static android.content.pm.ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080061import static android.content.pm.ActivityInfo.FLAG_MULTIPROCESS;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020062import static android.content.pm.ActivityInfo.FLAG_NO_HISTORY;
Chong Zhang87761972016-08-22 13:53:24 -070063import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020064import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080065import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
chaviw59b98852017-06-13 12:05:44 -070066import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080067import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -080068import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
69import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080070import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
Charles He2bf28322017-10-12 22:24:49 +010071import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
72import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
73import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
74import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
Ruben Brunkf53497c2017-03-27 20:26:17 -070075import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS;
76import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY;
Wale Ogunwaledf241e92016-10-13 15:14:21 -070077import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Jorim Jaggicd13d332016-04-27 15:40:20 -070078import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Wale Ogunwale72a73e32016-10-13 12:16:39 -070079import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Wale Ogunwaledf241e92016-10-13 15:14:21 -070080import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -070081import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
82import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -070083import static android.content.res.Configuration.EMPTY;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -070084import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
85import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
Riddle Hsu0a343c32018-12-21 00:40:48 +080086import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
Ruben Brunkf53497c2017-03-27 20:26:17 -070087import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
Zak Cohen90e7116742017-01-29 12:59:23 -080088import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080089import static android.os.Build.VERSION_CODES.HONEYCOMB;
Zak Cohen90e7116742017-01-29 12:59:23 -080090import static android.os.Build.VERSION_CODES.O;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080091import static android.os.Process.SYSTEM_UID;
Issei Suzuki62356a22019-04-11 16:46:37 +020092import static android.view.Display.DEFAULT_DISPLAY;
Riddle Hsufd4a0502018-10-16 01:05:16 +080093import static android.view.Display.INVALID_DISPLAY;
Riddle Hsu61987bc2019-04-03 13:08:47 +080094import static android.view.Surface.ROTATION_270;
95import static android.view.Surface.ROTATION_90;
Andrii Kuliande93eff2019-07-12 12:21:27 -070096import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
97import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
Riddle Hsu16567132018-08-16 21:37:47 +080098
Vishnu Nair9ba31652018-11-13 14:34:05 -080099import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
100import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
101import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
102import static com.android.server.am.ActivityRecordProto.PROC_ID;
103import static com.android.server.am.ActivityRecordProto.STATE;
104import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
105import static com.android.server.am.ActivityRecordProto.VISIBLE;
106import static com.android.server.am.EventLogTags.AM_RELAUNCH_ACTIVITY;
107import static com.android.server.am.EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY;
Hui Yu03d12402018-12-06 18:00:37 -0800108import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700109import static com.android.server.wm.ActivityStack.ActivityState.FINISHING;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800110import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
111import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
112import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
Riddle Hsu7b766fd2019-01-28 21:14:59 +0800113import static com.android.server.wm.ActivityStack.ActivityState.RESTARTING_PROCESS;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800114import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
Louis Changeadb22f2019-06-19 12:09:23 +0800115import static com.android.server.wm.ActivityStack.ActivityState.STARTED;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800116import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
117import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
118import static com.android.server.wm.ActivityStack.LAUNCH_TICK;
119import static com.android.server.wm.ActivityStack.LAUNCH_TICK_MSG;
120import static com.android.server.wm.ActivityStack.PAUSE_TIMEOUT_MSG;
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800121import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800122import static com.android.server.wm.ActivityStack.STOP_TIMEOUT_MSG;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700123import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
124import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
Wale Ogunwale59507092018-10-29 09:00:30 -0700125import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700126import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONTAINERS;
Wale Ogunwale59507092018-10-29 09:00:30 -0700127import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700128import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
129import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
Wale Ogunwale59507092018-10-29 09:00:30 -0700130import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
131import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
132import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
Jorim Jaggi346702a2019-05-08 17:49:33 +0200133import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700134import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
Wale Ogunwale59507092018-10-29 09:00:30 -0700135import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
136import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700137import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONTAINERS;
Wale Ogunwale59507092018-10-29 09:00:30 -0700138import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700139import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE;
140import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
Wale Ogunwale59507092018-10-29 09:00:30 -0700141import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SAVED_STATE;
142import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
143import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700144import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TRANSITION;
145import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
Wale Ogunwale59507092018-10-29 09:00:30 -0700146import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
147import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
148import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwale59507092018-10-29 09:00:30 -0700149import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
150import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
Hui Yu03d12402018-12-06 18:00:37 -0800151import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -0700152import static com.android.server.wm.IdentifierProto.HASH_CODE;
153import static com.android.server.wm.IdentifierProto.TITLE;
154import static com.android.server.wm.IdentifierProto.USER_ID;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800155import static com.android.server.wm.TaskPersister.DEBUG;
156import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800157import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
158import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
159import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
160import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
161import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700162
Ruben Brunkf53497c2017-03-27 20:26:17 -0700163import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
164import static org.xmlpull.v1.XmlPullParser.END_TAG;
165import static org.xmlpull.v1.XmlPullParser.START_TAG;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800166
Andrii Kulian057a6512019-07-15 16:15:51 -0700167import android.annotation.IntDef;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700168import android.annotation.NonNull;
Issei Suzuki74e1eb22018-12-20 17:42:52 +0100169import android.annotation.Nullable;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700170import android.app.Activity;
Craig Mautner21d24a22014-04-23 11:45:37 -0700171import android.app.ActivityManager.TaskDescription;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700172import android.app.ActivityOptions;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800173import android.app.PendingIntent;
Winson Chung709904f2017-04-25 11:00:48 -0700174import android.app.PictureInPictureParams;
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800175import android.app.ResultInfo;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -0800176import android.app.WaitResult.LaunchState;
Riddle Hsu16567132018-08-16 21:37:47 +0800177import android.app.servertransaction.ActivityConfigurationChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800178import android.app.servertransaction.ActivityLifecycleItem;
179import android.app.servertransaction.ActivityRelaunchItem;
180import android.app.servertransaction.ClientTransaction;
181import android.app.servertransaction.ClientTransactionItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700182import android.app.servertransaction.MoveToDisplayItem;
183import android.app.servertransaction.MultiWindowModeChangeItem;
184import android.app.servertransaction.NewIntentItem;
Bryce Lee0bd8d422018-01-09 09:45:57 -0800185import android.app.servertransaction.PauseActivityItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700186import android.app.servertransaction.PipModeChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800187import android.app.servertransaction.ResumeActivityItem;
Riddle Hsu7b766fd2019-01-28 21:14:59 +0800188import android.app.servertransaction.StopActivityItem;
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800189import android.app.servertransaction.TopResumedActivityChangeItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700190import android.app.servertransaction.WindowVisibilityItem;
Hui Yu03d12402018-12-06 18:00:37 -0800191import android.app.usage.UsageEvents.Event;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192import android.content.ComponentName;
193import android.content.Intent;
194import android.content.pm.ActivityInfo;
195import android.content.pm.ApplicationInfo;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700196import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197import android.content.res.Configuration;
198import android.graphics.Bitmap;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800199import android.graphics.GraphicBuffer;
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700200import android.graphics.Rect;
Patrick Baumann78380272018-04-04 10:41:01 -0700201import android.os.Binder;
Bryce Lee39791592017-04-26 09:29:12 -0700202import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203import android.os.Bundle;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700204import android.os.Debug;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800205import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206import android.os.Message;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800207import android.os.PersistableBundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208import android.os.Process;
Dianne Hackborn39792d22010-08-19 18:01:52 -0700209import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700211import android.os.UserHandle;
Bryce Lee8558ec72017-08-17 15:37:26 -0700212import android.os.storage.StorageManager;
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800213import android.service.voice.IVoiceInteractionSession;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700214import android.util.ArraySet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215import android.util.EventLog;
216import android.util.Log;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700217import android.util.MergedConfiguration;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700218import android.util.Slog;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700219import android.util.TimeUtils;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700220import android.util.proto.ProtoOutputStream;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800221import android.view.AppTransitionAnimationSpec;
Riddle Hsu61987bc2019-04-03 13:08:47 +0800222import android.view.DisplayCutout;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800223import android.view.IAppTransitionAnimationSpecsFuture;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224import android.view.IApplicationToken;
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100225import android.view.RemoteAnimationDefinition;
Jorim Jaggife762342016-10-13 14:33:27 +0200226import android.view.WindowManager.LayoutParams;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700227
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700228import com.android.internal.R;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800229import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800230import com.android.internal.app.ResolverActivity;
231import com.android.internal.content.ReferrerIntent;
232import com.android.internal.util.XmlUtils;
233import com.android.server.AttributeCache;
Ruben Brunkf53497c2017-03-27 20:26:17 -0700234import com.android.server.AttributeCache.Entry;
Wale Ogunwale59507092018-10-29 09:00:30 -0700235import com.android.server.am.AppTimeTracker;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700236import com.android.server.am.EventLogTags;
Wale Ogunwale59507092018-10-29 09:00:30 -0700237import com.android.server.am.PendingIntentRecord;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800238import com.android.server.uri.UriPermissionOwner;
Wale Ogunwale59507092018-10-29 09:00:30 -0700239import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
240import com.android.server.wm.ActivityStack.ActivityState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241
Andrii Kuliande93eff2019-07-12 12:21:27 -0700242import com.google.android.collect.Sets;
243
Jorim Jaggi02886a82016-12-06 09:10:06 -0800244import org.xmlpull.v1.XmlPullParser;
245import org.xmlpull.v1.XmlPullParserException;
246import org.xmlpull.v1.XmlSerializer;
247
Suprabh Shukla23593142015-11-03 17:31:15 -0800248import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -0700249import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250import java.io.PrintWriter;
251import java.lang.ref.WeakReference;
252import java.util.ArrayList;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800253import java.util.Arrays;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254import java.util.HashSet;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700255import java.util.List;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700256import java.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257
258/**
259 * An entry in the history stack, representing an activity.
260 */
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800261final class ActivityRecord extends ConfigurationContainer {
Wale Ogunwale98875612018-10-12 07:53:02 -0700262 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_ATM;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700263 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700264 private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
265 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
266 private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
267 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700268 private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700269 private static final String TAG_STATES = TAG + POSTFIX_STATES;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700270 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
Andrii Kuliande93eff2019-07-12 12:21:27 -0700271 private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION;
272 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700273 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800274
Craig Mautner21d24a22014-04-23 11:45:37 -0700275 private static final String ATTR_ID = "id";
276 private static final String TAG_INTENT = "intent";
277 private static final String ATTR_USERID = "user_id";
278 private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle";
279 private static final String ATTR_LAUNCHEDFROMUID = "launched_from_uid";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700280 private static final String ATTR_LAUNCHEDFROMPACKAGE = "launched_from_package";
Craig Mautner21d24a22014-04-23 11:45:37 -0700281 private static final String ATTR_RESOLVEDTYPE = "resolved_type";
282 private static final String ATTR_COMPONENTSPECIFIED = "component_specified";
Dianne Hackborn337abb32014-09-24 12:44:29 -0700283 static final String ACTIVITY_ICON_SUFFIX = "_activity_icon_";
Craig Mautner21d24a22014-04-23 11:45:37 -0700284
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800285 final ActivityTaskManagerService mAtmService; // owner
Dianne Hackbornbe707852011-11-11 14:32:10 -0800286 final IApplicationToken.Stub appToken; // window manager token
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800287 // TODO: Remove after unification
288 AppWindowToken mAppWindowToken;
289
Andrii Kulianeceebbf2019-06-26 17:36:51 -0700290 final ActivityInfo info; // activity info provided by developer in AndroidManifest
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800291 final int launchedFromPid; // always the pid who started the activity.
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700292 final int launchedFromUid; // always the uid who started the activity.
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800293 final String launchedFromPackage; // always the package who started the activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800294 final int mUserId; // Which user is this running for?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 final Intent intent; // the original intent that generated us
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800296 final ComponentName mActivityComponent; // the intent component, or target of an alias.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 final String shortComponentName; // the short component name of the intent
298 final String resolvedType; // as per original caller;
299 final String packageName; // the package implementing intent's component
300 final String processName; // process where this component wants to run
301 final String taskAffinity; // as per ActivityInfo.taskAffinity
302 final boolean stateNotNeeded; // As per ActivityInfo.flags
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700303 boolean fullscreen; // The activity is opaque and fills the entire space of this task.
304 // TODO: See if it possible to combine this with the fullscreen field.
305 final boolean hasWallpaper; // Has a wallpaper window as a background.
Louis Changd58cb672018-12-24 17:45:16 +0800306 @VisibleForTesting
307 boolean noDisplay; // activity is not displayed?
308 @VisibleForTesting
309 int mHandoverLaunchDisplayId = INVALID_DISPLAY; // Handover launch display id to next activity.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800310 private final boolean componentSpecified; // did caller specify an explicit component?
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700311 final boolean rootVoiceInteraction; // was this the root activity of a voice interaction?
Craig Mautner86d67a42013-05-14 10:34:38 -0700312
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800313 private CharSequence nonLocalizedLabel; // the label information from the package mgr.
314 private int labelRes; // the label information from the package mgr.
315 private int icon; // resource identifier of activity's icon.
316 private int logo; // resource identifier of activity's logo.
317 private int theme; // resource identifier of activity's theme.
318 private int realTheme; // actual theme resource we will use, never 0.
319 private int windowFlags; // custom window flags for preview window.
Bryce Leeaf691c02017-03-20 14:20:22 -0700320 private TaskRecord task; // the task this is in.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800321 private long createTime = System.currentTimeMillis();
Andrii Kulian86e70fc2019-02-12 11:04:10 +0000322 long lastVisibleTime; // last time this activity became visible
323 long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity
324 long pauseTime; // last time we started pausing the activity
325 long launchTickTime; // base time for launch tick messages
326 long topResumedStateLossTime; // last time we reported top resumed state loss to an activity
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700327 // Last configuration reported to the activity in the client process.
328 private MergedConfiguration mLastReportedConfiguration;
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800329 private int mLastReportedDisplayId;
Winson Chung609e1e92017-05-08 10:52:12 -0700330 private boolean mLastReportedMultiWindowMode;
331 private boolean mLastReportedPictureInPictureMode;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700332 CompatibilityInfo compat;// last used compatibility mode
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700333 ActivityRecord resultTo; // who started this entry, so will get our reply
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 final String resultWho; // additional identifier for use by resultTo.
335 final int requestCode; // code given by requester (resultTo)
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800336 ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
Dianne Hackborn85d558c2014-11-04 10:31:54 -0800338 ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700339 ActivityOptions pendingOptions; // most recently given options
George Mount6ba042b2014-07-28 11:12:28 -0700340 ActivityOptions returningOptions; // options that are coming back via convertToTranslucent
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700341 AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity
Wale Ogunwalec4e63a42018-10-02 13:19:54 -0700342 ActivityServiceConnectionsHolder mServiceConnectionsHolder; // Service connections.
Dianne Hackborn7e269642010-08-25 19:50:20 -0700343 UriPermissionOwner uriPermissions; // current special URI access perms.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700344 WindowProcessController app; // if non-null, hosting application
Bryce Lee7ace3952018-02-16 14:34:32 -0800345 private ActivityState mState; // current state we are in
Andrii Kulian06b8dcb2019-07-10 21:09:38 -0700346 private Bundle mIcicle; // last saved activity state
347 private PersistableBundle mPersistentState; // last persistently saved activity state
348 private boolean mHaveState = true; // Indicates whether the last saved state of activity is
349 // preserved. This starts out 'true', since the initial state
350 // of an activity is that we have everything, and we should
351 // never consider it lacking in state to be removed if it
352 // dies. After an activity is launched it follows the value
353 // of #mIcicle.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 boolean launchFailed; // set if a launched failed, to abort on 2nd try
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 boolean stopped; // is activity pause finished?
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700356 boolean delayedResume; // not yet resumed because of stopped app switches?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 boolean finishing; // activity in pending finish list?
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800358 boolean deferRelaunchUntilPaused; // relaunch of activity is being deferred until pause is
359 // completed
360 boolean preserveWindowOnDeferredRelaunch; // activity windows are preserved on deferred relaunch
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 int configChangeFlags; // which config values have changed
Wale Ogunwaleec950642017-04-25 07:44:21 -0700362 private boolean keysPaused; // has key dispatching been paused for it?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 int launchMode; // the launch mode activity attribute.
Charles He2bf28322017-10-12 22:24:49 +0100364 int lockTaskLaunchMode; // the lockTaskMode manifest attribute, subject to override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 boolean visible; // does this activity's window need to be shown?
Jorim Jaggi241ae102016-11-02 21:57:33 -0700366 boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
367 // might hide this activity?
Wale Ogunwaleec950642017-04-25 07:44:21 -0700368 private boolean mDeferHidingClient; // If true we told WM to defer reporting to the client
369 // process that it is hidden.
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800370 boolean sleeping; // have we told the activity to sleep?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 boolean nowVisible; // is this activity's window visible?
Vishnu Nair9ba31652018-11-13 14:34:05 -0800372 boolean mDrawn; // is this activity's window drawn?
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700373 boolean mClientVisibilityDeferred;// was the visibility change message to client deferred?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 boolean idle; // has the activity gone idle?
375 boolean hasBeenLaunched;// has this activity ever been launched?
376 boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
Daniel Sandler69a48172010-06-23 16:29:36 -0400377 boolean immersive; // immersive mode (don't interrupt if possible)
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400378 boolean forceNewConfig; // force re-create with new config next time
Winson Chungf7e03e12017-08-22 11:32:16 -0700379 boolean supportsEnterPipOnTaskSwitch; // This flag is set by the system to indicate that the
380 // activity can enter picture in picture while pausing (only when switching to another task)
Winson Chung709904f2017-04-25 11:00:48 -0700381 PictureInPictureParams pictureInPictureArgs = new PictureInPictureParams.Builder().build();
382 // The PiP params used when deferring the entering of picture-in-picture.
Dianne Hackborn07981492013-01-28 11:36:23 -0800383 int launchCount; // count of launches since last state
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800384 long lastLaunchTime; // time of last launch of this activity
Ruben Brunke24b9a62016-02-16 21:38:24 -0800385 ComponentName requestedVrComponent; // the requested component for handling VR mode.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700387 String stringName; // for caching of toString().
Craig Mautnerde4ef022013-04-07 19:01:33 -0700388
Dianne Hackbornf26fd992011-04-08 18:14:09 -0700389 private boolean inHistory; // are we in the history stack?
Craig Mautnerde4ef022013-04-07 19:01:33 -0700390 final ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800391 final RootActivityContainer mRootActivityContainer;
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800392
393 static final int STARTING_WINDOW_NOT_SHOWN = 0;
394 static final int STARTING_WINDOW_SHOWN = 1;
395 static final int STARTING_WINDOW_REMOVED = 2;
396 int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;
Wale Ogunwale3b232392016-05-13 15:37:13 -0700397 boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800398
Garfield Tan2746ab52018-07-25 12:33:01 -0700399 // Marking the reason why this activity is being relaunched. Mainly used to track that this
400 // activity is being relaunched to fulfill a resize request due to compatibility issues, e.g. in
401 // pre-NYC apps that don't have a sense of being resized.
402 int mRelaunchReason = RELAUNCH_REASON_NONE;
403
Craig Mautner21d24a22014-04-23 11:45:37 -0700404 TaskDescription taskDescription; // the recents information for this activity
Craig Mautnerbb742462014-07-07 15:28:55 -0700405 boolean mLaunchTaskBehind; // this activity is actively being launched with
406 // ActivityOptions.setLaunchTaskBehind, will be cleared once launch is completed.
Craig Mautner2fbd7542014-03-21 09:34:07 -0700407
Filip Gruszczynski23493322015-07-29 17:02:59 -0700408 // These configurations are collected from application's resources based on size-sensitive
409 // qualifiers. For example, layout-w800dp will be added to mHorizontalSizeConfigurations as 800
410 // and drawable-sw400dp will be added to both as 400.
411 private int[] mVerticalSizeConfigurations;
412 private int[] mHorizontalSizeConfigurations;
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700413 private int[] mSmallestSizeConfigurations;
Filip Gruszczynski23493322015-07-29 17:02:59 -0700414
Riddle Hsu61987bc2019-04-03 13:08:47 +0800415 /**
416 * The precomputed display insets for resolving configuration. It will be non-null if
417 * {@link #shouldUseSizeCompatMode} returns {@code true}.
418 */
419 private CompatDisplayInsets mCompatDisplayInsets;
420
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800421 boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session
422 IVoiceInteractionSession voiceSession; // Voice interaction session for this activity
423
Robert Carrd2265122016-08-05 10:25:21 -0700424 // A hint to override the window specified rotation animation, or -1
425 // to use the window specified value. We use this so that
426 // we can select the right animation in the cases of starting
427 // windows, where the app hasn't had time to set a value
428 // on the window.
429 int mRotationAnimationHint = -1;
Robert Carrfd10cd12016-06-29 16:41:50 -0700430
chaviw59b98852017-06-13 12:05:44 -0700431 private boolean mShowWhenLocked;
Issei Suzuki74e1eb22018-12-20 17:42:52 +0100432 private boolean mInheritShownWhenLocked;
chaviw59b98852017-06-13 12:05:44 -0700433 private boolean mTurnScreenOn;
434
Andrii Kulian21713ac2016-10-12 22:05:05 -0700435 /**
Garfield Tan0443b372019-01-04 15:00:13 -0800436 * Current sequencing integer of the configuration, for skipping old activity configurations.
437 */
438 private int mConfigurationSeq;
439
440 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800441 * Temp configs used in {@link #ensureActivityConfiguration(int, boolean)}
Andrii Kulian21713ac2016-10-12 22:05:05 -0700442 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700443 private final Configuration mTmpConfig = new Configuration();
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700444 private final Rect mTmpBounds = new Rect();
Andrii Kulian21713ac2016-10-12 22:05:05 -0700445
Sunny Goyald40c3452019-03-20 12:46:55 -0700446 // Token for targeting this activity for assist purposes.
447 final Binder assistToken = new Binder();
448
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800449 private static String startingWindowStateToString(int state) {
450 switch (state) {
451 case STARTING_WINDOW_NOT_SHOWN:
452 return "STARTING_WINDOW_NOT_SHOWN";
453 case STARTING_WINDOW_SHOWN:
454 return "STARTING_WINDOW_SHOWN";
455 case STARTING_WINDOW_REMOVED:
456 return "STARTING_WINDOW_REMOVED";
457 default:
458 return "unknown state=" + state;
459 }
460 }
461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700463 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700464 pw.print(prefix); pw.print("packageName="); pw.print(packageName);
465 pw.print(" processName="); pw.println(processName);
466 pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
Craig Mautnere11f2b72013-04-01 12:37:17 -0700467 pw.print(" launchedFromPackage="); pw.print(launchedFromPackage);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800468 pw.print(" userId="); pw.println(mUserId);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800469 pw.print(prefix); pw.print("app="); pw.println(app);
470 pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
Andrii Kulian39f27442019-06-26 19:09:19 -0700471 pw.print(prefix); pw.print("rootOfTask="); pw.print(isRootOfTask());
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700472 pw.print(" task="); pw.println(task);
473 pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800474 pw.print(prefix); pw.print("mActivityComponent=");
475 pw.println(mActivityComponent.flattenToShortString());
Andrii Kulianeceebbf2019-06-26 17:36:51 -0700476 if (info != null && info.applicationInfo != null) {
477 final ApplicationInfo appInfo = info.applicationInfo;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700478 pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir);
479 if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) {
480 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir);
481 }
482 pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800483 if (appInfo.splitSourceDirs != null) {
484 pw.print(prefix); pw.print("splitDir=");
485 pw.println(Arrays.toString(appInfo.splitSourceDirs));
486 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800487 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700488 pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
489 pw.print(" componentSpecified="); pw.print(componentSpecified);
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700490 pw.print(" mActivityType="); pw.println(
491 activityTypeToString(getActivityType()));
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700492 if (rootVoiceInteraction) {
493 pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
494 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800495 pw.print(prefix); pw.print("compat="); pw.print(compat);
496 pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
497 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
498 pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700499 pw.println(prefix + "mLastReportedConfigurations:");
500 mLastReportedConfiguration.dump(pw, prefix + " ");
501
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700502 pw.print(prefix); pw.print("CurrentConfiguration="); pw.println(getConfiguration());
Evan Roskydfe3da72018-10-26 17:21:06 -0700503 if (!getRequestedOverrideConfiguration().equals(EMPTY)) {
504 pw.println(prefix + "RequestedOverrideConfiguration="
505 + getRequestedOverrideConfiguration());
506 }
507 if (!getResolvedOverrideConfiguration().equals(getRequestedOverrideConfiguration())) {
508 pw.println(prefix + "ResolvedOverrideConfiguration="
509 + getResolvedOverrideConfiguration());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700510 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800511 if (!matchParentBounds()) {
512 pw.println(prefix + "bounds=" + getBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700513 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700514 if (resultTo != null || resultWho != null) {
515 pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
516 pw.print(" resultWho="); pw.print(resultWho);
517 pw.print(" resultCode="); pw.println(requestCode);
518 }
Craig Mautner29c58ca2014-10-14 16:17:06 -0700519 if (taskDescription != null) {
520 final String iconFilename = taskDescription.getIconFilename();
521 if (iconFilename != null || taskDescription.getLabel() != null ||
522 taskDescription.getPrimaryColor() != 0) {
523 pw.print(prefix); pw.print("taskDescription:");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700524 pw.print(" label=\""); pw.print(taskDescription.getLabel());
525 pw.print("\"");
Matthew Ng54bc9422017-10-02 17:16:28 -0700526 pw.print(" icon="); pw.print(taskDescription.getInMemoryIcon() != null
527 ? taskDescription.getInMemoryIcon().getByteCount() + " bytes"
528 : "null");
529 pw.print(" iconResource="); pw.print(taskDescription.getIconResource());
530 pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200531 pw.print(" primaryColor=");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700532 pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700533 pw.print(prefix + " backgroundColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200534 pw.println(Integer.toHexString(taskDescription.getBackgroundColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700535 pw.print(prefix + " statusBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200536 pw.println(Integer.toHexString(taskDescription.getStatusBarColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700537 pw.print(prefix + " navigationBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200538 pw.println(Integer.toHexString(taskDescription.getNavigationBarColor()));
Craig Mautner29c58ca2014-10-14 16:17:06 -0700539 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700540 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700541 if (results != null) {
542 pw.print(prefix); pw.print("results="); pw.println(results);
543 }
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700544 if (pendingResults != null && pendingResults.size() > 0) {
545 pw.print(prefix); pw.println("Pending Results:");
546 for (WeakReference<PendingIntentRecord> wpir : pendingResults) {
547 PendingIntentRecord pir = wpir != null ? wpir.get() : null;
548 pw.print(prefix); pw.print(" - ");
549 if (pir == null) {
550 pw.println("null");
551 } else {
552 pw.println(pir);
553 pir.dump(pw, prefix + " ");
554 }
555 }
556 }
557 if (newIntents != null && newIntents.size() > 0) {
558 pw.print(prefix); pw.println("Pending New Intents:");
559 for (int i=0; i<newIntents.size(); i++) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800560 Intent intent = newIntents.get(i);
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700561 pw.print(prefix); pw.print(" - ");
562 if (intent == null) {
563 pw.println("null");
564 } else {
565 pw.println(intent.toShortString(false, true, false, true));
566 }
567 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700568 }
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700569 if (pendingOptions != null) {
570 pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions);
571 }
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700572 if (appTimeTracker != null) {
573 appTimeTracker.dumpWithHeader(pw, prefix, false);
574 }
Dianne Hackborn7e269642010-08-25 19:50:20 -0700575 if (uriPermissions != null) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700576 uriPermissions.dump(pw, prefix);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700577 }
578 pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed);
Dianne Hackborn07981492013-01-28 11:36:23 -0800579 pw.print(" launchCount="); pw.print(launchCount);
580 pw.print(" lastLaunchTime=");
581 if (lastLaunchTime == 0) pw.print("0");
582 else TimeUtils.formatDuration(lastLaunchTime, now, pw);
583 pw.println();
Andrii Kulian06b8dcb2019-07-10 21:09:38 -0700584 pw.print(prefix); pw.print("mHaveState="); pw.print(mHaveState);
585 pw.print(" mIcicle="); pw.println(mIcicle);
Bryce Lee7ace3952018-02-16 14:34:32 -0800586 pw.print(prefix); pw.print("state="); pw.print(mState);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700587 pw.print(" stopped="); pw.print(stopped);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700588 pw.print(" delayedResume="); pw.print(delayedResume);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700589 pw.print(" finishing="); pw.println(finishing);
590 pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
591 pw.print(" inHistory="); pw.print(inHistory);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700592 pw.print(" visible="); pw.print(visible);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800593 pw.print(" sleeping="); pw.print(sleeping);
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800594 pw.print(" idle="); pw.print(idle);
595 pw.print(" mStartingWindowState=");
596 pw.println(startingWindowStateToString(mStartingWindowState));
Dianne Hackbornff801ec2011-01-22 18:05:38 -0800597 pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
598 pw.print(" noDisplay="); pw.print(noDisplay);
599 pw.print(" immersive="); pw.print(immersive);
600 pw.print(" launchMode="); pw.println(launchMode);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800601 pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400602 pw.print(" forceNewConfig="); pw.println(forceNewConfig);
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700603 pw.print(prefix); pw.print("mActivityType=");
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700604 pw.println(activityTypeToString(getActivityType()));
Ruben Brunke24b9a62016-02-16 21:38:24 -0800605 if (requestedVrComponent != null) {
606 pw.print(prefix);
607 pw.print("requestedVrComponent=");
608 pw.println(requestedVrComponent);
609 }
Jorim Jaggi9b5e3312019-03-01 18:08:00 +0100610 if (lastVisibleTime != 0 || nowVisible) {
611 pw.print(prefix); pw.print(" nowVisible="); pw.print(nowVisible);
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700612 pw.print(" lastVisibleTime=");
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700613 if (lastVisibleTime == 0) pw.print("0");
614 else TimeUtils.formatDuration(lastVisibleTime, now, pw);
615 pw.println();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700616 }
Wale Ogunwaleec950642017-04-25 07:44:21 -0700617 if (mDeferHidingClient) {
618 pw.println(prefix + "mDeferHidingClient=" + mDeferHidingClient);
619 }
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800620 if (deferRelaunchUntilPaused || configChangeFlags != 0) {
621 pw.print(prefix); pw.print("deferRelaunchUntilPaused="); pw.print(deferRelaunchUntilPaused);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700622 pw.print(" configChangeFlags=");
623 pw.println(Integer.toHexString(configChangeFlags));
624 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -0700625 if (mServiceConnectionsHolder != null) {
626 pw.print(prefix); pw.print("connections="); pw.println(mServiceConnectionsHolder);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700627 }
Wale Ogunwaled26176f2016-01-25 20:04:04 -0800628 if (info != null) {
629 pw.println(prefix + "resizeMode=" + ActivityInfo.resizeModeToString(info.resizeMode));
Winson Chung609e1e92017-05-08 10:52:12 -0700630 pw.println(prefix + "mLastReportedMultiWindowMode=" + mLastReportedMultiWindowMode
631 + " mLastReportedPictureInPictureMode=" + mLastReportedPictureInPictureMode);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700632 if (info.supportsPictureInPicture()) {
633 pw.println(prefix + "supportsPictureInPicture=" + info.supportsPictureInPicture());
Winson Chungf7e03e12017-08-22 11:32:16 -0700634 pw.println(prefix + "supportsEnterPipOnTaskSwitch: "
635 + supportsEnterPipOnTaskSwitch);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700636 }
637 if (info.maxAspectRatio != 0) {
638 pw.println(prefix + "maxAspectRatio=" + info.maxAspectRatio);
639 }
Adrian Roos917791e2018-11-28 16:30:44 +0100640 if (info.minAspectRatio != 0) {
641 pw.println(prefix + "minAspectRatio=" + info.minAspectRatio);
642 }
Wale Ogunwaled26176f2016-01-25 20:04:04 -0800643 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800644 }
645
Andrii Kulian06b8dcb2019-07-10 21:09:38 -0700646 /** Update the saved state of an activity. */
647 void setSavedState(@Nullable Bundle savedState) {
648 mIcicle = savedState;
649 mHaveState = mIcicle != null;
650 }
651
652 /**
653 * Get the actual Bundle instance of the saved state.
654 * @see #hasSavedState() for checking if the record has saved state.
655 */
656 @Nullable Bundle getSavedState() {
657 return mIcicle;
658 }
659
660 /**
661 * Check if the activity has saved state.
662 * @return {@code true} if the client reported a non-empty saved state from last onStop(), or
663 * if this record was just created and the client is yet to be launched and resumed.
664 */
665 boolean hasSavedState() {
666 return mHaveState;
667 }
668
669 /** @return The actual PersistableBundle instance of the saved persistent state. */
670 @Nullable PersistableBundle getPersistentSavedState() {
671 return mPersistentState;
672 }
673
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700674 void updateApplicationInfo(ApplicationInfo aInfo) {
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700675 info.applicationInfo = aInfo;
676 }
677
Andrii Kulian21713ac2016-10-12 22:05:05 -0700678 private boolean crossesHorizontalSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700679 return crossesSizeThreshold(mHorizontalSizeConfigurations, firstDp, secondDp);
680 }
681
Andrii Kulian21713ac2016-10-12 22:05:05 -0700682 private boolean crossesVerticalSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700683 return crossesSizeThreshold(mVerticalSizeConfigurations, firstDp, secondDp);
684 }
685
Andrii Kulian21713ac2016-10-12 22:05:05 -0700686 private boolean crossesSmallestSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700687 return crossesSizeThreshold(mSmallestSizeConfigurations, firstDp, secondDp);
688 }
689
Filip Gruszczynski23493322015-07-29 17:02:59 -0700690 /**
691 * The purpose of this method is to decide whether the activity needs to be relaunched upon
692 * changing its size. In most cases the activities don't need to be relaunched, if the resize
693 * is small, all the activity content has to do is relayout itself within new bounds. There are
694 * cases however, where the activity's content would be completely changed in the new size and
695 * the full relaunch is required.
696 *
697 * The activity will report to us vertical and horizontal thresholds after which a relaunch is
698 * required. These thresholds are collected from the application resource qualifiers. For
699 * example, if application has layout-w600dp resource directory, then it needs a relaunch when
700 * we resize from width of 650dp to 550dp, as it crosses the 600dp threshold. However, if
701 * it resizes width from 620dp to 700dp, it won't be relaunched as it stays on the same side
702 * of the threshold.
703 */
704 private static boolean crossesSizeThreshold(int[] thresholds, int firstDp,
705 int secondDp) {
706 if (thresholds == null) {
707 return false;
708 }
709 for (int i = thresholds.length - 1; i >= 0; i--) {
710 final int threshold = thresholds[i];
711 if ((firstDp < threshold && secondDp >= threshold)
712 || (firstDp >= threshold && secondDp < threshold)) {
713 return true;
714 }
715 }
716 return false;
717 }
718
Andrii Kulian21713ac2016-10-12 22:05:05 -0700719 void setSizeConfigurations(int[] horizontalSizeConfiguration,
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700720 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700721 mHorizontalSizeConfigurations = horizontalSizeConfiguration;
722 mVerticalSizeConfigurations = verticalSizeConfigurations;
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700723 mSmallestSizeConfigurations = smallestSizeConfigurations;
Filip Gruszczynski23493322015-07-29 17:02:59 -0700724 }
725
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800726 private void scheduleActivityMovedToDisplay(int displayId, Configuration config) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700727 if (!attachedToProcess()) {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800728 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.w(TAG,
729 "Can't report activity moved to display - client not running, activityRecord="
730 + this + ", displayId=" + displayId);
Wale Ogunwale22e25262016-02-01 10:32:02 -0800731 return;
732 }
733 try {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800734 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
735 "Reporting activity moved to display" + ", activityRecord=" + this
736 + ", displayId=" + displayId + ", config=" + config);
Chong Zhang6be533e2016-06-17 16:24:21 -0700737
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800738 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800739 MoveToDisplayItem.obtain(displayId, config));
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800740 } catch (RemoteException e) {
741 // If process died, whatever.
742 }
743 }
744
745 private void scheduleConfigurationChanged(Configuration config) {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700746 if (!attachedToProcess()) {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800747 if (DEBUG_CONFIGURATION) Slog.w(TAG,
748 "Can't report activity configuration update - client not running"
749 + ", activityRecord=" + this);
750 return;
751 }
752 try {
753 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + this + ", config: "
754 + config);
755
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800756 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800757 ActivityConfigurationChangeItem.obtain(config));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800758 } catch (RemoteException e) {
759 // If process died, whatever.
760 }
761 }
762
Louis Chang3b21bdc2019-03-25 15:49:14 +0800763 boolean scheduleTopResumedActivityChanged(boolean onTop) {
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800764 if (!attachedToProcess()) {
Andrii Kulian86e70fc2019-02-12 11:04:10 +0000765 if (DEBUG_STATES) {
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800766 Slog.w(TAG, "Can't report activity position update - client not running"
767 + ", activityRecord=" + this);
768 }
Louis Chang3b21bdc2019-03-25 15:49:14 +0800769 return false;
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800770 }
771 try {
Andrii Kulian86e70fc2019-02-12 11:04:10 +0000772 if (DEBUG_STATES) {
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800773 Slog.v(TAG, "Sending position change to " + this + ", onTop: " + onTop);
774 }
775
776 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
777 TopResumedActivityChangeItem.obtain(onTop));
778 } catch (RemoteException e) {
779 // If process died, whatever.
Louis Chang3b21bdc2019-03-25 15:49:14 +0800780 return false;
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800781 }
Louis Chang3b21bdc2019-03-25 15:49:14 +0800782 return true;
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800783 }
784
Winson Chung5af42fc2017-03-24 17:11:33 -0700785 void updateMultiWindowMode() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700786 if (task == null || task.getStack() == null || !attachedToProcess()) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800787 return;
788 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700789
Wale Ogunwaleeb76b762017-11-17 10:08:04 -0800790 if (task.getStack().deferScheduleMultiWindowModeChanged()) {
791 // Don't do anything if we are currently deferring multi-window mode change.
792 return;
793 }
794
Winson Chung5af42fc2017-03-24 17:11:33 -0700795 // An activity is considered to be in multi-window mode if its task isn't fullscreen.
Wale Ogunwaleeb76b762017-11-17 10:08:04 -0800796 final boolean inMultiWindowMode = inMultiWindowMode();
Winson Chung609e1e92017-05-08 10:52:12 -0700797 if (inMultiWindowMode != mLastReportedMultiWindowMode) {
798 mLastReportedMultiWindowMode = inMultiWindowMode;
Winson Chung5af42fc2017-03-24 17:11:33 -0700799 scheduleMultiWindowModeChanged(getConfiguration());
800 }
801 }
802
803 private void scheduleMultiWindowModeChanged(Configuration overrideConfig) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800804 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800805 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700806 MultiWindowModeChangeItem.obtain(mLastReportedMultiWindowMode, overrideConfig));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800807 } catch (Exception e) {
808 // If process died, I don't care.
809 }
810 }
811
Winson Chungab76bbc2017-08-14 13:33:51 -0700812 void updatePictureInPictureMode(Rect targetStackBounds, boolean forceUpdate) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700813 if (task == null || task.getStack() == null || !attachedToProcess()) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800814 return;
815 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700816
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700817 final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null;
Winson Chungab76bbc2017-08-14 13:33:51 -0700818 if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) {
Winson Chung5af42fc2017-03-24 17:11:33 -0700819 // Picture-in-picture mode changes also trigger a multi-window mode change as well, so
Winson Chung059955f2018-08-08 16:10:20 -0700820 // update that here in order. Set the last reported MW state to the same as the PiP
821 // state since we haven't yet actually resized the task (these callbacks need to
822 // preceed the configuration change from the resiez.
823 // TODO(110009072): Once we move these callbacks to the client, remove all logic related
824 // to forcing the update of the picture-in-picture mode as a part of the PiP animation.
Winson Chung609e1e92017-05-08 10:52:12 -0700825 mLastReportedPictureInPictureMode = inPictureInPictureMode;
Winson Chung059955f2018-08-08 16:10:20 -0700826 mLastReportedMultiWindowMode = inPictureInPictureMode;
Evan Rosky1ac84462018-11-13 11:25:30 -0800827 final Configuration newConfig = new Configuration();
828 if (targetStackBounds != null && !targetStackBounds.isEmpty()) {
Evan Rosky730f6e82018-12-03 17:40:11 -0800829 newConfig.setTo(task.getRequestedOverrideConfiguration());
830 Rect outBounds = newConfig.windowConfiguration.getBounds();
831 task.adjustForMinimalTaskDimensions(outBounds, outBounds);
832 task.computeConfigResourceOverrides(newConfig, task.getParent().getConfiguration());
Evan Rosky1ac84462018-11-13 11:25:30 -0800833 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700834 schedulePictureInPictureModeChanged(newConfig);
835 scheduleMultiWindowModeChanged(newConfig);
836 }
837 }
838
839 private void schedulePictureInPictureModeChanged(Configuration overrideConfig) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800840 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800841 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800842 PipModeChangeItem.obtain(mLastReportedPictureInPictureMode,
Andrii Kulian446e8242017-10-26 15:17:29 -0700843 overrideConfig));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800844 } catch (Exception e) {
845 // If process died, no one cares.
Filip Gruszczynskica664812015-12-04 12:43:36 -0800846 }
847 }
848
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700849 @Override
850 protected int getChildCount() {
851 // {@link ActivityRecord} is a leaf node and has no children.
852 return 0;
853 }
854
855 @Override
856 protected ConfigurationContainer getChildAt(int index) {
857 return null;
858 }
859
860 @Override
861 protected ConfigurationContainer getParent() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800862 return getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -0700863 }
864
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800865 TaskRecord getTaskRecord() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700866 return task;
867 }
868
Bryce Leeaf691c02017-03-20 14:20:22 -0700869 /**
870 * Sets reference to the {@link TaskRecord} the {@link ActivityRecord} will treat as its parent.
871 * Note that this does not actually add the {@link ActivityRecord} as a {@link TaskRecord}
872 * children. However, this method will clean up references to this {@link ActivityRecord} in
873 * {@link ActivityStack}.
874 * @param task The new parent {@link TaskRecord}.
875 */
876 void setTask(TaskRecord task) {
Bryce Lee84730a02018-04-03 14:10:04 -0700877 setTask(task /* task */, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -0700878 }
879
880 /**
881 * This method should only be called by {@link TaskRecord#removeActivity(ActivityRecord)}.
Bryce Lee84730a02018-04-03 14:10:04 -0700882 * @param task The new parent task.
883 * @param reparenting Whether we're in the middle of reparenting.
Bryce Leeaf691c02017-03-20 14:20:22 -0700884 */
885 void setTask(TaskRecord task, boolean reparenting) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800886 // Do nothing if the {@link TaskRecord} is the same as the current {@link getTaskRecord}.
887 if (task != null && task == getTaskRecord()) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700888 return;
889 }
890
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800891 final ActivityStack oldStack = getActivityStack();
Bryce Lee84730a02018-04-03 14:10:04 -0700892 final ActivityStack newStack = task != null ? task.getStack() : null;
Bryce Leeaf691c02017-03-20 14:20:22 -0700893
Bryce Lee84730a02018-04-03 14:10:04 -0700894 // Inform old stack (if present) of activity removal and new stack (if set) of activity
895 // addition.
896 if (oldStack != newStack) {
897 if (!reparenting && oldStack != null) {
898 oldStack.onActivityRemovedFromStack(this);
899 }
900
901 if (newStack != null) {
902 newStack.onActivityAddedToStack(this);
903 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700904 }
905
906 this.task = task;
907
908 if (!reparenting) {
909 onParentChanged();
910 }
911 }
912
chaviw4ad54912018-05-30 11:05:44 -0700913 /**
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800914 * Notifies AWT that this app is waiting to pause in order to determine if it will enter PIP.
915 * This information helps AWT know that the app is in the process of pausing before it gets the
916 * signal on the WM side.
chaviw4ad54912018-05-30 11:05:44 -0700917 */
918 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800919 if (mAppWindowToken == null) {
920 return;
921 }
922
923 mAppWindowToken.setWillCloseOrEnterPip(willCloseOrEnterPip);
chaviw4ad54912018-05-30 11:05:44 -0700924 }
925
Dianne Hackbornbe707852011-11-11 14:32:10 -0800926 static class Token extends IApplicationToken.Stub {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700927 private final WeakReference<ActivityRecord> weakActivity;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700928 private final String name;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800929
Steven Timotiusaf03df62017-07-18 16:56:43 -0700930 Token(ActivityRecord activity, Intent intent) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800931 weakActivity = new WeakReference<>(activity);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700932 name = intent.getComponent().flattenToShortString();
Wale Ogunwale7d701172015-03-11 15:36:30 -0700933 }
934
Charles Chen69362cd2019-03-29 15:18:45 +0800935 private static @Nullable ActivityRecord tokenToActivityRecordLocked(Token token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700936 if (token == null) {
937 return null;
938 }
939 ActivityRecord r = token.weakActivity.get();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800940 if (r == null || r.getActivityStack() == null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700941 return null;
942 }
943 return r;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800944 }
945
Craig Mautnerde4ef022013-04-07 19:01:33 -0700946 @Override
Dianne Hackbornbe707852011-11-11 14:32:10 -0800947 public String toString() {
948 StringBuilder sb = new StringBuilder(128);
949 sb.append("Token{");
950 sb.append(Integer.toHexString(System.identityHashCode(this)));
951 sb.append(' ');
952 sb.append(weakActivity.get());
953 sb.append('}');
954 return sb.toString();
955 }
Steven Timotiusaf03df62017-07-18 16:56:43 -0700956
957 @Override
958 public String getName() {
959 return name;
960 }
Dianne Hackbornbe707852011-11-11 14:32:10 -0800961 }
962
Charles Chen69362cd2019-03-29 15:18:45 +0800963 static @Nullable ActivityRecord forTokenLocked(IBinder token) {
Dianne Hackbornbe707852011-11-11 14:32:10 -0800964 try {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700965 return Token.tokenToActivityRecordLocked((Token)token);
Dianne Hackbornbe707852011-11-11 14:32:10 -0800966 } catch (ClassCastException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800967 Slog.w(TAG, "Bad activity token: " + token, e);
Dianne Hackbornbe707852011-11-11 14:32:10 -0800968 return null;
969 }
970 }
971
Riddle Hsuff9e8282019-04-24 23:55:11 +0800972 static boolean isResolverActivity(String className) {
973 return ResolverActivity.class.getName().equals(className);
974 }
975
Louis Chang6a9be162019-07-15 10:41:32 +0800976 boolean isResolverOrDelegateActivity() {
977 return isResolverActivity(mActivityComponent.getClassName()) || Objects.equals(
978 mActivityComponent, mAtmService.mStackSupervisor.getSystemChooserActivity());
Craig Mautnerac6f8432013-07-17 13:24:59 -0700979 }
980
Patrick Baumann31426b22018-05-21 13:46:40 -0700981 boolean isResolverOrChildActivity() {
982 if (!"android".equals(packageName)) {
983 return false;
984 }
985 try {
986 return ResolverActivity.class.isAssignableFrom(
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800987 Object.class.getClassLoader().loadClass(mActivityComponent.getClassName()));
Patrick Baumann31426b22018-05-21 13:46:40 -0700988 } catch (ClassNotFoundException e) {
989 return false;
990 }
991 }
992
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700993 ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
994 int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage, Intent _intent,
995 String _resolvedType, ActivityInfo aInfo, Configuration _configuration,
996 ActivityRecord _resultTo, String _resultWho, int _reqCode, boolean _componentSpecified,
997 boolean _rootVoiceInteraction, ActivityStackSupervisor supervisor,
998 ActivityOptions options, ActivityRecord sourceRecord) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800999 mAtmService = _service;
Wale Ogunwaled32da472018-11-16 07:19:28 -08001000 mRootActivityContainer = _service.mRootActivityContainer;
Steven Timotiusaf03df62017-07-18 16:56:43 -07001001 appToken = new Token(this, _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001002 info = aInfo;
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001003 launchedFromPid = _launchedFromPid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 launchedFromUid = _launchedFromUid;
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001005 launchedFromPackage = _launchedFromPackage;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001006 mUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 intent = _intent;
1008 shortComponentName = _intent.getComponent().flattenToShortString();
1009 resolvedType = _resolvedType;
The Android Open Source Project4df24232009-03-05 14:34:35 -08001010 componentSpecified = _componentSpecified;
Dianne Hackbornfb81d092015-08-03 17:14:46 -07001011 rootVoiceInteraction = _rootVoiceInteraction;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07001012 mLastReportedConfiguration = new MergedConfiguration(_configuration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001013 resultTo = _resultTo;
1014 resultWho = _resultWho;
1015 requestCode = _reqCode;
Bryce Lee7ace3952018-02-16 14:34:32 -08001016 setState(INITIALIZING, "ActivityRecord ctor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 launchFailed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 stopped = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001019 delayedResume = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 finishing = false;
Wale Ogunwalef81c1d12016-01-12 12:20:18 -08001021 deferRelaunchUntilPaused = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022 keysPaused = false;
1023 inHistory = false;
Chong Zhanga48ef662015-08-18 19:21:47 -07001024 visible = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 nowVisible = false;
Vishnu Nair9ba31652018-11-13 14:34:05 -08001026 mDrawn = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 idle = false;
1028 hasBeenLaunched = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -07001029 mStackSupervisor = supervisor;
Robert Carr0f5d7532016-10-17 16:39:17 -07001030
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001031 // If the class name in the intent doesn't match that of the target, this is
1032 // probably an alias. We have to create a new ComponentName object to keep track
1033 // of the real activity name, so that FLAG_ACTIVITY_CLEAR_TOP is handled properly.
1034 if (aInfo.targetActivity == null
1035 || (aInfo.targetActivity.equals(_intent.getComponent().getClassName())
1036 && (aInfo.launchMode == LAUNCH_MULTIPLE
1037 || aInfo.launchMode == LAUNCH_SINGLE_TOP))) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001038 mActivityComponent = _intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001039 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001040 mActivityComponent = new ComponentName(aInfo.packageName, aInfo.targetActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001042 taskAffinity = aInfo.taskAffinity;
1043 stateNotNeeded = (aInfo.flags & FLAG_STATE_NOT_NEEDED) != 0;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001044 nonLocalizedLabel = aInfo.nonLocalizedLabel;
1045 labelRes = aInfo.labelRes;
1046 if (nonLocalizedLabel == null && labelRes == 0) {
1047 ApplicationInfo app = aInfo.applicationInfo;
1048 nonLocalizedLabel = app.nonLocalizedLabel;
1049 labelRes = app.labelRes;
1050 }
1051 icon = aInfo.getIconResource();
1052 logo = aInfo.getLogoResource();
1053 theme = aInfo.getThemeResource();
1054 realTheme = theme;
1055 if (realTheme == 0) {
1056 realTheme = aInfo.applicationInfo.targetSdkVersion < HONEYCOMB
1057 ? android.R.style.Theme : android.R.style.Theme_Holo;
1058 }
1059 if ((aInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
1060 windowFlags |= LayoutParams.FLAG_HARDWARE_ACCELERATED;
1061 }
1062 if ((aInfo.flags & FLAG_MULTIPROCESS) != 0 && _caller != null
1063 && (aInfo.applicationInfo.uid == SYSTEM_UID
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001064 || aInfo.applicationInfo.uid == _caller.mInfo.uid)) {
1065 processName = _caller.mName;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001066 } else {
1067 processName = aInfo.processName;
1068 }
1069
1070 if ((aInfo.flags & FLAG_EXCLUDE_FROM_RECENTS) != 0) {
1071 intent.addFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
1072 }
1073
1074 packageName = aInfo.applicationInfo.packageName;
1075 launchMode = aInfo.launchMode;
1076
Ruben Brunkf53497c2017-03-27 20:26:17 -07001077 Entry ent = AttributeCache.instance().get(packageName,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001078 realTheme, com.android.internal.R.styleable.Window, mUserId);
Bryce Leee83f34cd2017-10-31 19:50:54 -07001079
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001080 if (ent != null) {
1081 fullscreen = !ActivityInfo.isTranslucentOrFloating(ent.array);
1082 hasWallpaper = ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
1083 noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
1084 } else {
1085 hasWallpaper = false;
1086 noDisplay = false;
1087 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001088
Winson Chung83471632016-12-13 11:02:12 -08001089 setActivityType(_componentSpecified, _launchedFromUid, _intent, options, sourceRecord);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001090
1091 immersive = (aInfo.flags & FLAG_IMMERSIVE) != 0;
1092
1093 requestedVrComponent = (aInfo.requestedVrComponent == null) ?
1094 null : ComponentName.unflattenFromString(aInfo.requestedVrComponent);
chaviw59b98852017-06-13 12:05:44 -07001095
1096 mShowWhenLocked = (aInfo.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
Issei Suzuki74e1eb22018-12-20 17:42:52 +01001097 mInheritShownWhenLocked = (aInfo.privateFlags & FLAG_INHERIT_SHOW_WHEN_LOCKED) != 0;
chaviw59b98852017-06-13 12:05:44 -07001098 mTurnScreenOn = (aInfo.flags & FLAG_TURN_SCREEN_ON) != 0;
Charles He2bf28322017-10-12 22:24:49 +01001099
1100 mRotationAnimationHint = aInfo.rotationAnimation;
1101 lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
Andrii Kulianeceebbf2019-06-26 17:36:51 -07001102 if (info.applicationInfo.isPrivilegedApp()
1103 && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
Charles He2bf28322017-10-12 22:24:49 +01001104 || lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
1105 lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
1106 }
1107
1108 if (options != null) {
1109 pendingOptions = options;
1110 mLaunchTaskBehind = options.getLaunchTaskBehind();
1111
1112 final int rotationAnimation = pendingOptions.getRotationAnimationHint();
1113 // Only override manifest supplied option if set.
1114 if (rotationAnimation >= 0) {
1115 mRotationAnimationHint = rotationAnimation;
1116 }
1117 final PendingIntent usageReport = pendingOptions.getUsageTimeReport();
1118 if (usageReport != null) {
1119 appTimeTracker = new AppTimeTracker(usageReport);
1120 }
1121 final boolean useLockTask = pendingOptions.getLockTaskMode();
1122 if (useLockTask && lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_DEFAULT) {
1123 lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
1124 }
Louis Changd58cb672018-12-24 17:45:16 +08001125 // Gets launch display id from options. It returns INVALID_DISPLAY if not set.
1126 mHandoverLaunchDisplayId = options.getLaunchDisplayId();
Charles He2bf28322017-10-12 22:24:49 +01001127 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001128 }
1129
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001130 void setProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08001131 app = proc;
1132 final ActivityRecord root = task != null ? task.getRootActivity() : null;
1133 if (root == this) {
1134 task.setRootProcess(proc);
1135 }
1136 }
1137
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001138 boolean hasProcess() {
1139 return app != null;
1140 }
1141
1142 boolean attachedToProcess() {
1143 return hasProcess() && app.hasThread();
1144 }
1145
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001146 void createAppWindowToken() {
1147 if (mAppWindowToken != null) {
1148 throw new IllegalArgumentException("App Window Token=" + mAppWindowToken
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001149 + " already created for r=" + this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001150 }
1151
1152 inHistory = true;
1153
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001154 // TODO(b/36505427): Maybe this call should be moved inside updateOverrideConfiguration()
1155 task.updateOverrideConfigurationFromLaunchBounds();
1156 // Make sure override configuration is up-to-date before using to create window controller.
1157 updateOverrideConfiguration();
1158
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001159 // TODO: remove after unification
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001160 mAppWindowToken = mAtmService.mWindowManager.mRoot.getAppWindowToken(appToken.asBinder());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001161 if (mAppWindowToken != null) {
1162 // TODO: Should this throw an exception instead?
1163 Slog.w(TAG, "Attempted to add existing app token: " + appToken);
1164 } else {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001165 final Task container = task.getTask();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001166 if (container == null) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001167 throw new IllegalArgumentException("createAppWindowToken: invalid task =" + task);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001168 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001169 mAppWindowToken = createAppWindow(mAtmService.mWindowManager, appToken,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001170 task.voiceSession != null, container.getDisplayContent(),
1171 ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this)
1172 * 1000000L, fullscreen,
Andrii Kulianeceebbf2019-06-26 17:36:51 -07001173 (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0,
1174 info.applicationInfo.targetSdkVersion,
Jorim Jaggi91d382a2019-03-27 17:00:48 +01001175 info.screenOrientation, mRotationAnimationHint,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001176 mLaunchTaskBehind, isAlwaysFocusable());
1177 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) {
1178 Slog.v(TAG, "addAppToken: "
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001179 + mAppWindowToken + " task=" + container + " at "
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001180 + Integer.MAX_VALUE);
1181 }
1182 container.addChild(mAppWindowToken, Integer.MAX_VALUE /* add on top */);
1183 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001184
1185 task.addActivityToTop(this);
1186
Winson Chung609e1e92017-05-08 10:52:12 -07001187 // When an activity is started directly into a split-screen fullscreen stack, we need to
1188 // update the initial multi-window modes so that the callbacks are scheduled correctly when
1189 // the user leaves that mode.
Bryce Leef3c6a472017-11-14 14:53:06 -08001190 mLastReportedMultiWindowMode = inMultiWindowMode();
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001191 mLastReportedPictureInPictureMode = inPinnedWindowingMode();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001192 }
1193
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001194 boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
1195 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
1196 IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
1197 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
1198 if (DEBUG_STARTING_WINDOW) {
1199 Slog.v(TAG, "setAppStartingWindow: token=" + appToken
1200 + " pkg=" + pkg + " transferFrom=" + transferFrom + " newTask=" + newTask
1201 + " taskSwitch=" + taskSwitch + " processRunning=" + processRunning
1202 + " allowTaskSnapshot=" + allowTaskSnapshot);
1203 }
1204 if (mAppWindowToken == null) {
1205 Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + appToken);
1206 return false;
1207 }
Yunfan Chen48c0ed082018-12-05 18:15:35 -08001208 if (mAppWindowToken.getTask() == null) {
1209 // Can be removed after unification of Task and TaskRecord.
1210 Slog.w(TAG_WM, "Attempted to start a window to an app token not having attached to any"
1211 + " task: " + appToken);
1212 return false;
1213 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001214 return mAppWindowToken.addStartingWindow(pkg, theme, compatInfo, nonLocalizedLabel,
1215 labelRes, icon, logo, windowFlags, transferFrom, newTask, taskSwitch,
1216 processRunning, allowTaskSnapshot, activityCreated, fromRecents);
1217 }
1218
1219 // TODO: Remove after unification
1220 @VisibleForTesting
1221 AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
1222 boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
1223 boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
Jorim Jaggi91d382a2019-03-27 17:00:48 +01001224 int rotationAnimationHint, boolean launchTaskBehind,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001225 boolean alwaysFocusable) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001226 return new AppWindowToken(service, token, mActivityComponent, voiceInteraction, dc,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001227 inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation,
Jorim Jaggi91d382a2019-03-27 17:00:48 +01001228 rotationAnimationHint, launchTaskBehind, alwaysFocusable,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001229 this);
1230 }
1231
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001232 void removeWindowContainer() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001233 if (mAtmService.mWindowManager.mRoot == null) return;
Yunfan Chend4ef3012018-11-28 21:14:32 -08001234
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001235 final DisplayContent dc = mAtmService.mWindowManager.mRoot.getDisplayContent(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001236 getDisplayId());
1237 if (dc == null) {
1238 Slog.w(TAG, "removeWindowContainer: Attempted to remove token: "
1239 + appToken + " from non-existing displayId=" + getDisplayId());
Bryce Lee7ace3952018-02-16 14:34:32 -08001240 return;
1241 }
Wale Ogunwalecc367f42017-02-01 08:12:14 -08001242 // Resume key dispatching if it is currently paused before we remove the container.
1243 resumeKeyDispatchingLocked();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001244 dc.removeAppToken(appToken.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 }
1246
Winson Chung30480042017-01-26 10:55:34 -08001247 /**
1248 * Reparents this activity into {@param newTask} at the provided {@param position}. The caller
1249 * should ensure that the {@param newTask} is not already the parent of this activity.
1250 */
1251 void reparent(TaskRecord newTask, int position, String reason) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001252 if (mAppWindowToken == null) {
1253 Slog.w(TAG, "reparent: Attempted to reparent non-existing app token: " + appToken);
1254 return;
1255 }
Winson Chung30480042017-01-26 10:55:34 -08001256 final TaskRecord prevTask = task;
1257 if (prevTask == newTask) {
1258 throw new IllegalArgumentException(reason + ": task=" + newTask
1259 + " is already the parent of r=" + this);
1260 }
1261
Winson Chung74666102017-02-22 17:49:24 -08001262 // TODO: Ensure that we do not directly reparent activities across stacks, as that may leave
1263 // the stacks in strange states. For now, we should use Task.reparent() to ensure that
1264 // the stack is left in an OK state.
1265 if (prevTask != null && newTask != null && prevTask.getStack() != newTask.getStack()) {
1266 throw new IllegalArgumentException(reason + ": task=" + newTask
1267 + " is in a different stack (" + newTask.getStackId() + ") than the parent of"
1268 + " r=" + this + " (" + prevTask.getStackId() + ")");
1269 }
1270
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001271 mAppWindowToken.reparent(newTask.getTask(), position);
Winson Chung30480042017-01-26 10:55:34 -08001272
Bryce Lee84730a02018-04-03 14:10:04 -07001273 // Reparenting prevents informing the parent stack of activity removal in the case that
1274 // the new stack has the same parent. we must manually signal here if this is not the case.
1275 final ActivityStack prevStack = prevTask.getStack();
1276
1277 if (prevStack != newTask.getStack()) {
1278 prevStack.onActivityRemovedFromStack(this);
1279 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001280 // Remove the activity from the old task and add it to the new task.
Bryce Lee84730a02018-04-03 14:10:04 -07001281 prevTask.removeActivity(this, true /* reparenting */);
Bryce Lee0f9bde82017-02-22 16:39:06 -08001282
Winson Chung30480042017-01-26 10:55:34 -08001283 newTask.addActivityAtIndex(position, this);
1284 }
1285
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001286 private boolean isHomeIntent(Intent intent) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001287 return ACTION_MAIN.equals(intent.getAction())
Chilun2ef71f72018-11-16 17:57:15 +08001288 && (intent.hasCategory(CATEGORY_HOME)
1289 || intent.hasCategory(CATEGORY_SECONDARY_HOME))
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001290 && intent.getCategories().size() == 1
1291 && intent.getData() == null
1292 && intent.getType() == null;
1293 }
1294
Chong Zhangad24f962016-08-25 12:12:33 -07001295 static boolean isMainIntent(Intent intent) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001296 return ACTION_MAIN.equals(intent.getAction())
1297 && intent.hasCategory(CATEGORY_LAUNCHER)
Chong Zhangad24f962016-08-25 12:12:33 -07001298 && intent.getCategories().size() == 1
1299 && intent.getData() == null
1300 && intent.getType() == null;
1301 }
1302
Louis Chang6a9be162019-07-15 10:41:32 +08001303 @VisibleForTesting
1304 boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001305 if (uid == Process.myUid() || uid == 0) {
1306 // System process can launch home activity.
1307 return true;
1308 }
Winson Chung547afd22018-05-17 16:03:25 -07001309 // Allow the recents component to launch the home activity.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001310 final RecentTasks recentTasks = mStackSupervisor.mService.getRecentTasks();
Winson Chung547afd22018-05-17 16:03:25 -07001311 if (recentTasks != null && recentTasks.isCallerRecents(uid)) {
1312 return true;
1313 }
Louis Chang6a9be162019-07-15 10:41:32 +08001314 // Resolver or system chooser activity can launch home activity.
1315 return sourceRecord != null && sourceRecord.isResolverOrDelegateActivity();
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001316 }
1317
Winson Chung83471632016-12-13 11:02:12 -08001318 /**
1319 * @return whether the given package name can launch an assist activity.
1320 */
1321 private boolean canLaunchAssistActivity(String packageName) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001322 final ComponentName assistComponent =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001323 mAtmService.mActiveVoiceInteractionServiceComponent;
Winson Chung83471632016-12-13 11:02:12 -08001324 if (assistComponent != null) {
1325 return assistComponent.getPackageName().equals(packageName);
1326 }
1327 return false;
1328 }
1329
1330 private void setActivityType(boolean componentSpecified, int launchedFromUid, Intent intent,
1331 ActivityOptions options, ActivityRecord sourceRecord) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001332 int activityType = ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001333 if ((!componentSpecified || canLaunchHomeActivity(launchedFromUid, sourceRecord))
Louis Chang6a9be162019-07-15 10:41:32 +08001334 && isHomeIntent(intent) && !isResolverOrDelegateActivity()) {
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001335 // This sure looks like a home activity!
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001336 activityType = ACTIVITY_TYPE_HOME;
Wale Ogunwaledf241e92016-10-13 15:14:21 -07001337
1338 if (info.resizeMode == RESIZE_MODE_FORCE_RESIZEABLE
1339 || info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
1340 // We only allow home activities to be resizeable if they explicitly requested it.
1341 info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
1342 }
Andrii Kulian3b3fb662019-06-26 17:52:26 -07001343 } else if (mAtmService.getRecentTasks().isRecentsComponent(mActivityComponent,
Andrii Kulianeceebbf2019-06-26 17:36:51 -07001344 info.applicationInfo.uid)) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001345 activityType = ACTIVITY_TYPE_RECENTS;
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001346 } else if (options != null && options.getLaunchActivityType() == ACTIVITY_TYPE_ASSISTANT
Winson Chung83471632016-12-13 11:02:12 -08001347 && canLaunchAssistActivity(launchedFromPackage)) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001348 activityType = ACTIVITY_TYPE_ASSISTANT;
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001349 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001350 setActivityType(activityType);
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001351 }
1352
Craig Mautnera228ae92014-07-09 05:44:55 -07001353 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001354 if (launchMode != LAUNCH_SINGLE_INSTANCE && launchMode != LAUNCH_SINGLE_TASK) {
Craig Mautnera228ae92014-07-09 05:44:55 -07001355 task.setTaskToAffiliateWith(taskToAffiliateWith);
1356 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001357 }
1358
Andrii Kulian02b7a832016-10-06 23:11:56 -07001359 /**
1360 * @return Stack value from current task, null if there is no task.
1361 */
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001362 <T extends ActivityStack> T getActivityStack() {
Winson Chung55893332017-02-17 17:13:10 -08001363 return task != null ? (T) task.getStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001364 }
1365
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001366 int getStackId() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001367 return getActivityStack() != null ? getActivityStack().mStackId : INVALID_STACK_ID;
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001368 }
1369
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001370 ActivityDisplay getDisplay() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001371 final ActivityStack stack = getActivityStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001372 return stack != null ? stack.getDisplay() : null;
1373 }
1374
Craig Mautner5eda9b32013-07-02 11:58:16 -07001375 boolean changeWindowTranslucency(boolean toOpaque) {
1376 if (fullscreen == toOpaque) {
1377 return false;
1378 }
Craig Mautner4addfc52013-06-25 08:05:45 -07001379
Craig Mautner5eda9b32013-07-02 11:58:16 -07001380 // Keep track of the number of fullscreen activities in this task.
1381 task.numFullscreen += toOpaque ? +1 : -1;
1382
1383 fullscreen = toOpaque;
1384 return true;
Craig Mautner4addfc52013-06-25 08:05:45 -07001385 }
1386
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001387 void takeFromHistory() {
1388 if (inHistory) {
1389 inHistory = false;
1390 if (task != null && !finishing) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001391 task = null;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001392 }
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -07001393 clearOptionsLocked();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001394 }
1395 }
1396
1397 boolean isInHistory() {
1398 return inHistory;
1399 }
1400
Wale Ogunwale7d701172015-03-11 15:36:30 -07001401 boolean isInStackLocked() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001402 final ActivityStack stack = getActivityStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001403 return stack != null && stack.isInStackLocked(this) != null;
Wale Ogunwale7d701172015-03-11 15:36:30 -07001404 }
1405
Craig Mautner21d24a22014-04-23 11:45:37 -07001406 boolean isPersistable() {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001407 return (info.persistableMode == PERSIST_ROOT_ONLY ||
1408 info.persistableMode == PERSIST_ACROSS_REBOOTS) &&
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001409 (intent == null || (intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
Craig Mautner21d24a22014-04-23 11:45:37 -07001410 }
1411
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08001412 boolean isFocusable() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001413 return mRootActivityContainer.isFocusable(this, isAlwaysFocusable());
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001414 }
1415
1416 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001417 return ActivityInfo.isResizeableMode(info.resizeMode) || info.supportsPictureInPicture();
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001418 }
1419
Winson Chungd3395382016-12-13 11:49:09 -08001420 /**
1421 * @return whether this activity is non-resizeable or forced to be resizeable
1422 */
1423 boolean isNonResizableOrForcedResizable() {
Wale Ogunwaledf241e92016-10-13 15:14:21 -07001424 return info.resizeMode != RESIZE_MODE_RESIZEABLE
Wale Ogunwale72a73e32016-10-13 12:16:39 -07001425 && info.resizeMode != RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Jorim Jaggicd13d332016-04-27 15:40:20 -07001426 }
1427
Winson Chunge6308042016-10-31 09:24:01 -07001428 /**
Winson Chungd3395382016-12-13 11:49:09 -08001429 * @return whether this activity supports PiP multi-window and can be put in the pinned stack.
Winson Chunge6308042016-10-31 09:24:01 -07001430 */
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001431 boolean supportsPictureInPicture() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001432 return mAtmService.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
Winson Chungd3395382016-12-13 11:49:09 -08001433 && info.supportsPictureInPicture();
1434 }
1435
1436 /**
1437 * @return whether this activity supports split-screen multi-window and can be put in the docked
1438 * stack.
1439 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001440 @Override
1441 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001442 // An activity can not be docked even if it is considered resizeable because it only
1443 // supports picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001444 return super.supportsSplitScreenWindowingMode()
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001445 && mAtmService.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow();
Winson Chungd3395382016-12-13 11:49:09 -08001446 }
1447
1448 /**
1449 * @return whether this activity supports freeform multi-window and can be put in the freeform
1450 * stack.
1451 */
1452 boolean supportsFreeform() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001453 return mAtmService.mSupportsFreeformWindowManagement && supportsResizeableMultiWindow();
Winson Chungd3395382016-12-13 11:49:09 -08001454 }
1455
1456 /**
1457 * @return whether this activity supports non-PiP multi-window.
1458 */
1459 private boolean supportsResizeableMultiWindow() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001460 return mAtmService.mSupportsMultiWindow && !isActivityTypeHome()
Winson Chungd3395382016-12-13 11:49:09 -08001461 && (ActivityInfo.isResizeableMode(info.resizeMode)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001462 || mAtmService.mForceResizableActivities);
Wale Ogunwaled26176f2016-01-25 20:04:04 -08001463 }
1464
Winson Chunge6308042016-10-31 09:24:01 -07001465 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001466 * Check whether this activity can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001467 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001468 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001469 * @return {@code true} if either it is the default display or this activity can be put on a
1470 * secondary screen.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001471 */
1472 boolean canBeLaunchedOnDisplay(int displayId) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001473 return mAtmService.mStackSupervisor.canPlaceEntityOnDisplay(displayId, launchedFromPid,
Riddle Hsu16567132018-08-16 21:37:47 +08001474 launchedFromUid, info);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001475 }
1476
1477 /**
Robert Carrc33658e2017-04-11 18:24:20 -07001478 * @param beforeStopping Whether this check is for an auto-enter-pip operation, that is to say
1479 * the activity has requested to enter PiP when it would otherwise be stopped.
1480 *
Winson Chung298f95b2017-08-10 15:57:18 -07001481 * @return whether this activity is currently allowed to enter PIP.
Winson Chunge6308042016-10-31 09:24:01 -07001482 */
Winson Chung298f95b2017-08-10 15:57:18 -07001483 boolean checkEnterPictureInPictureState(String caller, boolean beforeStopping) {
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07001484 if (!supportsPictureInPicture()) {
1485 return false;
1486 }
1487
Winson Chungf4ac0632017-03-17 12:34:12 -07001488 // Check app-ops and see if PiP is supported for this package
1489 if (!checkEnterPictureInPictureAppOpsState()) {
1490 return false;
1491 }
1492
Winson Chungf1bfee12017-03-24 17:11:33 -07001493 // Check to see if we are in VR mode, and disallow PiP if so
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001494 if (mAtmService.shouldDisableNonVrUiLocked()) {
Winson Chungf1bfee12017-03-24 17:11:33 -07001495 return false;
1496 }
1497
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001498 boolean isKeyguardLocked = mAtmService.isKeyguardLocked();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001499 boolean isCurrentAppLocked =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001500 mAtmService.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001501 final ActivityDisplay display = getDisplay();
1502 boolean hasPinnedStack = display != null && display.hasPinnedStack();
Winson Chungbb348802017-01-30 12:01:45 -08001503 // Don't return early if !isNotLocked, since we want to throw an exception if the activity
1504 // is in an incorrect state
Winson Chunge581ebf2017-02-21 08:25:03 -08001505 boolean isNotLockedOrOnKeyguard = !isKeyguardLocked && !isCurrentAppLocked;
Robert Carrc33658e2017-04-11 18:24:20 -07001506
1507 // We don't allow auto-PiP when something else is already pipped.
1508 if (beforeStopping && hasPinnedStack) {
1509 return false;
1510 }
1511
Bryce Lee7ace3952018-02-16 14:34:32 -08001512 switch (mState) {
Winson Chungc2baac02017-01-11 13:34:47 -08001513 case RESUMED:
Winson Chunge581ebf2017-02-21 08:25:03 -08001514 // When visible, allow entering PiP if the app is not locked. If it is over the
1515 // keyguard, then we will prompt to unlock in the caller before entering PiP.
Robert Carrc33658e2017-04-11 18:24:20 -07001516 return !isCurrentAppLocked &&
Winson Chungf7e03e12017-08-22 11:32:16 -07001517 (supportsEnterPipOnTaskSwitch || !beforeStopping);
Winson Chungc2baac02017-01-11 13:34:47 -08001518 case PAUSING:
1519 case PAUSED:
Winson Chungbb348802017-01-30 12:01:45 -08001520 // When pausing, then only allow enter PiP as in the resume state, and in addition,
1521 // require that there is not an existing PiP activity and that the current system
1522 // state supports entering PiP
Winson Chunge581ebf2017-02-21 08:25:03 -08001523 return isNotLockedOrOnKeyguard && !hasPinnedStack
Winson Chungf7e03e12017-08-22 11:32:16 -07001524 && supportsEnterPipOnTaskSwitch;
Winson Chungc2baac02017-01-11 13:34:47 -08001525 case STOPPING:
1526 // When stopping in a valid state, then only allow enter PiP as in the pause state.
1527 // Otherwise, fall through to throw an exception if the caller is trying to enter
1528 // PiP in an invalid stopping state.
Winson Chungf7e03e12017-08-22 11:32:16 -07001529 if (supportsEnterPipOnTaskSwitch) {
Winson Chungf4ac0632017-03-17 12:34:12 -07001530 return isNotLockedOrOnKeyguard && !hasPinnedStack;
Winson Chungc2baac02017-01-11 13:34:47 -08001531 }
1532 default:
Winson Chung298f95b2017-08-10 15:57:18 -07001533 return false;
Winson Chungb5c41b72016-12-07 15:00:47 -08001534 }
Winson Chunge6308042016-10-31 09:24:01 -07001535 }
1536
Winson Chung59fda9e2017-01-20 16:14:51 -08001537 /**
Winson Chungf4ac0632017-03-17 12:34:12 -07001538 * @return Whether AppOps allows this package to enter picture-in-picture.
Winson Chung59fda9e2017-01-20 16:14:51 -08001539 */
Winson Chungf4ac0632017-03-17 12:34:12 -07001540 private boolean checkEnterPictureInPictureAppOpsState() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001541 return mAtmService.getAppOpsService().checkOperation(
Andrii Kulianeceebbf2019-06-26 17:36:51 -07001542 OP_PICTURE_IN_PICTURE, info.applicationInfo.uid, packageName) == MODE_ALLOWED;
Winson Chung59fda9e2017-01-20 16:14:51 -08001543 }
1544
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001545 boolean isAlwaysFocusable() {
1546 return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08001547 }
1548
Louis Chang19443452018-10-09 12:10:21 +08001549 /** Move activity with its stack to front and make the stack focused. */
1550 boolean moveFocusableActivityToTop(String reason) {
1551 if (!isFocusable()) {
1552 if (DEBUG_FOCUS) {
1553 Slog.d(TAG_FOCUS, "moveActivityStackToFront: unfocusable activity=" + this);
1554 }
1555 return false;
1556 }
1557
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001558 final TaskRecord task = getTaskRecord();
1559 final ActivityStack stack = getActivityStack();
Louis Chang19443452018-10-09 12:10:21 +08001560 if (stack == null) {
1561 Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: activity="
1562 + this + " task=" + task);
1563 return false;
1564 }
1565
Wale Ogunwaled32da472018-11-16 07:19:28 -08001566 if (mRootActivityContainer.getTopResumedActivity() == this) {
Louis Chang19443452018-10-09 12:10:21 +08001567 if (DEBUG_FOCUS) {
1568 Slog.d(TAG_FOCUS, "moveActivityStackToFront: already on top, activity=" + this);
1569 }
1570 return false;
1571 }
1572
1573 if (DEBUG_FOCUS) {
1574 Slog.d(TAG_FOCUS, "moveActivityStackToFront: activity=" + this);
1575 }
1576
1577 stack.moveToFront(reason, task);
1578 // Report top activity change to tracking services and WM
Wale Ogunwaled32da472018-11-16 07:19:28 -08001579 if (mRootActivityContainer.getTopResumedActivity() == this) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001580 mAtmService.setResumedActivityUncheckLocked(this, reason);
Louis Chang19443452018-10-09 12:10:21 +08001581 }
1582 return true;
1583 }
Jorim Jaggife762342016-10-13 14:33:27 +02001584
Andrii Kuliande93eff2019-07-12 12:21:27 -07001585 /** Finish all activities in the task with the same affinity as this one. */
1586 void finishActivityAffinity() {
1587 final ArrayList<ActivityRecord> activities = getTaskRecord().mActivities;
1588 for (int index = activities.indexOf(this); index >= 0; --index) {
1589 final ActivityRecord cur = activities.get(index);
1590 if (!Objects.equals(cur.taskAffinity, taskAffinity)) {
1591 break;
1592 }
1593 cur.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
1594 "request-affinity", true /* oomAdj */);
1595 }
1596 }
1597
1598 /**
1599 * Sets the result for activity that started this one, clears the references to activities
1600 * started for result from this one, and clears new intents.
1601 */
1602 void finishActivityResults(int resultCode, Intent resultData) {
1603 // Send the result if needed
1604 if (resultTo != null) {
1605 if (DEBUG_RESULTS) {
1606 Slog.v(TAG_RESULTS, "Adding result to " + resultTo
1607 + " who=" + resultWho + " req=" + requestCode
1608 + " res=" + resultCode + " data=" + resultData);
1609 }
1610 if (resultTo.mUserId != mUserId) {
1611 if (resultData != null) {
1612 resultData.prepareToLeaveUser(mUserId);
1613 }
1614 }
1615 if (info.applicationInfo.uid > 0) {
1616 mAtmService.mUgmInternal.grantUriPermissionFromIntent(info.applicationInfo.uid,
1617 resultTo.packageName, resultData,
1618 resultTo.getUriPermissionsLocked(), resultTo.mUserId);
1619 }
1620 resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData);
1621 resultTo = null;
1622 } else if (DEBUG_RESULTS) {
1623 Slog.v(TAG_RESULTS, "No result destination from " + this);
1624 }
1625
1626 // Make sure this HistoryRecord is not holding on to other resources,
1627 // because clients have remote IPC references to this object so we
1628 // can't assume that will go away and want to avoid circular IPC refs.
1629 results = null;
1630 pendingResults = null;
1631 newIntents = null;
1632 setSavedState(null /* savedState */);
1633 }
1634
Andrii Kulian057a6512019-07-15 16:15:51 -07001635 /** Activity finish request was not executed. */
1636 static final int FINISH_RESULT_CANCELLED = 0;
1637 /** Activity finish was requested, activity will be fully removed later. */
1638 static final int FINISH_RESULT_REQUESTED = 1;
1639 /** Activity finish was requested, activity was removed from history. */
1640 static final int FINISH_RESULT_REMOVED = 2;
1641
1642 /** Definition of possible results for activity finish request. */
1643 @IntDef(prefix = { "FINISH_RESULT_" }, value = {
1644 FINISH_RESULT_CANCELLED,
1645 FINISH_RESULT_REQUESTED,
1646 FINISH_RESULT_REMOVED,
1647 })
1648 @interface FinishRequest {}
1649
Andrii Kuliande93eff2019-07-12 12:21:27 -07001650 /**
1651 * See {@link #finishActivityLocked(int, Intent, String, boolean, boolean)}
1652 */
Andrii Kulian057a6512019-07-15 16:15:51 -07001653 @FinishRequest int finishActivityLocked(int resultCode, Intent resultData, String reason,
1654 boolean oomAdj) {
Andrii Kuliande93eff2019-07-12 12:21:27 -07001655 return finishActivityLocked(resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
1656 }
1657
1658 /**
Andrii Kulian057a6512019-07-15 16:15:51 -07001659 * @return One of {@link FinishRequest} values:
1660 * {@link #FINISH_RESULT_REMOVED} if this activity has been removed from the history list.
1661 * {@link #FINISH_RESULT_REQUESTED} if removal process was started, but it is still in the list
1662 * and will be removed from history later.
1663 * {@link #FINISH_RESULT_CANCELLED} if activity is already finishing or in invalid state and the
1664 * request to finish it was not ignored.
Andrii Kuliande93eff2019-07-12 12:21:27 -07001665 */
Andrii Kulian057a6512019-07-15 16:15:51 -07001666 @FinishRequest int finishActivityLocked(int resultCode, Intent resultData, String reason,
1667 boolean oomAdj, boolean pauseImmediately) {
1668 if (DEBUG_RESULTS || DEBUG_STATES) {
1669 Slog.v(TAG_STATES, "Finishing activity r=" + this + ", result=" + resultCode
1670 + ", data=" + resultData + ", reason=" + reason);
1671 }
1672
Andrii Kuliande93eff2019-07-12 12:21:27 -07001673 if (finishing) {
Andrii Kulian057a6512019-07-15 16:15:51 -07001674 Slog.w(TAG, "Duplicate finish request for r=" + this);
1675 return FINISH_RESULT_CANCELLED;
1676 }
1677
1678 if (!isInStackLocked()) {
1679 Slog.w(TAG, "Finish request when not in stack for r=" + this);
1680 return FINISH_RESULT_CANCELLED;
Andrii Kuliande93eff2019-07-12 12:21:27 -07001681 }
1682
1683 mAtmService.mWindowManager.deferSurfaceLayout();
1684 try {
1685 makeFinishingLocked();
1686 final TaskRecord task = getTaskRecord();
1687 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
1688 mUserId, System.identityHashCode(this),
1689 task.taskId, shortComponentName, reason);
1690 final ArrayList<ActivityRecord> activities = task.mActivities;
1691 final int index = activities.indexOf(this);
1692 if (index < (activities.size() - 1)) {
1693 if ((intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
1694 // If the caller asked that this activity (and all above it)
1695 // be cleared when the task is reset, don't lose that information,
1696 // but propagate it up to the next activity.
1697 final ActivityRecord next = activities.get(index + 1);
1698 next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
1699 }
1700 }
1701
1702 pauseKeyDispatchingLocked();
1703
1704 final ActivityStack stack = getActivityStack();
1705 stack.adjustFocusedActivityStack(this, "finishActivity");
1706
1707 finishActivityResults(resultCode, resultData);
1708
1709 final boolean endTask = index <= 0 && !task.isClearingToReuseTask();
1710 final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
1711 if (stack.getResumedActivity() == this) {
1712 if (DEBUG_VISIBILITY || DEBUG_TRANSITION) {
1713 Slog.v(TAG_TRANSITION, "Prepare close transition: finishing " + this);
1714 }
1715 if (endTask) {
1716 mAtmService.getTaskChangeNotificationController().notifyTaskRemovalStarted(
1717 task.getTaskInfo());
1718 }
1719 getDisplay().mDisplayContent.prepareAppTransition(transit, false);
1720
1721 // When finishing the activity preemptively take the snapshot before the app window
1722 // is marked as hidden and any configuration changes take place
1723 if (mAtmService.mWindowManager.mTaskSnapshotController != null) {
1724 final ArraySet<Task> tasks = Sets.newArraySet(task.mTask);
1725 mAtmService.mWindowManager.mTaskSnapshotController.snapshotTasks(tasks);
1726 mAtmService.mWindowManager.mTaskSnapshotController
1727 .addSkipClosingAppSnapshotTasks(tasks);
1728 }
1729
1730 // Tell window manager to prepare for this one to be removed.
1731 setVisibility(false);
1732
1733 if (stack.mPausingActivity == null) {
1734 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + this);
1735 if (DEBUG_USER_LEAVING) {
1736 Slog.v(TAG_USER_LEAVING, "finish() => pause with userLeaving=false");
1737 }
1738 stack.startPausingLocked(false, false, null, pauseImmediately);
1739 }
1740
1741 if (endTask) {
1742 mAtmService.getLockTaskController().clearLockedTask(task);
1743 }
1744 } else if (!isState(PAUSING)) {
1745 // If the activity is PAUSING, we will complete the finish once
1746 // it is done pausing; else we can just directly finish it here.
1747 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + this);
1748 if (visible) {
1749 prepareActivityHideTransitionAnimation(transit);
1750 }
1751
1752 final int finishMode = (visible || nowVisible) ? FINISH_AFTER_VISIBLE
1753 : FINISH_AFTER_PAUSE;
1754 final boolean removedActivity = finishCurrentActivityLocked(finishMode, oomAdj,
1755 "finishActivityLocked") == null;
1756
1757 // The following code is an optimization. When the last non-task overlay activity
1758 // is removed from the task, we remove the entire task from the stack. However,
1759 // since that is done after the scheduled destroy callback from the activity, that
1760 // call to change the visibility of the task overlay activities would be out of
1761 // sync with the activity visibility being set for this finishing activity above.
1762 // In this case, we can set the visibility of all the task overlay activities when
1763 // we detect the last one is finishing to keep them in sync.
1764 if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) {
1765 for (ActivityRecord taskOverlay : task.mActivities) {
1766 if (!taskOverlay.mTaskOverlay) {
1767 continue;
1768 }
1769 taskOverlay.prepareActivityHideTransitionAnimation(transit);
1770 }
1771 }
Andrii Kulian057a6512019-07-15 16:15:51 -07001772 return removedActivity ? FINISH_RESULT_REMOVED : FINISH_RESULT_REQUESTED;
Andrii Kuliande93eff2019-07-12 12:21:27 -07001773 } else {
1774 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + this);
1775 }
1776
Andrii Kulian057a6512019-07-15 16:15:51 -07001777 return FINISH_RESULT_REQUESTED;
Andrii Kuliande93eff2019-07-12 12:21:27 -07001778 } finally {
1779 mAtmService.mWindowManager.continueSurfaceLayout();
1780 }
1781 }
1782
1783 private void prepareActivityHideTransitionAnimation(int transit) {
1784 final DisplayContent dc = getDisplay().mDisplayContent;
1785 dc.prepareAppTransition(transit, false);
1786 setVisibility(false);
1787 dc.executeAppTransition();
1788 }
1789
1790 static final int FINISH_IMMEDIATELY = 0;
1791 private static final int FINISH_AFTER_PAUSE = 1;
1792 static final int FINISH_AFTER_VISIBLE = 2;
1793
1794 ActivityRecord finishCurrentActivityLocked(int mode, boolean oomAdj, String reason) {
1795 // First things first: if this activity is currently visible,
1796 // and the resumed activity is not yet visible, then hold off on
1797 // finishing until the resumed one becomes visible.
1798
1799 // The activity that we are finishing may be over the lock screen. In this case, we do not
1800 // want to consider activities that cannot be shown on the lock screen as running and should
1801 // proceed with finishing the activity if there is no valid next top running activity.
1802 // Note that if this finishing activity is floating task, we don't need to wait the
1803 // next activity resume and can destroy it directly.
1804 final ActivityStack stack = getActivityStack();
1805 final ActivityDisplay display = getDisplay();
1806 final ActivityRecord next = display.topRunningActivity(true /* considerKeyguardState */);
1807 final boolean isFloating = getConfiguration().windowConfiguration.tasksAreFloating();
1808
1809 if (mode == FINISH_AFTER_VISIBLE && (visible || nowVisible)
1810 && next != null && !next.nowVisible && !isFloating) {
1811 if (!mStackSupervisor.mStoppingActivities.contains(this)) {
1812 stack.addToStopping(this, false /* scheduleIdle */, false /* idleDelayed */,
1813 "finishCurrentActivityLocked");
1814 }
1815 if (DEBUG_STATES) {
1816 Slog.v(TAG_STATES, "Moving to STOPPING: " + this + " (finish requested)");
1817 }
1818 setState(STOPPING, "finishCurrentActivityLocked");
1819 if (oomAdj) {
1820 mAtmService.updateOomAdj();
1821 }
1822 return this;
1823 }
1824
1825 // make sure the record is cleaned out of other places.
1826 mStackSupervisor.mStoppingActivities.remove(this);
1827 mStackSupervisor.mGoingToSleepActivities.remove(this);
1828 final ActivityState prevState = getState();
1829 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + this);
1830
1831 setState(FINISHING, "finishCurrentActivityLocked");
1832
1833 // Don't destroy activity immediately if the display contains home stack, although there is
1834 // no next activity at the moment but another home activity should be started later. Keep
1835 // this activity alive until next home activity is resumed then user won't see a temporary
1836 // black screen.
1837 final boolean noRunningStack = next == null && display.topRunningActivity() == null
1838 && display.getHomeStack() == null;
1839 final boolean noFocusedStack = stack != display.getFocusedStack();
1840 final boolean finishingInNonFocusedStackOrNoRunning = mode == FINISH_AFTER_VISIBLE
1841 && prevState == PAUSED && (noFocusedStack || noRunningStack);
1842
1843 if (mode == FINISH_IMMEDIATELY
1844 || (prevState == PAUSED && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
1845 || finishingInNonFocusedStackOrNoRunning
1846 || prevState == STARTED
1847 || prevState == STOPPING
1848 || prevState == STOPPED
1849 || prevState == ActivityState.INITIALIZING) {
1850 makeFinishingLocked();
1851 boolean activityRemoved = stack.destroyActivityLocked(this, true /* removeFromApp */,
1852 "finish-imm:" + reason);
1853
1854 if (finishingInNonFocusedStackOrNoRunning) {
1855 // Finishing activity that was in paused state and it was in not currently focused
1856 // stack, need to make something visible in its place. Also if the display does not
1857 // have running activity, the configuration may need to be updated for restoring
1858 // original orientation of the display.
1859 mRootActivityContainer.ensureVisibilityAndConfig(next, getDisplayId(),
1860 false /* markFrozenIfConfigChanged */, true /* deferResume */);
1861 }
1862 if (activityRemoved) {
1863 mRootActivityContainer.resumeFocusedStacksTopActivities();
1864 }
1865 if (DEBUG_CONTAINERS) {
1866 Slog.d(TAG_CONTAINERS, "destroyActivityLocked: finishCurrentActivityLocked r="
1867 + this + " destroy returned removed=" + activityRemoved);
1868 }
1869 return activityRemoved ? null : this;
1870 }
1871
1872 // Need to go through the full pause cycle to get this
1873 // activity into the stopped state and then finish it.
1874 if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + this);
1875 mStackSupervisor.mFinishingActivities.add(this);
1876 resumeKeyDispatchingLocked();
1877 mRootActivityContainer.resumeFocusedStacksTopActivities();
1878 // If activity was not paused at this point - explicitly pause it to start finishing
1879 // process. Finishing will be completed once it reports pause back.
1880 if (isState(RESUMED) && stack.mPausingActivity != null) {
1881 stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
1882 next /* resuming */, false /* dontWait */);
1883 }
1884 return this;
1885 }
1886
Wale Ogunwale7d701172015-03-11 15:36:30 -07001887 void makeFinishingLocked() {
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001888 if (finishing) {
1889 return;
1890 }
1891 finishing = true;
1892 if (stopped) {
1893 clearOptionsLocked();
1894 }
Yorke Leebd54c2a2016-10-25 13:49:23 -07001895
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001896 if (mAtmService != null) {
1897 mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08001898 }
1899 }
1900
Dianne Hackborn7e269642010-08-25 19:50:20 -07001901 UriPermissionOwner getUriPermissionsLocked() {
1902 if (uriPermissions == null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001903 uriPermissions = new UriPermissionOwner(mAtmService.mUgmInternal, this);
Dianne Hackborn7e269642010-08-25 19:50:20 -07001904 }
1905 return uriPermissions;
1906 }
1907
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001908 void addResultLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 int requestCode, int resultCode,
1910 Intent resultData) {
1911 ActivityResult r = new ActivityResult(from, resultWho,
John Spurlock8a985d22014-02-25 09:40:05 -05001912 requestCode, resultCode, resultData);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001913 if (results == null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001914 results = new ArrayList<ResultInfo>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001915 }
1916 results.add(r);
1917 }
1918
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001919 void removeResultsLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001920 int requestCode) {
1921 if (results != null) {
1922 for (int i=results.size()-1; i>=0; i--) {
1923 ActivityResult r = (ActivityResult)results.get(i);
1924 if (r.mFrom != from) continue;
1925 if (r.mResultWho == null) {
1926 if (resultWho != null) continue;
1927 } else {
1928 if (!r.mResultWho.equals(resultWho)) continue;
1929 }
1930 if (r.mRequestCode != requestCode) continue;
1931
1932 results.remove(i);
1933 }
1934 }
1935 }
1936
Andrii Kulian21713ac2016-10-12 22:05:05 -07001937 private void addNewIntentLocked(ReferrerIntent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001938 if (newIntents == null) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001939 newIntents = new ArrayList<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001940 }
1941 newIntents.add(intent);
1942 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001943
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001944 final boolean isSleeping() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001945 final ActivityStack stack = getActivityStack();
1946 return stack != null ? stack.shouldSleepActivities() : mAtmService.isSleepingLocked();
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001947 }
1948
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001949 /**
1950 * Deliver a new Intent to an existing activity, so that its onNewIntent()
1951 * method will be called at the proper time.
1952 */
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001953 final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
Dianne Hackborn514074f2013-02-11 10:52:46 -08001954 // The activity now gets access to the data associated with this Intent.
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001955 mAtmService.mUgmInternal.grantUriPermissionFromIntent(callingUid, packageName,
1956 intent, getUriPermissionsLocked(), mUserId);
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001957 final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
Craig Mautner86d67a42013-05-14 10:34:38 -07001958 boolean unsent = true;
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001959 final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping();
Wale Ogunwale826c7062016-09-13 08:25:54 -07001960
1961 // We want to immediately deliver the intent to the activity if:
Wale Ogunwale03f7e9e2016-09-22 09:04:09 -07001962 // - It is currently resumed or paused. i.e. it is currently visible to the user and we want
1963 // the user to see the visual effects caused by the intent delivery now.
Wale Ogunwale826c7062016-09-13 08:25:54 -07001964 // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001965 if ((mState == RESUMED || mState == PAUSED || isTopActivityWhileSleeping)
1966 && attachedToProcess()) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001967 try {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001968 ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
1969 ar.add(rintent);
Louis Changea203cd2019-07-01 12:39:31 +08001970 // Making sure the client state is RESUMED after transaction completed and doing
1971 // so only if activity is currently RESUMED. Otherwise, client may have extra
1972 // life-cycle calls to RESUMED (and PAUSED later).
Louis Chang92d16522019-02-27 12:56:18 +08001973 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Louis Changea203cd2019-07-01 12:39:31 +08001974 NewIntentItem.obtain(ar, mState == RESUMED));
Craig Mautner86d67a42013-05-14 10:34:38 -07001975 unsent = false;
Dianne Hackborn39792d22010-08-19 18:01:52 -07001976 } catch (RemoteException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001977 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
Dianne Hackborn39792d22010-08-19 18:01:52 -07001978 } catch (NullPointerException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001979 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001980 }
1981 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001982 if (unsent) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001983 addNewIntentLocked(rintent);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001984 }
1985 }
1986
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001987 void updateOptionsLocked(ActivityOptions options) {
1988 if (options != null) {
Jorim Jaggi346702a2019-05-08 17:49:33 +02001989 if (DEBUG_TRANSITION) Slog.i(TAG, "Update options for " + this);
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001990 if (pendingOptions != null) {
1991 pendingOptions.abort();
1992 }
1993 pendingOptions = options;
1994 }
1995 }
1996
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001997 void applyOptionsLocked() {
George Mount2c92c972014-03-20 09:38:23 -07001998 if (pendingOptions != null
Ruben Brunkf53497c2017-03-27 20:26:17 -07001999 && pendingOptions.getAnimationType() != ANIM_SCENE_TRANSITION) {
Jorim Jaggi346702a2019-05-08 17:49:33 +02002000 if (DEBUG_TRANSITION) Slog.i(TAG, "Applying options for " + this);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002001 applyOptionsLocked(pendingOptions, intent);
chaviw82a0ba82018-03-15 14:26:29 -07002002 if (task == null) {
2003 clearOptionsLocked(false /* withAbort */);
2004 } else {
2005 // This will clear the options for all the ActivityRecords for this Task.
2006 task.clearAllPendingOptions();
2007 }
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07002008 }
2009 }
2010
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002011 /**
2012 * Apply override app transition base on options & animation type.
2013 */
2014 void applyOptionsLocked(ActivityOptions pendingOptions, Intent intent) {
2015 final int animationType = pendingOptions.getAnimationType();
2016 final DisplayContent displayContent = mAppWindowToken.getDisplayContent();
2017 switch (animationType) {
2018 case ANIM_CUSTOM:
2019 displayContent.mAppTransition.overridePendingAppTransition(
2020 pendingOptions.getPackageName(),
2021 pendingOptions.getCustomEnterResId(),
2022 pendingOptions.getCustomExitResId(),
2023 pendingOptions.getOnAnimationStartListener());
2024 break;
2025 case ANIM_CLIP_REVEAL:
2026 displayContent.mAppTransition.overridePendingAppTransitionClipReveal(
2027 pendingOptions.getStartX(), pendingOptions.getStartY(),
2028 pendingOptions.getWidth(), pendingOptions.getHeight());
2029 if (intent.getSourceBounds() == null) {
2030 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
2031 pendingOptions.getStartY(),
2032 pendingOptions.getStartX() + pendingOptions.getWidth(),
2033 pendingOptions.getStartY() + pendingOptions.getHeight()));
2034 }
2035 break;
2036 case ANIM_SCALE_UP:
2037 displayContent.mAppTransition.overridePendingAppTransitionScaleUp(
2038 pendingOptions.getStartX(), pendingOptions.getStartY(),
2039 pendingOptions.getWidth(), pendingOptions.getHeight());
2040 if (intent.getSourceBounds() == null) {
2041 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
2042 pendingOptions.getStartY(),
2043 pendingOptions.getStartX() + pendingOptions.getWidth(),
2044 pendingOptions.getStartY() + pendingOptions.getHeight()));
2045 }
2046 break;
2047 case ANIM_THUMBNAIL_SCALE_UP:
2048 case ANIM_THUMBNAIL_SCALE_DOWN:
2049 final boolean scaleUp = (animationType == ANIM_THUMBNAIL_SCALE_UP);
2050 final GraphicBuffer buffer = pendingOptions.getThumbnail();
2051 displayContent.mAppTransition.overridePendingAppTransitionThumb(buffer,
2052 pendingOptions.getStartX(), pendingOptions.getStartY(),
2053 pendingOptions.getOnAnimationStartListener(),
2054 scaleUp);
2055 if (intent.getSourceBounds() == null && buffer != null) {
2056 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
2057 pendingOptions.getStartY(),
2058 pendingOptions.getStartX() + buffer.getWidth(),
2059 pendingOptions.getStartY() + buffer.getHeight()));
2060 }
2061 break;
2062 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
2063 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
2064 final AppTransitionAnimationSpec[] specs = pendingOptions.getAnimSpecs();
2065 final IAppTransitionAnimationSpecsFuture specsFuture =
2066 pendingOptions.getSpecsFuture();
2067 if (specsFuture != null) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002068 displayContent.mAppTransition.overridePendingAppTransitionMultiThumbFuture(
2069 specsFuture, pendingOptions.getOnAnimationStartListener(),
2070 animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP);
2071 } else if (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
2072 && specs != null) {
2073 displayContent.mAppTransition.overridePendingAppTransitionMultiThumb(
2074 specs, pendingOptions.getOnAnimationStartListener(),
2075 pendingOptions.getAnimationFinishedListener(), false);
2076 } else {
2077 displayContent.mAppTransition.overridePendingAppTransitionAspectScaledThumb(
2078 pendingOptions.getThumbnail(),
2079 pendingOptions.getStartX(), pendingOptions.getStartY(),
2080 pendingOptions.getWidth(), pendingOptions.getHeight(),
2081 pendingOptions.getOnAnimationStartListener(),
2082 (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP));
2083 if (intent.getSourceBounds() == null) {
2084 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
2085 pendingOptions.getStartY(),
2086 pendingOptions.getStartX() + pendingOptions.getWidth(),
2087 pendingOptions.getStartY() + pendingOptions.getHeight()));
2088 }
2089 }
2090 break;
2091 case ANIM_OPEN_CROSS_PROFILE_APPS:
2092 displayContent.mAppTransition
2093 .overridePendingAppTransitionStartCrossProfileApps();
2094 break;
2095 case ANIM_REMOTE_ANIMATION:
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002096 displayContent.mAppTransition.overridePendingAppTransitionRemote(
2097 pendingOptions.getRemoteAnimationAdapter());
2098 break;
2099 case ANIM_NONE:
Louis Chang477e93e2019-04-24 18:35:20 +08002100 case ANIM_UNDEFINED:
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002101 break;
2102 default:
2103 Slog.e(TAG_WM, "applyOptionsLocked: Unknown animationType=" + animationType);
2104 break;
2105 }
2106 }
2107
Adam Powellcfbe9be2013-11-06 14:58:58 -08002108 ActivityOptions getOptionsForTargetActivityLocked() {
2109 return pendingOptions != null ? pendingOptions.forTargetActivity() : null;
2110 }
2111
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07002112 void clearOptionsLocked() {
chaviw82a0ba82018-03-15 14:26:29 -07002113 clearOptionsLocked(true /* withAbort */);
2114 }
2115
2116 void clearOptionsLocked(boolean withAbort) {
2117 if (withAbort && pendingOptions != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002118 pendingOptions.abort();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002119 }
chaviw82a0ba82018-03-15 14:26:29 -07002120 pendingOptions = null;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07002121 }
2122
Jorim Jaggi346702a2019-05-08 17:49:33 +02002123 ActivityOptions takeOptionsLocked(boolean fromClient) {
2124 if (DEBUG_TRANSITION) Slog.i(TAG, "Taking options for " + this + " callers="
2125 + Debug.getCallers(6));
Dianne Hackborn9622ca42012-10-23 18:56:33 -07002126 ActivityOptions opts = pendingOptions;
Jorim Jaggi346702a2019-05-08 17:49:33 +02002127
2128 // If we are trying to take activity options from the client, do not null it out if it's a
2129 // remote animation as the client doesn't need it ever. This is a workaround when client is
2130 // faster to take the options than we are to resume the next activity.
2131 // TODO (b/132432864): Fix the root cause of these transition preparing/applying options
2132 // timing somehow
2133 if (!fromClient || opts == null || opts.getRemoteAnimationAdapter() == null) {
2134 pendingOptions = null;
2135 }
Dianne Hackborn9622ca42012-10-23 18:56:33 -07002136 return opts;
2137 }
2138
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002139 void removeUriPermissionsLocked() {
Dianne Hackborn7e269642010-08-25 19:50:20 -07002140 if (uriPermissions != null) {
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07002141 uriPermissions.removeUriPermissions();
Dianne Hackborn7e269642010-08-25 19:50:20 -07002142 uriPermissions = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002143 }
2144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002145
2146 void pauseKeyDispatchingLocked() {
2147 if (!keysPaused) {
2148 keysPaused = true;
Bryce Lee2b8e0372018-04-05 17:01:37 -07002149
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002150 // TODO: remove the check after unification with AppWindowToken. The DC check is not
2151 // needed after no mock mAppWindowToken in tests.
2152 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
2153 mAppWindowToken.getDisplayContent().getInputMonitor().pauseDispatchingLw(
2154 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07002155 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002156 }
2157 }
2158
2159 void resumeKeyDispatchingLocked() {
2160 if (keysPaused) {
2161 keysPaused = false;
Bryce Lee2b8e0372018-04-05 17:01:37 -07002162
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002163 // TODO: remove the check after unification with AppWindowToken. The DC check is not
2164 // needed after no mock mAppWindowToken in tests.
2165 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
2166 mAppWindowToken.getDisplayContent().getInputMonitor().resumeDispatchingLw(
2167 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07002168 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002169 }
2170 }
2171
Jorim Jaggie7d2b852017-08-28 17:55:15 +02002172 private void updateTaskDescription(CharSequence description) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07002173 task.lastDescription = description;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002174 }
2175
Wale Ogunwaleec950642017-04-25 07:44:21 -07002176 void setDeferHidingClient(boolean deferHidingClient) {
2177 if (mDeferHidingClient == deferHidingClient) {
2178 return;
2179 }
2180 mDeferHidingClient = deferHidingClient;
2181 if (!mDeferHidingClient && !visible) {
2182 // Hiding the client is no longer deferred and the app isn't visible still, go ahead and
2183 // update the visibility.
2184 setVisibility(false);
2185 }
Wale Ogunwale89973222017-04-23 18:39:45 -07002186 }
2187
Wale Ogunwaleec950642017-04-25 07:44:21 -07002188 void setVisibility(boolean visible) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002189 if (mAppWindowToken == null) {
2190 Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: "
2191 + appToken);
2192 return;
2193 }
2194 mAppWindowToken.setVisibility(visible, mDeferHidingClient);
Bryce Lee2a3cc462017-10-27 10:57:35 -07002195 mStackSupervisor.getActivityMetricsLogger().notifyVisibilityChanged(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002196 }
2197
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002198 // TODO: Look into merging with #commitVisibility()
Wale Ogunwaleec950642017-04-25 07:44:21 -07002199 void setVisible(boolean newVisible) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002200 visible = newVisible;
Wale Ogunwaleec950642017-04-25 07:44:21 -07002201 mDeferHidingClient = !visible && mDeferHidingClient;
Wale Ogunwaleec950642017-04-25 07:44:21 -07002202 setVisibility(visible);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002203 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
2204 }
2205
Bryce Lee7ace3952018-02-16 14:34:32 -08002206 void setState(ActivityState state, String reason) {
2207 if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState()
2208 + " to:" + state + " reason:" + reason);
Bryce Lee6ff17072018-02-28 07:26:17 -08002209
Bryce Leeb0f993f2018-03-02 15:38:01 -08002210 if (state == mState) {
2211 // No need to do anything if state doesn't change.
2212 if (DEBUG_STATES) Slog.v(TAG_STATES, "State unchanged from:" + state);
2213 return;
2214 }
2215
Bryce Leeb0f993f2018-03-02 15:38:01 -08002216 mState = state;
2217
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002218 final TaskRecord parent = getTaskRecord();
Bryce Leec4ab62a2018-03-05 14:19:26 -08002219
2220 if (parent != null) {
2221 parent.onActivityStateChanged(this, state, reason);
2222 }
Robert Carr29daa922018-04-27 11:56:48 -07002223
Robert Carr9e1bf7c2018-05-31 15:39:07 -07002224 // The WindowManager interprets the app stopping signal as
2225 // an indication that the Surface will eventually be destroyed.
2226 // This however isn't necessarily true if we are going to sleep.
2227 if (state == STOPPING && !isSleeping()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002228 if (mAppWindowToken == null) {
2229 Slog.w(TAG_WM, "Attempted to notify stopping on non-existing app token: "
2230 + appToken);
2231 return;
2232 }
2233 mAppWindowToken.detachChildren();
Robert Carr29daa922018-04-27 11:56:48 -07002234 }
Hui Yu03d12402018-12-06 18:00:37 -08002235
2236 if (state == RESUMED) {
2237 mAtmService.updateBatteryStats(this, true);
2238 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_RESUMED);
2239 } else if (state == PAUSED) {
2240 mAtmService.updateBatteryStats(this, false);
2241 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_PAUSED);
2242 } else if (state == STOPPED) {
2243 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_STOPPED);
2244 } else if (state == DESTROYED) {
2245 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_DESTROYED);
2246 }
Bryce Lee7ace3952018-02-16 14:34:32 -08002247 }
2248
2249 ActivityState getState() {
2250 return mState;
2251 }
2252
2253 /**
2254 * Returns {@code true} if the Activity is in the specified state.
2255 */
2256 boolean isState(ActivityState state) {
2257 return state == mState;
2258 }
2259
2260 /**
2261 * Returns {@code true} if the Activity is in one of the specified states.
2262 */
2263 boolean isState(ActivityState state1, ActivityState state2) {
2264 return state1 == mState || state2 == mState;
2265 }
2266
2267 /**
2268 * Returns {@code true} if the Activity is in one of the specified states.
2269 */
2270 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3) {
2271 return state1 == mState || state2 == mState || state3 == mState;
2272 }
2273
2274 /**
2275 * Returns {@code true} if the Activity is in one of the specified states.
2276 */
2277 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3,
2278 ActivityState state4) {
2279 return state1 == mState || state2 == mState || state3 == mState || state4 == mState;
2280 }
2281
Louis Changeadb22f2019-06-19 12:09:23 +08002282 /**
2283 * Returns {@code true} if the Activity is in one of the specified states.
2284 */
2285 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3,
2286 ActivityState state4, ActivityState state5) {
2287 return state1 == mState || state2 == mState || state3 == mState || state4 == mState
2288 || state5 == mState;
2289 }
2290
Jorim Jaggibae01b12017-04-11 16:29:10 -07002291 void notifyAppResumed(boolean wasStopped) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002292 if (mAppWindowToken == null) {
2293 Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: "
2294 + appToken);
2295 return;
2296 }
2297 mAppWindowToken.notifyAppResumed(wasStopped);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002298 }
2299
2300 void notifyUnknownVisibilityLaunched() {
Jorim Jaggi838c2452017-08-28 15:44:43 +02002301
2302 // No display activities never add a window, so there is no point in waiting them for
2303 // relayout.
2304 if (!noDisplay) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002305 if (mAppWindowToken != null) {
2306 mAppWindowToken.getDisplayContent().mUnknownAppVisibilityController
2307 .notifyLaunched(mAppWindowToken);
2308 }
Jorim Jaggi838c2452017-08-28 15:44:43 +02002309 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002310 }
2311
Jorim Jaggi241ae102016-11-02 21:57:33 -07002312 /**
2313 * @return true if the input activity should be made visible, ignoring any effect Keyguard
2314 * might have on the visibility
2315 *
Garfield Tan47e576c2019-01-28 10:26:23 -08002316 * TODO(b/123540470): Combine this method and {@link #shouldBeVisible(boolean)}.
2317 *
Jorim Jaggi241ae102016-11-02 21:57:33 -07002318 * @see {@link ActivityStack#checkKeyguardVisibility}
2319 */
Wale Ogunwalec981ad52017-06-13 11:40:06 -07002320 boolean shouldBeVisibleIgnoringKeyguard(boolean behindFullscreenActivity) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002321 if (!okToShowLocked()) {
2322 return false;
2323 }
2324
Winson Chung3f0e59a2017-10-25 10:19:05 -07002325 return !behindFullscreenActivity || mLaunchTaskBehind;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002326 }
2327
Garfield Tan47e576c2019-01-28 10:26:23 -08002328 boolean shouldBeVisible(boolean behindFullscreenActivity) {
2329 // Check whether activity should be visible without Keyguard influence
2330 visibleIgnoringKeyguard = shouldBeVisibleIgnoringKeyguard(behindFullscreenActivity);
2331
2332 final ActivityStack stack = getActivityStack();
2333 if (stack == null) {
2334 return false;
2335 }
2336
Issei Suzuki62356a22019-04-11 16:46:37 +02002337 // Whether the activity is on the sleeping display.
2338 // TODO(b/129750406): This should be applied for the default display, too.
2339 final boolean isDisplaySleeping = getDisplay().isSleeping()
2340 && getDisplayId() != DEFAULT_DISPLAY;
Garfield Tan47e576c2019-01-28 10:26:23 -08002341 // Whether this activity is the top activity of this stack.
2342 final boolean isTop = this == stack.getTopActivity();
2343 // Exclude the case where this is the top activity in a pinned stack.
2344 final boolean isTopNotPinnedStack = stack.isAttached()
2345 && stack.getDisplay().isTopNotPinnedStack(stack);
Issei Suzuki62356a22019-04-11 16:46:37 +02002346 // Now check whether it's really visible depending on Keyguard state, and update
2347 // {@link ActivityStack} internal states.
2348 final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this,
Garfield Tan47e576c2019-01-28 10:26:23 -08002349 visibleIgnoringKeyguard, isTop && isTopNotPinnedStack);
Issei Suzuki62356a22019-04-11 16:46:37 +02002350 return visibleIgnoringDisplayStatus && !isDisplaySleeping;
Garfield Tan47e576c2019-01-28 10:26:23 -08002351 }
2352
2353 boolean shouldBeVisible() {
2354 final ActivityStack stack = getActivityStack();
2355 if (stack == null) {
2356 return false;
2357 }
2358
2359 // TODO: Use real value of behindFullscreenActivity calculated using the same logic in
2360 // ActivityStack#ensureActivitiesVisibleLocked().
2361 return shouldBeVisible(!stack.shouldBeVisible(null /* starting */));
2362 }
2363
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002364 void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002365 // This activity is not currently visible, but is running. Tell it to become visible.
Bryce Lee7ace3952018-02-16 14:34:32 -08002366 if (mState == RESUMED || this == starting) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002367 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
Bryce Lee7ace3952018-02-16 14:34:32 -08002368 "Not making visible, r=" + this + " state=" + mState + " starting=" + starting);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002369 return;
2370 }
2371
2372 // If this activity is paused, tell it to now show its window.
2373 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
2374 "Making visible and scheduling visibility: " + this);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002375 final ActivityStack stack = getActivityStack();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002376 try {
2377 if (stack.mTranslucentActivityWaiting != null) {
2378 updateOptionsLocked(returningOptions);
2379 stack.mUndrawnActivitiesBelowTopTranslucent.add(this);
2380 }
2381 setVisible(true);
2382 sleeping = false;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002383 app.postPendingUiCleanMsg(true);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002384 if (reportToClient) {
2385 makeClientVisible();
2386 } else {
2387 mClientVisibilityDeferred = true;
2388 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002389 // The activity may be waiting for stop, but that is no longer appropriate for it.
2390 mStackSupervisor.mStoppingActivities.remove(this);
2391 mStackSupervisor.mGoingToSleepActivities.remove(this);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002392 } catch (Exception e) {
2393 // Just skip on any failure; we'll make it visible when it next restarts.
2394 Slog.w(TAG, "Exception thrown making visible: " + intent.getComponent(), e);
2395 }
2396 handleAlreadyVisible();
2397 }
Andrii Kulian0d595f32018-02-21 15:47:33 -08002398
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002399 /** Send visibility change message to the client and pause if needed. */
2400 void makeClientVisible() {
2401 mClientVisibilityDeferred = false;
2402 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002403 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002404 WindowVisibilityItem.obtain(true /* showWindow */));
Andrii Kulian6b321512019-01-23 06:37:00 +00002405 makeActiveIfNeeded(null /* activeActivity*/);
Louis Changeadb22f2019-06-19 12:09:23 +08002406 if (isState(STOPPING, STOPPED)) {
2407 // Set state to STARTED in order to have consistent state with client while
2408 // making an non-active activity visible from stopped.
2409 setState(STARTED, "makeClientVisible");
Louis Chang3d119a92019-04-22 10:45:37 +08002410 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002411 } catch (Exception e) {
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002412 Slog.w(TAG, "Exception thrown sending visibility update: " + intent.getComponent(), e);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002413 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002414 }
2415
Andrii Kulian6b321512019-01-23 06:37:00 +00002416 /**
2417 * Make activity resumed or paused if needed.
2418 * @param activeActivity an activity that is resumed or just completed pause action.
2419 * We won't change the state of this activity.
2420 */
2421 boolean makeActiveIfNeeded(ActivityRecord activeActivity) {
2422 if (shouldResumeActivity(activeActivity)) {
2423 if (DEBUG_VISIBILITY) {
2424 Slog.v("TAG_VISIBILITY", "Resume visible activity, " + this);
2425 }
2426 return getActivityStack().resumeTopActivityUncheckedLocked(activeActivity /* prev */,
2427 null /* options */);
2428 } else if (shouldPauseActivity(activeActivity)) {
2429 if (DEBUG_VISIBILITY) {
2430 Slog.v("TAG_VISIBILITY", "Pause visible activity, " + this);
2431 }
2432 // An activity must be in the {@link PAUSING} state for the system to validate
2433 // the move to {@link PAUSED}.
2434 setState(PAUSING, "makeVisibleIfNeeded");
2435 try {
2436 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
2437 PauseActivityItem.obtain(finishing, false /* userLeaving */,
2438 configChangeFlags, false /* dontReport */));
2439 } catch (Exception e) {
2440 Slog.w(TAG, "Exception thrown sending pause: " + intent.getComponent(), e);
2441 }
2442 }
2443 return false;
2444 }
2445
2446 /**
2447 * Check if activity should be moved to PAUSED state. The activity:
2448 * - should be eligible to be made active (see {@link #shouldMakeActive(ActivityRecord)})
2449 * - should be non-focusable
2450 * - should not be currently pausing or paused
2451 * @param activeActivity the activity that is active or just completed pause action. We won't
2452 * resume if this activity is active.
2453 */
2454 private boolean shouldPauseActivity(ActivityRecord activeActivity) {
2455 return shouldMakeActive(activeActivity) && !isFocusable() && !isState(PAUSING, PAUSED);
2456 }
2457
2458 /**
2459 * Check if activity should be moved to RESUMED state. The activity:
2460 * - should be eligible to be made active (see {@link #shouldMakeActive(ActivityRecord)})
2461 * - should be focusable
2462 * @param activeActivity the activity that is active or just completed pause action. We won't
2463 * resume if this activity is active.
2464 */
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002465 @VisibleForTesting
2466 boolean shouldResumeActivity(ActivityRecord activeActivity) {
2467 return shouldMakeActive(activeActivity) && isFocusable() && !isState(RESUMED)
2468 && getActivityStack().getVisibility(activeActivity) == STACK_VISIBILITY_VISIBLE;
Andrii Kulian6b321512019-01-23 06:37:00 +00002469 }
2470
2471 /**
2472 * Check if activity is eligible to be made active (resumed of paused). The activity:
2473 * - should be paused, stopped or stopping
Andrii Kulian996df0d2019-01-24 17:04:36 -08002474 * - should not be the currently active one or launching behind other tasks
Andrii Kulian6b321512019-01-23 06:37:00 +00002475 * - should be either the topmost in task, or right below the top activity that is finishing
2476 * If all of these conditions are not met at the same time, the activity cannot be made active.
2477 */
Andrii Kulianf2195362019-01-31 18:20:11 -08002478 @VisibleForTesting
2479 boolean shouldMakeActive(ActivityRecord activeActivity) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002480 // If the activity is stopped, stopping, cycle to an active state. We avoid doing
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002481 // this when there is an activity waiting to become translucent as the extra binder
2482 // calls will lead to noticeable jank. A later call to
Andrii Kulian6b321512019-01-23 06:37:00 +00002483 // ActivityStack#ensureActivitiesVisibleLocked will bring the activity to a proper
2484 // active state.
Louis Changeadb22f2019-06-19 12:09:23 +08002485 if (!isState(STARTED, RESUMED, PAUSED, STOPPED, STOPPING)
Andrii Kulian6b321512019-01-23 06:37:00 +00002486 || getActivityStack().mTranslucentActivityWaiting != null) {
2487 return false;
2488 }
2489
2490 if (this == activeActivity) {
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002491 return false;
2492 }
2493
Andrii Kulianf2195362019-01-31 18:20:11 -08002494 if (!mStackSupervisor.readyToResume()) {
2495 // Making active is currently deferred (e.g. because an activity launch is in progress).
2496 return false;
2497 }
2498
Andrii Kulian996df0d2019-01-24 17:04:36 -08002499 if (this.mLaunchTaskBehind) {
2500 // This activity is being launched from behind, which means that it's not intended to be
2501 // presented to user right now, even if it's set to be visible.
2502 return false;
2503 }
2504
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002505 // Check if position in task allows to become paused
2506 final int positionInTask = task.mActivities.indexOf(this);
2507 if (positionInTask == -1) {
2508 throw new IllegalStateException("Activity not found in its task");
2509 }
2510 if (positionInTask == task.mActivities.size() - 1) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002511 // It's the topmost activity in the task - should become resumed now
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002512 return true;
2513 }
2514 // Check if activity above is finishing now and this one becomes the topmost in task.
2515 final ActivityRecord activityAbove = task.mActivities.get(positionInTask + 1);
2516 if (activityAbove.finishing && results == null) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002517 // We will only allow making active if activity above wasn't launched for result.
2518 // Otherwise it will cause this activity to resume before getting result.
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002519 return true;
2520 }
2521 return false;
2522 }
2523
Andrii Kulian21713ac2016-10-12 22:05:05 -07002524 boolean handleAlreadyVisible() {
2525 stopFreezingScreenLocked(false);
2526 try {
2527 if (returningOptions != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002528 app.getThread().scheduleOnNewActivityOptions(appToken, returningOptions.toBundle());
Andrii Kulian21713ac2016-10-12 22:05:05 -07002529 }
2530 } catch(RemoteException e) {
2531 }
Bryce Lee7ace3952018-02-16 14:34:32 -08002532 return mState == RESUMED;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002533 }
2534
2535 static void activityResumedLocked(IBinder token) {
2536 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2537 if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
Charles Chen69362cd2019-03-29 15:18:45 +08002538 if (r == null) {
2539 // If an app reports resumed after a long delay, the record on server side might have
2540 // been removed (e.g. destroy timeout), so the token could be null.
2541 return;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002542 }
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07002543 r.setSavedState(null /* savedState */);
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002544
2545 final ActivityDisplay display = r.getDisplay();
2546 if (display != null) {
2547 display.handleActivitySizeCompatModeIfNeeded(r);
2548 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002549 }
2550
2551 /**
2552 * Once we know that we have asked an application to put an activity in the resumed state
2553 * (either by launching it or explicitly telling it), this function updates the rest of our
2554 * state to match that fact.
2555 */
2556 void completeResumeLocked() {
2557 final boolean wasVisible = visible;
Jorim Jaggi8d062052017-08-22 14:55:17 +02002558 setVisible(true);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002559 if (!wasVisible) {
2560 // Visibility has changed, so take a note of it so we call the TaskStackChangedListener
2561 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
2562 }
2563 idle = false;
2564 results = null;
2565 newIntents = null;
2566 stopped = false;
2567
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002568 if (isActivityTypeHome()) {
Louis Changdcdde952018-12-04 15:38:44 +08002569 mStackSupervisor.updateHomeProcess(task.mActivities.get(0).app);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002570 }
2571
2572 if (nowVisible) {
Louis Changa59937a2019-03-20 17:17:22 +08002573 mStackSupervisor.stopWaitingForActivityVisible(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002574 }
2575
2576 // Schedule an idle timeout in case the app doesn't do it for us.
2577 mStackSupervisor.scheduleIdleTimeoutLocked(this);
2578
2579 mStackSupervisor.reportResumedActivityLocked(this);
2580
2581 resumeKeyDispatchingLocked();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002582 final ActivityStack stack = getActivityStack();
Jorim Jaggifa9ed962018-01-25 00:16:49 +01002583 mStackSupervisor.mNoAnimActivities.clear();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002584
2585 // Mark the point when the activity is resuming
2586 // TODO: To be more accurate, the mark should be before the onCreate,
2587 // not after the onResume. But for subsequent starts, onResume is fine.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002588 if (hasProcess()) {
Wale Ogunwale86b74462018-07-02 08:42:43 -07002589 cpuTimeAtResume = app.getCpuTime();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002590 } else {
2591 cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2592 }
2593
2594 returningOptions = null;
chaviw59b98852017-06-13 12:05:44 -07002595
2596 if (canTurnScreenOn()) {
2597 mStackSupervisor.wakeUp("turnScreenOnFlag");
2598 } else {
2599 // If the screen is going to turn on because the caller explicitly requested it and
2600 // the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
2601 // pause and then resume again later, which will result in a double life-cycle event.
David Stevens9440dc82017-03-16 19:00:20 -07002602 stack.checkReadyForSleep();
chaviw59b98852017-06-13 12:05:44 -07002603 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002604 }
2605
2606 final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
2607 CharSequence description) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002608 final ActivityStack stack = getActivityStack();
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002609 final boolean isStopping = mState == STOPPING;
2610 if (!isStopping && mState != RESTARTING_PROCESS) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002611 Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
Ruben Brunkf53497c2017-03-27 20:26:17 -07002612 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002613 return;
2614 }
2615 if (newPersistentState != null) {
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07002616 mPersistentState = newPersistentState;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002617 mAtmService.notifyTaskPersisterLocked(task, false);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002618 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002619
Andrii Kulian21713ac2016-10-12 22:05:05 -07002620 if (newIcicle != null) {
2621 // If icicle is null, this is happening due to a timeout, so we haven't really saved
2622 // the state.
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07002623 setSavedState(newIcicle);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002624 launchCount = 0;
Jorim Jaggie7d2b852017-08-28 17:55:15 +02002625 updateTaskDescription(description);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002626 }
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07002627 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + mIcicle);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002628 if (!stopped) {
2629 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
Ruben Brunkf53497c2017-03-27 20:26:17 -07002630 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002631 stopped = true;
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002632 if (isStopping) {
2633 setState(STOPPED, "activityStoppedLocked");
2634 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002635
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002636 if (mAppWindowToken != null) {
2637 mAppWindowToken.notifyAppStopped();
2638 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002639
Andrii Kulian21713ac2016-10-12 22:05:05 -07002640 if (finishing) {
2641 clearOptionsLocked();
2642 } else {
2643 if (deferRelaunchUntilPaused) {
2644 stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002645 mRootActivityContainer.resumeFocusedStacksTopActivities();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002646 } else {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002647 mRootActivityContainer.updatePreviousProcess(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002648 }
2649 }
2650 }
2651 }
2652
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002653 void startLaunchTickingLocked() {
Jeff Sharkey5ab02432017-06-27 11:01:36 -06002654 if (Build.IS_USER) {
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002655 return;
2656 }
2657 if (launchTickTime == 0) {
2658 launchTickTime = SystemClock.uptimeMillis();
2659 continueLaunchTickingLocked();
2660 }
2661 }
2662
2663 boolean continueLaunchTickingLocked() {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002664 if (launchTickTime == 0) {
2665 return false;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002666 }
Wale Ogunwale7d701172015-03-11 15:36:30 -07002667
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002668 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002669 if (stack == null) {
2670 return false;
2671 }
2672
Ruben Brunkf53497c2017-03-27 20:26:17 -07002673 Message msg = stack.mHandler.obtainMessage(LAUNCH_TICK_MSG, this);
2674 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
2675 stack.mHandler.sendMessageDelayed(msg, LAUNCH_TICK);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002676 return true;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002677 }
2678
2679 void finishLaunchTickingLocked() {
2680 launchTickTime = 0;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002681 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002682 if (stack != null) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07002683 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002684 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002685 }
2686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002687 // IApplicationToken
2688
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002689 public boolean mayFreezeScreenLocked(WindowProcessController app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002690 // Only freeze the screen if this activity is currently attached to
2691 // an application, and that application is not blocked or unresponding.
2692 // In any other case, we can't count on getting the screen unfrozen,
2693 // so it is best to leave as-is.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002694 return hasProcess() && !app.isCrashing() && !app.isNotResponding();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002695 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002696
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002697 public void startFreezingScreenLocked(WindowProcessController app, int configChanges) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 if (mayFreezeScreenLocked(app)) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002699 if (mAppWindowToken == null) {
2700 Slog.w(TAG_WM,
2701 "Attempted to freeze screen with non-existing app token: " + appToken);
2702 return;
2703 }
2704
Evan Roskyb1e75f72019-04-26 20:23:26 -07002705 // Window configuration changes only effect windows, so don't require a screen freeze.
2706 int freezableConfigChanges = configChanges & ~(CONFIG_WINDOW_CONFIGURATION);
2707 if (freezableConfigChanges == 0 && mAppWindowToken.okToDisplay()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002708 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + appToken);
2709 return;
2710 }
2711
2712 mAppWindowToken.startFreezingScreen();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002713 }
2714 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 public void stopFreezingScreenLocked(boolean force) {
2717 if (force || frozenBeforeDestroy) {
2718 frozenBeforeDestroy = false;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002719 if (mAppWindowToken == null) {
2720 return;
2721 }
2722 if (DEBUG_ORIENTATION) {
2723 Slog.v(TAG_WM, "Clear freezing of " + appToken + ": hidden="
2724 + mAppWindowToken.isHidden() + " freezing="
2725 + mAppWindowToken.isFreezingScreen());
2726 }
2727 mAppWindowToken.stopFreezingScreen(true, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002728 }
2729 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002730
Jorim Jaggi4d27b842017-08-17 17:22:26 +02002731 public void reportFullyDrawnLocked(boolean restoredFromBundle) {
Vishnu Nair132ee832018-09-28 15:00:05 -07002732 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2733 .getActivityMetricsLogger().logAppTransitionReportedDrawn(this, restoredFromBundle);
2734 if (info != null) {
2735 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002736 info.windowsFullyDrawnDelayMs, info.getLaunchState());
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002737 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002738 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002739
2740 /**
2741 * Called when the starting window for this container is drawn.
2742 */
Sudheer Shankac766db02017-06-12 10:37:29 -07002743 public void onStartingWindowDrawn(long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002744 synchronized (mAtmService.mGlobalLock) {
Bryce Lee2a3cc462017-10-27 10:57:35 -07002745 mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +01002746 getWindowingMode(), timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -08002747 }
2748 }
2749
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002750 /** Called when the windows associated app window container are drawn. */
Vishnu Nair9ba31652018-11-13 14:34:05 -08002751 public void onWindowsDrawn(boolean drawn, long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002752 synchronized (mAtmService.mGlobalLock) {
Vishnu Nair9ba31652018-11-13 14:34:05 -08002753 mDrawn = drawn;
2754 if (!drawn) {
2755 return;
2756 }
Vishnu Nair132ee832018-09-28 15:00:05 -07002757 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2758 .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
2759 final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002760 final @LaunchState int launchState = info != null ? info.getLaunchState() : -1;
Vishnu Nair132ee832018-09-28 15:00:05 -07002761 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002762 windowsDrawnDelayMs, launchState);
Louis Changa59937a2019-03-20 17:17:22 +08002763 mStackSupervisor.stopWaitingForActivityVisible(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002764 finishLaunchTickingLocked();
2765 if (task != null) {
2766 task.hasBeenVisible = true;
2767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002768 }
2769 }
2770
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002771 /** Called when the windows associated app window container are visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002772 public void onWindowsVisible() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002773 synchronized (mAtmService.mGlobalLock) {
Louis Changa59937a2019-03-20 17:17:22 +08002774 mStackSupervisor.stopWaitingForActivityVisible(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002775 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
2776 if (!nowVisible) {
2777 nowVisible = true;
2778 lastVisibleTime = SystemClock.uptimeMillis();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002779 mAtmService.scheduleAppGcsLocked();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002780 }
2781 }
2782 }
2783
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002784 /** Called when the windows associated app window container are no longer visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002785 public void onWindowsGone() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002786 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002787 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + this);
2788 nowVisible = false;
2789 }
2790 }
2791
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002792 void onAnimationFinished() {
2793 if (mRootActivityContainer.allResumedActivitiesIdle()
2794 || mStackSupervisor.isStoppingNoHistoryActivity()) {
2795 // If all activities are already idle or there is an activity that must be
2796 // stopped immediately after visible, then we now need to make sure we perform
2797 // the full stop of this activity. This is because we won't do that while they are still
2798 // waiting for the animation to finish.
2799 if (mStackSupervisor.mStoppingActivities.contains(this)) {
2800 mStackSupervisor.scheduleIdleLocked();
2801 }
2802 } else {
2803 // Instead of doing the full stop routine here, let's just hide any activities
2804 // we now can, and let them stop when the normal idle happens.
2805 mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
2806 false /* remove */, true /* processPausingActivities */);
2807 }
2808 }
2809
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002810 /**
2811 * Called when the key dispatching to a window associated with the app window container
2812 * timed-out.
2813 *
2814 * @param reason The reason for the key dispatching time out.
2815 * @param windowPid The pid of the window key dispatching timed out on.
2816 * @return True if input dispatching should be aborted.
2817 */
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002818 public boolean keyDispatchingTimedOut(String reason, int windowPid) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002819 ActivityRecord anrActivity;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002820 WindowProcessController anrApp;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002821 boolean windowFromSameProcessAsActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002822 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002823 anrActivity = getWaitingHistoryRecordLocked();
2824 anrApp = app;
Brian Carlstrom7b0f2e82017-03-31 00:24:18 -07002825 windowFromSameProcessAsActivity =
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002826 !hasProcess() || app.getPid() == windowPid || windowPid == -1;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002827 }
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002828
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002829 if (windowFromSameProcessAsActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002830 return mAtmService.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner,
Andrii Kulianeceebbf2019-06-26 17:36:51 -07002831 anrActivity.shortComponentName, anrActivity.info.applicationInfo,
2832 shortComponentName, app, false, reason);
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002833 } else {
2834 // In this case another process added windows using this activity token. So, we call the
2835 // generic service input dispatch timed out method so that the right process is blamed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002836 return mAtmService.mAmInternal.inputDispatchingTimedOut(
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002837 windowPid, false /* aboveSystem */, reason) < 0;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002838 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002839 }
2840
2841 private ActivityRecord getWaitingHistoryRecordLocked() {
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002842 // First find the real culprit... if this activity has stopped, then the key dispatching
riddle_hsudb46d6b2015-04-01 18:58:07 +08002843 // timeout should not be caused by this.
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002844 if (stopped) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002845 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
riddle_hsudb46d6b2015-04-01 18:58:07 +08002846 // Try to use the one which is closest to top.
Bryce Leec4ab62a2018-03-05 14:19:26 -08002847 ActivityRecord r = stack.getResumedActivity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002848 if (r == null) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002849 r = stack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002850 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002851 if (r != null) {
2852 return r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 }
2854 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002855 return this;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002856 }
2857
Chong Zhang87761972016-08-22 13:53:24 -07002858 /** Checks whether the activity should be shown for current user. */
2859 public boolean okToShowLocked() {
Bryce Lee8558ec72017-08-17 15:37:26 -07002860 // We cannot show activities when the device is locked and the application is not
2861 // encryption aware.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002862 if (!StorageManager.isUserKeyUnlocked(mUserId)
Bryce Lee8558ec72017-08-17 15:37:26 -07002863 && !info.applicationInfo.isEncryptionAware()) {
2864 return false;
2865 }
2866
Chong Zhang87761972016-08-22 13:53:24 -07002867 return (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002868 || (mStackSupervisor.isCurrentProfileLocked(mUserId)
2869 && mAtmService.mAmInternal.isUserRunning(mUserId, 0 /* flags */));
Chong Zhang87761972016-08-22 13:53:24 -07002870 }
2871
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002872 /**
2873 * This method will return true if the activity is either visible, is becoming visible, is
2874 * currently pausing, or is resumed.
2875 */
2876 public boolean isInterestingToUserLocked() {
Bryce Lee7ace3952018-02-16 14:34:32 -08002877 return visible || nowVisible || mState == PAUSING || mState == RESUMED;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002878 }
2879
Wale Ogunwale3e997362016-09-06 10:37:56 -07002880 void setSleeping(boolean _sleeping) {
2881 setSleeping(_sleeping, false);
2882 }
2883
2884 void setSleeping(boolean _sleeping, boolean force) {
2885 if (!force && sleeping == _sleeping) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002886 return;
2887 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002888 if (attachedToProcess()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002889 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002890 app.getThread().scheduleSleeping(appToken, _sleeping);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002891 if (_sleeping && !mStackSupervisor.mGoingToSleepActivities.contains(this)) {
2892 mStackSupervisor.mGoingToSleepActivities.add(this);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002893 }
2894 sleeping = _sleeping;
2895 } catch (RemoteException e) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002896 Slog.w(TAG, "Exception thrown when sleeping: " + intent.getComponent(), e);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002897 }
2898 }
2899 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08002900
Craig Mautnerd2328952013-03-05 12:46:26 -08002901 static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002902 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Craig Mautnerd2328952013-03-05 12:46:26 -08002903 if (r == null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002904 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002905 }
2906 final TaskRecord task = r.task;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002907 final int activityNdx = task.mActivities.indexOf(r);
Andrii Kulian39f27442019-06-26 19:09:19 -07002908 if (activityNdx < 0
2909 || (onlyRoot && activityNdx > task.findRootIndex(true /* effectiveRoot */))) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002910 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002911 }
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002912 return task.taskId;
Craig Mautnerd2328952013-03-05 12:46:26 -08002913 }
2914
2915 static ActivityRecord isInStackLocked(IBinder token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002916 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002917 return (r != null) ? r.getActivityStack().isInStackLocked(r) : null;
Craig Mautnerd2328952013-03-05 12:46:26 -08002918 }
2919
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002920 static ActivityStack getStackLocked(IBinder token) {
Craig Mautnerd2328952013-03-05 12:46:26 -08002921 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2922 if (r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002923 return r.getActivityStack();
Craig Mautnerd2328952013-03-05 12:46:26 -08002924 }
2925 return null;
2926 }
2927
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002928 /**
Riddle Hsufd4a0502018-10-16 01:05:16 +08002929 * @return display id to which this record is attached,
2930 * {@link android.view.Display#INVALID_DISPLAY} if not attached.
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002931 */
2932 int getDisplayId() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002933 final ActivityStack stack = getActivityStack();
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002934 if (stack == null) {
Riddle Hsufd4a0502018-10-16 01:05:16 +08002935 return INVALID_DISPLAY;
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002936 }
2937 return stack.mDisplayId;
2938 }
2939
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002940 final boolean isDestroyable() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002941 if (finishing || !hasProcess()) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002942 // This would be redundant.
2943 return false;
2944 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002945 final ActivityStack stack = getActivityStack();
Bryce Leec4ab62a2018-03-05 14:19:26 -08002946 if (stack == null || this == stack.getResumedActivity() || this == stack.mPausingActivity
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07002947 || !mHaveState || !stopped) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002948 // We're not ready for this kind of thing.
2949 return false;
2950 }
2951 if (visible) {
2952 // The user would notice this!
2953 return false;
2954 }
2955 return true;
2956 }
2957
Winson Chung3bad5cc02014-08-19 17:44:32 -07002958 private static String createImageFilename(long createTime, int taskId) {
2959 return String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX + createTime +
Ruben Brunkf53497c2017-03-27 20:26:17 -07002960 IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -07002961 }
2962
Craig Mautner648f69b2014-09-18 14:16:26 -07002963 void setTaskDescription(TaskDescription _taskDescription) {
2964 Bitmap icon;
2965 if (_taskDescription.getIconFilename() == null &&
2966 (icon = _taskDescription.getIcon()) != null) {
2967 final String iconFilename = createImageFilename(createTime, task.taskId);
Winson Chungc8408b82017-01-25 17:58:56 -08002968 final File iconFile = new File(TaskPersister.getUserImagesDir(task.userId),
2969 iconFilename);
Suprabh Shukla23593142015-11-03 17:31:15 -08002970 final String iconFilePath = iconFile.getAbsolutePath();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002971 mAtmService.getRecentTasks().saveImage(icon, iconFilePath);
Suprabh Shukla23593142015-11-03 17:31:15 -08002972 _taskDescription.setIconFilename(iconFilePath);
Craig Mautner648f69b2014-09-18 14:16:26 -07002973 }
2974 taskDescription = _taskDescription;
2975 }
2976
Amith Yamasani0af6fa72016-01-17 15:36:19 -08002977 void setVoiceSessionLocked(IVoiceInteractionSession session) {
2978 voiceSession = session;
2979 pendingVoiceInteractionStart = false;
2980 }
2981
2982 void clearVoiceSessionLocked() {
2983 voiceSession = null;
2984 pendingVoiceInteractionStart = false;
2985 }
2986
Jorim Jaggi02886a82016-12-06 09:10:06 -08002987 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch) {
Jorim Jaggi42befc62017-06-13 11:54:04 -07002988 showStartingWindow(prev, newTask, taskSwitch, false /* fromRecents */);
2989 }
2990
2991 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
2992 boolean fromRecents) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002993 if (mAppWindowToken == null) {
Jorim Jaggi70176432017-01-18 12:52:13 +01002994 return;
2995 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002996 if (mTaskOverlay) {
2997 // We don't show starting window for overlay activities.
2998 return;
2999 }
Sunny Goyald85bed52018-09-25 12:01:01 -07003000 if (pendingOptions != null
3001 && pendingOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
3002 // Don't show starting window when using shared element transition.
3003 return;
3004 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07003005
Wale Ogunwale3b232392016-05-13 15:37:13 -07003006 final CompatibilityInfo compatInfo =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003007 mAtmService.compatibilityInfoForPackageLocked(info.applicationInfo);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003008 final boolean shown = addStartingWindow(packageName, theme,
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08003009 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
Jorim Jaggibae01b12017-04-11 16:29:10 -07003010 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
Jorim Jaggi70aa4d12017-05-15 00:05:54 +02003011 allowTaskSnapshot(),
Louis Changeadb22f2019-06-19 12:09:23 +08003012 mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
Jorim Jaggi42befc62017-06-13 11:54:04 -07003013 fromRecents);
Wale Ogunwale3b232392016-05-13 15:37:13 -07003014 if (shown) {
3015 mStartingWindowState = STARTING_WINDOW_SHOWN;
3016 }
3017 }
3018
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08003019 void removeOrphanedStartingWindow(boolean behindFullscreenActivity) {
Jorim Jaggicb956052017-05-09 16:27:24 +02003020 if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08003021 if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
3022 mStartingWindowState = STARTING_WINDOW_REMOVED;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003023 mAppWindowToken.removeStartingWindow();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08003024 }
3025 }
3026
Andrii Kulian5406e7a2016-10-21 11:55:23 -07003027 void setRequestedOrientation(int requestedOrientation) {
Garfield Tan90b04282018-12-11 14:04:42 -08003028 setOrientation(requestedOrientation, mayFreezeScreenLocked(app));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003029 mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
Yorke Leebd54c2a2016-10-25 13:49:23 -07003030 task.taskId, requestedOrientation);
Andrii Kulian5406e7a2016-10-21 11:55:23 -07003031 }
3032
Garfield Tan90b04282018-12-11 14:04:42 -08003033 private void setOrientation(int requestedOrientation, boolean freezeScreenIfNeeded) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003034 if (mAppWindowToken == null) {
3035 Slog.w(TAG_WM,
3036 "Attempted to set orientation of non-existing app token: " + appToken);
Garfield Tan90b04282018-12-11 14:04:42 -08003037 return;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003038 }
3039
Evan Rosky730f6e82018-12-03 17:40:11 -08003040 final IBinder binder =
3041 (freezeScreenIfNeeded && appToken != null) ? appToken.asBinder() : null;
Garfield Tan90b04282018-12-11 14:04:42 -08003042 mAppWindowToken.setOrientation(requestedOrientation, binder, this);
Garfield Tan36a69ad2019-01-16 17:08:23 -08003043
3044 // Push the new configuration to the requested app in case where it's not pushed, e.g. when
3045 // the request is handled at task level with letterbox.
3046 if (!getMergedOverrideConfiguration().equals(
3047 mLastReportedConfiguration.getMergedConfiguration())) {
3048 ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
3049 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003050 }
3051
3052 int getOrientation() {
3053 if (mAppWindowToken == null) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08003054 return info.screenOrientation;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003055 }
3056
3057 return mAppWindowToken.getOrientationIgnoreVisibility();
3058 }
3059
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01003060 void setDisablePreviewScreenshots(boolean disable) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003061 if (mAppWindowToken == null) {
3062 Slog.w(TAG_WM, "Attempted to set disable screenshots of non-existing app"
3063 + " token: " + appToken);
3064 return;
3065 }
3066 mAppWindowToken.setDisablePreviewScreenshots(disable);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01003067 }
3068
Bryce Leea163b762017-01-24 11:05:01 -08003069 /**
3070 * Set the last reported global configuration to the client. Should be called whenever a new
3071 * global configuration is sent to the client for this activity.
3072 */
3073 void setLastReportedGlobalConfiguration(@NonNull Configuration config) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003074 mLastReportedConfiguration.setGlobalConfiguration(config);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003075 }
3076
Bryce Leea163b762017-01-24 11:05:01 -08003077 /**
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003078 * Set the last reported configuration to the client. Should be called whenever
Bryce Leea163b762017-01-24 11:05:01 -08003079 * a new merged configuration is sent to the client for this activity.
3080 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003081 void setLastReportedConfiguration(@NonNull MergedConfiguration config) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07003082 setLastReportedConfiguration(config.getGlobalConfiguration(),
3083 config.getOverrideConfiguration());
Bryce Leea163b762017-01-24 11:05:01 -08003084 }
3085
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07003086 private void setLastReportedConfiguration(Configuration global, Configuration override) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07003087 mLastReportedConfiguration.setConfiguration(global, override);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003088 }
3089
Riddle Hsu0a343c32018-12-21 00:40:48 +08003090 /**
3091 * Get the configuration orientation by the requested screen orientation
3092 * ({@link ActivityInfo.ScreenOrientation}) of this activity.
3093 *
Tiger Huang3d2b8982019-01-29 22:56:48 +08003094 * @return orientation in ({@link Configuration#ORIENTATION_LANDSCAPE},
3095 * {@link Configuration#ORIENTATION_PORTRAIT},
3096 * {@link Configuration#ORIENTATION_UNDEFINED}).
Riddle Hsu0a343c32018-12-21 00:40:48 +08003097 */
3098 int getRequestedConfigurationOrientation() {
3099 final int screenOrientation = getOrientation();
3100 if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
3101 // NOSENSOR means the display's "natural" orientation, so return that.
3102 final ActivityDisplay display = getDisplay();
3103 if (display != null && display.mDisplayContent != null) {
3104 return display.mDisplayContent.getNaturalOrientation();
3105 }
3106 } else if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
3107 // LOCKED means the activity's orientation remains unchanged, so return existing value.
3108 return getConfiguration().orientation;
3109 } else if (isFixedOrientationLandscape(screenOrientation)) {
3110 return ORIENTATION_LANDSCAPE;
3111 } else if (isFixedOrientationPortrait(screenOrientation)) {
3112 return ORIENTATION_PORTRAIT;
3113 }
3114 return ORIENTATION_UNDEFINED;
3115 }
3116
3117 /**
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003118 * @return {@code true} if this activity is in size compatibility mode that uses the different
3119 * density or bounds from its parent.
3120 */
3121 boolean inSizeCompatMode() {
3122 if (!shouldUseSizeCompatMode()) {
3123 return false;
3124 }
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003125 final Configuration resolvedConfig = getResolvedOverrideConfiguration();
Riddle Hsu04164182019-03-07 18:03:27 +08003126 final Rect resolvedAppBounds = resolvedConfig.windowConfiguration.getAppBounds();
3127 if (resolvedAppBounds == null) {
3128 // The override configuration has not been resolved yet.
3129 return false;
3130 }
3131
3132 final Configuration parentConfig = getParent().getConfiguration();
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003133 // Although colorMode, screenLayout, smallestScreenWidthDp are also fixed, generally these
3134 // fields should be changed with density and bounds, so here only compares the most
3135 // significant field.
3136 if (parentConfig.densityDpi != resolvedConfig.densityDpi) {
3137 return true;
3138 }
Riddle Hsu04164182019-03-07 18:03:27 +08003139
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003140 final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds();
Riddle Hsuaec55442019-03-12 17:25:35 +08003141 final int appWidth = resolvedAppBounds.width();
3142 final int appHeight = resolvedAppBounds.height();
3143 final int parentAppWidth = parentAppBounds.width();
3144 final int parentAppHeight = parentAppBounds.height();
Riddle Hsu9ad1785102019-03-26 00:26:54 +08003145 if (parentAppWidth == appWidth && parentAppHeight == appHeight) {
3146 // Matched the parent bounds.
3147 return false;
3148 }
3149 if (parentAppWidth > appWidth && parentAppHeight > appHeight) {
3150 // Both sides are smaller than the parent.
3151 return true;
3152 }
Riddle Hsuaec55442019-03-12 17:25:35 +08003153 if (parentAppWidth < appWidth || parentAppHeight < appHeight) {
Riddle Hsu04164182019-03-07 18:03:27 +08003154 // One side is larger than the parent.
3155 return true;
3156 }
3157
Riddle Hsu9ad1785102019-03-26 00:26:54 +08003158 // The rest of the condition is that only one side is smaller than the parent, but it still
3159 // needs to exclude the cases where the size is limited by the fixed aspect ratio.
3160 if (info.maxAspectRatio > 0) {
Riddle Hsuaec55442019-03-12 17:25:35 +08003161 final float aspectRatio = (0.5f + Math.max(appWidth, appHeight))
3162 / Math.min(appWidth, appHeight);
Riddle Hsu9ad1785102019-03-26 00:26:54 +08003163 if (aspectRatio >= info.maxAspectRatio) {
3164 // The current size has reached the max aspect ratio.
3165 return false;
Riddle Hsuaec55442019-03-12 17:25:35 +08003166 }
3167 }
Riddle Hsu9ad1785102019-03-26 00:26:54 +08003168 if (info.minAspectRatio > 0) {
3169 // The activity should have at least the min aspect ratio, so this checks if the parent
3170 // still has available space to provide larger aspect ratio.
3171 final float parentAspectRatio = (0.5f + Math.max(parentAppWidth, parentAppHeight))
3172 / Math.min(parentAppWidth, parentAppHeight);
3173 if (parentAspectRatio <= info.minAspectRatio) {
3174 // The long side has reached the parent.
3175 return false;
3176 }
3177 }
3178 return true;
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003179 }
3180
3181 /**
Riddle Hsu0a343c32018-12-21 00:40:48 +08003182 * Indicates the activity will keep the bounds and screen configuration when it was first
3183 * launched, no matter how its parent changes.
3184 *
3185 * @return {@code true} if this activity is declared as non-resizable and fixed orientation or
3186 * aspect ratio.
3187 */
Riddle Hsu74826262019-04-17 14:57:42 +08003188 boolean shouldUseSizeCompatMode() {
Riddle Hsu0a343c32018-12-21 00:40:48 +08003189 return !isResizeable() && (info.isFixedOrientation() || info.hasFixedAspectRatio())
3190 // The configuration of non-standard type should be enforced by system.
3191 && isActivityTypeStandard()
3192 && !mAtmService.mForceResizableActivities;
3193 }
3194
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003195 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003196 private void updateOverrideConfiguration() {
Riddle Hsu74826262019-04-17 14:57:42 +08003197 final Configuration overrideConfig = mTmpConfig;
3198 if (shouldUseSizeCompatMode()) {
3199 if (mCompatDisplayInsets != null) {
3200 // The override configuration is set only once in size compatibility mode.
Riddle Hsu0a343c32018-12-21 00:40:48 +08003201 return;
3202 }
Riddle Hsu74826262019-04-17 14:57:42 +08003203 final Configuration parentConfig = getParent().getConfiguration();
3204 if (!hasProcess() && !isConfigurationCompatible(parentConfig)) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08003205 // Don't compute when launching in fullscreen and the fixed orientation is not the
3206 // current orientation. It is more accurately to compute the override bounds from
3207 // the updated configuration after the fixed orientation is applied.
3208 return;
3209 }
Riddle Hsu0a343c32018-12-21 00:40:48 +08003210
Riddle Hsu74826262019-04-17 14:57:42 +08003211 // Ensure the screen related fields are set. It is used to prevent activity relaunch
3212 // when moving between displays. For screenWidthDp and screenWidthDp, because they
3213 // are relative to bounds and density, they will be calculated in
3214 // {@link TaskRecord#computeConfigResourceOverrides} and the result will also be
3215 // relatively fixed.
3216 overrideConfig.unset();
3217 overrideConfig.colorMode = parentConfig.colorMode;
3218 overrideConfig.densityDpi = parentConfig.densityDpi;
3219 overrideConfig.screenLayout = parentConfig.screenLayout
3220 & (Configuration.SCREENLAYOUT_LONG_MASK
3221 | Configuration.SCREENLAYOUT_SIZE_MASK);
3222 // The smallest screen width is the short side of screen bounds. Because the bounds
3223 // and density won't be changed, smallestScreenWidthDp is also fixed.
3224 overrideConfig.smallestScreenWidthDp = parentConfig.smallestScreenWidthDp;
Bryce Leef3c6a472017-11-14 14:53:06 -08003225
Riddle Hsu74826262019-04-17 14:57:42 +08003226 // The role of CompatDisplayInsets is like the override bounds.
3227 final ActivityDisplay display = getDisplay();
3228 if (display != null && display.mDisplayContent != null) {
3229 mCompatDisplayInsets = new CompatDisplayInsets(display.mDisplayContent);
Riddle Hsu0a343c32018-12-21 00:40:48 +08003230 }
Riddle Hsu74826262019-04-17 14:57:42 +08003231 } else {
3232 // We must base this on the parent configuration, because we set our override
3233 // configuration's appBounds based on the result of this method. If we used our own
3234 // configuration, it would be influenced by past invocations.
3235 computeBounds(mTmpBounds, getParent().getWindowConfiguration().getAppBounds());
3236
3237 if (mTmpBounds.equals(getRequestedOverrideBounds())) {
3238 // The bounds is not changed or the activity is resizable (both the 2 bounds are
3239 // empty).
3240 return;
3241 }
3242
3243 overrideConfig.unset();
3244 overrideConfig.windowConfiguration.setBounds(mTmpBounds);
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003245 }
Riddle Hsu74826262019-04-17 14:57:42 +08003246
Riddle Hsu0a343c32018-12-21 00:40:48 +08003247 onRequestedOverrideConfigurationChanged(overrideConfig);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003248 }
3249
Garfield Tan0443b372019-01-04 15:00:13 -08003250 @Override
3251 void resolveOverrideConfiguration(Configuration newParentConfiguration) {
Riddle Hsu74826262019-04-17 14:57:42 +08003252 if (mCompatDisplayInsets != null) {
Riddle Hsu04164182019-03-07 18:03:27 +08003253 resolveSizeCompatModeConfiguration(newParentConfiguration);
3254 } else {
3255 super.resolveOverrideConfiguration(newParentConfiguration);
Riddle Hsu74826262019-04-17 14:57:42 +08003256 // If the activity has override bounds, the relative configuration (e.g. screen size,
3257 // layout) needs to be resolved according to the bounds.
3258 if (!matchParentBounds()) {
Riddle Hsu04164182019-03-07 18:03:27 +08003259 task.computeConfigResourceOverrides(getResolvedOverrideConfiguration(),
Riddle Hsu61987bc2019-04-03 13:08:47 +08003260 newParentConfiguration);
Riddle Hsu04164182019-03-07 18:03:27 +08003261 }
3262 }
Garfield Tan0443b372019-01-04 15:00:13 -08003263
3264 // Assign configuration sequence number into hierarchy because there is a different way than
3265 // ensureActivityConfiguration() in this class that uses configuration in WindowState during
3266 // layout traversals.
3267 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
3268 getResolvedOverrideConfiguration().seq = mConfigurationSeq;
Riddle Hsu04164182019-03-07 18:03:27 +08003269 }
Riddle Hsu0a343c32018-12-21 00:40:48 +08003270
Riddle Hsu74826262019-04-17 14:57:42 +08003271 /**
3272 * Resolves consistent screen configuration for orientation and rotation changes without
3273 * inheriting the parent bounds.
3274 */
Riddle Hsu04164182019-03-07 18:03:27 +08003275 private void resolveSizeCompatModeConfiguration(Configuration newParentConfiguration) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08003276 final Configuration resolvedConfig = getResolvedOverrideConfiguration();
Riddle Hsu04164182019-03-07 18:03:27 +08003277 final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
Riddle Hsu0a343c32018-12-21 00:40:48 +08003278
Riddle Hsu74826262019-04-17 14:57:42 +08003279 final int parentRotation = newParentConfiguration.windowConfiguration.getRotation();
3280 final int parentOrientation = newParentConfiguration.orientation;
Riddle Hsu0a343c32018-12-21 00:40:48 +08003281 int orientation = getConfiguration().orientation;
Riddle Hsu74826262019-04-17 14:57:42 +08003282 if (orientation != parentOrientation && isConfigurationCompatible(newParentConfiguration)) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08003283 // The activity is compatible to apply the orientation change or it requests different
3284 // fixed orientation.
Riddle Hsu74826262019-04-17 14:57:42 +08003285 orientation = parentOrientation;
Riddle Hsu0a343c32018-12-21 00:40:48 +08003286 } else {
Riddle Hsu74826262019-04-17 14:57:42 +08003287 if (!resolvedBounds.isEmpty()
3288 // The decor insets may be different according to the rotation.
3289 && getWindowConfiguration().getRotation() == parentRotation) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08003290 // Keep the computed resolved override configuration.
3291 return;
3292 }
3293 final int requestedOrientation = getRequestedConfigurationOrientation();
3294 if (requestedOrientation != ORIENTATION_UNDEFINED) {
3295 orientation = requestedOrientation;
3296 }
3297 }
3298
Riddle Hsu04164182019-03-07 18:03:27 +08003299 super.resolveOverrideConfiguration(newParentConfiguration);
3300
Riddle Hsu74826262019-04-17 14:57:42 +08003301 boolean useParentOverrideBounds = false;
3302 final Rect displayBounds = mTmpBounds;
3303 final Rect containingAppBounds = new Rect();
3304 if (task.handlesOrientationChangeFromDescendant()) {
3305 // Prefer to use the orientation which is determined by this activity to calculate
3306 // bounds because the parent will follow the requested orientation.
3307 mCompatDisplayInsets.getDisplayBoundsByOrientation(displayBounds, orientation);
3308 } else {
3309 // The parent hierarchy doesn't handle the orientation changes. This is usually because
3310 // the aspect ratio of display is close to square or the display rotation is fixed.
3311 // In this case, task will compute override bounds to fit the app with respect to the
3312 // requested orientation. So here we perform similar calculation to have consistent
3313 // bounds even the original parent hierarchies were changed.
3314 final int baseOrientation = task.getParent().getConfiguration().orientation;
3315 mCompatDisplayInsets.getDisplayBoundsByOrientation(displayBounds, baseOrientation);
3316 task.computeFullscreenBounds(containingAppBounds, this, displayBounds, baseOrientation);
3317 useParentOverrideBounds = !containingAppBounds.isEmpty();
Riddle Hsu0a343c32018-12-21 00:40:48 +08003318 }
3319
Riddle Hsu74826262019-04-17 14:57:42 +08003320 // The offsets will be non-zero if the parent has override bounds.
3321 final int containingOffsetX = containingAppBounds.left;
3322 final int containingOffsetY = containingAppBounds.top;
3323 if (!useParentOverrideBounds) {
3324 containingAppBounds.set(displayBounds);
Riddle Hsu04164182019-03-07 18:03:27 +08003325 }
Riddle Hsu74826262019-04-17 14:57:42 +08003326 if (parentRotation != ROTATION_UNDEFINED) {
3327 // Ensure the container bounds won't overlap with the decors.
3328 TaskRecord.intersectWithInsetsIfFits(containingAppBounds, displayBounds,
3329 mCompatDisplayInsets.mNonDecorInsets[parentRotation]);
3330 }
3331
3332 computeBounds(resolvedBounds, containingAppBounds);
3333 if (resolvedBounds.isEmpty()) {
3334 // Use the entire available bounds because there is no restriction.
3335 resolvedBounds.set(useParentOverrideBounds ? containingAppBounds : displayBounds);
3336 } else {
3337 // The offsets are included in width and height by {@link #computeBounds}, so we have to
3338 // restore it.
3339 resolvedBounds.left += containingOffsetX;
3340 resolvedBounds.top += containingOffsetY;
3341 }
3342 task.computeConfigResourceOverrides(resolvedConfig, newParentConfiguration,
3343 mCompatDisplayInsets);
3344
Riddle Hsu04164182019-03-07 18:03:27 +08003345 // The horizontal inset included in width is not needed if the activity cannot fill the
3346 // parent, because the offset will be applied by {@link AppWindowToken#mSizeCompatBounds}.
Riddle Hsu74826262019-04-17 14:57:42 +08003347 final Rect resolvedAppBounds = resolvedConfig.windowConfiguration.getAppBounds();
3348 final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds();
Riddle Hsu04164182019-03-07 18:03:27 +08003349 if (resolvedBounds.width() < parentAppBounds.width()) {
3350 resolvedBounds.right -= resolvedAppBounds.left;
3351 }
Riddle Hsu04164182019-03-07 18:03:27 +08003352 // Use parent orientation if it cannot be decided by bounds, so the activity can fit inside
3353 // the parent bounds appropriately.
3354 if (resolvedConfig.screenWidthDp == resolvedConfig.screenHeightDp) {
3355 resolvedConfig.orientation = newParentConfiguration.orientation;
Riddle Hsu0a343c32018-12-21 00:40:48 +08003356 }
Garfield Tan0443b372019-01-04 15:00:13 -08003357 }
3358
3359 @Override
3360 public void onConfigurationChanged(Configuration newParentConfig) {
3361 super.onConfigurationChanged(newParentConfig);
3362
3363 // Configuration's equality doesn't consider seq so if only seq number changes in resolved
3364 // override configuration. Therefore ConfigurationContainer doesn't change merged override
3365 // configuration, but it's used to push configuration changes so explicitly update that.
3366 if (getMergedOverrideConfiguration().seq != getResolvedOverrideConfiguration().seq) {
3367 onMergedOverrideConfigurationChanged();
3368 }
3369
3370 // TODO(b/80414790): Remove code below after unification.
3371 // Same as above it doesn't notify configuration listeners, and consequently AppWindowToken
3372 // can't get updated seq number. However WindowState's merged override configuration needs
3373 // to have this seq number because that's also used for activity config pushes during layout
3374 // traversal. Therefore explicitly update them here.
3375 if (mAppWindowToken == null) {
3376 return;
3377 }
3378 final Configuration appWindowTokenRequestedOverrideConfig =
3379 mAppWindowToken.getRequestedOverrideConfiguration();
3380 if (appWindowTokenRequestedOverrideConfig.seq != getResolvedOverrideConfiguration().seq) {
3381 appWindowTokenRequestedOverrideConfig.seq =
3382 getResolvedOverrideConfiguration().seq;
3383 mAppWindowToken.onMergedOverrideConfigurationChanged();
3384 }
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003385
3386 final ActivityDisplay display = getDisplay();
Riddle Hsuaec55442019-03-12 17:25:35 +08003387 if (display == null) {
3388 return;
3389 }
3390 if (visible) {
3391 // It may toggle the UI for user to restart the size compatibility mode activity.
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003392 display.handleActivitySizeCompatModeIfNeeded(this);
Riddle Hsuaec55442019-03-12 17:25:35 +08003393 } else if (shouldUseSizeCompatMode()) {
3394 // The override changes can only be obtained from display, because we don't have the
3395 // difference of full configuration in each hierarchy.
3396 final int displayChanges = display.getLastOverrideConfigurationChanges();
3397 final int orientationChanges = CONFIG_WINDOW_CONFIGURATION
3398 | CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION;
3399 final boolean hasNonOrienSizeChanged = hasResizeChange(displayChanges)
3400 // Filter out the case of simple orientation change.
3401 && (displayChanges & orientationChanges) != orientationChanges;
3402 // For background activity that uses size compatibility mode, if the size or density of
3403 // the display is changed, then reset the override configuration and kill the activity's
3404 // process if its process state is not important to user.
3405 if (hasNonOrienSizeChanged || (displayChanges & ActivityInfo.CONFIG_DENSITY) != 0) {
3406 restartProcessIfVisible();
3407 }
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003408 }
Garfield Tan0443b372019-01-04 15:00:13 -08003409 }
3410
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07003411 /** Returns true if the configuration is compatible with this activity. */
Wale Ogunwale42f07d92017-05-01 21:32:58 -07003412 boolean isConfigurationCompatible(Configuration config) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08003413 final int orientation = getOrientation();
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07003414 if (isFixedOrientationPortrait(orientation)
3415 && config.orientation != ORIENTATION_PORTRAIT) {
3416 return false;
3417 }
3418 if (isFixedOrientationLandscape(orientation)
3419 && config.orientation != ORIENTATION_LANDSCAPE) {
3420 return false;
3421 }
3422 return true;
3423 }
3424
Bryce Lee7566d762017-03-30 09:34:15 -07003425 /**
3426 * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}.
3427 */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003428 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
Riddle Hsu74826262019-04-17 14:57:42 +08003429 private void computeBounds(Rect outBounds, Rect containingAppBounds) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003430 outBounds.setEmpty();
3431 final float maxAspectRatio = info.maxAspectRatio;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003432 final ActivityStack stack = getActivityStack();
Adrian Roos917791e2018-11-28 16:30:44 +01003433 final float minAspectRatio = info.minAspectRatio;
3434
3435 if (task == null || stack == null || task.inMultiWindowMode()
3436 || (maxAspectRatio == 0 && minAspectRatio == 0)
Bryce Leee5ab4502017-07-11 08:58:05 -07003437 || isInVrUiMode(getConfiguration())) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003438 // We don't set override configuration if that activity task isn't fullscreen. I.e. the
3439 // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
Bryce Leee5ab4502017-07-11 08:58:05 -07003440 // the activity. This is indicated by an empty {@link outBounds}. We also don't set it
3441 // if we are in VR mode.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003442 return;
3443 }
3444
Riddle Hsu74826262019-04-17 14:57:42 +08003445 final int containingAppWidth = containingAppBounds.width();
3446 final int containingAppHeight = containingAppBounds.height();
Adrian Roos917791e2018-11-28 16:30:44 +01003447 final float containingRatio = Math.max(containingAppWidth, containingAppHeight)
3448 / (float) Math.min(containingAppWidth, containingAppHeight);
Bryce Lee7566d762017-03-30 09:34:15 -07003449
Adrian Roos917791e2018-11-28 16:30:44 +01003450 int activityWidth = containingAppWidth;
3451 int activityHeight = containingAppHeight;
3452
3453 if (containingRatio > maxAspectRatio && maxAspectRatio != 0) {
3454 if (containingAppWidth < containingAppHeight) {
3455 // Width is the shorter side, so we use that to figure-out what the max. height
3456 // should be given the aspect ratio.
3457 activityHeight = (int) ((activityWidth * maxAspectRatio) + 0.5f);
3458 } else {
3459 // Height is the shorter side, so we use that to figure-out what the max. width
3460 // should be given the aspect ratio.
3461 activityWidth = (int) ((activityHeight * maxAspectRatio) + 0.5f);
3462 }
Tiger Huang3d2b8982019-01-29 22:56:48 +08003463 } else if (containingRatio < minAspectRatio) {
3464 boolean adjustWidth;
3465 switch (getRequestedConfigurationOrientation()) {
3466 case ORIENTATION_LANDSCAPE:
3467 // Width should be the longer side for this landscape app, so we use the width
3468 // to figure-out what the max. height should be given the aspect ratio.
3469 adjustWidth = false;
3470 break;
3471 case ORIENTATION_PORTRAIT:
3472 // Height should be the longer side for this portrait app, so we use the height
3473 // to figure-out what the max. width should be given the aspect ratio.
3474 adjustWidth = true;
3475 break;
3476 default:
3477 // This app doesn't have a preferred orientation, so we keep the length of the
3478 // longer side, and use it to figure-out the length of the shorter side.
3479 if (containingAppWidth < containingAppHeight) {
3480 // Width is the shorter side, so we use the height to figure-out what the
3481 // max. width should be given the aspect ratio.
3482 adjustWidth = true;
3483 } else {
3484 // Height is the shorter side, so we use the width to figure-out what the
3485 // max. height should be given the aspect ratio.
3486 adjustWidth = false;
3487 }
3488 break;
3489 }
3490 if (adjustWidth) {
Adrian Roos917791e2018-11-28 16:30:44 +01003491 activityWidth = (int) ((activityHeight / minAspectRatio) + 0.5f);
3492 } else {
Adrian Roos917791e2018-11-28 16:30:44 +01003493 activityHeight = (int) ((activityWidth / minAspectRatio) + 0.5f);
3494 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003495 }
3496
Adrian Roos917791e2018-11-28 16:30:44 +01003497 if (containingAppWidth <= activityWidth && containingAppHeight <= activityHeight) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003498 // The display matches or is less than the activity aspect ratio, so nothing else to do.
Bryce Lee7566d762017-03-30 09:34:15 -07003499 // Return the existing bounds. If this method is running for the first time,
Evan Roskydfe3da72018-10-26 17:21:06 -07003500 // {@link #getRequestedOverrideBounds()} will be empty (representing no override). If
3501 // the method has run before, then effect of {@link #getRequestedOverrideBounds()} will
3502 // already have been applied to the value returned from {@link getConfiguration}. Refer
Riddle Hsu04164182019-03-07 18:03:27 +08003503 // to {@link TaskRecord#computeConfigResourceOverrides()}.
Evan Roskydfe3da72018-10-26 17:21:06 -07003504 outBounds.set(getRequestedOverrideBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003505 return;
3506 }
3507
3508 // Compute configuration based on max supported width and height.
Adrian Roos24be34d2018-05-28 18:55:38 +02003509 // Also account for the left / top insets (e.g. from display cutouts), which will be clipped
Riddle Hsu04164182019-03-07 18:03:27 +08003510 // away later in {@link TaskRecord#computeConfigResourceOverrides()}. Otherwise, the app
Adrian Roos24be34d2018-05-28 18:55:38 +02003511 // bounds would end up too small.
Riddle Hsu74826262019-04-17 14:57:42 +08003512 outBounds.set(0, 0, activityWidth + containingAppBounds.left,
3513 activityHeight + containingAppBounds.top);
Andrii Kulian3a1619d2017-07-07 14:38:09 -07003514 }
3515
Riddle Hsu16567132018-08-16 21:37:47 +08003516 /**
3517 * @return {@code true} if this activity was reparented to another display but
3518 * {@link #ensureActivityConfiguration} is not called.
3519 */
3520 boolean shouldUpdateConfigForDisplayChanged() {
3521 return mLastReportedDisplayId != getDisplayId();
3522 }
3523
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003524 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
3525 return ensureActivityConfiguration(globalChanges, preserveWindow,
Riddle Hsu609a8e22019-06-27 16:46:29 -06003526 false /* ignoreVisibility */);
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003527 }
3528
Andrii Kulian21713ac2016-10-12 22:05:05 -07003529 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003530 * Make sure the given activity matches the current configuration. Ensures the HistoryRecord
3531 * is updated with the correct configuration and all other bookkeeping is handled.
3532 *
3533 * @param globalChanges The changes to the global configuration.
3534 * @param preserveWindow If the activity window should be preserved on screen if the activity
3535 * is relaunched.
Riddle Hsu609a8e22019-06-27 16:46:29 -06003536 * @param ignoreVisibility If we should try to relaunch the activity even if it is invisible
3537 * (stopped state). This is useful for the case where we know the
3538 * activity will be visible soon and we want to ensure its configuration
3539 * before we make it visible.
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003540 * @return False if the activity was relaunched and true if it wasn't relaunched because we
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003541 * can't or the app handles the specific configuration that is changing.
Andrii Kulian21713ac2016-10-12 22:05:05 -07003542 */
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003543 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
Riddle Hsu609a8e22019-06-27 16:46:29 -06003544 boolean ignoreVisibility) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003545 final ActivityStack stack = getActivityStack();
Andrii Kulian21713ac2016-10-12 22:05:05 -07003546 if (stack.mConfigWillChange) {
3547 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3548 "Skipping config check (will change): " + this);
3549 return true;
3550 }
3551
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003552 // We don't worry about activities that are finishing.
3553 if (finishing) {
3554 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3555 "Configuration doesn't matter in finishing " + this);
3556 stopFreezingScreenLocked(false);
3557 return true;
3558 }
3559
Riddle Hsu609a8e22019-06-27 16:46:29 -06003560 if (!ignoreVisibility && (mState == STOPPING || mState == STOPPED || !shouldBeVisible())) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07003561 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Riddle Hsu609a8e22019-06-27 16:46:29 -06003562 "Skipping config check invisible: " + this);
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07003563 return true;
3564 }
3565
Andrii Kulian21713ac2016-10-12 22:05:05 -07003566 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3567 "Ensuring correct configuration: " + this);
3568
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003569 final int newDisplayId = getDisplayId();
3570 final boolean displayChanged = mLastReportedDisplayId != newDisplayId;
3571 if (displayChanged) {
3572 mLastReportedDisplayId = newDisplayId;
3573 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003574 // TODO(b/36505427): Is there a better place to do this?
3575 updateOverrideConfiguration();
3576
Winson Chungbdc646f2017-02-13 12:12:22 -08003577 // Short circuit: if the two full configurations are equal (the common case), then there is
3578 // nothing to do. We test the full configuration instead of the global and merged override
3579 // configurations because there are cases (like moving a task to the pinned stack) where
3580 // the combine configurations are equal, but would otherwise differ in the override config
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003581 mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
3582 if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003583 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003584 "Configuration & display unchanged in " + this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003585 return true;
3586 }
3587
3588 // Okay we now are going to make this activity have the new config.
3589 // But then we need to figure out how it needs to deal with that.
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003590
3591 // Find changes between last reported merged configuration and the current one. This is used
3592 // to decide whether to relaunch an activity or just report a configuration change.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003593 final int changes = getConfigurationChanges(mTmpConfig);
Ruben Brunkf64af332017-03-22 22:03:25 -07003594
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003595 // Update last reported values.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003596 final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
Bryce Lee8104e7a2017-08-17 09:16:03 -07003597
Andrii Kulianbeadacc2019-05-20 12:18:01 +00003598 setLastReportedConfiguration(mAtmService.getGlobalConfiguration(), newMergedOverrideConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003599
Bryce Lee7ace3952018-02-16 14:34:32 -08003600 if (mState == INITIALIZING) {
Andrii Kulianb372da62018-01-18 10:46:24 -08003601 // No need to relaunch or schedule new config for activity that hasn't been launched
3602 // yet. We do, however, return after applying the config to activity record, so that
3603 // it will use it for launch transaction.
3604 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3605 "Skipping config check for initializing activity: " + this);
3606 return true;
3607 }
3608
Andrii Kulian21713ac2016-10-12 22:05:05 -07003609 if (changes == 0 && !forceNewConfig) {
3610 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3611 "Configuration no differences in " + this);
3612 // There are no significant differences, so we won't relaunch but should still deliver
3613 // the new configuration to the client process.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003614 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003615 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003616 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003617 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003618 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07003619 return true;
3620 }
3621
3622 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003623 "Configuration changes for " + this + ", allChanges="
Andrii Kulian21713ac2016-10-12 22:05:05 -07003624 + Configuration.configurationDiffToString(changes));
3625
3626 // If the activity isn't currently running, just leave the new configuration and it will
3627 // pick that up next time it starts.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003628 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003629 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3630 "Configuration doesn't matter not running " + this);
3631 stopFreezingScreenLocked(false);
3632 forceNewConfig = false;
3633 return true;
3634 }
3635
3636 // Figure out how to handle the changes between the configurations.
3637 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3638 "Checking to restart " + info.name + ": changed=0x"
3639 + Integer.toHexString(changes) + ", handles=0x"
3640 + Integer.toHexString(info.getRealConfigChanged())
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003641 + ", mLastReportedConfiguration=" + mLastReportedConfiguration);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003642
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003643 if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003644 // Aha, the activity isn't handling the change, so DIE DIE DIE.
3645 configChangeFlags |= changes;
3646 startFreezingScreenLocked(app, globalChanges);
3647 forceNewConfig = false;
3648 preserveWindow &= isResizeOnlyChange(changes);
Garfield Tan2746ab52018-07-25 12:33:01 -07003649 final boolean hasResizeChange = hasResizeChange(changes & ~info.getRealConfigChanged());
3650 if (hasResizeChange) {
3651 final boolean isDragResizing =
Yunfan Chen0e7aff92018-12-05 16:35:32 -08003652 getTaskRecord().getTask().isDragResizing();
Garfield Tan2746ab52018-07-25 12:33:01 -07003653 mRelaunchReason = isDragResizing ? RELAUNCH_REASON_FREE_RESIZE
3654 : RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
3655 } else {
3656 mRelaunchReason = RELAUNCH_REASON_NONE;
3657 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003658 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003659 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3660 "Config is destroying non-running " + this);
3661 stack.destroyActivityLocked(this, true, "config");
Bryce Lee7ace3952018-02-16 14:34:32 -08003662 } else if (mState == PAUSING) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003663 // A little annoying: we are waiting for this activity to finish pausing. Let's not
3664 // do anything now, but just flag that it needs to be restarted when done pausing.
3665 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3666 "Config is skipping already pausing " + this);
3667 deferRelaunchUntilPaused = true;
3668 preserveWindowOnDeferredRelaunch = preserveWindow;
3669 return true;
Bryce Lee7ace3952018-02-16 14:34:32 -08003670 } else if (mState == RESUMED) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003671 // Try to optimize this case: the configuration is changing and we need to restart
3672 // the top, resumed activity. Instead of doing the normal handshaking, just say
3673 // "restart!".
3674 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3675 "Config is relaunching resumed " + this);
3676
3677 if (DEBUG_STATES && !visible) {
3678 Slog.v(TAG_STATES, "Config is relaunching resumed invisible activity " + this
3679 + " called by " + Debug.getCallers(4));
3680 }
3681
3682 relaunchActivityLocked(true /* andResume */, preserveWindow);
3683 } else {
3684 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3685 "Config is relaunching non-resumed " + this);
3686 relaunchActivityLocked(false /* andResume */, preserveWindow);
3687 }
3688
3689 // All done... tell the caller we weren't able to keep this activity around.
3690 return false;
3691 }
3692
3693 // Default case: the activity can handle this new configuration, so hand it over.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003694 // NOTE: We only forward the override configuration as the system level configuration
Andrii Kulian21713ac2016-10-12 22:05:05 -07003695 // changes is always sent to all processes when they happen so it can just use whatever
3696 // system level configuration it last got.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003697 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003698 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003699 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003700 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003701 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07003702 stopFreezingScreenLocked(false);
3703
3704 return true;
3705 }
3706
Zak Cohen90e7116742017-01-29 12:59:23 -08003707 /**
3708 * When assessing a configuration change, decide if the changes flags and the new configurations
3709 * should cause the Activity to relaunch.
Ruben Brunkf64af332017-03-22 22:03:25 -07003710 *
3711 * @param changes the changes due to the given configuration.
3712 * @param changesConfig the configuration that was used to calculate the given changes via a
3713 * call to getConfigurationChanges.
Zak Cohen90e7116742017-01-29 12:59:23 -08003714 */
Ruben Brunkf64af332017-03-22 22:03:25 -07003715 private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
Zak Cohen90e7116742017-01-29 12:59:23 -08003716 int configChanged = info.getRealConfigChanged();
Ruben Brunkf64af332017-03-22 22:03:25 -07003717 boolean onlyVrUiModeChanged = onlyVrUiModeChanged(changes, changesConfig);
Zak Cohen90e7116742017-01-29 12:59:23 -08003718
3719 // Override for apps targeting pre-O sdks
3720 // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
3721 // to the config change.
3722 // For O and later, apps will be required to add configChanges="uimode" to their manifest.
Andrii Kulianeceebbf2019-06-26 17:36:51 -07003723 if (info.applicationInfo.targetSdkVersion < O
Zak Cohen90e7116742017-01-29 12:59:23 -08003724 && requestedVrComponent != null
Ruben Brunkf64af332017-03-22 22:03:25 -07003725 && onlyVrUiModeChanged) {
Zak Cohen90e7116742017-01-29 12:59:23 -08003726 configChanged |= CONFIG_UI_MODE;
3727 }
3728
3729 return (changes&(~configChanged)) != 0;
3730 }
3731
Ruben Brunkf64af332017-03-22 22:03:25 -07003732 /**
3733 * Returns true if the configuration change is solely due to the UI mode switching into or out
3734 * of UI_MODE_TYPE_VR_HEADSET.
3735 */
3736 private boolean onlyVrUiModeChanged(int changes, Configuration lastReportedConfig) {
3737 final Configuration currentConfig = getConfiguration();
Ruben Brunkf53497c2017-03-27 20:26:17 -07003738 return changes == CONFIG_UI_MODE && (isInVrUiMode(currentConfig)
Ruben Brunkf64af332017-03-22 22:03:25 -07003739 != isInVrUiMode(lastReportedConfig));
3740 }
3741
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003742 private int getConfigurationChanges(Configuration lastReportedConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003743 // Determine what has changed. May be nothing, if this is a config that has come back from
3744 // the app after going idle. In that case we just want to leave the official config object
3745 // now in the activity and do nothing else.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003746 final Configuration currentConfig = getConfiguration();
3747 int changes = lastReportedConfig.diff(currentConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003748 // We don't want to use size changes if they don't cross boundaries that are important to
3749 // the app.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003750 if ((changes & CONFIG_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003751 final boolean crosses = crossesHorizontalSizeThreshold(lastReportedConfig.screenWidthDp,
3752 currentConfig.screenWidthDp)
3753 || crossesVerticalSizeThreshold(lastReportedConfig.screenHeightDp,
3754 currentConfig.screenHeightDp);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003755 if (!crosses) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003756 changes &= ~CONFIG_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003757 }
3758 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003759 if ((changes & CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003760 final int oldSmallest = lastReportedConfig.smallestScreenWidthDp;
3761 final int newSmallest = currentConfig.smallestScreenWidthDp;
3762 if (!crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003763 changes &= ~CONFIG_SMALLEST_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003764 }
3765 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07003766 // We don't want window configuration to cause relaunches.
3767 if ((changes & CONFIG_WINDOW_CONFIGURATION) != 0) {
3768 changes &= ~CONFIG_WINDOW_CONFIGURATION;
3769 }
Bryce Lee600dadd2017-07-25 10:48:42 -07003770
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003771 return changes;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003772 }
3773
3774 private static boolean isResizeOnlyChange(int change) {
3775 return (change & ~(CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
3776 | CONFIG_SCREEN_LAYOUT)) == 0;
3777 }
3778
Garfield Tan2746ab52018-07-25 12:33:01 -07003779 private static boolean hasResizeChange(int change) {
3780 return (change & (CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
3781 | CONFIG_SCREEN_LAYOUT)) != 0;
3782 }
3783
Andrii Kulian21713ac2016-10-12 22:05:05 -07003784 void relaunchActivityLocked(boolean andResume, boolean preserveWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003785 if (mAtmService.mSuppressResizeConfigChanges && preserveWindow) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003786 configChangeFlags = 0;
3787 return;
3788 }
3789
3790 List<ResultInfo> pendingResults = null;
3791 List<ReferrerIntent> pendingNewIntents = null;
3792 if (andResume) {
3793 pendingResults = results;
3794 pendingNewIntents = newIntents;
3795 }
3796 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
3797 "Relaunching: " + this + " with results=" + pendingResults
3798 + " newIntents=" + pendingNewIntents + " andResume=" + andResume
3799 + " preserveWindow=" + preserveWindow);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003800 EventLog.writeEvent(andResume ? AM_RELAUNCH_RESUME_ACTIVITY
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003801 : AM_RELAUNCH_ACTIVITY, mUserId, System.identityHashCode(this),
Andrii Kulian21713ac2016-10-12 22:05:05 -07003802 task.taskId, shortComponentName);
3803
3804 startFreezingScreenLocked(app, 0);
3805
Andrii Kulian21713ac2016-10-12 22:05:05 -07003806 try {
3807 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
3808 "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this
3809 + " callers=" + Debug.getCallers(6));
3810 forceNewConfig = false;
3811 mStackSupervisor.activityRelaunchingLocked(this);
Andrii Kulianb372da62018-01-18 10:46:24 -08003812 final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
3813 pendingNewIntents, configChangeFlags,
Andrii Kulianbeadacc2019-05-20 12:18:01 +00003814 new MergedConfiguration(mAtmService.getGlobalConfiguration(),
Andrii Kulianb372da62018-01-18 10:46:24 -08003815 getMergedOverrideConfiguration()),
3816 preserveWindow);
3817 final ActivityLifecycleItem lifecycleItem;
3818 if (andResume) {
lumark588a3e82018-07-20 18:53:54 +08003819 lifecycleItem = ResumeActivityItem.obtain(
Wale Ogunwale3a256e62018-12-06 14:41:18 -08003820 getDisplay().mDisplayContent.isNextTransitionForward());
Andrii Kulianb372da62018-01-18 10:46:24 -08003821 } else {
Bryce Lee1d0d5142018-04-12 10:35:07 -07003822 lifecycleItem = PauseActivityItem.obtain();
Andrii Kulianb372da62018-01-18 10:46:24 -08003823 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003824 final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), appToken);
Andrii Kulianb372da62018-01-18 10:46:24 -08003825 transaction.addCallback(callbackItem);
3826 transaction.setLifecycleStateRequest(lifecycleItem);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003827 mAtmService.getLifecycleManager().scheduleTransaction(transaction);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003828 // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
Andrii Kulianb372da62018-01-18 10:46:24 -08003829 // request resume if this activity is currently resumed, which implies we aren't
Andrii Kulian21713ac2016-10-12 22:05:05 -07003830 // sleeping.
3831 } catch (RemoteException e) {
3832 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
3833 }
3834
3835 if (andResume) {
3836 if (DEBUG_STATES) {
3837 Slog.d(TAG_STATES, "Resumed after relaunch " + this);
3838 }
3839 results = null;
3840 newIntents = null;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003841 mAtmService.getAppWarningsLocked().onResumeActivity(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003842 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003843 final ActivityStack stack = getActivityStack();
Wale Ogunwale008163e2018-07-23 23:11:08 -07003844 if (stack != null) {
3845 stack.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
3846 }
Bryce Lee7ace3952018-02-16 14:34:32 -08003847 setState(PAUSED, "relaunchActivityLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07003848 }
3849
3850 configChangeFlags = 0;
3851 deferRelaunchUntilPaused = false;
3852 preserveWindowOnDeferredRelaunch = false;
3853 }
3854
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003855 /**
3856 * Request the process of the activity to restart with its saved state (from
3857 * {@link android.app.Activity#onSaveInstanceState}) if possible. It also forces to recompute
3858 * the override configuration. Note if the activity is in background, the process will be killed
3859 * directly with keeping its record.
3860 */
3861 void restartProcessIfVisible() {
3862 Slog.i(TAG, "Request to restart process of " + this);
3863
Riddle Hsuaec55442019-03-12 17:25:35 +08003864 // Reset the existing override configuration so it can be updated according to the latest
3865 // configuration.
Riddle Hsu74826262019-04-17 14:57:42 +08003866 getRequestedOverrideConfiguration().unset();
3867 getResolvedOverrideConfiguration().unset();
Riddle Hsu61987bc2019-04-03 13:08:47 +08003868 mCompatDisplayInsets = null;
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003869 if (visible) {
3870 // Configuration will be ensured when becoming visible, so if it is already visible,
3871 // then the manual update is needed.
3872 updateOverrideConfiguration();
3873 }
3874
3875 if (!attachedToProcess()) {
3876 return;
3877 }
3878
3879 // The restarting state avoids removing this record when process is died.
3880 setState(RESTARTING_PROCESS, "restartActivityProcess");
3881
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07003882 if (!visible || mHaveState) {
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003883 // Kill its process immediately because the activity should be in background.
3884 // The activity state will be update to {@link #DESTROYED} in
3885 // {@link ActivityStack#cleanUpActivityLocked} when handling process died.
Riddle Hsuaec55442019-03-12 17:25:35 +08003886 mAtmService.mH.post(() -> {
3887 final WindowProcessController wpc;
3888 synchronized (mAtmService.mGlobalLock) {
3889 if (!hasProcess()
3890 || app.getReportedProcState() <= PROCESS_STATE_IMPORTANT_FOREGROUND) {
3891 return;
3892 }
3893 wpc = app;
3894 }
3895 mAtmService.mAmInternal.killProcess(wpc.mName, wpc.mUid, "resetConfig");
3896 });
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003897 return;
3898 }
3899
3900 if (mAppWindowToken != null) {
3901 mAppWindowToken.startFreezingScreen();
3902 }
3903 // The process will be killed until the activity reports stopped with saved state (see
3904 // {@link ActivityTaskManagerService.activityStopped}).
3905 try {
3906 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
3907 StopActivityItem.obtain(false /* showWindow */, 0 /* configChanges */));
3908 } catch (RemoteException e) {
3909 Slog.w(TAG, "Exception thrown during restart " + this, e);
3910 }
3911 mStackSupervisor.scheduleRestartTimeout(this);
3912 }
3913
Riddle Hsu32dbdca2019-05-17 23:10:16 -06003914 boolean isProcessRunning() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003915 WindowProcessController proc = app;
Jorim Jaggi02886a82016-12-06 09:10:06 -08003916 if (proc == null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003917 proc = mAtmService.mProcessNames.get(processName, info.applicationInfo.uid);
Jorim Jaggi02886a82016-12-06 09:10:06 -08003918 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003919 return proc != null && proc.hasThread();
Jorim Jaggi02886a82016-12-06 09:10:06 -08003920 }
3921
Jorim Jaggibae01b12017-04-11 16:29:10 -07003922 /**
3923 * @return Whether a task snapshot starting window may be shown.
3924 */
3925 private boolean allowTaskSnapshot() {
3926 if (newIntents == null) {
3927 return true;
3928 }
3929
3930 // Restrict task snapshot starting window to launcher start, or there is no intent at all
3931 // (eg. task being brought to front). If the intent is something else, likely the app is
3932 // going to show some specific page or view, instead of what's left last time.
3933 for (int i = newIntents.size() - 1; i >= 0; i--) {
3934 final Intent intent = newIntents.get(i);
3935 if (intent != null && !ActivityRecord.isMainIntent(intent)) {
3936 return false;
3937 }
3938 }
3939 return true;
3940 }
3941
Bryce Leeb7c9b802017-05-02 14:20:24 -07003942 /**
3943 * Returns {@code true} if the associated activity has the no history flag set on it.
3944 * {@code false} otherwise.
3945 */
3946 boolean isNoHistory() {
3947 return (intent.getFlags() & FLAG_ACTIVITY_NO_HISTORY) != 0
3948 || (info.flags & FLAG_NO_HISTORY) != 0;
3949 }
3950
Craig Mautner21d24a22014-04-23 11:45:37 -07003951 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
3952 out.attribute(null, ATTR_ID, String.valueOf(createTime));
3953 out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
3954 if (launchedFromPackage != null) {
3955 out.attribute(null, ATTR_LAUNCHEDFROMPACKAGE, launchedFromPackage);
3956 }
3957 if (resolvedType != null) {
3958 out.attribute(null, ATTR_RESOLVEDTYPE, resolvedType);
3959 }
3960 out.attribute(null, ATTR_COMPONENTSPECIFIED, String.valueOf(componentSpecified));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003961 out.attribute(null, ATTR_USERID, String.valueOf(mUserId));
Winson Chung2cb86c72014-06-25 12:03:30 -07003962
Craig Mautner21d24a22014-04-23 11:45:37 -07003963 if (taskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003964 taskDescription.saveToXml(out);
Craig Mautner21d24a22014-04-23 11:45:37 -07003965 }
3966
3967 out.startTag(null, TAG_INTENT);
3968 intent.saveToXml(out);
3969 out.endTag(null, TAG_INTENT);
3970
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07003971 if (isPersistable() && mPersistentState != null) {
Craig Mautner21d24a22014-04-23 11:45:37 -07003972 out.startTag(null, TAG_PERSISTABLEBUNDLE);
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07003973 mPersistentState.saveToXml(out);
Craig Mautner21d24a22014-04-23 11:45:37 -07003974 out.endTag(null, TAG_PERSISTABLEBUNDLE);
3975 }
3976 }
3977
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07003978 static ActivityRecord restoreFromXml(XmlPullParser in,
3979 ActivityStackSupervisor stackSupervisor) throws IOException, XmlPullParserException {
Craig Mautner21d24a22014-04-23 11:45:37 -07003980 Intent intent = null;
3981 PersistableBundle persistentState = null;
3982 int launchedFromUid = 0;
3983 String launchedFromPackage = null;
3984 String resolvedType = null;
3985 boolean componentSpecified = false;
3986 int userId = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07003987 long createTime = -1;
3988 final int outerDepth = in.getDepth();
Winson Chung2cb86c72014-06-25 12:03:30 -07003989 TaskDescription taskDescription = new TaskDescription();
Craig Mautner21d24a22014-04-23 11:45:37 -07003990
3991 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
3992 final String attrName = in.getAttributeName(attrNdx);
3993 final String attrValue = in.getAttributeValue(attrNdx);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003994 if (DEBUG) Slog.d(TaskPersister.TAG,
Wale Ogunwale18795a22014-12-03 11:38:33 -08003995 "ActivityRecord: attribute name=" + attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003996 if (ATTR_ID.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01003997 createTime = Long.parseLong(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003998 } else if (ATTR_LAUNCHEDFROMUID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003999 launchedFromUid = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07004000 } else if (ATTR_LAUNCHEDFROMPACKAGE.equals(attrName)) {
4001 launchedFromPackage = attrValue;
4002 } else if (ATTR_RESOLVEDTYPE.equals(attrName)) {
4003 resolvedType = attrValue;
4004 } else if (ATTR_COMPONENTSPECIFIED.equals(attrName)) {
Tobias Thiererb0800dc2016-04-21 17:51:41 +01004005 componentSpecified = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07004006 } else if (ATTR_USERID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01004007 userId = Integer.parseInt(attrValue);
Ruben Brunkf53497c2017-03-27 20:26:17 -07004008 } else if (attrName.startsWith(ATTR_TASKDESCRIPTION_PREFIX)) {
Craig Mautner648f69b2014-09-18 14:16:26 -07004009 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07004010 } else {
4011 Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
4012 }
4013 }
4014
4015 int event;
Ruben Brunkf53497c2017-03-27 20:26:17 -07004016 while (((event = in.next()) != END_DOCUMENT) &&
4017 (event != END_TAG || in.getDepth() >= outerDepth)) {
4018 if (event == START_TAG) {
Craig Mautner21d24a22014-04-23 11:45:37 -07004019 final String name = in.getName();
Ruben Brunkf53497c2017-03-27 20:26:17 -07004020 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08004021 Slog.d(TaskPersister.TAG, "ActivityRecord: START_TAG name=" + name);
Craig Mautner21d24a22014-04-23 11:45:37 -07004022 if (TAG_INTENT.equals(name)) {
4023 intent = Intent.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07004024 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08004025 Slog.d(TaskPersister.TAG, "ActivityRecord: intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07004026 } else if (TAG_PERSISTABLEBUNDLE.equals(name)) {
4027 persistentState = PersistableBundle.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07004028 if (DEBUG) Slog.d(TaskPersister.TAG,
Craig Mautner21d24a22014-04-23 11:45:37 -07004029 "ActivityRecord: persistentState=" + persistentState);
4030 } else {
4031 Slog.w(TAG, "restoreActivity: unexpected name=" + name);
4032 XmlUtils.skipCurrentTag(in);
4033 }
4034 }
4035 }
4036
4037 if (intent == null) {
Craig Mautnere0129b32014-05-25 16:41:09 -07004038 throw new XmlPullParserException("restoreActivity error intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07004039 }
4040
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07004041 final ActivityTaskManagerService service = stackSupervisor.mService;
Craig Mautner21d24a22014-04-23 11:45:37 -07004042 final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null,
Patrick Baumann78380272018-04-04 10:41:01 -07004043 userId, Binder.getCallingUid());
Craig Mautnere0129b32014-05-25 16:41:09 -07004044 if (aInfo == null) {
Craig Mautner77b04262014-06-27 15:22:12 -07004045 throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
4046 " resolvedType=" + resolvedType);
Craig Mautnere0129b32014-05-25 16:41:09 -07004047 }
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07004048 final ActivityRecord r = new ActivityRecord(service, null /* caller */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08004049 0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType,
Wale Ogunwalef6733932018-06-27 05:14:34 -07004050 aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08004051 0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07004052 stackSupervisor, null /* options */, null /* sourceRecord */);
Craig Mautner21d24a22014-04-23 11:45:37 -07004053
Andrii Kulian06b8dcb2019-07-10 21:09:38 -07004054 r.mPersistentState = persistentState;
Winson Chung2cb86c72014-06-25 12:03:30 -07004055 r.taskDescription = taskDescription;
Craig Mautner21d24a22014-04-23 11:45:37 -07004056 r.createTime = createTime;
4057
4058 return r;
4059 }
4060
Zak Cohen90e7116742017-01-29 12:59:23 -08004061 private static boolean isInVrUiMode(Configuration config) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07004062 return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
Zak Cohen90e7116742017-01-29 12:59:23 -08004063 }
4064
David Stevens82ea6cb2017-03-03 16:18:50 -08004065 int getUid() {
4066 return info.applicationInfo.uid;
4067 }
4068
chaviw59b98852017-06-13 12:05:44 -07004069 void setShowWhenLocked(boolean showWhenLocked) {
4070 mShowWhenLocked = showWhenLocked;
Wale Ogunwaled32da472018-11-16 07:19:28 -08004071 mRootActivityContainer.ensureActivitiesVisible(null, 0 /* configChanges */,
Kevin Chyn44639482017-10-09 18:34:41 -07004072 false /* preserveWindows */);
chaviw59b98852017-06-13 12:05:44 -07004073 }
4074
Issei Suzuki74e1eb22018-12-20 17:42:52 +01004075 void setInheritShowWhenLocked(boolean inheritShowWhenLocked) {
4076 mInheritShownWhenLocked = inheritShowWhenLocked;
4077 mRootActivityContainer.ensureActivitiesVisible(null, 0, false);
4078 }
4079
chaviw59b98852017-06-13 12:05:44 -07004080 /**
chaviw2c500982018-01-04 17:05:05 -08004081 * @return true if the activity windowing mode is not
Issei Suzuki74e1eb22018-12-20 17:42:52 +01004082 * {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and a) activity
4083 * contains windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the
4084 * activity has set {@link #mShowWhenLocked}, or b) if the activity has set
4085 * {@link #mInheritShownWhenLocked} and the activity behind this satisfies the
4086 * conditions a) above.
chaviw2c500982018-01-04 17:05:05 -08004087 * Multi-windowing mode will be exited if true is returned.
chaviw59b98852017-06-13 12:05:44 -07004088 */
4089 boolean canShowWhenLocked() {
Issei Suzuki74e1eb22018-12-20 17:42:52 +01004090 if (!inPinnedWindowingMode() && (mShowWhenLocked
4091 || (mAppWindowToken != null && mAppWindowToken.containsShowWhenLockedWindow()))) {
4092 return true;
4093 } else if (mInheritShownWhenLocked) {
4094 ActivityRecord r = getActivityBelow();
4095 return r != null && !r.inPinnedWindowingMode() && (r.mShowWhenLocked
4096 || (r.mAppWindowToken != null
4097 && r.mAppWindowToken.containsShowWhenLockedWindow()));
4098 } else {
4099 return false;
4100 }
4101 }
4102
4103 /**
4104 * @return an {@link ActivityRecord} of the activity below this activity, or {@code null} if no
4105 * such activity exists.
4106 */
4107 @Nullable
4108 private ActivityRecord getActivityBelow() {
4109 final int pos = task.mActivities.indexOf(this);
4110 if (pos == -1) {
4111 throw new IllegalStateException("Activity not found in its task");
4112 }
4113 return pos == 0 ? null : task.getChildAt(pos - 1);
chaviw59b98852017-06-13 12:05:44 -07004114 }
4115
4116 void setTurnScreenOn(boolean turnScreenOn) {
4117 mTurnScreenOn = turnScreenOn;
4118 }
4119
4120 /**
4121 * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
4122 * {@link #mTurnScreenOn} is set and checks whether the ActivityRecord should be visible
4123 * depending on Keyguard state
4124 *
4125 * @return true if the screen can be turned on, false otherwise.
4126 */
4127 boolean canTurnScreenOn() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004128 final ActivityStack stack = getActivityStack();
chaviw59b98852017-06-13 12:05:44 -07004129 return mTurnScreenOn && stack != null &&
4130 stack.checkKeyguardVisibility(this, true /* shouldBeVisible */, true /* isTop */);
4131 }
4132
Louis Chang77ce34d2019-01-03 15:45:12 +08004133 /**
4134 * Check if this activity is able to resume. For pre-Q apps, only the topmost activities of each
4135 * process are allowed to be resumed.
4136 *
4137 * @return true if this activity can be resumed.
4138 */
4139 boolean canResumeByCompat() {
4140 return app == null || app.updateTopResumingActivityInProcessIfNeeded(this);
4141 }
4142
chaviw59b98852017-06-13 12:05:44 -07004143 boolean getTurnScreenOnFlag() {
4144 return mTurnScreenOn;
4145 }
4146
4147 boolean isTopRunningActivity() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08004148 return mRootActivityContainer.topRunningActivity() == this;
chaviw59b98852017-06-13 12:05:44 -07004149 }
4150
Andrii Kulian52d255c2018-07-13 11:32:19 -07004151 /**
4152 * @return {@code true} if this is the resumed activity on its current display, {@code false}
4153 * otherwise.
4154 */
4155 boolean isResumedActivityOnDisplay() {
4156 final ActivityDisplay display = getDisplay();
4157 return display != null && this == display.getResumedActivity();
4158 }
4159
Andrii Kulian39f27442019-06-26 19:09:19 -07004160
4161 /**
4162 * Check if this is the root of the task - first activity that is not finishing, starting from
4163 * the bottom of the task. If all activities are finishing - then this method will return
4164 * {@code true} if the activity is at the bottom.
4165 *
4166 * NOTE: This is different from 'effective root' - an activity that defines the task identity.
4167 */
4168 boolean isRootOfTask() {
4169 if (task == null) {
4170 return false;
4171 }
4172 final ActivityRecord rootActivity = task.getRootActivity();
4173 if (rootActivity != null) {
4174 return this == rootActivity;
4175 }
4176 // No non-finishing activity found. In this case the bottom-most activity is considered to
4177 // be the root.
4178 return task.getChildAt(0) == this;
4179 }
4180
Jorim Jaggif84e2f62018-01-16 14:17:59 +01004181 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08004182 if (mAppWindowToken == null) {
4183 Slog.w(TAG_WM, "Attempted to register remote animations with non-existing app"
4184 + " token: " + appToken);
4185 return;
4186 }
4187 mAppWindowToken.registerRemoteAnimations(definition);
Jorim Jaggif84e2f62018-01-16 14:17:59 +01004188 }
4189
Craig Mautnerf81b90872013-02-26 13:02:43 -08004190 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 public String toString() {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07004192 if (stringName != null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08004193 return stringName + " t" + (task == null ? INVALID_TASK_ID : task.taskId) +
Craig Mautnerf3333272013-04-22 10:55:53 -07004194 (finishing ? " f}" : "}");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07004195 }
4196 StringBuilder sb = new StringBuilder(128);
Dianne Hackborn30d71892010-12-11 10:37:55 -08004197 sb.append("ActivityRecord{");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07004198 sb.append(Integer.toHexString(System.identityHashCode(this)));
Dianne Hackbornb12e1352012-09-26 11:39:20 -07004199 sb.append(" u");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004200 sb.append(mUserId);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07004201 sb.append(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -07004202 sb.append(intent.getComponent().flattenToShortString());
Craig Mautnerf81b90872013-02-26 13:02:43 -08004203 stringName = sb.toString();
4204 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004205 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07004206
4207 void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
4208 final long token = proto.start(fieldId);
4209 proto.write(HASH_CODE, System.identityHashCode(this));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08004210 proto.write(USER_ID, mUserId);
Steven Timotius4346f0a2017-09-12 11:07:21 -07004211 proto.write(TITLE, intent.getComponent().flattenToShortString());
4212 proto.end(token);
4213 }
4214
Igor Murashkinc0b47e42018-11-07 15:54:18 -08004215 /**
4216 * Write all fields to an {@code ActivityRecordProto}. This assumes the
4217 * {@code ActivityRecordProto} is the outer-most proto data.
4218 */
4219 void writeToProto(ProtoOutputStream proto) {
Nataniel Borges023ecb52019-01-16 14:15:43 -08004220 super.writeToProto(proto, CONFIGURATION_CONTAINER, WindowTraceLogLevel.ALL);
Steven Timotius4346f0a2017-09-12 11:07:21 -07004221 writeIdentifierToProto(proto, IDENTIFIER);
Bryce Lee7ace3952018-02-16 14:34:32 -08004222 proto.write(STATE, mState.toString());
Steven Timotius4346f0a2017-09-12 11:07:21 -07004223 proto.write(VISIBLE, visible);
Andrii Kulian39f27442019-06-26 19:09:19 -07004224 proto.write(FRONT_OF_TASK, isRootOfTask());
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07004225 if (hasProcess()) {
4226 proto.write(PROC_ID, app.getPid());
Steven Timotius4346f0a2017-09-12 11:07:21 -07004227 }
Wale Ogunwale30eab1f2018-05-24 18:25:25 -07004228 proto.write(TRANSLUCENT, !fullscreen);
Igor Murashkinc0b47e42018-11-07 15:54:18 -08004229 }
4230
4231 public void writeToProto(ProtoOutputStream proto, long fieldId) {
4232 final long token = proto.start(fieldId);
4233 writeToProto(proto);
Steven Timotius4346f0a2017-09-12 11:07:21 -07004234 proto.end(token);
4235 }
Riddle Hsu61987bc2019-04-03 13:08:47 +08004236
4237 /**
4238 * The precomputed insets of the display in each rotation. This is used to make the size
4239 * compatibility mode activity compute the configuration without relying on its current display.
4240 */
4241 static class CompatDisplayInsets {
4242 final int mDisplayWidth;
4243 final int mDisplayHeight;
4244
Riddle Hsu74826262019-04-17 14:57:42 +08004245 /**
4246 * The nonDecorInsets for each rotation. Includes the navigation bar and cutout insets. It
4247 * is used to compute the appBounds.
4248 */
Riddle Hsu61987bc2019-04-03 13:08:47 +08004249 final Rect[] mNonDecorInsets = new Rect[4];
4250 /**
4251 * The stableInsets for each rotation. Includes the status bar inset and the
4252 * nonDecorInsets. It is used to compute {@link Configuration#screenWidthDp} and
4253 * {@link Configuration#screenHeightDp}.
4254 */
4255 final Rect[] mStableInsets = new Rect[4];
4256
4257 CompatDisplayInsets(DisplayContent display) {
4258 mDisplayWidth = display.mBaseDisplayWidth;
4259 mDisplayHeight = display.mBaseDisplayHeight;
4260 final DisplayPolicy policy = display.getDisplayPolicy();
Riddle Hsu61987bc2019-04-03 13:08:47 +08004261 for (int rotation = 0; rotation < 4; rotation++) {
4262 mNonDecorInsets[rotation] = new Rect();
4263 mStableInsets[rotation] = new Rect();
4264 final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
4265 final int dw = rotated ? mDisplayHeight : mDisplayWidth;
4266 final int dh = rotated ? mDisplayWidth : mDisplayHeight;
Riddle Hsu74826262019-04-17 14:57:42 +08004267 final DisplayCutout cutout = display.calculateDisplayCutoutForRotation(rotation)
4268 .getDisplayCutout();
Riddle Hsu61987bc2019-04-03 13:08:47 +08004269 policy.getNonDecorInsetsLw(rotation, dw, dh, cutout, mNonDecorInsets[rotation]);
4270 mStableInsets[rotation].set(mNonDecorInsets[rotation]);
4271 policy.convertNonDecorInsetsToStableInsets(mStableInsets[rotation], rotation);
4272 }
4273 }
4274
Riddle Hsu74826262019-04-17 14:57:42 +08004275 void getDisplayBoundsByRotation(Rect outBounds, int rotation) {
Riddle Hsu61987bc2019-04-03 13:08:47 +08004276 final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
4277 final int dw = rotated ? mDisplayHeight : mDisplayWidth;
4278 final int dh = rotated ? mDisplayWidth : mDisplayHeight;
4279 outBounds.set(0, 0, dw, dh);
4280 }
Riddle Hsu74826262019-04-17 14:57:42 +08004281
4282 void getDisplayBoundsByOrientation(Rect outBounds, int orientation) {
4283 final int longSide = Math.max(mDisplayWidth, mDisplayHeight);
4284 final int shortSide = Math.min(mDisplayWidth, mDisplayHeight);
4285 final boolean isLandscape = orientation == ORIENTATION_LANDSCAPE;
4286 outBounds.set(0, 0, isLandscape ? longSide : shortSide,
4287 isLandscape ? shortSide : longSide);
4288 }
Riddle Hsu61987bc2019-04-03 13:08:47 +08004289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004290}