blob: 7c4b5711cbe6b8d7bcdccc729eefc2322b1a67b8 [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;
Riddle Hsu16567132018-08-16 21:37:47 +080033import static android.app.ActivityTaskManager.INVALID_STACK_ID;
Vishnu Nair9ba31652018-11-13 14:34:05 -080034import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Winson Chung59fda9e2017-01-20 16:14:51 -080035import static android.app.AppOpsManager.MODE_ALLOWED;
Winson Chungf4ac0632017-03-17 12:34:12 -070036import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
Vishnu Nair132ee832018-09-28 15:00:05 -070037import static android.app.WaitResult.INVALID_DELAY;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070038import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
39import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
40import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070041import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Riddle Hsu74826262019-04-17 14:57:42 +080042import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070043import static android.app.WindowConfiguration.activityTypeToString;
Ruben Brunkf53497c2017-03-27 20:26:17 -070044import static android.content.Intent.ACTION_MAIN;
45import static android.content.Intent.CATEGORY_HOME;
46import static android.content.Intent.CATEGORY_LAUNCHER;
Chilun2ef71f72018-11-16 17:57:15 +080047import static android.content.Intent.CATEGORY_SECONDARY_HOME;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080048import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
Bryce Leeb7c9b802017-05-02 14:20:24 -070049import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY;
Andrii Kulian21713ac2016-10-12 22:05:05 -070050import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
51import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
52import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
53import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
Zak Cohen90e7116742017-01-29 12:59:23 -080054import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
Wale Ogunwale822e5122017-07-26 06:02:24 -070055import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
Jorim Jaggi02886a82016-12-06 09:10:06 -080056import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080057import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
58import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
Issei Suzuki74e1eb22018-12-20 17:42:52 +010059import static android.content.pm.ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080060import static android.content.pm.ActivityInfo.FLAG_MULTIPROCESS;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020061import static android.content.pm.ActivityInfo.FLAG_NO_HISTORY;
Chong Zhang87761972016-08-22 13:53:24 -070062import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020063import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080064import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
chaviw59b98852017-06-13 12:05:44 -070065import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080066import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -080067import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
68import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080069import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
Charles He2bf28322017-10-12 22:24:49 +010070import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
71import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
72import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
73import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
Ruben Brunkf53497c2017-03-27 20:26:17 -070074import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS;
75import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY;
Wale Ogunwaledf241e92016-10-13 15:14:21 -070076import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Jorim Jaggicd13d332016-04-27 15:40:20 -070077import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Wale Ogunwale72a73e32016-10-13 12:16:39 -070078import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Wale Ogunwaledf241e92016-10-13 15:14:21 -070079import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -070080import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
81import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -070082import static android.content.res.Configuration.EMPTY;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -070083import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
84import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
Riddle Hsu0a343c32018-12-21 00:40:48 +080085import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
Ruben Brunkf53497c2017-03-27 20:26:17 -070086import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
Zak Cohen90e7116742017-01-29 12:59:23 -080087import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080088import static android.os.Build.VERSION_CODES.HONEYCOMB;
Zak Cohen90e7116742017-01-29 12:59:23 -080089import static android.os.Build.VERSION_CODES.O;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080090import static android.os.Process.SYSTEM_UID;
Issei Suzuki62356a22019-04-11 16:46:37 +020091import static android.view.Display.DEFAULT_DISPLAY;
Riddle Hsufd4a0502018-10-16 01:05:16 +080092import static android.view.Display.INVALID_DISPLAY;
Riddle Hsu61987bc2019-04-03 13:08:47 +080093import static android.view.Surface.ROTATION_270;
94import static android.view.Surface.ROTATION_90;
Riddle Hsu16567132018-08-16 21:37:47 +080095
Vishnu Nair9ba31652018-11-13 14:34:05 -080096import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
97import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
98import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
99import static com.android.server.am.ActivityRecordProto.PROC_ID;
100import static com.android.server.am.ActivityRecordProto.STATE;
101import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
102import static com.android.server.am.ActivityRecordProto.VISIBLE;
103import static com.android.server.am.EventLogTags.AM_RELAUNCH_ACTIVITY;
104import static com.android.server.am.EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY;
Hui Yu03d12402018-12-06 18:00:37 -0800105import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800106import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
107import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
108import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
Riddle Hsu7b766fd2019-01-28 21:14:59 +0800109import static com.android.server.wm.ActivityStack.ActivityState.RESTARTING_PROCESS;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800110import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
111import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
112import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
113import static com.android.server.wm.ActivityStack.LAUNCH_TICK;
114import static com.android.server.wm.ActivityStack.LAUNCH_TICK_MSG;
115import static com.android.server.wm.ActivityStack.PAUSE_TIMEOUT_MSG;
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800116import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800117import static com.android.server.wm.ActivityStack.STOP_TIMEOUT_MSG;
Wale Ogunwale59507092018-10-29 09:00:30 -0700118import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
119import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
120import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
121import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
122import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
Jorim Jaggi346702a2019-05-08 17:49:33 +0200123import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
Wale Ogunwale59507092018-10-29 09:00:30 -0700124import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
125import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
126import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
127import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SAVED_STATE;
128import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
129import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
130import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
131import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
132import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwale59507092018-10-29 09:00:30 -0700133import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
134import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
Hui Yu03d12402018-12-06 18:00:37 -0800135import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -0700136import static com.android.server.wm.IdentifierProto.HASH_CODE;
137import static com.android.server.wm.IdentifierProto.TITLE;
138import static com.android.server.wm.IdentifierProto.USER_ID;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800139import static com.android.server.wm.TaskPersister.DEBUG;
140import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800141import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
142import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
143import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
144import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
145import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700146
Ruben Brunkf53497c2017-03-27 20:26:17 -0700147import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
148import static org.xmlpull.v1.XmlPullParser.END_TAG;
149import static org.xmlpull.v1.XmlPullParser.START_TAG;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800150
Andrii Kulian21713ac2016-10-12 22:05:05 -0700151import android.annotation.NonNull;
Issei Suzuki74e1eb22018-12-20 17:42:52 +0100152import android.annotation.Nullable;
Craig Mautner21d24a22014-04-23 11:45:37 -0700153import android.app.ActivityManager.TaskDescription;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700154import android.app.ActivityOptions;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800155import android.app.PendingIntent;
Winson Chung709904f2017-04-25 11:00:48 -0700156import android.app.PictureInPictureParams;
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800157import android.app.ResultInfo;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -0800158import android.app.WaitResult.LaunchState;
Riddle Hsu16567132018-08-16 21:37:47 +0800159import android.app.servertransaction.ActivityConfigurationChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800160import android.app.servertransaction.ActivityLifecycleItem;
161import android.app.servertransaction.ActivityRelaunchItem;
162import android.app.servertransaction.ClientTransaction;
163import android.app.servertransaction.ClientTransactionItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700164import android.app.servertransaction.MoveToDisplayItem;
165import android.app.servertransaction.MultiWindowModeChangeItem;
166import android.app.servertransaction.NewIntentItem;
Bryce Lee0bd8d422018-01-09 09:45:57 -0800167import android.app.servertransaction.PauseActivityItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700168import android.app.servertransaction.PipModeChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800169import android.app.servertransaction.ResumeActivityItem;
Riddle Hsu7b766fd2019-01-28 21:14:59 +0800170import android.app.servertransaction.StopActivityItem;
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800171import android.app.servertransaction.TopResumedActivityChangeItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700172import android.app.servertransaction.WindowVisibilityItem;
Hui Yu03d12402018-12-06 18:00:37 -0800173import android.app.usage.UsageEvents.Event;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174import android.content.ComponentName;
175import android.content.Intent;
176import android.content.pm.ActivityInfo;
177import android.content.pm.ApplicationInfo;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700178import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179import android.content.res.Configuration;
180import android.graphics.Bitmap;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800181import android.graphics.GraphicBuffer;
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700182import android.graphics.Rect;
Patrick Baumann78380272018-04-04 10:41:01 -0700183import android.os.Binder;
Bryce Lee39791592017-04-26 09:29:12 -0700184import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185import android.os.Bundle;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700186import android.os.Debug;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800187import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188import android.os.Message;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800189import android.os.PersistableBundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190import android.os.Process;
Dianne Hackborn39792d22010-08-19 18:01:52 -0700191import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700193import android.os.UserHandle;
Bryce Lee8558ec72017-08-17 15:37:26 -0700194import android.os.storage.StorageManager;
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800195import android.service.voice.IVoiceInteractionSession;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196import android.util.EventLog;
197import android.util.Log;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700198import android.util.MergedConfiguration;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700199import android.util.Slog;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700200import android.util.TimeUtils;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700201import android.util.proto.ProtoOutputStream;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800202import android.view.AppTransitionAnimationSpec;
Riddle Hsu61987bc2019-04-03 13:08:47 +0800203import android.view.DisplayCutout;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800204import android.view.IAppTransitionAnimationSpecsFuture;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205import android.view.IApplicationToken;
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100206import android.view.RemoteAnimationDefinition;
Jorim Jaggife762342016-10-13 14:33:27 +0200207import android.view.WindowManager.LayoutParams;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700208
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700209import com.android.internal.R;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800210import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800211import com.android.internal.app.ResolverActivity;
212import com.android.internal.content.ReferrerIntent;
213import com.android.internal.util.XmlUtils;
214import com.android.server.AttributeCache;
Ruben Brunkf53497c2017-03-27 20:26:17 -0700215import com.android.server.AttributeCache.Entry;
Wale Ogunwale59507092018-10-29 09:00:30 -0700216import com.android.server.am.AppTimeTracker;
217import com.android.server.am.PendingIntentRecord;
Jeff Sharkey344ce7c2019-05-29 14:52:59 -0600218import com.android.server.uri.NeededUriGrants;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800219import com.android.server.uri.UriPermissionOwner;
Wale Ogunwale59507092018-10-29 09:00:30 -0700220import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
221import com.android.server.wm.ActivityStack.ActivityState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222
Jorim Jaggi02886a82016-12-06 09:10:06 -0800223import org.xmlpull.v1.XmlPullParser;
224import org.xmlpull.v1.XmlPullParserException;
225import org.xmlpull.v1.XmlSerializer;
226
Suprabh Shukla23593142015-11-03 17:31:15 -0800227import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -0700228import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229import java.io.PrintWriter;
230import java.lang.ref.WeakReference;
231import java.util.ArrayList;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800232import java.util.Arrays;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233import java.util.HashSet;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700234import java.util.List;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700235import java.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236
237/**
238 * An entry in the history stack, representing an activity.
239 */
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800240final class ActivityRecord extends ConfigurationContainer {
Wale Ogunwale98875612018-10-12 07:53:02 -0700241 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_ATM;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700242 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
243 private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700244 private static final String TAG_STATES = TAG + POSTFIX_STATES;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700245 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700246 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
Louis Chang19443452018-10-09 12:10:21 +0800247 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
Winson Chung16e185e2017-11-07 08:30:54 -0800248 // TODO(b/67864419): Remove once recents component is overridden
249 private static final String LEGACY_RECENTS_PACKAGE_NAME = "com.android.systemui.recents";
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800250
Wale Ogunwale3ab9a272015-03-16 09:55:45 -0700251 private static final boolean SHOW_ACTIVITY_START_TIME = true;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700252
Craig Mautner21d24a22014-04-23 11:45:37 -0700253 private static final String ATTR_ID = "id";
254 private static final String TAG_INTENT = "intent";
255 private static final String ATTR_USERID = "user_id";
256 private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle";
257 private static final String ATTR_LAUNCHEDFROMUID = "launched_from_uid";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700258 private static final String ATTR_LAUNCHEDFROMPACKAGE = "launched_from_package";
Craig Mautner21d24a22014-04-23 11:45:37 -0700259 private static final String ATTR_RESOLVEDTYPE = "resolved_type";
260 private static final String ATTR_COMPONENTSPECIFIED = "component_specified";
Dianne Hackborn337abb32014-09-24 12:44:29 -0700261 static final String ACTIVITY_ICON_SUFFIX = "_activity_icon_";
Craig Mautner21d24a22014-04-23 11:45:37 -0700262
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800263 final ActivityTaskManagerService mAtmService; // owner
Dianne Hackbornbe707852011-11-11 14:32:10 -0800264 final IApplicationToken.Stub appToken; // window manager token
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800265 // TODO: Remove after unification
266 AppWindowToken mAppWindowToken;
267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 final ActivityInfo info; // all about me
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700269 // TODO: This is duplicated state already contained in info.applicationInfo - remove
270 ApplicationInfo appInfo; // information about activity's app
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800271 final int launchedFromPid; // always the pid who started the activity.
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700272 final int launchedFromUid; // always the uid who started the activity.
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800273 final String launchedFromPackage; // always the package who started the activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800274 final int mUserId; // Which user is this running for?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 final Intent intent; // the original intent that generated us
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800276 final ComponentName mActivityComponent; // the intent component, or target of an alias.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 final String shortComponentName; // the short component name of the intent
278 final String resolvedType; // as per original caller;
279 final String packageName; // the package implementing intent's component
280 final String processName; // process where this component wants to run
281 final String taskAffinity; // as per ActivityInfo.taskAffinity
282 final boolean stateNotNeeded; // As per ActivityInfo.flags
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700283 boolean fullscreen; // The activity is opaque and fills the entire space of this task.
284 // TODO: See if it possible to combine this with the fullscreen field.
285 final boolean hasWallpaper; // Has a wallpaper window as a background.
Louis Changd58cb672018-12-24 17:45:16 +0800286 @VisibleForTesting
287 boolean noDisplay; // activity is not displayed?
288 @VisibleForTesting
289 int mHandoverLaunchDisplayId = INVALID_DISPLAY; // Handover launch display id to next activity.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800290 private final boolean componentSpecified; // did caller specify an explicit component?
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700291 final boolean rootVoiceInteraction; // was this the root activity of a voice interaction?
Craig Mautner86d67a42013-05-14 10:34:38 -0700292
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800293 private CharSequence nonLocalizedLabel; // the label information from the package mgr.
294 private int labelRes; // the label information from the package mgr.
295 private int icon; // resource identifier of activity's icon.
296 private int logo; // resource identifier of activity's logo.
297 private int theme; // resource identifier of activity's theme.
298 private int realTheme; // actual theme resource we will use, never 0.
299 private int windowFlags; // custom window flags for preview window.
Bryce Leeaf691c02017-03-20 14:20:22 -0700300 private TaskRecord task; // the task this is in.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800301 private long createTime = System.currentTimeMillis();
Andrii Kulian86e70fc2019-02-12 11:04:10 +0000302 long lastVisibleTime; // last time this activity became visible
303 long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity
304 long pauseTime; // last time we started pausing the activity
305 long launchTickTime; // base time for launch tick messages
306 long topResumedStateLossTime; // last time we reported top resumed state loss to an activity
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700307 // Last configuration reported to the activity in the client process.
308 private MergedConfiguration mLastReportedConfiguration;
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800309 private int mLastReportedDisplayId;
Winson Chung609e1e92017-05-08 10:52:12 -0700310 private boolean mLastReportedMultiWindowMode;
311 private boolean mLastReportedPictureInPictureMode;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700312 CompatibilityInfo compat;// last used compatibility mode
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700313 ActivityRecord resultTo; // who started this entry, so will get our reply
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 final String resultWho; // additional identifier for use by resultTo.
315 final int requestCode; // code given by requester (resultTo)
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800316 ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
Dianne Hackborn85d558c2014-11-04 10:31:54 -0800318 ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700319 ActivityOptions pendingOptions; // most recently given options
George Mount6ba042b2014-07-28 11:12:28 -0700320 ActivityOptions returningOptions; // options that are coming back via convertToTranslucent
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700321 AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity
Wale Ogunwalec4e63a42018-10-02 13:19:54 -0700322 ActivityServiceConnectionsHolder mServiceConnectionsHolder; // Service connections.
Dianne Hackborn7e269642010-08-25 19:50:20 -0700323 UriPermissionOwner uriPermissions; // current special URI access perms.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700324 WindowProcessController app; // if non-null, hosting application
Bryce Lee7ace3952018-02-16 14:34:32 -0800325 private ActivityState mState; // current state we are in
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 Bundle icicle; // last saved activity state
Craig Mautnera0026042014-04-23 11:45:37 -0700327 PersistableBundle persistentState; // last persistently saved activity state
Wale Ogunwale66e16852017-10-19 13:35:52 -0700328 // TODO: See if this is still needed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 boolean frontOfTask; // is this the root activity of its task?
330 boolean launchFailed; // set if a launched failed, to abort on 2nd try
331 boolean haveState; // have we gotten the last activity state?
332 boolean stopped; // is activity pause finished?
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700333 boolean delayedResume; // not yet resumed because of stopped app switches?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 boolean finishing; // activity in pending finish list?
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800335 boolean deferRelaunchUntilPaused; // relaunch of activity is being deferred until pause is
336 // completed
337 boolean preserveWindowOnDeferredRelaunch; // activity windows are preserved on deferred relaunch
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 int configChangeFlags; // which config values have changed
Wale Ogunwaleec950642017-04-25 07:44:21 -0700339 private boolean keysPaused; // has key dispatching been paused for it?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 int launchMode; // the launch mode activity attribute.
Charles He2bf28322017-10-12 22:24:49 +0100341 int lockTaskLaunchMode; // the lockTaskMode manifest attribute, subject to override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 boolean visible; // does this activity's window need to be shown?
Jorim Jaggi241ae102016-11-02 21:57:33 -0700343 boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
344 // might hide this activity?
Wale Ogunwaleec950642017-04-25 07:44:21 -0700345 private boolean mDeferHidingClient; // If true we told WM to defer reporting to the client
346 // process that it is hidden.
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800347 boolean sleeping; // have we told the activity to sleep?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 boolean nowVisible; // is this activity's window visible?
Vishnu Nair9ba31652018-11-13 14:34:05 -0800349 boolean mDrawn; // is this activity's window drawn?
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700350 boolean mClientVisibilityDeferred;// was the visibility change message to client deferred?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 boolean idle; // has the activity gone idle?
352 boolean hasBeenLaunched;// has this activity ever been launched?
353 boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
Daniel Sandler69a48172010-06-23 16:29:36 -0400354 boolean immersive; // immersive mode (don't interrupt if possible)
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400355 boolean forceNewConfig; // force re-create with new config next time
Winson Chungf7e03e12017-08-22 11:32:16 -0700356 boolean supportsEnterPipOnTaskSwitch; // This flag is set by the system to indicate that the
357 // activity can enter picture in picture while pausing (only when switching to another task)
Winson Chung709904f2017-04-25 11:00:48 -0700358 PictureInPictureParams pictureInPictureArgs = new PictureInPictureParams.Builder().build();
359 // The PiP params used when deferring the entering of picture-in-picture.
Dianne Hackborn07981492013-01-28 11:36:23 -0800360 int launchCount; // count of launches since last state
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800361 long lastLaunchTime; // time of last launch of this activity
Ruben Brunke24b9a62016-02-16 21:38:24 -0800362 ComponentName requestedVrComponent; // the requested component for handling VR mode.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700364 String stringName; // for caching of toString().
Craig Mautnerde4ef022013-04-07 19:01:33 -0700365
Dianne Hackbornf26fd992011-04-08 18:14:09 -0700366 private boolean inHistory; // are we in the history stack?
Craig Mautnerde4ef022013-04-07 19:01:33 -0700367 final ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800368 final RootActivityContainer mRootActivityContainer;
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800369
370 static final int STARTING_WINDOW_NOT_SHOWN = 0;
371 static final int STARTING_WINDOW_SHOWN = 1;
372 static final int STARTING_WINDOW_REMOVED = 2;
373 int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;
Wale Ogunwale3b232392016-05-13 15:37:13 -0700374 boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800375
Garfield Tan2746ab52018-07-25 12:33:01 -0700376 // Marking the reason why this activity is being relaunched. Mainly used to track that this
377 // activity is being relaunched to fulfill a resize request due to compatibility issues, e.g. in
378 // pre-NYC apps that don't have a sense of being resized.
379 int mRelaunchReason = RELAUNCH_REASON_NONE;
380
Craig Mautner21d24a22014-04-23 11:45:37 -0700381 TaskDescription taskDescription; // the recents information for this activity
Craig Mautnerbb742462014-07-07 15:28:55 -0700382 boolean mLaunchTaskBehind; // this activity is actively being launched with
383 // ActivityOptions.setLaunchTaskBehind, will be cleared once launch is completed.
Craig Mautner2fbd7542014-03-21 09:34:07 -0700384
Filip Gruszczynski23493322015-07-29 17:02:59 -0700385 // These configurations are collected from application's resources based on size-sensitive
386 // qualifiers. For example, layout-w800dp will be added to mHorizontalSizeConfigurations as 800
387 // and drawable-sw400dp will be added to both as 400.
388 private int[] mVerticalSizeConfigurations;
389 private int[] mHorizontalSizeConfigurations;
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700390 private int[] mSmallestSizeConfigurations;
Filip Gruszczynski23493322015-07-29 17:02:59 -0700391
Riddle Hsu61987bc2019-04-03 13:08:47 +0800392 /**
393 * The precomputed display insets for resolving configuration. It will be non-null if
394 * {@link #shouldUseSizeCompatMode} returns {@code true}.
395 */
396 private CompatDisplayInsets mCompatDisplayInsets;
397
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800398 boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session
399 IVoiceInteractionSession voiceSession; // Voice interaction session for this activity
400
Robert Carrd2265122016-08-05 10:25:21 -0700401 // A hint to override the window specified rotation animation, or -1
402 // to use the window specified value. We use this so that
403 // we can select the right animation in the cases of starting
404 // windows, where the app hasn't had time to set a value
405 // on the window.
406 int mRotationAnimationHint = -1;
Robert Carrfd10cd12016-06-29 16:41:50 -0700407
chaviw59b98852017-06-13 12:05:44 -0700408 private boolean mShowWhenLocked;
Issei Suzuki74e1eb22018-12-20 17:42:52 +0100409 private boolean mInheritShownWhenLocked;
chaviw59b98852017-06-13 12:05:44 -0700410 private boolean mTurnScreenOn;
411
Andrii Kulian21713ac2016-10-12 22:05:05 -0700412 /**
Garfield Tan0443b372019-01-04 15:00:13 -0800413 * Current sequencing integer of the configuration, for skipping old activity configurations.
414 */
415 private int mConfigurationSeq;
416
417 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800418 * Temp configs used in {@link #ensureActivityConfiguration(int, boolean)}
Andrii Kulian21713ac2016-10-12 22:05:05 -0700419 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700420 private final Configuration mTmpConfig = new Configuration();
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700421 private final Rect mTmpBounds = new Rect();
Andrii Kulian21713ac2016-10-12 22:05:05 -0700422
Sunny Goyald40c3452019-03-20 12:46:55 -0700423 // Token for targeting this activity for assist purposes.
424 final Binder assistToken = new Binder();
425
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800426 private static String startingWindowStateToString(int state) {
427 switch (state) {
428 case STARTING_WINDOW_NOT_SHOWN:
429 return "STARTING_WINDOW_NOT_SHOWN";
430 case STARTING_WINDOW_SHOWN:
431 return "STARTING_WINDOW_SHOWN";
432 case STARTING_WINDOW_REMOVED:
433 return "STARTING_WINDOW_REMOVED";
434 default:
435 return "unknown state=" + state;
436 }
437 }
438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700440 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700441 pw.print(prefix); pw.print("packageName="); pw.print(packageName);
442 pw.print(" processName="); pw.println(processName);
443 pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
Craig Mautnere11f2b72013-04-01 12:37:17 -0700444 pw.print(" launchedFromPackage="); pw.print(launchedFromPackage);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800445 pw.print(" userId="); pw.println(mUserId);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800446 pw.print(prefix); pw.print("app="); pw.println(app);
447 pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700448 pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask);
449 pw.print(" task="); pw.println(task);
450 pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800451 pw.print(prefix); pw.print("mActivityComponent=");
452 pw.println(mActivityComponent.flattenToShortString());
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700453 if (appInfo != null) {
454 pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir);
455 if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) {
456 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir);
457 }
458 pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800459 if (appInfo.splitSourceDirs != null) {
460 pw.print(prefix); pw.print("splitDir=");
461 pw.println(Arrays.toString(appInfo.splitSourceDirs));
462 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800463 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700464 pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
465 pw.print(" componentSpecified="); pw.print(componentSpecified);
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700466 pw.print(" mActivityType="); pw.println(
467 activityTypeToString(getActivityType()));
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700468 if (rootVoiceInteraction) {
469 pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
470 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800471 pw.print(prefix); pw.print("compat="); pw.print(compat);
472 pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
473 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
474 pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700475 pw.println(prefix + "mLastReportedConfigurations:");
476 mLastReportedConfiguration.dump(pw, prefix + " ");
477
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700478 pw.print(prefix); pw.print("CurrentConfiguration="); pw.println(getConfiguration());
Evan Roskydfe3da72018-10-26 17:21:06 -0700479 if (!getRequestedOverrideConfiguration().equals(EMPTY)) {
480 pw.println(prefix + "RequestedOverrideConfiguration="
481 + getRequestedOverrideConfiguration());
482 }
483 if (!getResolvedOverrideConfiguration().equals(getRequestedOverrideConfiguration())) {
484 pw.println(prefix + "ResolvedOverrideConfiguration="
485 + getResolvedOverrideConfiguration());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700486 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800487 if (!matchParentBounds()) {
488 pw.println(prefix + "bounds=" + getBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700489 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700490 if (resultTo != null || resultWho != null) {
491 pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
492 pw.print(" resultWho="); pw.print(resultWho);
493 pw.print(" resultCode="); pw.println(requestCode);
494 }
Craig Mautner29c58ca2014-10-14 16:17:06 -0700495 if (taskDescription != null) {
496 final String iconFilename = taskDescription.getIconFilename();
497 if (iconFilename != null || taskDescription.getLabel() != null ||
498 taskDescription.getPrimaryColor() != 0) {
499 pw.print(prefix); pw.print("taskDescription:");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700500 pw.print(" label=\""); pw.print(taskDescription.getLabel());
501 pw.print("\"");
Matthew Ng54bc9422017-10-02 17:16:28 -0700502 pw.print(" icon="); pw.print(taskDescription.getInMemoryIcon() != null
503 ? taskDescription.getInMemoryIcon().getByteCount() + " bytes"
504 : "null");
505 pw.print(" iconResource="); pw.print(taskDescription.getIconResource());
506 pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200507 pw.print(" primaryColor=");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700508 pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700509 pw.print(prefix + " backgroundColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200510 pw.println(Integer.toHexString(taskDescription.getBackgroundColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700511 pw.print(prefix + " statusBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200512 pw.println(Integer.toHexString(taskDescription.getStatusBarColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700513 pw.print(prefix + " navigationBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200514 pw.println(Integer.toHexString(taskDescription.getNavigationBarColor()));
Craig Mautner29c58ca2014-10-14 16:17:06 -0700515 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700516 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700517 if (results != null) {
518 pw.print(prefix); pw.print("results="); pw.println(results);
519 }
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700520 if (pendingResults != null && pendingResults.size() > 0) {
521 pw.print(prefix); pw.println("Pending Results:");
522 for (WeakReference<PendingIntentRecord> wpir : pendingResults) {
523 PendingIntentRecord pir = wpir != null ? wpir.get() : null;
524 pw.print(prefix); pw.print(" - ");
525 if (pir == null) {
526 pw.println("null");
527 } else {
528 pw.println(pir);
529 pir.dump(pw, prefix + " ");
530 }
531 }
532 }
533 if (newIntents != null && newIntents.size() > 0) {
534 pw.print(prefix); pw.println("Pending New Intents:");
535 for (int i=0; i<newIntents.size(); i++) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800536 Intent intent = newIntents.get(i);
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700537 pw.print(prefix); pw.print(" - ");
538 if (intent == null) {
539 pw.println("null");
540 } else {
541 pw.println(intent.toShortString(false, true, false, true));
542 }
543 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700544 }
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700545 if (pendingOptions != null) {
546 pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions);
547 }
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700548 if (appTimeTracker != null) {
549 appTimeTracker.dumpWithHeader(pw, prefix, false);
550 }
Dianne Hackborn7e269642010-08-25 19:50:20 -0700551 if (uriPermissions != null) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700552 uriPermissions.dump(pw, prefix);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700553 }
554 pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed);
Dianne Hackborn07981492013-01-28 11:36:23 -0800555 pw.print(" launchCount="); pw.print(launchCount);
556 pw.print(" lastLaunchTime=");
557 if (lastLaunchTime == 0) pw.print("0");
558 else TimeUtils.formatDuration(lastLaunchTime, now, pw);
559 pw.println();
Dianne Hackborncfc837f2013-06-27 18:32:07 -0700560 pw.print(prefix); pw.print("haveState="); pw.print(haveState);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700561 pw.print(" icicle="); pw.println(icicle);
Bryce Lee7ace3952018-02-16 14:34:32 -0800562 pw.print(prefix); pw.print("state="); pw.print(mState);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700563 pw.print(" stopped="); pw.print(stopped);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700564 pw.print(" delayedResume="); pw.print(delayedResume);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700565 pw.print(" finishing="); pw.println(finishing);
566 pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
567 pw.print(" inHistory="); pw.print(inHistory);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700568 pw.print(" visible="); pw.print(visible);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800569 pw.print(" sleeping="); pw.print(sleeping);
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800570 pw.print(" idle="); pw.print(idle);
571 pw.print(" mStartingWindowState=");
572 pw.println(startingWindowStateToString(mStartingWindowState));
Dianne Hackbornff801ec2011-01-22 18:05:38 -0800573 pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
574 pw.print(" noDisplay="); pw.print(noDisplay);
575 pw.print(" immersive="); pw.print(immersive);
576 pw.print(" launchMode="); pw.println(launchMode);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800577 pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400578 pw.print(" forceNewConfig="); pw.println(forceNewConfig);
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700579 pw.print(prefix); pw.print("mActivityType=");
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700580 pw.println(activityTypeToString(getActivityType()));
Ruben Brunke24b9a62016-02-16 21:38:24 -0800581 if (requestedVrComponent != null) {
582 pw.print(prefix);
583 pw.print("requestedVrComponent=");
584 pw.println(requestedVrComponent);
585 }
Jorim Jaggi9b5e3312019-03-01 18:08:00 +0100586 if (lastVisibleTime != 0 || nowVisible) {
587 pw.print(prefix); pw.print(" nowVisible="); pw.print(nowVisible);
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700588 pw.print(" lastVisibleTime=");
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700589 if (lastVisibleTime == 0) pw.print("0");
590 else TimeUtils.formatDuration(lastVisibleTime, now, pw);
591 pw.println();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700592 }
Wale Ogunwaleec950642017-04-25 07:44:21 -0700593 if (mDeferHidingClient) {
594 pw.println(prefix + "mDeferHidingClient=" + mDeferHidingClient);
595 }
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800596 if (deferRelaunchUntilPaused || configChangeFlags != 0) {
597 pw.print(prefix); pw.print("deferRelaunchUntilPaused="); pw.print(deferRelaunchUntilPaused);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700598 pw.print(" configChangeFlags=");
599 pw.println(Integer.toHexString(configChangeFlags));
600 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -0700601 if (mServiceConnectionsHolder != null) {
602 pw.print(prefix); pw.print("connections="); pw.println(mServiceConnectionsHolder);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700603 }
Wale Ogunwaled26176f2016-01-25 20:04:04 -0800604 if (info != null) {
605 pw.println(prefix + "resizeMode=" + ActivityInfo.resizeModeToString(info.resizeMode));
Winson Chung609e1e92017-05-08 10:52:12 -0700606 pw.println(prefix + "mLastReportedMultiWindowMode=" + mLastReportedMultiWindowMode
607 + " mLastReportedPictureInPictureMode=" + mLastReportedPictureInPictureMode);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700608 if (info.supportsPictureInPicture()) {
609 pw.println(prefix + "supportsPictureInPicture=" + info.supportsPictureInPicture());
Winson Chungf7e03e12017-08-22 11:32:16 -0700610 pw.println(prefix + "supportsEnterPipOnTaskSwitch: "
611 + supportsEnterPipOnTaskSwitch);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700612 }
613 if (info.maxAspectRatio != 0) {
614 pw.println(prefix + "maxAspectRatio=" + info.maxAspectRatio);
615 }
Adrian Roos917791e2018-11-28 16:30:44 +0100616 if (info.minAspectRatio != 0) {
617 pw.println(prefix + "minAspectRatio=" + info.minAspectRatio);
618 }
Wale Ogunwaled26176f2016-01-25 20:04:04 -0800619 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800620 }
621
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700622 void updateApplicationInfo(ApplicationInfo aInfo) {
623 appInfo = aInfo;
624 info.applicationInfo = aInfo;
625 }
626
Andrii Kulian21713ac2016-10-12 22:05:05 -0700627 private boolean crossesHorizontalSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700628 return crossesSizeThreshold(mHorizontalSizeConfigurations, firstDp, secondDp);
629 }
630
Andrii Kulian21713ac2016-10-12 22:05:05 -0700631 private boolean crossesVerticalSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700632 return crossesSizeThreshold(mVerticalSizeConfigurations, firstDp, secondDp);
633 }
634
Andrii Kulian21713ac2016-10-12 22:05:05 -0700635 private boolean crossesSmallestSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700636 return crossesSizeThreshold(mSmallestSizeConfigurations, firstDp, secondDp);
637 }
638
Filip Gruszczynski23493322015-07-29 17:02:59 -0700639 /**
640 * The purpose of this method is to decide whether the activity needs to be relaunched upon
641 * changing its size. In most cases the activities don't need to be relaunched, if the resize
642 * is small, all the activity content has to do is relayout itself within new bounds. There are
643 * cases however, where the activity's content would be completely changed in the new size and
644 * the full relaunch is required.
645 *
646 * The activity will report to us vertical and horizontal thresholds after which a relaunch is
647 * required. These thresholds are collected from the application resource qualifiers. For
648 * example, if application has layout-w600dp resource directory, then it needs a relaunch when
649 * we resize from width of 650dp to 550dp, as it crosses the 600dp threshold. However, if
650 * it resizes width from 620dp to 700dp, it won't be relaunched as it stays on the same side
651 * of the threshold.
652 */
653 private static boolean crossesSizeThreshold(int[] thresholds, int firstDp,
654 int secondDp) {
655 if (thresholds == null) {
656 return false;
657 }
658 for (int i = thresholds.length - 1; i >= 0; i--) {
659 final int threshold = thresholds[i];
660 if ((firstDp < threshold && secondDp >= threshold)
661 || (firstDp >= threshold && secondDp < threshold)) {
662 return true;
663 }
664 }
665 return false;
666 }
667
Andrii Kulian21713ac2016-10-12 22:05:05 -0700668 void setSizeConfigurations(int[] horizontalSizeConfiguration,
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700669 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700670 mHorizontalSizeConfigurations = horizontalSizeConfiguration;
671 mVerticalSizeConfigurations = verticalSizeConfigurations;
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700672 mSmallestSizeConfigurations = smallestSizeConfigurations;
Filip Gruszczynski23493322015-07-29 17:02:59 -0700673 }
674
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800675 private void scheduleActivityMovedToDisplay(int displayId, Configuration config) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700676 if (!attachedToProcess()) {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800677 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.w(TAG,
678 "Can't report activity moved to display - client not running, activityRecord="
679 + this + ", displayId=" + displayId);
Wale Ogunwale22e25262016-02-01 10:32:02 -0800680 return;
681 }
682 try {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800683 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
684 "Reporting activity moved to display" + ", activityRecord=" + this
685 + ", displayId=" + displayId + ", config=" + config);
Chong Zhang6be533e2016-06-17 16:24:21 -0700686
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800687 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800688 MoveToDisplayItem.obtain(displayId, config));
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800689 } catch (RemoteException e) {
690 // If process died, whatever.
691 }
692 }
693
694 private void scheduleConfigurationChanged(Configuration config) {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700695 if (!attachedToProcess()) {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800696 if (DEBUG_CONFIGURATION) Slog.w(TAG,
697 "Can't report activity configuration update - client not running"
698 + ", activityRecord=" + this);
699 return;
700 }
701 try {
702 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + this + ", config: "
703 + config);
704
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800705 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800706 ActivityConfigurationChangeItem.obtain(config));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800707 } catch (RemoteException e) {
708 // If process died, whatever.
709 }
710 }
711
Louis Chang3b21bdc2019-03-25 15:49:14 +0800712 boolean scheduleTopResumedActivityChanged(boolean onTop) {
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800713 if (!attachedToProcess()) {
Andrii Kulian86e70fc2019-02-12 11:04:10 +0000714 if (DEBUG_STATES) {
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800715 Slog.w(TAG, "Can't report activity position update - client not running"
716 + ", activityRecord=" + this);
717 }
Louis Chang3b21bdc2019-03-25 15:49:14 +0800718 return false;
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800719 }
720 try {
Andrii Kulian86e70fc2019-02-12 11:04:10 +0000721 if (DEBUG_STATES) {
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800722 Slog.v(TAG, "Sending position change to " + this + ", onTop: " + onTop);
723 }
724
725 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
726 TopResumedActivityChangeItem.obtain(onTop));
727 } catch (RemoteException e) {
728 // If process died, whatever.
Louis Chang3b21bdc2019-03-25 15:49:14 +0800729 return false;
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800730 }
Louis Chang3b21bdc2019-03-25 15:49:14 +0800731 return true;
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800732 }
733
Winson Chung5af42fc2017-03-24 17:11:33 -0700734 void updateMultiWindowMode() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700735 if (task == null || task.getStack() == null || !attachedToProcess()) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800736 return;
737 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700738
Wale Ogunwaleeb76b762017-11-17 10:08:04 -0800739 if (task.getStack().deferScheduleMultiWindowModeChanged()) {
740 // Don't do anything if we are currently deferring multi-window mode change.
741 return;
742 }
743
Winson Chung5af42fc2017-03-24 17:11:33 -0700744 // An activity is considered to be in multi-window mode if its task isn't fullscreen.
Wale Ogunwaleeb76b762017-11-17 10:08:04 -0800745 final boolean inMultiWindowMode = inMultiWindowMode();
Winson Chung609e1e92017-05-08 10:52:12 -0700746 if (inMultiWindowMode != mLastReportedMultiWindowMode) {
747 mLastReportedMultiWindowMode = inMultiWindowMode;
Winson Chung5af42fc2017-03-24 17:11:33 -0700748 scheduleMultiWindowModeChanged(getConfiguration());
749 }
750 }
751
752 private void scheduleMultiWindowModeChanged(Configuration overrideConfig) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800753 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800754 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700755 MultiWindowModeChangeItem.obtain(mLastReportedMultiWindowMode, overrideConfig));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800756 } catch (Exception e) {
757 // If process died, I don't care.
758 }
759 }
760
Winson Chungab76bbc2017-08-14 13:33:51 -0700761 void updatePictureInPictureMode(Rect targetStackBounds, boolean forceUpdate) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700762 if (task == null || task.getStack() == null || !attachedToProcess()) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800763 return;
764 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700765
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700766 final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null;
Winson Chungab76bbc2017-08-14 13:33:51 -0700767 if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) {
Winson Chung5af42fc2017-03-24 17:11:33 -0700768 // Picture-in-picture mode changes also trigger a multi-window mode change as well, so
Winson Chung059955f2018-08-08 16:10:20 -0700769 // update that here in order. Set the last reported MW state to the same as the PiP
770 // state since we haven't yet actually resized the task (these callbacks need to
771 // preceed the configuration change from the resiez.
772 // TODO(110009072): Once we move these callbacks to the client, remove all logic related
773 // to forcing the update of the picture-in-picture mode as a part of the PiP animation.
Winson Chung609e1e92017-05-08 10:52:12 -0700774 mLastReportedPictureInPictureMode = inPictureInPictureMode;
Winson Chung059955f2018-08-08 16:10:20 -0700775 mLastReportedMultiWindowMode = inPictureInPictureMode;
Evan Rosky1ac84462018-11-13 11:25:30 -0800776 final Configuration newConfig = new Configuration();
777 if (targetStackBounds != null && !targetStackBounds.isEmpty()) {
Evan Rosky730f6e82018-12-03 17:40:11 -0800778 newConfig.setTo(task.getRequestedOverrideConfiguration());
779 Rect outBounds = newConfig.windowConfiguration.getBounds();
780 task.adjustForMinimalTaskDimensions(outBounds, outBounds);
781 task.computeConfigResourceOverrides(newConfig, task.getParent().getConfiguration());
Evan Rosky1ac84462018-11-13 11:25:30 -0800782 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700783 schedulePictureInPictureModeChanged(newConfig);
784 scheduleMultiWindowModeChanged(newConfig);
785 }
786 }
787
788 private void schedulePictureInPictureModeChanged(Configuration overrideConfig) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800789 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800790 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800791 PipModeChangeItem.obtain(mLastReportedPictureInPictureMode,
Andrii Kulian446e8242017-10-26 15:17:29 -0700792 overrideConfig));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800793 } catch (Exception e) {
794 // If process died, no one cares.
Filip Gruszczynskica664812015-12-04 12:43:36 -0800795 }
796 }
797
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700798 @Override
799 protected int getChildCount() {
800 // {@link ActivityRecord} is a leaf node and has no children.
801 return 0;
802 }
803
804 @Override
805 protected ConfigurationContainer getChildAt(int index) {
806 return null;
807 }
808
809 @Override
810 protected ConfigurationContainer getParent() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800811 return getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -0700812 }
813
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800814 TaskRecord getTaskRecord() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700815 return task;
816 }
817
Bryce Leeaf691c02017-03-20 14:20:22 -0700818 /**
819 * Sets reference to the {@link TaskRecord} the {@link ActivityRecord} will treat as its parent.
820 * Note that this does not actually add the {@link ActivityRecord} as a {@link TaskRecord}
821 * children. However, this method will clean up references to this {@link ActivityRecord} in
822 * {@link ActivityStack}.
823 * @param task The new parent {@link TaskRecord}.
824 */
825 void setTask(TaskRecord task) {
Bryce Lee84730a02018-04-03 14:10:04 -0700826 setTask(task /* task */, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -0700827 }
828
829 /**
830 * This method should only be called by {@link TaskRecord#removeActivity(ActivityRecord)}.
Bryce Lee84730a02018-04-03 14:10:04 -0700831 * @param task The new parent task.
832 * @param reparenting Whether we're in the middle of reparenting.
Bryce Leeaf691c02017-03-20 14:20:22 -0700833 */
834 void setTask(TaskRecord task, boolean reparenting) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800835 // Do nothing if the {@link TaskRecord} is the same as the current {@link getTaskRecord}.
836 if (task != null && task == getTaskRecord()) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700837 return;
838 }
839
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800840 final ActivityStack oldStack = getActivityStack();
Bryce Lee84730a02018-04-03 14:10:04 -0700841 final ActivityStack newStack = task != null ? task.getStack() : null;
Bryce Leeaf691c02017-03-20 14:20:22 -0700842
Bryce Lee84730a02018-04-03 14:10:04 -0700843 // Inform old stack (if present) of activity removal and new stack (if set) of activity
844 // addition.
845 if (oldStack != newStack) {
846 if (!reparenting && oldStack != null) {
847 oldStack.onActivityRemovedFromStack(this);
848 }
849
850 if (newStack != null) {
851 newStack.onActivityAddedToStack(this);
852 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700853 }
854
855 this.task = task;
856
857 if (!reparenting) {
858 onParentChanged();
859 }
860 }
861
chaviw4ad54912018-05-30 11:05:44 -0700862 /**
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800863 * Notifies AWT that this app is waiting to pause in order to determine if it will enter PIP.
864 * This information helps AWT know that the app is in the process of pausing before it gets the
865 * signal on the WM side.
chaviw4ad54912018-05-30 11:05:44 -0700866 */
867 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800868 if (mAppWindowToken == null) {
869 return;
870 }
871
872 mAppWindowToken.setWillCloseOrEnterPip(willCloseOrEnterPip);
chaviw4ad54912018-05-30 11:05:44 -0700873 }
874
Dianne Hackbornbe707852011-11-11 14:32:10 -0800875 static class Token extends IApplicationToken.Stub {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700876 private final WeakReference<ActivityRecord> weakActivity;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700877 private final String name;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800878
Steven Timotiusaf03df62017-07-18 16:56:43 -0700879 Token(ActivityRecord activity, Intent intent) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800880 weakActivity = new WeakReference<>(activity);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700881 name = intent.getComponent().flattenToShortString();
Wale Ogunwale7d701172015-03-11 15:36:30 -0700882 }
883
Charles Chen69362cd2019-03-29 15:18:45 +0800884 private static @Nullable ActivityRecord tokenToActivityRecordLocked(Token token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700885 if (token == null) {
886 return null;
887 }
888 ActivityRecord r = token.weakActivity.get();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800889 if (r == null || r.getActivityStack() == null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700890 return null;
891 }
892 return r;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800893 }
894
Craig Mautnerde4ef022013-04-07 19:01:33 -0700895 @Override
Dianne Hackbornbe707852011-11-11 14:32:10 -0800896 public String toString() {
897 StringBuilder sb = new StringBuilder(128);
898 sb.append("Token{");
899 sb.append(Integer.toHexString(System.identityHashCode(this)));
900 sb.append(' ');
901 sb.append(weakActivity.get());
902 sb.append('}');
903 return sb.toString();
904 }
Steven Timotiusaf03df62017-07-18 16:56:43 -0700905
906 @Override
907 public String getName() {
908 return name;
909 }
Dianne Hackbornbe707852011-11-11 14:32:10 -0800910 }
911
Charles Chen69362cd2019-03-29 15:18:45 +0800912 static @Nullable ActivityRecord forTokenLocked(IBinder token) {
Dianne Hackbornbe707852011-11-11 14:32:10 -0800913 try {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700914 return Token.tokenToActivityRecordLocked((Token)token);
Dianne Hackbornbe707852011-11-11 14:32:10 -0800915 } catch (ClassCastException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800916 Slog.w(TAG, "Bad activity token: " + token, e);
Dianne Hackbornbe707852011-11-11 14:32:10 -0800917 return null;
918 }
919 }
920
Riddle Hsuff9e8282019-04-24 23:55:11 +0800921 static boolean isResolverActivity(String className) {
922 return ResolverActivity.class.getName().equals(className);
923 }
924
Chong Zhang85ee6542015-10-02 13:36:38 -0700925 boolean isResolverActivity() {
Riddle Hsuff9e8282019-04-24 23:55:11 +0800926 return isResolverActivity(mActivityComponent.getClassName());
Craig Mautnerac6f8432013-07-17 13:24:59 -0700927 }
928
Patrick Baumann31426b22018-05-21 13:46:40 -0700929 boolean isResolverOrChildActivity() {
930 if (!"android".equals(packageName)) {
931 return false;
932 }
933 try {
934 return ResolverActivity.class.isAssignableFrom(
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800935 Object.class.getClassLoader().loadClass(mActivityComponent.getClassName()));
Patrick Baumann31426b22018-05-21 13:46:40 -0700936 } catch (ClassNotFoundException e) {
937 return false;
938 }
939 }
940
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700941 ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
942 int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage, Intent _intent,
943 String _resolvedType, ActivityInfo aInfo, Configuration _configuration,
944 ActivityRecord _resultTo, String _resultWho, int _reqCode, boolean _componentSpecified,
945 boolean _rootVoiceInteraction, ActivityStackSupervisor supervisor,
946 ActivityOptions options, ActivityRecord sourceRecord) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800947 mAtmService = _service;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800948 mRootActivityContainer = _service.mRootActivityContainer;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700949 appToken = new Token(this, _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950 info = aInfo;
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800951 launchedFromPid = _launchedFromPid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 launchedFromUid = _launchedFromUid;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800953 launchedFromPackage = _launchedFromPackage;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800954 mUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 intent = _intent;
956 shortComponentName = _intent.getComponent().flattenToShortString();
957 resolvedType = _resolvedType;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800958 componentSpecified = _componentSpecified;
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700959 rootVoiceInteraction = _rootVoiceInteraction;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700960 mLastReportedConfiguration = new MergedConfiguration(_configuration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 resultTo = _resultTo;
962 resultWho = _resultWho;
963 requestCode = _reqCode;
Bryce Lee7ace3952018-02-16 14:34:32 -0800964 setState(INITIALIZING, "ActivityRecord ctor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965 frontOfTask = false;
966 launchFailed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 stopped = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700968 delayedResume = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 finishing = false;
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800970 deferRelaunchUntilPaused = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 keysPaused = false;
972 inHistory = false;
Chong Zhanga48ef662015-08-18 19:21:47 -0700973 visible = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 nowVisible = false;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800975 mDrawn = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 idle = false;
977 hasBeenLaunched = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700978 mStackSupervisor = supervisor;
Robert Carr0f5d7532016-10-17 16:39:17 -0700979
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800980 // This starts out true, since the initial state of an activity is that we have everything,
981 // and we shouldn't never consider it lacking in state to be removed if it dies.
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700982 haveState = true;
983
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800984 // If the class name in the intent doesn't match that of the target, this is
985 // probably an alias. We have to create a new ComponentName object to keep track
986 // of the real activity name, so that FLAG_ACTIVITY_CLEAR_TOP is handled properly.
987 if (aInfo.targetActivity == null
988 || (aInfo.targetActivity.equals(_intent.getComponent().getClassName())
989 && (aInfo.launchMode == LAUNCH_MULTIPLE
990 || aInfo.launchMode == LAUNCH_SINGLE_TOP))) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800991 mActivityComponent = _intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800993 mActivityComponent = new ComponentName(aInfo.packageName, aInfo.targetActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800995 taskAffinity = aInfo.taskAffinity;
996 stateNotNeeded = (aInfo.flags & FLAG_STATE_NOT_NEEDED) != 0;
997 appInfo = aInfo.applicationInfo;
998 nonLocalizedLabel = aInfo.nonLocalizedLabel;
999 labelRes = aInfo.labelRes;
1000 if (nonLocalizedLabel == null && labelRes == 0) {
1001 ApplicationInfo app = aInfo.applicationInfo;
1002 nonLocalizedLabel = app.nonLocalizedLabel;
1003 labelRes = app.labelRes;
1004 }
1005 icon = aInfo.getIconResource();
1006 logo = aInfo.getLogoResource();
1007 theme = aInfo.getThemeResource();
1008 realTheme = theme;
1009 if (realTheme == 0) {
1010 realTheme = aInfo.applicationInfo.targetSdkVersion < HONEYCOMB
1011 ? android.R.style.Theme : android.R.style.Theme_Holo;
1012 }
1013 if ((aInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
1014 windowFlags |= LayoutParams.FLAG_HARDWARE_ACCELERATED;
1015 }
1016 if ((aInfo.flags & FLAG_MULTIPROCESS) != 0 && _caller != null
1017 && (aInfo.applicationInfo.uid == SYSTEM_UID
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001018 || aInfo.applicationInfo.uid == _caller.mInfo.uid)) {
1019 processName = _caller.mName;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001020 } else {
1021 processName = aInfo.processName;
1022 }
1023
1024 if ((aInfo.flags & FLAG_EXCLUDE_FROM_RECENTS) != 0) {
1025 intent.addFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
1026 }
1027
1028 packageName = aInfo.applicationInfo.packageName;
1029 launchMode = aInfo.launchMode;
1030
Ruben Brunkf53497c2017-03-27 20:26:17 -07001031 Entry ent = AttributeCache.instance().get(packageName,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001032 realTheme, com.android.internal.R.styleable.Window, mUserId);
Bryce Leee83f34cd2017-10-31 19:50:54 -07001033
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001034 if (ent != null) {
1035 fullscreen = !ActivityInfo.isTranslucentOrFloating(ent.array);
1036 hasWallpaper = ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
1037 noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
1038 } else {
1039 hasWallpaper = false;
1040 noDisplay = false;
1041 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001042
Winson Chung83471632016-12-13 11:02:12 -08001043 setActivityType(_componentSpecified, _launchedFromUid, _intent, options, sourceRecord);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001044
1045 immersive = (aInfo.flags & FLAG_IMMERSIVE) != 0;
1046
1047 requestedVrComponent = (aInfo.requestedVrComponent == null) ?
1048 null : ComponentName.unflattenFromString(aInfo.requestedVrComponent);
chaviw59b98852017-06-13 12:05:44 -07001049
1050 mShowWhenLocked = (aInfo.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
Issei Suzuki74e1eb22018-12-20 17:42:52 +01001051 mInheritShownWhenLocked = (aInfo.privateFlags & FLAG_INHERIT_SHOW_WHEN_LOCKED) != 0;
chaviw59b98852017-06-13 12:05:44 -07001052 mTurnScreenOn = (aInfo.flags & FLAG_TURN_SCREEN_ON) != 0;
Charles He2bf28322017-10-12 22:24:49 +01001053
1054 mRotationAnimationHint = aInfo.rotationAnimation;
1055 lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
1056 if (appInfo.isPrivilegedApp() && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
1057 || lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
1058 lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
1059 }
1060
1061 if (options != null) {
1062 pendingOptions = options;
1063 mLaunchTaskBehind = options.getLaunchTaskBehind();
1064
1065 final int rotationAnimation = pendingOptions.getRotationAnimationHint();
1066 // Only override manifest supplied option if set.
1067 if (rotationAnimation >= 0) {
1068 mRotationAnimationHint = rotationAnimation;
1069 }
1070 final PendingIntent usageReport = pendingOptions.getUsageTimeReport();
1071 if (usageReport != null) {
1072 appTimeTracker = new AppTimeTracker(usageReport);
1073 }
1074 final boolean useLockTask = pendingOptions.getLockTaskMode();
1075 if (useLockTask && lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_DEFAULT) {
1076 lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
1077 }
Louis Changd58cb672018-12-24 17:45:16 +08001078 // Gets launch display id from options. It returns INVALID_DISPLAY if not set.
1079 mHandoverLaunchDisplayId = options.getLaunchDisplayId();
Charles He2bf28322017-10-12 22:24:49 +01001080 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001081 }
1082
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001083 void setProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08001084 app = proc;
1085 final ActivityRecord root = task != null ? task.getRootActivity() : null;
1086 if (root == this) {
1087 task.setRootProcess(proc);
1088 }
1089 }
1090
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001091 boolean hasProcess() {
1092 return app != null;
1093 }
1094
1095 boolean attachedToProcess() {
1096 return hasProcess() && app.hasThread();
1097 }
1098
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001099 void createAppWindowToken() {
1100 if (mAppWindowToken != null) {
1101 throw new IllegalArgumentException("App Window Token=" + mAppWindowToken
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001102 + " already created for r=" + this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001103 }
1104
1105 inHistory = true;
1106
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001107 // TODO(b/36505427): Maybe this call should be moved inside updateOverrideConfiguration()
1108 task.updateOverrideConfigurationFromLaunchBounds();
1109 // Make sure override configuration is up-to-date before using to create window controller.
1110 updateOverrideConfiguration();
1111
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001112 // TODO: remove after unification
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001113 mAppWindowToken = mAtmService.mWindowManager.mRoot.getAppWindowToken(appToken.asBinder());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001114 if (mAppWindowToken != null) {
1115 // TODO: Should this throw an exception instead?
1116 Slog.w(TAG, "Attempted to add existing app token: " + appToken);
1117 } else {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001118 final Task container = task.getTask();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001119 if (container == null) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001120 throw new IllegalArgumentException("createAppWindowToken: invalid task =" + task);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001121 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001122 mAppWindowToken = createAppWindow(mAtmService.mWindowManager, appToken,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001123 task.voiceSession != null, container.getDisplayContent(),
1124 ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this)
1125 * 1000000L, fullscreen,
1126 (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, appInfo.targetSdkVersion,
Jorim Jaggi91d382a2019-03-27 17:00:48 +01001127 info.screenOrientation, mRotationAnimationHint,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001128 mLaunchTaskBehind, isAlwaysFocusable());
1129 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) {
1130 Slog.v(TAG, "addAppToken: "
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001131 + mAppWindowToken + " task=" + container + " at "
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001132 + Integer.MAX_VALUE);
1133 }
1134 container.addChild(mAppWindowToken, Integer.MAX_VALUE /* add on top */);
1135 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001136
1137 task.addActivityToTop(this);
1138
Winson Chung609e1e92017-05-08 10:52:12 -07001139 // When an activity is started directly into a split-screen fullscreen stack, we need to
1140 // update the initial multi-window modes so that the callbacks are scheduled correctly when
1141 // the user leaves that mode.
Bryce Leef3c6a472017-11-14 14:53:06 -08001142 mLastReportedMultiWindowMode = inMultiWindowMode();
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001143 mLastReportedPictureInPictureMode = inPinnedWindowingMode();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001144 }
1145
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001146 boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
1147 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
1148 IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
1149 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
1150 if (DEBUG_STARTING_WINDOW) {
1151 Slog.v(TAG, "setAppStartingWindow: token=" + appToken
1152 + " pkg=" + pkg + " transferFrom=" + transferFrom + " newTask=" + newTask
1153 + " taskSwitch=" + taskSwitch + " processRunning=" + processRunning
1154 + " allowTaskSnapshot=" + allowTaskSnapshot);
1155 }
1156 if (mAppWindowToken == null) {
1157 Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + appToken);
1158 return false;
1159 }
Yunfan Chen48c0ed082018-12-05 18:15:35 -08001160 if (mAppWindowToken.getTask() == null) {
1161 // Can be removed after unification of Task and TaskRecord.
1162 Slog.w(TAG_WM, "Attempted to start a window to an app token not having attached to any"
1163 + " task: " + appToken);
1164 return false;
1165 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001166 return mAppWindowToken.addStartingWindow(pkg, theme, compatInfo, nonLocalizedLabel,
1167 labelRes, icon, logo, windowFlags, transferFrom, newTask, taskSwitch,
1168 processRunning, allowTaskSnapshot, activityCreated, fromRecents);
1169 }
1170
1171 // TODO: Remove after unification
1172 @VisibleForTesting
1173 AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
1174 boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
1175 boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
Jorim Jaggi91d382a2019-03-27 17:00:48 +01001176 int rotationAnimationHint, boolean launchTaskBehind,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001177 boolean alwaysFocusable) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001178 return new AppWindowToken(service, token, mActivityComponent, voiceInteraction, dc,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001179 inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation,
Jorim Jaggi91d382a2019-03-27 17:00:48 +01001180 rotationAnimationHint, launchTaskBehind, alwaysFocusable,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001181 this);
1182 }
1183
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001184 void removeWindowContainer() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001185 if (mAtmService.mWindowManager.mRoot == null) return;
Yunfan Chend4ef3012018-11-28 21:14:32 -08001186
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001187 final DisplayContent dc = mAtmService.mWindowManager.mRoot.getDisplayContent(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001188 getDisplayId());
1189 if (dc == null) {
1190 Slog.w(TAG, "removeWindowContainer: Attempted to remove token: "
1191 + appToken + " from non-existing displayId=" + getDisplayId());
Bryce Lee7ace3952018-02-16 14:34:32 -08001192 return;
1193 }
Wale Ogunwalecc367f42017-02-01 08:12:14 -08001194 // Resume key dispatching if it is currently paused before we remove the container.
1195 resumeKeyDispatchingLocked();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001196 dc.removeAppToken(appToken.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001197 }
1198
Winson Chung30480042017-01-26 10:55:34 -08001199 /**
1200 * Reparents this activity into {@param newTask} at the provided {@param position}. The caller
1201 * should ensure that the {@param newTask} is not already the parent of this activity.
1202 */
1203 void reparent(TaskRecord newTask, int position, String reason) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001204 if (mAppWindowToken == null) {
1205 Slog.w(TAG, "reparent: Attempted to reparent non-existing app token: " + appToken);
1206 return;
1207 }
Winson Chung30480042017-01-26 10:55:34 -08001208 final TaskRecord prevTask = task;
1209 if (prevTask == newTask) {
1210 throw new IllegalArgumentException(reason + ": task=" + newTask
1211 + " is already the parent of r=" + this);
1212 }
1213
Winson Chung74666102017-02-22 17:49:24 -08001214 // TODO: Ensure that we do not directly reparent activities across stacks, as that may leave
1215 // the stacks in strange states. For now, we should use Task.reparent() to ensure that
1216 // the stack is left in an OK state.
1217 if (prevTask != null && newTask != null && prevTask.getStack() != newTask.getStack()) {
1218 throw new IllegalArgumentException(reason + ": task=" + newTask
1219 + " is in a different stack (" + newTask.getStackId() + ") than the parent of"
1220 + " r=" + this + " (" + prevTask.getStackId() + ")");
1221 }
1222
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001223 mAppWindowToken.reparent(newTask.getTask(), position);
Winson Chung30480042017-01-26 10:55:34 -08001224
Bryce Lee84730a02018-04-03 14:10:04 -07001225 // Reparenting prevents informing the parent stack of activity removal in the case that
1226 // the new stack has the same parent. we must manually signal here if this is not the case.
1227 final ActivityStack prevStack = prevTask.getStack();
1228
1229 if (prevStack != newTask.getStack()) {
1230 prevStack.onActivityRemovedFromStack(this);
1231 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001232 // Remove the activity from the old task and add it to the new task.
Bryce Lee84730a02018-04-03 14:10:04 -07001233 prevTask.removeActivity(this, true /* reparenting */);
Bryce Lee0f9bde82017-02-22 16:39:06 -08001234
Winson Chung30480042017-01-26 10:55:34 -08001235 newTask.addActivityAtIndex(position, this);
1236 }
1237
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001238 private boolean isHomeIntent(Intent intent) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001239 return ACTION_MAIN.equals(intent.getAction())
Chilun2ef71f72018-11-16 17:57:15 +08001240 && (intent.hasCategory(CATEGORY_HOME)
1241 || intent.hasCategory(CATEGORY_SECONDARY_HOME))
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001242 && intent.getCategories().size() == 1
1243 && intent.getData() == null
1244 && intent.getType() == null;
1245 }
1246
Chong Zhangad24f962016-08-25 12:12:33 -07001247 static boolean isMainIntent(Intent intent) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001248 return ACTION_MAIN.equals(intent.getAction())
1249 && intent.hasCategory(CATEGORY_LAUNCHER)
Chong Zhangad24f962016-08-25 12:12:33 -07001250 && intent.getCategories().size() == 1
1251 && intent.getData() == null
1252 && intent.getType() == null;
1253 }
1254
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001255 private boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
1256 if (uid == Process.myUid() || uid == 0) {
1257 // System process can launch home activity.
1258 return true;
1259 }
Winson Chung547afd22018-05-17 16:03:25 -07001260 // Allow the recents component to launch the home activity.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001261 final RecentTasks recentTasks = mStackSupervisor.mService.getRecentTasks();
Winson Chung547afd22018-05-17 16:03:25 -07001262 if (recentTasks != null && recentTasks.isCallerRecents(uid)) {
1263 return true;
1264 }
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001265 // Resolver activity can launch home activity.
1266 return sourceRecord != null && sourceRecord.isResolverActivity();
1267 }
1268
Winson Chung83471632016-12-13 11:02:12 -08001269 /**
1270 * @return whether the given package name can launch an assist activity.
1271 */
1272 private boolean canLaunchAssistActivity(String packageName) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001273 final ComponentName assistComponent =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001274 mAtmService.mActiveVoiceInteractionServiceComponent;
Winson Chung83471632016-12-13 11:02:12 -08001275 if (assistComponent != null) {
1276 return assistComponent.getPackageName().equals(packageName);
1277 }
1278 return false;
1279 }
1280
1281 private void setActivityType(boolean componentSpecified, int launchedFromUid, Intent intent,
1282 ActivityOptions options, ActivityRecord sourceRecord) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001283 int activityType = ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001284 if ((!componentSpecified || canLaunchHomeActivity(launchedFromUid, sourceRecord))
1285 && isHomeIntent(intent) && !isResolverActivity()) {
1286 // This sure looks like a home activity!
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001287 activityType = ACTIVITY_TYPE_HOME;
Wale Ogunwaledf241e92016-10-13 15:14:21 -07001288
1289 if (info.resizeMode == RESIZE_MODE_FORCE_RESIZEABLE
1290 || info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
1291 // We only allow home activities to be resizeable if they explicitly requested it.
1292 info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
1293 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001294 } else if (mActivityComponent.getClassName().contains(LEGACY_RECENTS_PACKAGE_NAME)
1295 || mAtmService.getRecentTasks().isRecentsComponent(mActivityComponent, appInfo.uid)) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001296 activityType = ACTIVITY_TYPE_RECENTS;
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001297 } else if (options != null && options.getLaunchActivityType() == ACTIVITY_TYPE_ASSISTANT
Winson Chung83471632016-12-13 11:02:12 -08001298 && canLaunchAssistActivity(launchedFromPackage)) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001299 activityType = ACTIVITY_TYPE_ASSISTANT;
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001300 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001301 setActivityType(activityType);
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001302 }
1303
Craig Mautnera228ae92014-07-09 05:44:55 -07001304 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001305 if (launchMode != LAUNCH_SINGLE_INSTANCE && launchMode != LAUNCH_SINGLE_TASK) {
Craig Mautnera228ae92014-07-09 05:44:55 -07001306 task.setTaskToAffiliateWith(taskToAffiliateWith);
1307 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001308 }
1309
Andrii Kulian02b7a832016-10-06 23:11:56 -07001310 /**
1311 * @return Stack value from current task, null if there is no task.
1312 */
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001313 <T extends ActivityStack> T getActivityStack() {
Winson Chung55893332017-02-17 17:13:10 -08001314 return task != null ? (T) task.getStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001315 }
1316
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001317 int getStackId() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001318 return getActivityStack() != null ? getActivityStack().mStackId : INVALID_STACK_ID;
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001319 }
1320
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001321 ActivityDisplay getDisplay() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001322 final ActivityStack stack = getActivityStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001323 return stack != null ? stack.getDisplay() : null;
1324 }
1325
Craig Mautner5eda9b32013-07-02 11:58:16 -07001326 boolean changeWindowTranslucency(boolean toOpaque) {
1327 if (fullscreen == toOpaque) {
1328 return false;
1329 }
Craig Mautner4addfc52013-06-25 08:05:45 -07001330
Craig Mautner5eda9b32013-07-02 11:58:16 -07001331 // Keep track of the number of fullscreen activities in this task.
1332 task.numFullscreen += toOpaque ? +1 : -1;
1333
1334 fullscreen = toOpaque;
1335 return true;
Craig Mautner4addfc52013-06-25 08:05:45 -07001336 }
1337
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001338 void takeFromHistory() {
1339 if (inHistory) {
1340 inHistory = false;
1341 if (task != null && !finishing) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001342 task = null;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001343 }
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -07001344 clearOptionsLocked();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001345 }
1346 }
1347
1348 boolean isInHistory() {
1349 return inHistory;
1350 }
1351
Wale Ogunwale7d701172015-03-11 15:36:30 -07001352 boolean isInStackLocked() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001353 final ActivityStack stack = getActivityStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001354 return stack != null && stack.isInStackLocked(this) != null;
Wale Ogunwale7d701172015-03-11 15:36:30 -07001355 }
1356
Craig Mautner21d24a22014-04-23 11:45:37 -07001357 boolean isPersistable() {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001358 return (info.persistableMode == PERSIST_ROOT_ONLY ||
1359 info.persistableMode == PERSIST_ACROSS_REBOOTS) &&
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001360 (intent == null || (intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
Craig Mautner21d24a22014-04-23 11:45:37 -07001361 }
1362
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08001363 boolean isFocusable() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001364 return mRootActivityContainer.isFocusable(this, isAlwaysFocusable());
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001365 }
1366
1367 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001368 return ActivityInfo.isResizeableMode(info.resizeMode) || info.supportsPictureInPicture();
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001369 }
1370
Winson Chungd3395382016-12-13 11:49:09 -08001371 /**
1372 * @return whether this activity is non-resizeable or forced to be resizeable
1373 */
1374 boolean isNonResizableOrForcedResizable() {
Wale Ogunwaledf241e92016-10-13 15:14:21 -07001375 return info.resizeMode != RESIZE_MODE_RESIZEABLE
Wale Ogunwale72a73e32016-10-13 12:16:39 -07001376 && info.resizeMode != RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Jorim Jaggicd13d332016-04-27 15:40:20 -07001377 }
1378
Winson Chunge6308042016-10-31 09:24:01 -07001379 /**
Winson Chungd3395382016-12-13 11:49:09 -08001380 * @return whether this activity supports PiP multi-window and can be put in the pinned stack.
Winson Chunge6308042016-10-31 09:24:01 -07001381 */
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001382 boolean supportsPictureInPicture() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001383 return mAtmService.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
Winson Chungd3395382016-12-13 11:49:09 -08001384 && info.supportsPictureInPicture();
1385 }
1386
1387 /**
1388 * @return whether this activity supports split-screen multi-window and can be put in the docked
1389 * stack.
1390 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001391 @Override
1392 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001393 // An activity can not be docked even if it is considered resizeable because it only
1394 // supports picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001395 return super.supportsSplitScreenWindowingMode()
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001396 && mAtmService.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow();
Winson Chungd3395382016-12-13 11:49:09 -08001397 }
1398
1399 /**
1400 * @return whether this activity supports freeform multi-window and can be put in the freeform
1401 * stack.
1402 */
1403 boolean supportsFreeform() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001404 return mAtmService.mSupportsFreeformWindowManagement && supportsResizeableMultiWindow();
Winson Chungd3395382016-12-13 11:49:09 -08001405 }
1406
1407 /**
1408 * @return whether this activity supports non-PiP multi-window.
1409 */
1410 private boolean supportsResizeableMultiWindow() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001411 return mAtmService.mSupportsMultiWindow && !isActivityTypeHome()
Winson Chungd3395382016-12-13 11:49:09 -08001412 && (ActivityInfo.isResizeableMode(info.resizeMode)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001413 || mAtmService.mForceResizableActivities);
Wale Ogunwaled26176f2016-01-25 20:04:04 -08001414 }
1415
Winson Chunge6308042016-10-31 09:24:01 -07001416 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001417 * Check whether this activity can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001418 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001419 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001420 * @return {@code true} if either it is the default display or this activity can be put on a
1421 * secondary screen.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001422 */
1423 boolean canBeLaunchedOnDisplay(int displayId) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001424 return mAtmService.mStackSupervisor.canPlaceEntityOnDisplay(displayId, launchedFromPid,
Riddle Hsu16567132018-08-16 21:37:47 +08001425 launchedFromUid, info);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001426 }
1427
1428 /**
Robert Carrc33658e2017-04-11 18:24:20 -07001429 * @param beforeStopping Whether this check is for an auto-enter-pip operation, that is to say
1430 * the activity has requested to enter PiP when it would otherwise be stopped.
1431 *
Winson Chung298f95b2017-08-10 15:57:18 -07001432 * @return whether this activity is currently allowed to enter PIP.
Winson Chunge6308042016-10-31 09:24:01 -07001433 */
Winson Chung298f95b2017-08-10 15:57:18 -07001434 boolean checkEnterPictureInPictureState(String caller, boolean beforeStopping) {
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07001435 if (!supportsPictureInPicture()) {
1436 return false;
1437 }
1438
Winson Chungf4ac0632017-03-17 12:34:12 -07001439 // Check app-ops and see if PiP is supported for this package
1440 if (!checkEnterPictureInPictureAppOpsState()) {
1441 return false;
1442 }
1443
Winson Chungf1bfee12017-03-24 17:11:33 -07001444 // Check to see if we are in VR mode, and disallow PiP if so
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001445 if (mAtmService.shouldDisableNonVrUiLocked()) {
Winson Chungf1bfee12017-03-24 17:11:33 -07001446 return false;
1447 }
1448
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001449 boolean isKeyguardLocked = mAtmService.isKeyguardLocked();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001450 boolean isCurrentAppLocked =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001451 mAtmService.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001452 final ActivityDisplay display = getDisplay();
1453 boolean hasPinnedStack = display != null && display.hasPinnedStack();
Winson Chungbb348802017-01-30 12:01:45 -08001454 // Don't return early if !isNotLocked, since we want to throw an exception if the activity
1455 // is in an incorrect state
Winson Chunge581ebf2017-02-21 08:25:03 -08001456 boolean isNotLockedOrOnKeyguard = !isKeyguardLocked && !isCurrentAppLocked;
Robert Carrc33658e2017-04-11 18:24:20 -07001457
1458 // We don't allow auto-PiP when something else is already pipped.
1459 if (beforeStopping && hasPinnedStack) {
1460 return false;
1461 }
1462
Bryce Lee7ace3952018-02-16 14:34:32 -08001463 switch (mState) {
Winson Chungc2baac02017-01-11 13:34:47 -08001464 case RESUMED:
Winson Chunge581ebf2017-02-21 08:25:03 -08001465 // When visible, allow entering PiP if the app is not locked. If it is over the
1466 // keyguard, then we will prompt to unlock in the caller before entering PiP.
Robert Carrc33658e2017-04-11 18:24:20 -07001467 return !isCurrentAppLocked &&
Winson Chungf7e03e12017-08-22 11:32:16 -07001468 (supportsEnterPipOnTaskSwitch || !beforeStopping);
Winson Chungc2baac02017-01-11 13:34:47 -08001469 case PAUSING:
1470 case PAUSED:
Winson Chungbb348802017-01-30 12:01:45 -08001471 // When pausing, then only allow enter PiP as in the resume state, and in addition,
1472 // require that there is not an existing PiP activity and that the current system
1473 // state supports entering PiP
Winson Chunge581ebf2017-02-21 08:25:03 -08001474 return isNotLockedOrOnKeyguard && !hasPinnedStack
Winson Chungf7e03e12017-08-22 11:32:16 -07001475 && supportsEnterPipOnTaskSwitch;
Winson Chungc2baac02017-01-11 13:34:47 -08001476 case STOPPING:
1477 // When stopping in a valid state, then only allow enter PiP as in the pause state.
1478 // Otherwise, fall through to throw an exception if the caller is trying to enter
1479 // PiP in an invalid stopping state.
Winson Chungf7e03e12017-08-22 11:32:16 -07001480 if (supportsEnterPipOnTaskSwitch) {
Winson Chungf4ac0632017-03-17 12:34:12 -07001481 return isNotLockedOrOnKeyguard && !hasPinnedStack;
Winson Chungc2baac02017-01-11 13:34:47 -08001482 }
1483 default:
Winson Chung298f95b2017-08-10 15:57:18 -07001484 return false;
Winson Chungb5c41b72016-12-07 15:00:47 -08001485 }
Winson Chunge6308042016-10-31 09:24:01 -07001486 }
1487
Winson Chung59fda9e2017-01-20 16:14:51 -08001488 /**
Winson Chungf4ac0632017-03-17 12:34:12 -07001489 * @return Whether AppOps allows this package to enter picture-in-picture.
Winson Chung59fda9e2017-01-20 16:14:51 -08001490 */
Winson Chungf4ac0632017-03-17 12:34:12 -07001491 private boolean checkEnterPictureInPictureAppOpsState() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001492 return mAtmService.getAppOpsService().checkOperation(
Wale Ogunwalef6733932018-06-27 05:14:34 -07001493 OP_PICTURE_IN_PICTURE, appInfo.uid, packageName) == MODE_ALLOWED;
Winson Chung59fda9e2017-01-20 16:14:51 -08001494 }
1495
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001496 boolean isAlwaysFocusable() {
1497 return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08001498 }
1499
Louis Chang19443452018-10-09 12:10:21 +08001500 /** Move activity with its stack to front and make the stack focused. */
1501 boolean moveFocusableActivityToTop(String reason) {
1502 if (!isFocusable()) {
1503 if (DEBUG_FOCUS) {
1504 Slog.d(TAG_FOCUS, "moveActivityStackToFront: unfocusable activity=" + this);
1505 }
1506 return false;
1507 }
1508
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001509 final TaskRecord task = getTaskRecord();
1510 final ActivityStack stack = getActivityStack();
Louis Chang19443452018-10-09 12:10:21 +08001511 if (stack == null) {
1512 Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: activity="
1513 + this + " task=" + task);
1514 return false;
1515 }
1516
Wale Ogunwaled32da472018-11-16 07:19:28 -08001517 if (mRootActivityContainer.getTopResumedActivity() == this) {
Louis Chang19443452018-10-09 12:10:21 +08001518 if (DEBUG_FOCUS) {
1519 Slog.d(TAG_FOCUS, "moveActivityStackToFront: already on top, activity=" + this);
1520 }
1521 return false;
1522 }
1523
1524 if (DEBUG_FOCUS) {
1525 Slog.d(TAG_FOCUS, "moveActivityStackToFront: activity=" + this);
1526 }
1527
1528 stack.moveToFront(reason, task);
1529 // Report top activity change to tracking services and WM
Wale Ogunwaled32da472018-11-16 07:19:28 -08001530 if (mRootActivityContainer.getTopResumedActivity() == this) {
Louis Chang19443452018-10-09 12:10:21 +08001531 // TODO(b/111361570): Support multiple focused apps in WM
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001532 mAtmService.setResumedActivityUncheckLocked(this, reason);
Louis Chang19443452018-10-09 12:10:21 +08001533 }
1534 return true;
1535 }
Jorim Jaggife762342016-10-13 14:33:27 +02001536
Wale Ogunwale7d701172015-03-11 15:36:30 -07001537 void makeFinishingLocked() {
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001538 if (finishing) {
1539 return;
1540 }
1541 finishing = true;
1542 if (stopped) {
1543 clearOptionsLocked();
1544 }
Yorke Leebd54c2a2016-10-25 13:49:23 -07001545
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001546 if (mAtmService != null) {
1547 mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08001548 }
1549 }
1550
Dianne Hackborn7e269642010-08-25 19:50:20 -07001551 UriPermissionOwner getUriPermissionsLocked() {
1552 if (uriPermissions == null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001553 uriPermissions = new UriPermissionOwner(mAtmService.mUgmInternal, this);
Dianne Hackborn7e269642010-08-25 19:50:20 -07001554 }
1555 return uriPermissions;
1556 }
1557
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001558 void addResultLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 int requestCode, int resultCode,
1560 Intent resultData) {
1561 ActivityResult r = new ActivityResult(from, resultWho,
John Spurlock8a985d22014-02-25 09:40:05 -05001562 requestCode, resultCode, resultData);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 if (results == null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001564 results = new ArrayList<ResultInfo>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 }
1566 results.add(r);
1567 }
1568
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001569 void removeResultsLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 int requestCode) {
1571 if (results != null) {
1572 for (int i=results.size()-1; i>=0; i--) {
1573 ActivityResult r = (ActivityResult)results.get(i);
1574 if (r.mFrom != from) continue;
1575 if (r.mResultWho == null) {
1576 if (resultWho != null) continue;
1577 } else {
1578 if (!r.mResultWho.equals(resultWho)) continue;
1579 }
1580 if (r.mRequestCode != requestCode) continue;
1581
1582 results.remove(i);
1583 }
1584 }
1585 }
1586
Andrii Kulian21713ac2016-10-12 22:05:05 -07001587 private void addNewIntentLocked(ReferrerIntent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001588 if (newIntents == null) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001589 newIntents = new ArrayList<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001590 }
1591 newIntents.add(intent);
1592 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001593
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001594 final boolean isSleeping() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001595 final ActivityStack stack = getActivityStack();
1596 return stack != null ? stack.shouldSleepActivities() : mAtmService.isSleepingLocked();
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001597 }
1598
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001599 /**
1600 * Deliver a new Intent to an existing activity, so that its onNewIntent()
1601 * method will be called at the proper time.
1602 */
Jeff Sharkey344ce7c2019-05-29 14:52:59 -06001603 final void deliverNewIntentLocked(int callingUid, Intent intent, NeededUriGrants intentGrants,
1604 String referrer) {
Dianne Hackborn514074f2013-02-11 10:52:46 -08001605 // The activity now gets access to the data associated with this Intent.
Jeff Sharkey344ce7c2019-05-29 14:52:59 -06001606 mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
1607 getUriPermissionsLocked());
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001608 final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
Craig Mautner86d67a42013-05-14 10:34:38 -07001609 boolean unsent = true;
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001610 final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping();
Wale Ogunwale826c7062016-09-13 08:25:54 -07001611
1612 // We want to immediately deliver the intent to the activity if:
Wale Ogunwale03f7e9e2016-09-22 09:04:09 -07001613 // - It is currently resumed or paused. i.e. it is currently visible to the user and we want
1614 // the user to see the visual effects caused by the intent delivery now.
Wale Ogunwale826c7062016-09-13 08:25:54 -07001615 // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001616 if ((mState == RESUMED || mState == PAUSED || isTopActivityWhileSleeping)
1617 && attachedToProcess()) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001618 try {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001619 ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
1620 ar.add(rintent);
Louis Chang92d16522019-02-27 12:56:18 +08001621 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
1622 NewIntentItem.obtain(ar));
Craig Mautner86d67a42013-05-14 10:34:38 -07001623 unsent = false;
Dianne Hackborn39792d22010-08-19 18:01:52 -07001624 } catch (RemoteException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001625 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
Dianne Hackborn39792d22010-08-19 18:01:52 -07001626 } catch (NullPointerException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001627 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001628 }
1629 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001630 if (unsent) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001631 addNewIntentLocked(rintent);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001632 }
1633 }
1634
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001635 void updateOptionsLocked(ActivityOptions options) {
1636 if (options != null) {
Jorim Jaggi346702a2019-05-08 17:49:33 +02001637 if (DEBUG_TRANSITION) Slog.i(TAG, "Update options for " + this);
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001638 if (pendingOptions != null) {
1639 pendingOptions.abort();
1640 }
1641 pendingOptions = options;
1642 }
1643 }
1644
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001645 void applyOptionsLocked() {
George Mount2c92c972014-03-20 09:38:23 -07001646 if (pendingOptions != null
Ruben Brunkf53497c2017-03-27 20:26:17 -07001647 && pendingOptions.getAnimationType() != ANIM_SCENE_TRANSITION) {
Jorim Jaggi346702a2019-05-08 17:49:33 +02001648 if (DEBUG_TRANSITION) Slog.i(TAG, "Applying options for " + this);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001649 applyOptionsLocked(pendingOptions, intent);
chaviw82a0ba82018-03-15 14:26:29 -07001650 if (task == null) {
1651 clearOptionsLocked(false /* withAbort */);
1652 } else {
1653 // This will clear the options for all the ActivityRecords for this Task.
1654 task.clearAllPendingOptions();
1655 }
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001656 }
1657 }
1658
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001659 /**
1660 * Apply override app transition base on options & animation type.
1661 */
1662 void applyOptionsLocked(ActivityOptions pendingOptions, Intent intent) {
1663 final int animationType = pendingOptions.getAnimationType();
1664 final DisplayContent displayContent = mAppWindowToken.getDisplayContent();
1665 switch (animationType) {
1666 case ANIM_CUSTOM:
1667 displayContent.mAppTransition.overridePendingAppTransition(
1668 pendingOptions.getPackageName(),
1669 pendingOptions.getCustomEnterResId(),
1670 pendingOptions.getCustomExitResId(),
1671 pendingOptions.getOnAnimationStartListener());
1672 break;
1673 case ANIM_CLIP_REVEAL:
1674 displayContent.mAppTransition.overridePendingAppTransitionClipReveal(
1675 pendingOptions.getStartX(), pendingOptions.getStartY(),
1676 pendingOptions.getWidth(), pendingOptions.getHeight());
1677 if (intent.getSourceBounds() == null) {
1678 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1679 pendingOptions.getStartY(),
1680 pendingOptions.getStartX() + pendingOptions.getWidth(),
1681 pendingOptions.getStartY() + pendingOptions.getHeight()));
1682 }
1683 break;
1684 case ANIM_SCALE_UP:
1685 displayContent.mAppTransition.overridePendingAppTransitionScaleUp(
1686 pendingOptions.getStartX(), pendingOptions.getStartY(),
1687 pendingOptions.getWidth(), pendingOptions.getHeight());
1688 if (intent.getSourceBounds() == null) {
1689 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1690 pendingOptions.getStartY(),
1691 pendingOptions.getStartX() + pendingOptions.getWidth(),
1692 pendingOptions.getStartY() + pendingOptions.getHeight()));
1693 }
1694 break;
1695 case ANIM_THUMBNAIL_SCALE_UP:
1696 case ANIM_THUMBNAIL_SCALE_DOWN:
1697 final boolean scaleUp = (animationType == ANIM_THUMBNAIL_SCALE_UP);
1698 final GraphicBuffer buffer = pendingOptions.getThumbnail();
1699 displayContent.mAppTransition.overridePendingAppTransitionThumb(buffer,
1700 pendingOptions.getStartX(), pendingOptions.getStartY(),
1701 pendingOptions.getOnAnimationStartListener(),
1702 scaleUp);
1703 if (intent.getSourceBounds() == null && buffer != null) {
1704 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1705 pendingOptions.getStartY(),
1706 pendingOptions.getStartX() + buffer.getWidth(),
1707 pendingOptions.getStartY() + buffer.getHeight()));
1708 }
1709 break;
1710 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
1711 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
1712 final AppTransitionAnimationSpec[] specs = pendingOptions.getAnimSpecs();
1713 final IAppTransitionAnimationSpecsFuture specsFuture =
1714 pendingOptions.getSpecsFuture();
1715 if (specsFuture != null) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001716 displayContent.mAppTransition.overridePendingAppTransitionMultiThumbFuture(
1717 specsFuture, pendingOptions.getOnAnimationStartListener(),
1718 animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP);
1719 } else if (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
1720 && specs != null) {
1721 displayContent.mAppTransition.overridePendingAppTransitionMultiThumb(
1722 specs, pendingOptions.getOnAnimationStartListener(),
1723 pendingOptions.getAnimationFinishedListener(), false);
1724 } else {
1725 displayContent.mAppTransition.overridePendingAppTransitionAspectScaledThumb(
1726 pendingOptions.getThumbnail(),
1727 pendingOptions.getStartX(), pendingOptions.getStartY(),
1728 pendingOptions.getWidth(), pendingOptions.getHeight(),
1729 pendingOptions.getOnAnimationStartListener(),
1730 (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP));
1731 if (intent.getSourceBounds() == null) {
1732 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1733 pendingOptions.getStartY(),
1734 pendingOptions.getStartX() + pendingOptions.getWidth(),
1735 pendingOptions.getStartY() + pendingOptions.getHeight()));
1736 }
1737 }
1738 break;
1739 case ANIM_OPEN_CROSS_PROFILE_APPS:
1740 displayContent.mAppTransition
1741 .overridePendingAppTransitionStartCrossProfileApps();
1742 break;
1743 case ANIM_REMOTE_ANIMATION:
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001744 displayContent.mAppTransition.overridePendingAppTransitionRemote(
1745 pendingOptions.getRemoteAnimationAdapter());
1746 break;
1747 case ANIM_NONE:
1748 break;
1749 default:
1750 Slog.e(TAG_WM, "applyOptionsLocked: Unknown animationType=" + animationType);
1751 break;
1752 }
1753 }
1754
Adam Powellcfbe9be2013-11-06 14:58:58 -08001755 ActivityOptions getOptionsForTargetActivityLocked() {
1756 return pendingOptions != null ? pendingOptions.forTargetActivity() : null;
1757 }
1758
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001759 void clearOptionsLocked() {
chaviw82a0ba82018-03-15 14:26:29 -07001760 clearOptionsLocked(true /* withAbort */);
1761 }
1762
1763 void clearOptionsLocked(boolean withAbort) {
1764 if (withAbort && pendingOptions != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001765 pendingOptions.abort();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001766 }
chaviw82a0ba82018-03-15 14:26:29 -07001767 pendingOptions = null;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001768 }
1769
Jorim Jaggi346702a2019-05-08 17:49:33 +02001770 ActivityOptions takeOptionsLocked(boolean fromClient) {
1771 if (DEBUG_TRANSITION) Slog.i(TAG, "Taking options for " + this + " callers="
1772 + Debug.getCallers(6));
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001773 ActivityOptions opts = pendingOptions;
Jorim Jaggi346702a2019-05-08 17:49:33 +02001774
1775 // If we are trying to take activity options from the client, do not null it out if it's a
1776 // remote animation as the client doesn't need it ever. This is a workaround when client is
1777 // faster to take the options than we are to resume the next activity.
1778 // TODO (b/132432864): Fix the root cause of these transition preparing/applying options
1779 // timing somehow
1780 if (!fromClient || opts == null || opts.getRemoteAnimationAdapter() == null) {
1781 pendingOptions = null;
1782 }
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001783 return opts;
1784 }
1785
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001786 void removeUriPermissionsLocked() {
Dianne Hackborn7e269642010-08-25 19:50:20 -07001787 if (uriPermissions != null) {
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07001788 uriPermissions.removeUriPermissions();
Dianne Hackborn7e269642010-08-25 19:50:20 -07001789 uriPermissions = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001790 }
1791 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001792
1793 void pauseKeyDispatchingLocked() {
1794 if (!keysPaused) {
1795 keysPaused = true;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001796
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001797 // TODO: remove the check after unification with AppWindowToken. The DC check is not
1798 // needed after no mock mAppWindowToken in tests.
1799 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
1800 mAppWindowToken.getDisplayContent().getInputMonitor().pauseDispatchingLw(
1801 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07001802 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001803 }
1804 }
1805
1806 void resumeKeyDispatchingLocked() {
1807 if (keysPaused) {
1808 keysPaused = false;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001809
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001810 // TODO: remove the check after unification with AppWindowToken. The DC check is not
1811 // needed after no mock mAppWindowToken in tests.
1812 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
1813 mAppWindowToken.getDisplayContent().getInputMonitor().resumeDispatchingLw(
1814 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07001815 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 }
1817 }
1818
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001819 private void updateTaskDescription(CharSequence description) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001820 task.lastDescription = description;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001821 }
1822
Wale Ogunwaleec950642017-04-25 07:44:21 -07001823 void setDeferHidingClient(boolean deferHidingClient) {
1824 if (mDeferHidingClient == deferHidingClient) {
1825 return;
1826 }
1827 mDeferHidingClient = deferHidingClient;
1828 if (!mDeferHidingClient && !visible) {
1829 // Hiding the client is no longer deferred and the app isn't visible still, go ahead and
1830 // update the visibility.
1831 setVisibility(false);
1832 }
Wale Ogunwale89973222017-04-23 18:39:45 -07001833 }
1834
Wale Ogunwaleec950642017-04-25 07:44:21 -07001835 void setVisibility(boolean visible) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001836 if (mAppWindowToken == null) {
1837 Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: "
1838 + appToken);
1839 return;
1840 }
1841 mAppWindowToken.setVisibility(visible, mDeferHidingClient);
Bryce Lee2a3cc462017-10-27 10:57:35 -07001842 mStackSupervisor.getActivityMetricsLogger().notifyVisibilityChanged(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001843 }
1844
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001845 // TODO: Look into merging with #commitVisibility()
Wale Ogunwaleec950642017-04-25 07:44:21 -07001846 void setVisible(boolean newVisible) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001847 visible = newVisible;
Wale Ogunwaleec950642017-04-25 07:44:21 -07001848 mDeferHidingClient = !visible && mDeferHidingClient;
Wale Ogunwaleec950642017-04-25 07:44:21 -07001849 setVisibility(visible);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001850 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
1851 }
1852
Bryce Lee7ace3952018-02-16 14:34:32 -08001853 void setState(ActivityState state, String reason) {
1854 if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState()
1855 + " to:" + state + " reason:" + reason);
Bryce Lee6ff17072018-02-28 07:26:17 -08001856
Bryce Leeb0f993f2018-03-02 15:38:01 -08001857 if (state == mState) {
1858 // No need to do anything if state doesn't change.
1859 if (DEBUG_STATES) Slog.v(TAG_STATES, "State unchanged from:" + state);
1860 return;
1861 }
1862
Bryce Leeb0f993f2018-03-02 15:38:01 -08001863 mState = state;
1864
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001865 final TaskRecord parent = getTaskRecord();
Bryce Leec4ab62a2018-03-05 14:19:26 -08001866
1867 if (parent != null) {
1868 parent.onActivityStateChanged(this, state, reason);
1869 }
Robert Carr29daa922018-04-27 11:56:48 -07001870
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001871 // The WindowManager interprets the app stopping signal as
1872 // an indication that the Surface will eventually be destroyed.
1873 // This however isn't necessarily true if we are going to sleep.
1874 if (state == STOPPING && !isSleeping()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001875 if (mAppWindowToken == null) {
1876 Slog.w(TAG_WM, "Attempted to notify stopping on non-existing app token: "
1877 + appToken);
1878 return;
1879 }
1880 mAppWindowToken.detachChildren();
Robert Carr29daa922018-04-27 11:56:48 -07001881 }
Hui Yu03d12402018-12-06 18:00:37 -08001882
1883 if (state == RESUMED) {
1884 mAtmService.updateBatteryStats(this, true);
1885 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_RESUMED);
1886 } else if (state == PAUSED) {
1887 mAtmService.updateBatteryStats(this, false);
1888 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_PAUSED);
1889 } else if (state == STOPPED) {
1890 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_STOPPED);
1891 } else if (state == DESTROYED) {
1892 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_DESTROYED);
1893 }
Bryce Lee7ace3952018-02-16 14:34:32 -08001894 }
1895
1896 ActivityState getState() {
1897 return mState;
1898 }
1899
1900 /**
1901 * Returns {@code true} if the Activity is in the specified state.
1902 */
1903 boolean isState(ActivityState state) {
1904 return state == mState;
1905 }
1906
1907 /**
1908 * Returns {@code true} if the Activity is in one of the specified states.
1909 */
1910 boolean isState(ActivityState state1, ActivityState state2) {
1911 return state1 == mState || state2 == mState;
1912 }
1913
1914 /**
1915 * Returns {@code true} if the Activity is in one of the specified states.
1916 */
1917 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3) {
1918 return state1 == mState || state2 == mState || state3 == mState;
1919 }
1920
1921 /**
1922 * Returns {@code true} if the Activity is in one of the specified states.
1923 */
1924 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3,
1925 ActivityState state4) {
1926 return state1 == mState || state2 == mState || state3 == mState || state4 == mState;
1927 }
1928
Jorim Jaggibae01b12017-04-11 16:29:10 -07001929 void notifyAppResumed(boolean wasStopped) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001930 if (mAppWindowToken == null) {
1931 Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: "
1932 + appToken);
1933 return;
1934 }
1935 mAppWindowToken.notifyAppResumed(wasStopped);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001936 }
1937
1938 void notifyUnknownVisibilityLaunched() {
Jorim Jaggi838c2452017-08-28 15:44:43 +02001939
1940 // No display activities never add a window, so there is no point in waiting them for
1941 // relayout.
1942 if (!noDisplay) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001943 if (mAppWindowToken != null) {
1944 mAppWindowToken.getDisplayContent().mUnknownAppVisibilityController
1945 .notifyLaunched(mAppWindowToken);
1946 }
Jorim Jaggi838c2452017-08-28 15:44:43 +02001947 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001948 }
1949
Jorim Jaggi241ae102016-11-02 21:57:33 -07001950 /**
1951 * @return true if the input activity should be made visible, ignoring any effect Keyguard
1952 * might have on the visibility
1953 *
Garfield Tan47e576c2019-01-28 10:26:23 -08001954 * TODO(b/123540470): Combine this method and {@link #shouldBeVisible(boolean)}.
1955 *
Jorim Jaggi241ae102016-11-02 21:57:33 -07001956 * @see {@link ActivityStack#checkKeyguardVisibility}
1957 */
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001958 boolean shouldBeVisibleIgnoringKeyguard(boolean behindFullscreenActivity) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001959 if (!okToShowLocked()) {
1960 return false;
1961 }
1962
Winson Chung3f0e59a2017-10-25 10:19:05 -07001963 return !behindFullscreenActivity || mLaunchTaskBehind;
Andrii Kulian21713ac2016-10-12 22:05:05 -07001964 }
1965
Garfield Tan47e576c2019-01-28 10:26:23 -08001966 boolean shouldBeVisible(boolean behindFullscreenActivity) {
1967 // Check whether activity should be visible without Keyguard influence
1968 visibleIgnoringKeyguard = shouldBeVisibleIgnoringKeyguard(behindFullscreenActivity);
1969
1970 final ActivityStack stack = getActivityStack();
1971 if (stack == null) {
1972 return false;
1973 }
1974
Issei Suzuki62356a22019-04-11 16:46:37 +02001975 // Whether the activity is on the sleeping display.
1976 // TODO(b/129750406): This should be applied for the default display, too.
1977 final boolean isDisplaySleeping = getDisplay().isSleeping()
1978 && getDisplayId() != DEFAULT_DISPLAY;
Garfield Tan47e576c2019-01-28 10:26:23 -08001979 // Whether this activity is the top activity of this stack.
1980 final boolean isTop = this == stack.getTopActivity();
1981 // Exclude the case where this is the top activity in a pinned stack.
1982 final boolean isTopNotPinnedStack = stack.isAttached()
1983 && stack.getDisplay().isTopNotPinnedStack(stack);
Issei Suzuki62356a22019-04-11 16:46:37 +02001984 // Now check whether it's really visible depending on Keyguard state, and update
1985 // {@link ActivityStack} internal states.
1986 final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this,
Garfield Tan47e576c2019-01-28 10:26:23 -08001987 visibleIgnoringKeyguard, isTop && isTopNotPinnedStack);
Issei Suzuki62356a22019-04-11 16:46:37 +02001988 return visibleIgnoringDisplayStatus && !isDisplaySleeping;
Garfield Tan47e576c2019-01-28 10:26:23 -08001989 }
1990
1991 boolean shouldBeVisible() {
1992 final ActivityStack stack = getActivityStack();
1993 if (stack == null) {
1994 return false;
1995 }
1996
1997 // TODO: Use real value of behindFullscreenActivity calculated using the same logic in
1998 // ActivityStack#ensureActivitiesVisibleLocked().
1999 return shouldBeVisible(!stack.shouldBeVisible(null /* starting */));
2000 }
2001
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002002 void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002003 // This activity is not currently visible, but is running. Tell it to become visible.
Bryce Lee7ace3952018-02-16 14:34:32 -08002004 if (mState == RESUMED || this == starting) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002005 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
Bryce Lee7ace3952018-02-16 14:34:32 -08002006 "Not making visible, r=" + this + " state=" + mState + " starting=" + starting);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002007 return;
2008 }
2009
2010 // If this activity is paused, tell it to now show its window.
2011 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
2012 "Making visible and scheduling visibility: " + this);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002013 final ActivityStack stack = getActivityStack();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002014 try {
2015 if (stack.mTranslucentActivityWaiting != null) {
2016 updateOptionsLocked(returningOptions);
2017 stack.mUndrawnActivitiesBelowTopTranslucent.add(this);
2018 }
2019 setVisible(true);
2020 sleeping = false;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07002021 app.postPendingUiCleanMsg(true);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002022 if (reportToClient) {
2023 makeClientVisible();
2024 } else {
2025 mClientVisibilityDeferred = true;
2026 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002027 // The activity may be waiting for stop, but that is no longer appropriate for it.
2028 mStackSupervisor.mStoppingActivities.remove(this);
2029 mStackSupervisor.mGoingToSleepActivities.remove(this);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002030 } catch (Exception e) {
2031 // Just skip on any failure; we'll make it visible when it next restarts.
2032 Slog.w(TAG, "Exception thrown making visible: " + intent.getComponent(), e);
2033 }
2034 handleAlreadyVisible();
2035 }
Andrii Kulian0d595f32018-02-21 15:47:33 -08002036
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002037 /** Send visibility change message to the client and pause if needed. */
2038 void makeClientVisible() {
2039 mClientVisibilityDeferred = false;
2040 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002041 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002042 WindowVisibilityItem.obtain(true /* showWindow */));
Andrii Kulian6b321512019-01-23 06:37:00 +00002043 makeActiveIfNeeded(null /* activeActivity*/);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002044 } catch (Exception e) {
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002045 Slog.w(TAG, "Exception thrown sending visibility update: " + intent.getComponent(), e);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002046 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002047 }
2048
Andrii Kulian6b321512019-01-23 06:37:00 +00002049 /**
2050 * Make activity resumed or paused if needed.
2051 * @param activeActivity an activity that is resumed or just completed pause action.
2052 * We won't change the state of this activity.
2053 */
2054 boolean makeActiveIfNeeded(ActivityRecord activeActivity) {
2055 if (shouldResumeActivity(activeActivity)) {
2056 if (DEBUG_VISIBILITY) {
2057 Slog.v("TAG_VISIBILITY", "Resume visible activity, " + this);
2058 }
2059 return getActivityStack().resumeTopActivityUncheckedLocked(activeActivity /* prev */,
2060 null /* options */);
2061 } else if (shouldPauseActivity(activeActivity)) {
2062 if (DEBUG_VISIBILITY) {
2063 Slog.v("TAG_VISIBILITY", "Pause visible activity, " + this);
2064 }
2065 // An activity must be in the {@link PAUSING} state for the system to validate
2066 // the move to {@link PAUSED}.
2067 setState(PAUSING, "makeVisibleIfNeeded");
2068 try {
2069 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
2070 PauseActivityItem.obtain(finishing, false /* userLeaving */,
2071 configChangeFlags, false /* dontReport */));
2072 } catch (Exception e) {
2073 Slog.w(TAG, "Exception thrown sending pause: " + intent.getComponent(), e);
2074 }
2075 }
2076 return false;
2077 }
2078
2079 /**
2080 * Check if activity should be moved to PAUSED state. The activity:
2081 * - should be eligible to be made active (see {@link #shouldMakeActive(ActivityRecord)})
2082 * - should be non-focusable
2083 * - should not be currently pausing or paused
2084 * @param activeActivity the activity that is active or just completed pause action. We won't
2085 * resume if this activity is active.
2086 */
2087 private boolean shouldPauseActivity(ActivityRecord activeActivity) {
2088 return shouldMakeActive(activeActivity) && !isFocusable() && !isState(PAUSING, PAUSED);
2089 }
2090
2091 /**
2092 * Check if activity should be moved to RESUMED state. The activity:
2093 * - should be eligible to be made active (see {@link #shouldMakeActive(ActivityRecord)})
2094 * - should be focusable
2095 * @param activeActivity the activity that is active or just completed pause action. We won't
2096 * resume if this activity is active.
2097 */
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002098 @VisibleForTesting
2099 boolean shouldResumeActivity(ActivityRecord activeActivity) {
2100 return shouldMakeActive(activeActivity) && isFocusable() && !isState(RESUMED)
2101 && getActivityStack().getVisibility(activeActivity) == STACK_VISIBILITY_VISIBLE;
Andrii Kulian6b321512019-01-23 06:37:00 +00002102 }
2103
2104 /**
2105 * Check if activity is eligible to be made active (resumed of paused). The activity:
2106 * - should be paused, stopped or stopping
Andrii Kulian996df0d2019-01-24 17:04:36 -08002107 * - should not be the currently active one or launching behind other tasks
Andrii Kulian6b321512019-01-23 06:37:00 +00002108 * - should be either the topmost in task, or right below the top activity that is finishing
2109 * If all of these conditions are not met at the same time, the activity cannot be made active.
2110 */
Andrii Kulianf2195362019-01-31 18:20:11 -08002111 @VisibleForTesting
2112 boolean shouldMakeActive(ActivityRecord activeActivity) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002113 // If the activity is stopped, stopping, cycle to an active state. We avoid doing
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002114 // this when there is an activity waiting to become translucent as the extra binder
2115 // calls will lead to noticeable jank. A later call to
Andrii Kulian6b321512019-01-23 06:37:00 +00002116 // ActivityStack#ensureActivitiesVisibleLocked will bring the activity to a proper
2117 // active state.
2118 if (!isState(RESUMED, PAUSED, STOPPED, STOPPING)
2119 || getActivityStack().mTranslucentActivityWaiting != null) {
2120 return false;
2121 }
2122
2123 if (this == activeActivity) {
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002124 return false;
2125 }
2126
Andrii Kulianf2195362019-01-31 18:20:11 -08002127 if (!mStackSupervisor.readyToResume()) {
2128 // Making active is currently deferred (e.g. because an activity launch is in progress).
2129 return false;
2130 }
2131
Andrii Kulian996df0d2019-01-24 17:04:36 -08002132 if (this.mLaunchTaskBehind) {
2133 // This activity is being launched from behind, which means that it's not intended to be
2134 // presented to user right now, even if it's set to be visible.
2135 return false;
2136 }
2137
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002138 // Check if position in task allows to become paused
2139 final int positionInTask = task.mActivities.indexOf(this);
2140 if (positionInTask == -1) {
2141 throw new IllegalStateException("Activity not found in its task");
2142 }
2143 if (positionInTask == task.mActivities.size() - 1) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002144 // It's the topmost activity in the task - should become resumed now
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002145 return true;
2146 }
2147 // Check if activity above is finishing now and this one becomes the topmost in task.
2148 final ActivityRecord activityAbove = task.mActivities.get(positionInTask + 1);
2149 if (activityAbove.finishing && results == null) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002150 // We will only allow making active if activity above wasn't launched for result.
2151 // Otherwise it will cause this activity to resume before getting result.
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002152 return true;
2153 }
2154 return false;
2155 }
2156
Andrii Kulian21713ac2016-10-12 22:05:05 -07002157 boolean handleAlreadyVisible() {
2158 stopFreezingScreenLocked(false);
2159 try {
2160 if (returningOptions != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002161 app.getThread().scheduleOnNewActivityOptions(appToken, returningOptions.toBundle());
Andrii Kulian21713ac2016-10-12 22:05:05 -07002162 }
2163 } catch(RemoteException e) {
2164 }
Bryce Lee7ace3952018-02-16 14:34:32 -08002165 return mState == RESUMED;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002166 }
2167
2168 static void activityResumedLocked(IBinder token) {
2169 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2170 if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
Charles Chen69362cd2019-03-29 15:18:45 +08002171 if (r == null) {
2172 // If an app reports resumed after a long delay, the record on server side might have
2173 // been removed (e.g. destroy timeout), so the token could be null.
2174 return;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002175 }
Charles Chen69362cd2019-03-29 15:18:45 +08002176 r.icicle = null;
2177 r.haveState = false;
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002178
2179 final ActivityDisplay display = r.getDisplay();
2180 if (display != null) {
2181 display.handleActivitySizeCompatModeIfNeeded(r);
2182 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002183 }
2184
2185 /**
2186 * Once we know that we have asked an application to put an activity in the resumed state
2187 * (either by launching it or explicitly telling it), this function updates the rest of our
2188 * state to match that fact.
2189 */
2190 void completeResumeLocked() {
2191 final boolean wasVisible = visible;
Jorim Jaggi8d062052017-08-22 14:55:17 +02002192 setVisible(true);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002193 if (!wasVisible) {
2194 // Visibility has changed, so take a note of it so we call the TaskStackChangedListener
2195 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
2196 }
2197 idle = false;
2198 results = null;
2199 newIntents = null;
2200 stopped = false;
2201
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002202 if (isActivityTypeHome()) {
Louis Changdcdde952018-12-04 15:38:44 +08002203 mStackSupervisor.updateHomeProcess(task.mActivities.get(0).app);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002204 }
2205
2206 if (nowVisible) {
Louis Changa59937a2019-03-20 17:17:22 +08002207 mStackSupervisor.stopWaitingForActivityVisible(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002208 }
2209
2210 // Schedule an idle timeout in case the app doesn't do it for us.
2211 mStackSupervisor.scheduleIdleTimeoutLocked(this);
2212
2213 mStackSupervisor.reportResumedActivityLocked(this);
2214
2215 resumeKeyDispatchingLocked();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002216 final ActivityStack stack = getActivityStack();
Jorim Jaggifa9ed962018-01-25 00:16:49 +01002217 mStackSupervisor.mNoAnimActivities.clear();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002218
2219 // Mark the point when the activity is resuming
2220 // TODO: To be more accurate, the mark should be before the onCreate,
2221 // not after the onResume. But for subsequent starts, onResume is fine.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002222 if (hasProcess()) {
Wale Ogunwale86b74462018-07-02 08:42:43 -07002223 cpuTimeAtResume = app.getCpuTime();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002224 } else {
2225 cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2226 }
2227
2228 returningOptions = null;
chaviw59b98852017-06-13 12:05:44 -07002229
2230 if (canTurnScreenOn()) {
2231 mStackSupervisor.wakeUp("turnScreenOnFlag");
2232 } else {
2233 // If the screen is going to turn on because the caller explicitly requested it and
2234 // the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
2235 // pause and then resume again later, which will result in a double life-cycle event.
David Stevens9440dc82017-03-16 19:00:20 -07002236 stack.checkReadyForSleep();
chaviw59b98852017-06-13 12:05:44 -07002237 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002238 }
2239
2240 final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
2241 CharSequence description) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002242 final ActivityStack stack = getActivityStack();
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002243 final boolean isStopping = mState == STOPPING;
2244 if (!isStopping && mState != RESTARTING_PROCESS) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002245 Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
Ruben Brunkf53497c2017-03-27 20:26:17 -07002246 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002247 return;
2248 }
2249 if (newPersistentState != null) {
2250 persistentState = newPersistentState;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002251 mAtmService.notifyTaskPersisterLocked(task, false);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002252 }
2253 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + icicle);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002254
Andrii Kulian21713ac2016-10-12 22:05:05 -07002255 if (newIcicle != null) {
2256 // If icicle is null, this is happening due to a timeout, so we haven't really saved
2257 // the state.
2258 icicle = newIcicle;
2259 haveState = true;
2260 launchCount = 0;
Jorim Jaggie7d2b852017-08-28 17:55:15 +02002261 updateTaskDescription(description);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002262 }
2263 if (!stopped) {
2264 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
Ruben Brunkf53497c2017-03-27 20:26:17 -07002265 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002266 stopped = true;
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002267 if (isStopping) {
2268 setState(STOPPED, "activityStoppedLocked");
2269 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002270
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002271 if (mAppWindowToken != null) {
2272 mAppWindowToken.notifyAppStopped();
2273 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002274
Andrii Kulian21713ac2016-10-12 22:05:05 -07002275 if (finishing) {
2276 clearOptionsLocked();
2277 } else {
2278 if (deferRelaunchUntilPaused) {
2279 stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002280 mRootActivityContainer.resumeFocusedStacksTopActivities();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002281 } else {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002282 mRootActivityContainer.updatePreviousProcess(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002283 }
2284 }
2285 }
2286 }
2287
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002288 void startLaunchTickingLocked() {
Jeff Sharkey5ab02432017-06-27 11:01:36 -06002289 if (Build.IS_USER) {
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002290 return;
2291 }
2292 if (launchTickTime == 0) {
2293 launchTickTime = SystemClock.uptimeMillis();
2294 continueLaunchTickingLocked();
2295 }
2296 }
2297
2298 boolean continueLaunchTickingLocked() {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002299 if (launchTickTime == 0) {
2300 return false;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002301 }
Wale Ogunwale7d701172015-03-11 15:36:30 -07002302
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002303 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002304 if (stack == null) {
2305 return false;
2306 }
2307
Ruben Brunkf53497c2017-03-27 20:26:17 -07002308 Message msg = stack.mHandler.obtainMessage(LAUNCH_TICK_MSG, this);
2309 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
2310 stack.mHandler.sendMessageDelayed(msg, LAUNCH_TICK);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002311 return true;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002312 }
2313
2314 void finishLaunchTickingLocked() {
2315 launchTickTime = 0;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002316 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002317 if (stack != null) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07002318 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002319 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002320 }
2321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 // IApplicationToken
2323
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002324 public boolean mayFreezeScreenLocked(WindowProcessController app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 // Only freeze the screen if this activity is currently attached to
2326 // an application, and that application is not blocked or unresponding.
2327 // In any other case, we can't count on getting the screen unfrozen,
2328 // so it is best to leave as-is.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002329 return hasProcess() && !app.isCrashing() && !app.isNotResponding();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002330 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002331
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002332 public void startFreezingScreenLocked(WindowProcessController app, int configChanges) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 if (mayFreezeScreenLocked(app)) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002334 if (mAppWindowToken == null) {
2335 Slog.w(TAG_WM,
2336 "Attempted to freeze screen with non-existing app token: " + appToken);
2337 return;
2338 }
2339
Evan Roskyb1e75f72019-04-26 20:23:26 -07002340 // Window configuration changes only effect windows, so don't require a screen freeze.
2341 int freezableConfigChanges = configChanges & ~(CONFIG_WINDOW_CONFIGURATION);
2342 if (freezableConfigChanges == 0 && mAppWindowToken.okToDisplay()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002343 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + appToken);
2344 return;
2345 }
2346
2347 mAppWindowToken.startFreezingScreen();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 }
2349 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002351 public void stopFreezingScreenLocked(boolean force) {
2352 if (force || frozenBeforeDestroy) {
2353 frozenBeforeDestroy = false;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002354 if (mAppWindowToken == null) {
2355 return;
2356 }
2357 if (DEBUG_ORIENTATION) {
2358 Slog.v(TAG_WM, "Clear freezing of " + appToken + ": hidden="
2359 + mAppWindowToken.isHidden() + " freezing="
2360 + mAppWindowToken.isFreezingScreen());
2361 }
2362 mAppWindowToken.stopFreezingScreen(true, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 }
2364 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002365
Jorim Jaggi4d27b842017-08-17 17:22:26 +02002366 public void reportFullyDrawnLocked(boolean restoredFromBundle) {
Vishnu Nair132ee832018-09-28 15:00:05 -07002367 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2368 .getActivityMetricsLogger().logAppTransitionReportedDrawn(this, restoredFromBundle);
2369 if (info != null) {
2370 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002371 info.windowsFullyDrawnDelayMs, info.getLaunchState());
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002372 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002373 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002374
2375 /**
2376 * Called when the starting window for this container is drawn.
2377 */
Sudheer Shankac766db02017-06-12 10:37:29 -07002378 public void onStartingWindowDrawn(long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002379 synchronized (mAtmService.mGlobalLock) {
Bryce Lee2a3cc462017-10-27 10:57:35 -07002380 mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +01002381 getWindowingMode(), timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -08002382 }
2383 }
2384
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002385 /** Called when the windows associated app window container are drawn. */
Vishnu Nair9ba31652018-11-13 14:34:05 -08002386 public void onWindowsDrawn(boolean drawn, long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002387 synchronized (mAtmService.mGlobalLock) {
Vishnu Nair9ba31652018-11-13 14:34:05 -08002388 mDrawn = drawn;
2389 if (!drawn) {
2390 return;
2391 }
Vishnu Nair132ee832018-09-28 15:00:05 -07002392 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2393 .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
2394 final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002395 final @LaunchState int launchState = info != null ? info.getLaunchState() : -1;
Vishnu Nair132ee832018-09-28 15:00:05 -07002396 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002397 windowsDrawnDelayMs, launchState);
Louis Changa59937a2019-03-20 17:17:22 +08002398 mStackSupervisor.stopWaitingForActivityVisible(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002399 finishLaunchTickingLocked();
2400 if (task != null) {
2401 task.hasBeenVisible = true;
2402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002403 }
2404 }
2405
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002406 /** Called when the windows associated app window container are visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002407 public void onWindowsVisible() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002408 synchronized (mAtmService.mGlobalLock) {
Louis Changa59937a2019-03-20 17:17:22 +08002409 mStackSupervisor.stopWaitingForActivityVisible(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002410 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
2411 if (!nowVisible) {
2412 nowVisible = true;
2413 lastVisibleTime = SystemClock.uptimeMillis();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002414 mAtmService.scheduleAppGcsLocked();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002415 }
2416 }
2417 }
2418
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002419 /** Called when the windows associated app window container are no longer visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002420 public void onWindowsGone() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002421 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002422 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + this);
2423 nowVisible = false;
2424 }
2425 }
2426
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002427 void onAnimationFinished() {
2428 if (mRootActivityContainer.allResumedActivitiesIdle()
2429 || mStackSupervisor.isStoppingNoHistoryActivity()) {
2430 // If all activities are already idle or there is an activity that must be
2431 // stopped immediately after visible, then we now need to make sure we perform
2432 // the full stop of this activity. This is because we won't do that while they are still
2433 // waiting for the animation to finish.
2434 if (mStackSupervisor.mStoppingActivities.contains(this)) {
2435 mStackSupervisor.scheduleIdleLocked();
2436 }
2437 } else {
2438 // Instead of doing the full stop routine here, let's just hide any activities
2439 // we now can, and let them stop when the normal idle happens.
2440 mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
2441 false /* remove */, true /* processPausingActivities */);
2442 }
2443 }
2444
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002445 /**
2446 * Called when the key dispatching to a window associated with the app window container
2447 * timed-out.
2448 *
2449 * @param reason The reason for the key dispatching time out.
2450 * @param windowPid The pid of the window key dispatching timed out on.
2451 * @return True if input dispatching should be aborted.
2452 */
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002453 public boolean keyDispatchingTimedOut(String reason, int windowPid) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002454 ActivityRecord anrActivity;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002455 WindowProcessController anrApp;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002456 boolean windowFromSameProcessAsActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002457 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002458 anrActivity = getWaitingHistoryRecordLocked();
2459 anrApp = app;
Brian Carlstrom7b0f2e82017-03-31 00:24:18 -07002460 windowFromSameProcessAsActivity =
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002461 !hasProcess() || app.getPid() == windowPid || windowPid == -1;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002462 }
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002463
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002464 if (windowFromSameProcessAsActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002465 return mAtmService.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner,
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002466 anrActivity.shortComponentName, anrActivity.appInfo, shortComponentName,
2467 app, false, reason);
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002468 } else {
2469 // In this case another process added windows using this activity token. So, we call the
2470 // generic service input dispatch timed out method so that the right process is blamed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002471 return mAtmService.mAmInternal.inputDispatchingTimedOut(
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002472 windowPid, false /* aboveSystem */, reason) < 0;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002473 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002474 }
2475
2476 private ActivityRecord getWaitingHistoryRecordLocked() {
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002477 // First find the real culprit... if this activity has stopped, then the key dispatching
riddle_hsudb46d6b2015-04-01 18:58:07 +08002478 // timeout should not be caused by this.
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002479 if (stopped) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002480 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
riddle_hsudb46d6b2015-04-01 18:58:07 +08002481 // Try to use the one which is closest to top.
Bryce Leec4ab62a2018-03-05 14:19:26 -08002482 ActivityRecord r = stack.getResumedActivity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002483 if (r == null) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002484 r = stack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002485 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002486 if (r != null) {
2487 return r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002488 }
2489 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002490 return this;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002491 }
2492
Chong Zhang87761972016-08-22 13:53:24 -07002493 /** Checks whether the activity should be shown for current user. */
2494 public boolean okToShowLocked() {
Bryce Lee8558ec72017-08-17 15:37:26 -07002495 // We cannot show activities when the device is locked and the application is not
2496 // encryption aware.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002497 if (!StorageManager.isUserKeyUnlocked(mUserId)
Bryce Lee8558ec72017-08-17 15:37:26 -07002498 && !info.applicationInfo.isEncryptionAware()) {
2499 return false;
2500 }
2501
Chong Zhang87761972016-08-22 13:53:24 -07002502 return (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002503 || (mStackSupervisor.isCurrentProfileLocked(mUserId)
2504 && mAtmService.mAmInternal.isUserRunning(mUserId, 0 /* flags */));
Chong Zhang87761972016-08-22 13:53:24 -07002505 }
2506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002507 /**
2508 * This method will return true if the activity is either visible, is becoming visible, is
2509 * currently pausing, or is resumed.
2510 */
2511 public boolean isInterestingToUserLocked() {
Bryce Lee7ace3952018-02-16 14:34:32 -08002512 return visible || nowVisible || mState == PAUSING || mState == RESUMED;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002513 }
2514
Wale Ogunwale3e997362016-09-06 10:37:56 -07002515 void setSleeping(boolean _sleeping) {
2516 setSleeping(_sleeping, false);
2517 }
2518
2519 void setSleeping(boolean _sleeping, boolean force) {
2520 if (!force && sleeping == _sleeping) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002521 return;
2522 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002523 if (attachedToProcess()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002524 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002525 app.getThread().scheduleSleeping(appToken, _sleeping);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002526 if (_sleeping && !mStackSupervisor.mGoingToSleepActivities.contains(this)) {
2527 mStackSupervisor.mGoingToSleepActivities.add(this);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002528 }
2529 sleeping = _sleeping;
2530 } catch (RemoteException e) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002531 Slog.w(TAG, "Exception thrown when sleeping: " + intent.getComponent(), e);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002532 }
2533 }
2534 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08002535
Craig Mautnerd2328952013-03-05 12:46:26 -08002536 static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002537 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Craig Mautnerd2328952013-03-05 12:46:26 -08002538 if (r == null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002539 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002540 }
2541 final TaskRecord task = r.task;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002542 final int activityNdx = task.mActivities.indexOf(r);
2543 if (activityNdx < 0 || (onlyRoot && activityNdx > task.findEffectiveRootIndex())) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002544 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002545 }
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002546 return task.taskId;
Craig Mautnerd2328952013-03-05 12:46:26 -08002547 }
2548
2549 static ActivityRecord isInStackLocked(IBinder token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002550 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002551 return (r != null) ? r.getActivityStack().isInStackLocked(r) : null;
Craig Mautnerd2328952013-03-05 12:46:26 -08002552 }
2553
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002554 static ActivityStack getStackLocked(IBinder token) {
Craig Mautnerd2328952013-03-05 12:46:26 -08002555 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2556 if (r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002557 return r.getActivityStack();
Craig Mautnerd2328952013-03-05 12:46:26 -08002558 }
2559 return null;
2560 }
2561
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002562 /**
Riddle Hsufd4a0502018-10-16 01:05:16 +08002563 * @return display id to which this record is attached,
2564 * {@link android.view.Display#INVALID_DISPLAY} if not attached.
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002565 */
2566 int getDisplayId() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002567 final ActivityStack stack = getActivityStack();
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002568 if (stack == null) {
Riddle Hsufd4a0502018-10-16 01:05:16 +08002569 return INVALID_DISPLAY;
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002570 }
2571 return stack.mDisplayId;
2572 }
2573
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002574 final boolean isDestroyable() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002575 if (finishing || !hasProcess()) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002576 // This would be redundant.
2577 return false;
2578 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002579 final ActivityStack stack = getActivityStack();
Bryce Leec4ab62a2018-03-05 14:19:26 -08002580 if (stack == null || this == stack.getResumedActivity() || this == stack.mPausingActivity
Andrii Kulian02b7a832016-10-06 23:11:56 -07002581 || !haveState || !stopped) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002582 // We're not ready for this kind of thing.
2583 return false;
2584 }
2585 if (visible) {
2586 // The user would notice this!
2587 return false;
2588 }
2589 return true;
2590 }
2591
Winson Chung3bad5cc02014-08-19 17:44:32 -07002592 private static String createImageFilename(long createTime, int taskId) {
2593 return String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX + createTime +
Ruben Brunkf53497c2017-03-27 20:26:17 -07002594 IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -07002595 }
2596
Craig Mautner648f69b2014-09-18 14:16:26 -07002597 void setTaskDescription(TaskDescription _taskDescription) {
2598 Bitmap icon;
2599 if (_taskDescription.getIconFilename() == null &&
2600 (icon = _taskDescription.getIcon()) != null) {
2601 final String iconFilename = createImageFilename(createTime, task.taskId);
Winson Chungc8408b82017-01-25 17:58:56 -08002602 final File iconFile = new File(TaskPersister.getUserImagesDir(task.userId),
2603 iconFilename);
Suprabh Shukla23593142015-11-03 17:31:15 -08002604 final String iconFilePath = iconFile.getAbsolutePath();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002605 mAtmService.getRecentTasks().saveImage(icon, iconFilePath);
Suprabh Shukla23593142015-11-03 17:31:15 -08002606 _taskDescription.setIconFilename(iconFilePath);
Craig Mautner648f69b2014-09-18 14:16:26 -07002607 }
2608 taskDescription = _taskDescription;
2609 }
2610
Amith Yamasani0af6fa72016-01-17 15:36:19 -08002611 void setVoiceSessionLocked(IVoiceInteractionSession session) {
2612 voiceSession = session;
2613 pendingVoiceInteractionStart = false;
2614 }
2615
2616 void clearVoiceSessionLocked() {
2617 voiceSession = null;
2618 pendingVoiceInteractionStart = false;
2619 }
2620
Jorim Jaggi02886a82016-12-06 09:10:06 -08002621 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch) {
Jorim Jaggi42befc62017-06-13 11:54:04 -07002622 showStartingWindow(prev, newTask, taskSwitch, false /* fromRecents */);
2623 }
2624
2625 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
2626 boolean fromRecents) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002627 if (mAppWindowToken == null) {
Jorim Jaggi70176432017-01-18 12:52:13 +01002628 return;
2629 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002630 if (mTaskOverlay) {
2631 // We don't show starting window for overlay activities.
2632 return;
2633 }
Sunny Goyald85bed52018-09-25 12:01:01 -07002634 if (pendingOptions != null
2635 && pendingOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
2636 // Don't show starting window when using shared element transition.
2637 return;
2638 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002639
Wale Ogunwale3b232392016-05-13 15:37:13 -07002640 final CompatibilityInfo compatInfo =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002641 mAtmService.compatibilityInfoForPackageLocked(info.applicationInfo);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002642 final boolean shown = addStartingWindow(packageName, theme,
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002643 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
Jorim Jaggibae01b12017-04-11 16:29:10 -07002644 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
Jorim Jaggi70aa4d12017-05-15 00:05:54 +02002645 allowTaskSnapshot(),
Bryce Lee7ace3952018-02-16 14:34:32 -08002646 mState.ordinal() >= RESUMED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
Jorim Jaggi42befc62017-06-13 11:54:04 -07002647 fromRecents);
Wale Ogunwale3b232392016-05-13 15:37:13 -07002648 if (shown) {
2649 mStartingWindowState = STARTING_WINDOW_SHOWN;
2650 }
2651 }
2652
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002653 void removeOrphanedStartingWindow(boolean behindFullscreenActivity) {
Jorim Jaggicb956052017-05-09 16:27:24 +02002654 if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002655 if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
2656 mStartingWindowState = STARTING_WINDOW_REMOVED;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002657 mAppWindowToken.removeStartingWindow();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002658 }
2659 }
2660
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002661 void setRequestedOrientation(int requestedOrientation) {
Garfield Tan90b04282018-12-11 14:04:42 -08002662 setOrientation(requestedOrientation, mayFreezeScreenLocked(app));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002663 mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
Yorke Leebd54c2a2016-10-25 13:49:23 -07002664 task.taskId, requestedOrientation);
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002665 }
2666
Garfield Tan90b04282018-12-11 14:04:42 -08002667 private void setOrientation(int requestedOrientation, boolean freezeScreenIfNeeded) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002668 if (mAppWindowToken == null) {
2669 Slog.w(TAG_WM,
2670 "Attempted to set orientation of non-existing app token: " + appToken);
Garfield Tan90b04282018-12-11 14:04:42 -08002671 return;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002672 }
2673
Evan Rosky730f6e82018-12-03 17:40:11 -08002674 final IBinder binder =
2675 (freezeScreenIfNeeded && appToken != null) ? appToken.asBinder() : null;
Garfield Tan90b04282018-12-11 14:04:42 -08002676 mAppWindowToken.setOrientation(requestedOrientation, binder, this);
Garfield Tan36a69ad2019-01-16 17:08:23 -08002677
2678 // Push the new configuration to the requested app in case where it's not pushed, e.g. when
2679 // the request is handled at task level with letterbox.
2680 if (!getMergedOverrideConfiguration().equals(
2681 mLastReportedConfiguration.getMergedConfiguration())) {
2682 ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
2683 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002684 }
2685
2686 int getOrientation() {
2687 if (mAppWindowToken == null) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002688 return info.screenOrientation;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002689 }
2690
2691 return mAppWindowToken.getOrientationIgnoreVisibility();
2692 }
2693
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002694 void setDisablePreviewScreenshots(boolean disable) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002695 if (mAppWindowToken == null) {
2696 Slog.w(TAG_WM, "Attempted to set disable screenshots of non-existing app"
2697 + " token: " + appToken);
2698 return;
2699 }
2700 mAppWindowToken.setDisablePreviewScreenshots(disable);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002701 }
2702
Bryce Leea163b762017-01-24 11:05:01 -08002703 /**
2704 * Set the last reported global configuration to the client. Should be called whenever a new
2705 * global configuration is sent to the client for this activity.
2706 */
2707 void setLastReportedGlobalConfiguration(@NonNull Configuration config) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002708 mLastReportedConfiguration.setGlobalConfiguration(config);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002709 }
2710
Bryce Leea163b762017-01-24 11:05:01 -08002711 /**
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002712 * Set the last reported configuration to the client. Should be called whenever
Bryce Leea163b762017-01-24 11:05:01 -08002713 * a new merged configuration is sent to the client for this activity.
2714 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002715 void setLastReportedConfiguration(@NonNull MergedConfiguration config) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002716 setLastReportedConfiguration(config.getGlobalConfiguration(),
2717 config.getOverrideConfiguration());
Bryce Leea163b762017-01-24 11:05:01 -08002718 }
2719
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002720 private void setLastReportedConfiguration(Configuration global, Configuration override) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002721 mLastReportedConfiguration.setConfiguration(global, override);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002722 }
2723
Riddle Hsu0a343c32018-12-21 00:40:48 +08002724 /**
2725 * Get the configuration orientation by the requested screen orientation
2726 * ({@link ActivityInfo.ScreenOrientation}) of this activity.
2727 *
Tiger Huang3d2b8982019-01-29 22:56:48 +08002728 * @return orientation in ({@link Configuration#ORIENTATION_LANDSCAPE},
2729 * {@link Configuration#ORIENTATION_PORTRAIT},
2730 * {@link Configuration#ORIENTATION_UNDEFINED}).
Riddle Hsu0a343c32018-12-21 00:40:48 +08002731 */
2732 int getRequestedConfigurationOrientation() {
2733 final int screenOrientation = getOrientation();
2734 if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
2735 // NOSENSOR means the display's "natural" orientation, so return that.
2736 final ActivityDisplay display = getDisplay();
2737 if (display != null && display.mDisplayContent != null) {
2738 return display.mDisplayContent.getNaturalOrientation();
2739 }
2740 } else if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
2741 // LOCKED means the activity's orientation remains unchanged, so return existing value.
2742 return getConfiguration().orientation;
2743 } else if (isFixedOrientationLandscape(screenOrientation)) {
2744 return ORIENTATION_LANDSCAPE;
2745 } else if (isFixedOrientationPortrait(screenOrientation)) {
2746 return ORIENTATION_PORTRAIT;
2747 }
2748 return ORIENTATION_UNDEFINED;
2749 }
2750
2751 /**
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002752 * @return {@code true} if this activity is in size compatibility mode that uses the different
2753 * density or bounds from its parent.
2754 */
2755 boolean inSizeCompatMode() {
2756 if (!shouldUseSizeCompatMode()) {
2757 return false;
2758 }
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002759 final Configuration resolvedConfig = getResolvedOverrideConfiguration();
Riddle Hsu04164182019-03-07 18:03:27 +08002760 final Rect resolvedAppBounds = resolvedConfig.windowConfiguration.getAppBounds();
2761 if (resolvedAppBounds == null) {
2762 // The override configuration has not been resolved yet.
2763 return false;
2764 }
2765
2766 final Configuration parentConfig = getParent().getConfiguration();
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002767 // Although colorMode, screenLayout, smallestScreenWidthDp are also fixed, generally these
2768 // fields should be changed with density and bounds, so here only compares the most
2769 // significant field.
2770 if (parentConfig.densityDpi != resolvedConfig.densityDpi) {
2771 return true;
2772 }
Riddle Hsu04164182019-03-07 18:03:27 +08002773
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002774 final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds();
Riddle Hsuaec55442019-03-12 17:25:35 +08002775 final int appWidth = resolvedAppBounds.width();
2776 final int appHeight = resolvedAppBounds.height();
2777 final int parentAppWidth = parentAppBounds.width();
2778 final int parentAppHeight = parentAppBounds.height();
Riddle Hsu9ad1785102019-03-26 00:26:54 +08002779 if (parentAppWidth == appWidth && parentAppHeight == appHeight) {
2780 // Matched the parent bounds.
2781 return false;
2782 }
2783 if (parentAppWidth > appWidth && parentAppHeight > appHeight) {
2784 // Both sides are smaller than the parent.
2785 return true;
2786 }
Riddle Hsuaec55442019-03-12 17:25:35 +08002787 if (parentAppWidth < appWidth || parentAppHeight < appHeight) {
Riddle Hsu04164182019-03-07 18:03:27 +08002788 // One side is larger than the parent.
2789 return true;
2790 }
2791
Riddle Hsu9ad1785102019-03-26 00:26:54 +08002792 // The rest of the condition is that only one side is smaller than the parent, but it still
2793 // needs to exclude the cases where the size is limited by the fixed aspect ratio.
2794 if (info.maxAspectRatio > 0) {
Riddle Hsuaec55442019-03-12 17:25:35 +08002795 final float aspectRatio = (0.5f + Math.max(appWidth, appHeight))
2796 / Math.min(appWidth, appHeight);
Riddle Hsu9ad1785102019-03-26 00:26:54 +08002797 if (aspectRatio >= info.maxAspectRatio) {
2798 // The current size has reached the max aspect ratio.
2799 return false;
Riddle Hsuaec55442019-03-12 17:25:35 +08002800 }
2801 }
Riddle Hsu9ad1785102019-03-26 00:26:54 +08002802 if (info.minAspectRatio > 0) {
2803 // The activity should have at least the min aspect ratio, so this checks if the parent
2804 // still has available space to provide larger aspect ratio.
2805 final float parentAspectRatio = (0.5f + Math.max(parentAppWidth, parentAppHeight))
2806 / Math.min(parentAppWidth, parentAppHeight);
2807 if (parentAspectRatio <= info.minAspectRatio) {
2808 // The long side has reached the parent.
2809 return false;
2810 }
2811 }
2812 return true;
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002813 }
2814
2815 /**
Riddle Hsu0a343c32018-12-21 00:40:48 +08002816 * Indicates the activity will keep the bounds and screen configuration when it was first
2817 * launched, no matter how its parent changes.
2818 *
2819 * @return {@code true} if this activity is declared as non-resizable and fixed orientation or
2820 * aspect ratio.
2821 */
Riddle Hsu74826262019-04-17 14:57:42 +08002822 boolean shouldUseSizeCompatMode() {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002823 return !isResizeable() && (info.isFixedOrientation() || info.hasFixedAspectRatio())
2824 // The configuration of non-standard type should be enforced by system.
2825 && isActivityTypeStandard()
2826 && !mAtmService.mForceResizableActivities;
2827 }
2828
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002829 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002830 private void updateOverrideConfiguration() {
Riddle Hsu74826262019-04-17 14:57:42 +08002831 final Configuration overrideConfig = mTmpConfig;
2832 if (shouldUseSizeCompatMode()) {
2833 if (mCompatDisplayInsets != null) {
2834 // The override configuration is set only once in size compatibility mode.
Riddle Hsu0a343c32018-12-21 00:40:48 +08002835 return;
2836 }
Riddle Hsu74826262019-04-17 14:57:42 +08002837 final Configuration parentConfig = getParent().getConfiguration();
2838 if (!hasProcess() && !isConfigurationCompatible(parentConfig)) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002839 // Don't compute when launching in fullscreen and the fixed orientation is not the
2840 // current orientation. It is more accurately to compute the override bounds from
2841 // the updated configuration after the fixed orientation is applied.
2842 return;
2843 }
Riddle Hsu0a343c32018-12-21 00:40:48 +08002844
Riddle Hsu74826262019-04-17 14:57:42 +08002845 // Ensure the screen related fields are set. It is used to prevent activity relaunch
2846 // when moving between displays. For screenWidthDp and screenWidthDp, because they
2847 // are relative to bounds and density, they will be calculated in
2848 // {@link TaskRecord#computeConfigResourceOverrides} and the result will also be
2849 // relatively fixed.
2850 overrideConfig.unset();
2851 overrideConfig.colorMode = parentConfig.colorMode;
2852 overrideConfig.densityDpi = parentConfig.densityDpi;
2853 overrideConfig.screenLayout = parentConfig.screenLayout
2854 & (Configuration.SCREENLAYOUT_LONG_MASK
2855 | Configuration.SCREENLAYOUT_SIZE_MASK);
2856 // The smallest screen width is the short side of screen bounds. Because the bounds
2857 // and density won't be changed, smallestScreenWidthDp is also fixed.
2858 overrideConfig.smallestScreenWidthDp = parentConfig.smallestScreenWidthDp;
Bryce Leef3c6a472017-11-14 14:53:06 -08002859
Riddle Hsu74826262019-04-17 14:57:42 +08002860 // The role of CompatDisplayInsets is like the override bounds.
2861 final ActivityDisplay display = getDisplay();
2862 if (display != null && display.mDisplayContent != null) {
2863 mCompatDisplayInsets = new CompatDisplayInsets(display.mDisplayContent);
Riddle Hsu0a343c32018-12-21 00:40:48 +08002864 }
Riddle Hsu74826262019-04-17 14:57:42 +08002865 } else {
2866 // We must base this on the parent configuration, because we set our override
2867 // configuration's appBounds based on the result of this method. If we used our own
2868 // configuration, it would be influenced by past invocations.
2869 computeBounds(mTmpBounds, getParent().getWindowConfiguration().getAppBounds());
2870
2871 if (mTmpBounds.equals(getRequestedOverrideBounds())) {
2872 // The bounds is not changed or the activity is resizable (both the 2 bounds are
2873 // empty).
2874 return;
2875 }
2876
2877 overrideConfig.unset();
2878 overrideConfig.windowConfiguration.setBounds(mTmpBounds);
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002879 }
Riddle Hsu74826262019-04-17 14:57:42 +08002880
Riddle Hsu0a343c32018-12-21 00:40:48 +08002881 onRequestedOverrideConfigurationChanged(overrideConfig);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002882 }
2883
Garfield Tan0443b372019-01-04 15:00:13 -08002884 @Override
2885 void resolveOverrideConfiguration(Configuration newParentConfiguration) {
Riddle Hsu74826262019-04-17 14:57:42 +08002886 if (mCompatDisplayInsets != null) {
Riddle Hsu04164182019-03-07 18:03:27 +08002887 resolveSizeCompatModeConfiguration(newParentConfiguration);
2888 } else {
2889 super.resolveOverrideConfiguration(newParentConfiguration);
Riddle Hsu74826262019-04-17 14:57:42 +08002890 // If the activity has override bounds, the relative configuration (e.g. screen size,
2891 // layout) needs to be resolved according to the bounds.
2892 if (!matchParentBounds()) {
Riddle Hsu04164182019-03-07 18:03:27 +08002893 task.computeConfigResourceOverrides(getResolvedOverrideConfiguration(),
Riddle Hsu61987bc2019-04-03 13:08:47 +08002894 newParentConfiguration);
Riddle Hsu04164182019-03-07 18:03:27 +08002895 }
2896 }
Garfield Tan0443b372019-01-04 15:00:13 -08002897
2898 // Assign configuration sequence number into hierarchy because there is a different way than
2899 // ensureActivityConfiguration() in this class that uses configuration in WindowState during
2900 // layout traversals.
2901 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
2902 getResolvedOverrideConfiguration().seq = mConfigurationSeq;
Riddle Hsu04164182019-03-07 18:03:27 +08002903 }
Riddle Hsu0a343c32018-12-21 00:40:48 +08002904
Riddle Hsu74826262019-04-17 14:57:42 +08002905 /**
2906 * Resolves consistent screen configuration for orientation and rotation changes without
2907 * inheriting the parent bounds.
2908 */
Riddle Hsu04164182019-03-07 18:03:27 +08002909 private void resolveSizeCompatModeConfiguration(Configuration newParentConfiguration) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002910 final Configuration resolvedConfig = getResolvedOverrideConfiguration();
Riddle Hsu04164182019-03-07 18:03:27 +08002911 final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
Riddle Hsu0a343c32018-12-21 00:40:48 +08002912
Riddle Hsu74826262019-04-17 14:57:42 +08002913 final int parentRotation = newParentConfiguration.windowConfiguration.getRotation();
2914 final int parentOrientation = newParentConfiguration.orientation;
Riddle Hsu0a343c32018-12-21 00:40:48 +08002915 int orientation = getConfiguration().orientation;
Riddle Hsu74826262019-04-17 14:57:42 +08002916 if (orientation != parentOrientation && isConfigurationCompatible(newParentConfiguration)) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002917 // The activity is compatible to apply the orientation change or it requests different
2918 // fixed orientation.
Riddle Hsu74826262019-04-17 14:57:42 +08002919 orientation = parentOrientation;
Riddle Hsu0a343c32018-12-21 00:40:48 +08002920 } else {
Riddle Hsu74826262019-04-17 14:57:42 +08002921 if (!resolvedBounds.isEmpty()
2922 // The decor insets may be different according to the rotation.
2923 && getWindowConfiguration().getRotation() == parentRotation) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002924 // Keep the computed resolved override configuration.
2925 return;
2926 }
2927 final int requestedOrientation = getRequestedConfigurationOrientation();
2928 if (requestedOrientation != ORIENTATION_UNDEFINED) {
2929 orientation = requestedOrientation;
2930 }
2931 }
2932
Riddle Hsu04164182019-03-07 18:03:27 +08002933 super.resolveOverrideConfiguration(newParentConfiguration);
2934
Riddle Hsu74826262019-04-17 14:57:42 +08002935 boolean useParentOverrideBounds = false;
2936 final Rect displayBounds = mTmpBounds;
2937 final Rect containingAppBounds = new Rect();
2938 if (task.handlesOrientationChangeFromDescendant()) {
2939 // Prefer to use the orientation which is determined by this activity to calculate
2940 // bounds because the parent will follow the requested orientation.
2941 mCompatDisplayInsets.getDisplayBoundsByOrientation(displayBounds, orientation);
2942 } else {
2943 // The parent hierarchy doesn't handle the orientation changes. This is usually because
2944 // the aspect ratio of display is close to square or the display rotation is fixed.
2945 // In this case, task will compute override bounds to fit the app with respect to the
2946 // requested orientation. So here we perform similar calculation to have consistent
2947 // bounds even the original parent hierarchies were changed.
2948 final int baseOrientation = task.getParent().getConfiguration().orientation;
2949 mCompatDisplayInsets.getDisplayBoundsByOrientation(displayBounds, baseOrientation);
2950 task.computeFullscreenBounds(containingAppBounds, this, displayBounds, baseOrientation);
2951 useParentOverrideBounds = !containingAppBounds.isEmpty();
Riddle Hsu0a343c32018-12-21 00:40:48 +08002952 }
2953
Riddle Hsu74826262019-04-17 14:57:42 +08002954 // The offsets will be non-zero if the parent has override bounds.
2955 final int containingOffsetX = containingAppBounds.left;
2956 final int containingOffsetY = containingAppBounds.top;
2957 if (!useParentOverrideBounds) {
2958 containingAppBounds.set(displayBounds);
Riddle Hsu04164182019-03-07 18:03:27 +08002959 }
Riddle Hsu74826262019-04-17 14:57:42 +08002960 if (parentRotation != ROTATION_UNDEFINED) {
2961 // Ensure the container bounds won't overlap with the decors.
2962 TaskRecord.intersectWithInsetsIfFits(containingAppBounds, displayBounds,
2963 mCompatDisplayInsets.mNonDecorInsets[parentRotation]);
2964 }
2965
2966 computeBounds(resolvedBounds, containingAppBounds);
2967 if (resolvedBounds.isEmpty()) {
2968 // Use the entire available bounds because there is no restriction.
2969 resolvedBounds.set(useParentOverrideBounds ? containingAppBounds : displayBounds);
2970 } else {
2971 // The offsets are included in width and height by {@link #computeBounds}, so we have to
2972 // restore it.
2973 resolvedBounds.left += containingOffsetX;
2974 resolvedBounds.top += containingOffsetY;
2975 }
2976 task.computeConfigResourceOverrides(resolvedConfig, newParentConfiguration,
2977 mCompatDisplayInsets);
2978
Riddle Hsu04164182019-03-07 18:03:27 +08002979 // The horizontal inset included in width is not needed if the activity cannot fill the
2980 // parent, because the offset will be applied by {@link AppWindowToken#mSizeCompatBounds}.
Riddle Hsu74826262019-04-17 14:57:42 +08002981 final Rect resolvedAppBounds = resolvedConfig.windowConfiguration.getAppBounds();
2982 final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds();
Riddle Hsu04164182019-03-07 18:03:27 +08002983 if (resolvedBounds.width() < parentAppBounds.width()) {
2984 resolvedBounds.right -= resolvedAppBounds.left;
2985 }
Riddle Hsu04164182019-03-07 18:03:27 +08002986 // Use parent orientation if it cannot be decided by bounds, so the activity can fit inside
2987 // the parent bounds appropriately.
2988 if (resolvedConfig.screenWidthDp == resolvedConfig.screenHeightDp) {
2989 resolvedConfig.orientation = newParentConfiguration.orientation;
Riddle Hsu0a343c32018-12-21 00:40:48 +08002990 }
Garfield Tan0443b372019-01-04 15:00:13 -08002991 }
2992
2993 @Override
2994 public void onConfigurationChanged(Configuration newParentConfig) {
2995 super.onConfigurationChanged(newParentConfig);
2996
2997 // Configuration's equality doesn't consider seq so if only seq number changes in resolved
2998 // override configuration. Therefore ConfigurationContainer doesn't change merged override
2999 // configuration, but it's used to push configuration changes so explicitly update that.
3000 if (getMergedOverrideConfiguration().seq != getResolvedOverrideConfiguration().seq) {
3001 onMergedOverrideConfigurationChanged();
3002 }
3003
3004 // TODO(b/80414790): Remove code below after unification.
3005 // Same as above it doesn't notify configuration listeners, and consequently AppWindowToken
3006 // can't get updated seq number. However WindowState's merged override configuration needs
3007 // to have this seq number because that's also used for activity config pushes during layout
3008 // traversal. Therefore explicitly update them here.
3009 if (mAppWindowToken == null) {
3010 return;
3011 }
3012 final Configuration appWindowTokenRequestedOverrideConfig =
3013 mAppWindowToken.getRequestedOverrideConfiguration();
3014 if (appWindowTokenRequestedOverrideConfig.seq != getResolvedOverrideConfiguration().seq) {
3015 appWindowTokenRequestedOverrideConfig.seq =
3016 getResolvedOverrideConfiguration().seq;
3017 mAppWindowToken.onMergedOverrideConfigurationChanged();
3018 }
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003019
3020 final ActivityDisplay display = getDisplay();
Riddle Hsuaec55442019-03-12 17:25:35 +08003021 if (display == null) {
3022 return;
3023 }
3024 if (visible) {
3025 // It may toggle the UI for user to restart the size compatibility mode activity.
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003026 display.handleActivitySizeCompatModeIfNeeded(this);
Riddle Hsuaec55442019-03-12 17:25:35 +08003027 } else if (shouldUseSizeCompatMode()) {
3028 // The override changes can only be obtained from display, because we don't have the
3029 // difference of full configuration in each hierarchy.
3030 final int displayChanges = display.getLastOverrideConfigurationChanges();
3031 final int orientationChanges = CONFIG_WINDOW_CONFIGURATION
3032 | CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION;
3033 final boolean hasNonOrienSizeChanged = hasResizeChange(displayChanges)
3034 // Filter out the case of simple orientation change.
3035 && (displayChanges & orientationChanges) != orientationChanges;
3036 // For background activity that uses size compatibility mode, if the size or density of
3037 // the display is changed, then reset the override configuration and kill the activity's
3038 // process if its process state is not important to user.
3039 if (hasNonOrienSizeChanged || (displayChanges & ActivityInfo.CONFIG_DENSITY) != 0) {
3040 restartProcessIfVisible();
3041 }
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003042 }
Garfield Tan0443b372019-01-04 15:00:13 -08003043 }
3044
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07003045 /** Returns true if the configuration is compatible with this activity. */
Wale Ogunwale42f07d92017-05-01 21:32:58 -07003046 boolean isConfigurationCompatible(Configuration config) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08003047 final int orientation = getOrientation();
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07003048 if (isFixedOrientationPortrait(orientation)
3049 && config.orientation != ORIENTATION_PORTRAIT) {
3050 return false;
3051 }
3052 if (isFixedOrientationLandscape(orientation)
3053 && config.orientation != ORIENTATION_LANDSCAPE) {
3054 return false;
3055 }
3056 return true;
3057 }
3058
Bryce Lee7566d762017-03-30 09:34:15 -07003059 /**
3060 * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}.
3061 */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003062 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
Riddle Hsu74826262019-04-17 14:57:42 +08003063 private void computeBounds(Rect outBounds, Rect containingAppBounds) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003064 outBounds.setEmpty();
3065 final float maxAspectRatio = info.maxAspectRatio;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003066 final ActivityStack stack = getActivityStack();
Adrian Roos917791e2018-11-28 16:30:44 +01003067 final float minAspectRatio = info.minAspectRatio;
3068
3069 if (task == null || stack == null || task.inMultiWindowMode()
3070 || (maxAspectRatio == 0 && minAspectRatio == 0)
Bryce Leee5ab4502017-07-11 08:58:05 -07003071 || isInVrUiMode(getConfiguration())) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003072 // We don't set override configuration if that activity task isn't fullscreen. I.e. the
3073 // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
Bryce Leee5ab4502017-07-11 08:58:05 -07003074 // the activity. This is indicated by an empty {@link outBounds}. We also don't set it
3075 // if we are in VR mode.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003076 return;
3077 }
3078
Riddle Hsu74826262019-04-17 14:57:42 +08003079 final int containingAppWidth = containingAppBounds.width();
3080 final int containingAppHeight = containingAppBounds.height();
Adrian Roos917791e2018-11-28 16:30:44 +01003081 final float containingRatio = Math.max(containingAppWidth, containingAppHeight)
3082 / (float) Math.min(containingAppWidth, containingAppHeight);
Bryce Lee7566d762017-03-30 09:34:15 -07003083
Adrian Roos917791e2018-11-28 16:30:44 +01003084 int activityWidth = containingAppWidth;
3085 int activityHeight = containingAppHeight;
3086
3087 if (containingRatio > maxAspectRatio && maxAspectRatio != 0) {
3088 if (containingAppWidth < containingAppHeight) {
3089 // Width is the shorter side, so we use that to figure-out what the max. height
3090 // should be given the aspect ratio.
3091 activityHeight = (int) ((activityWidth * maxAspectRatio) + 0.5f);
3092 } else {
3093 // Height is the shorter side, so we use that to figure-out what the max. width
3094 // should be given the aspect ratio.
3095 activityWidth = (int) ((activityHeight * maxAspectRatio) + 0.5f);
3096 }
Tiger Huang3d2b8982019-01-29 22:56:48 +08003097 } else if (containingRatio < minAspectRatio) {
3098 boolean adjustWidth;
3099 switch (getRequestedConfigurationOrientation()) {
3100 case ORIENTATION_LANDSCAPE:
3101 // Width should be the longer side for this landscape app, so we use the width
3102 // to figure-out what the max. height should be given the aspect ratio.
3103 adjustWidth = false;
3104 break;
3105 case ORIENTATION_PORTRAIT:
3106 // Height should be the longer side for this portrait app, so we use the height
3107 // to figure-out what the max. width should be given the aspect ratio.
3108 adjustWidth = true;
3109 break;
3110 default:
3111 // This app doesn't have a preferred orientation, so we keep the length of the
3112 // longer side, and use it to figure-out the length of the shorter side.
3113 if (containingAppWidth < containingAppHeight) {
3114 // Width is the shorter side, so we use the height to figure-out what the
3115 // max. width should be given the aspect ratio.
3116 adjustWidth = true;
3117 } else {
3118 // Height is the shorter side, so we use the width to figure-out what the
3119 // max. height should be given the aspect ratio.
3120 adjustWidth = false;
3121 }
3122 break;
3123 }
3124 if (adjustWidth) {
Adrian Roos917791e2018-11-28 16:30:44 +01003125 activityWidth = (int) ((activityHeight / minAspectRatio) + 0.5f);
3126 } else {
Adrian Roos917791e2018-11-28 16:30:44 +01003127 activityHeight = (int) ((activityWidth / minAspectRatio) + 0.5f);
3128 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003129 }
3130
Adrian Roos917791e2018-11-28 16:30:44 +01003131 if (containingAppWidth <= activityWidth && containingAppHeight <= activityHeight) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003132 // The display matches or is less than the activity aspect ratio, so nothing else to do.
Bryce Lee7566d762017-03-30 09:34:15 -07003133 // Return the existing bounds. If this method is running for the first time,
Evan Roskydfe3da72018-10-26 17:21:06 -07003134 // {@link #getRequestedOverrideBounds()} will be empty (representing no override). If
3135 // the method has run before, then effect of {@link #getRequestedOverrideBounds()} will
3136 // already have been applied to the value returned from {@link getConfiguration}. Refer
Riddle Hsu04164182019-03-07 18:03:27 +08003137 // to {@link TaskRecord#computeConfigResourceOverrides()}.
Evan Roskydfe3da72018-10-26 17:21:06 -07003138 outBounds.set(getRequestedOverrideBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003139 return;
3140 }
3141
3142 // Compute configuration based on max supported width and height.
Adrian Roos24be34d2018-05-28 18:55:38 +02003143 // Also account for the left / top insets (e.g. from display cutouts), which will be clipped
Riddle Hsu04164182019-03-07 18:03:27 +08003144 // away later in {@link TaskRecord#computeConfigResourceOverrides()}. Otherwise, the app
Adrian Roos24be34d2018-05-28 18:55:38 +02003145 // bounds would end up too small.
Riddle Hsu74826262019-04-17 14:57:42 +08003146 outBounds.set(0, 0, activityWidth + containingAppBounds.left,
3147 activityHeight + containingAppBounds.top);
Andrii Kulian3a1619d2017-07-07 14:38:09 -07003148 }
3149
Riddle Hsu16567132018-08-16 21:37:47 +08003150 /**
3151 * @return {@code true} if this activity was reparented to another display but
3152 * {@link #ensureActivityConfiguration} is not called.
3153 */
3154 boolean shouldUpdateConfigForDisplayChanged() {
3155 return mLastReportedDisplayId != getDisplayId();
3156 }
3157
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003158 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
3159 return ensureActivityConfiguration(globalChanges, preserveWindow,
3160 false /* ignoreStopState */);
3161 }
3162
Andrii Kulian21713ac2016-10-12 22:05:05 -07003163 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003164 * Make sure the given activity matches the current configuration. Ensures the HistoryRecord
3165 * is updated with the correct configuration and all other bookkeeping is handled.
3166 *
3167 * @param globalChanges The changes to the global configuration.
3168 * @param preserveWindow If the activity window should be preserved on screen if the activity
3169 * is relaunched.
3170 * @param ignoreStopState If we should try to relaunch the activity even if it is in the stopped
3171 * state. This is useful for the case where we know the activity will be
3172 * visible soon and we want to ensure its configuration before we make it
3173 * visible.
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003174 * @return False if the activity was relaunched and true if it wasn't relaunched because we
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003175 * can't or the app handles the specific configuration that is changing.
Andrii Kulian21713ac2016-10-12 22:05:05 -07003176 */
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003177 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
3178 boolean ignoreStopState) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003179 final ActivityStack stack = getActivityStack();
Andrii Kulian21713ac2016-10-12 22:05:05 -07003180 if (stack.mConfigWillChange) {
3181 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3182 "Skipping config check (will change): " + this);
3183 return true;
3184 }
3185
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003186 // We don't worry about activities that are finishing.
3187 if (finishing) {
3188 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3189 "Configuration doesn't matter in finishing " + this);
3190 stopFreezingScreenLocked(false);
3191 return true;
3192 }
3193
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003194 if (!ignoreStopState && (mState == STOPPING || mState == STOPPED)) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07003195 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3196 "Skipping config check stopped or stopping: " + this);
3197 return true;
3198 }
3199
Garfield Tan47e576c2019-01-28 10:26:23 -08003200 if (!shouldBeVisible()) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07003201 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3202 "Skipping config check invisible stack: " + this);
3203 return true;
3204 }
3205
Andrii Kulian21713ac2016-10-12 22:05:05 -07003206 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3207 "Ensuring correct configuration: " + this);
3208
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003209 final int newDisplayId = getDisplayId();
3210 final boolean displayChanged = mLastReportedDisplayId != newDisplayId;
3211 if (displayChanged) {
3212 mLastReportedDisplayId = newDisplayId;
3213 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003214 // TODO(b/36505427): Is there a better place to do this?
3215 updateOverrideConfiguration();
3216
Winson Chungbdc646f2017-02-13 12:12:22 -08003217 // Short circuit: if the two full configurations are equal (the common case), then there is
3218 // nothing to do. We test the full configuration instead of the global and merged override
3219 // configurations because there are cases (like moving a task to the pinned stack) where
3220 // the combine configurations are equal, but would otherwise differ in the override config
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003221 mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
3222 if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003223 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003224 "Configuration & display unchanged in " + this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003225 return true;
3226 }
3227
3228 // Okay we now are going to make this activity have the new config.
3229 // But then we need to figure out how it needs to deal with that.
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003230
3231 // Find changes between last reported merged configuration and the current one. This is used
3232 // to decide whether to relaunch an activity or just report a configuration change.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003233 final int changes = getConfigurationChanges(mTmpConfig);
Ruben Brunkf64af332017-03-22 22:03:25 -07003234
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003235 // Update last reported values.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003236 final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
Bryce Lee8104e7a2017-08-17 09:16:03 -07003237
Andrii Kulianbeadacc2019-05-20 12:18:01 +00003238 setLastReportedConfiguration(mAtmService.getGlobalConfiguration(), newMergedOverrideConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003239
Bryce Lee7ace3952018-02-16 14:34:32 -08003240 if (mState == INITIALIZING) {
Andrii Kulianb372da62018-01-18 10:46:24 -08003241 // No need to relaunch or schedule new config for activity that hasn't been launched
3242 // yet. We do, however, return after applying the config to activity record, so that
3243 // it will use it for launch transaction.
3244 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3245 "Skipping config check for initializing activity: " + this);
3246 return true;
3247 }
3248
Andrii Kulian21713ac2016-10-12 22:05:05 -07003249 if (changes == 0 && !forceNewConfig) {
3250 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3251 "Configuration no differences in " + this);
3252 // There are no significant differences, so we won't relaunch but should still deliver
3253 // the new configuration to the client process.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003254 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003255 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003256 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003257 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003258 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07003259 return true;
3260 }
3261
3262 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003263 "Configuration changes for " + this + ", allChanges="
Andrii Kulian21713ac2016-10-12 22:05:05 -07003264 + Configuration.configurationDiffToString(changes));
3265
3266 // If the activity isn't currently running, just leave the new configuration and it will
3267 // pick that up next time it starts.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003268 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003269 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3270 "Configuration doesn't matter not running " + this);
3271 stopFreezingScreenLocked(false);
3272 forceNewConfig = false;
3273 return true;
3274 }
3275
3276 // Figure out how to handle the changes between the configurations.
3277 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3278 "Checking to restart " + info.name + ": changed=0x"
3279 + Integer.toHexString(changes) + ", handles=0x"
3280 + Integer.toHexString(info.getRealConfigChanged())
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003281 + ", mLastReportedConfiguration=" + mLastReportedConfiguration);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003282
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003283 if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003284 // Aha, the activity isn't handling the change, so DIE DIE DIE.
3285 configChangeFlags |= changes;
3286 startFreezingScreenLocked(app, globalChanges);
3287 forceNewConfig = false;
3288 preserveWindow &= isResizeOnlyChange(changes);
Garfield Tan2746ab52018-07-25 12:33:01 -07003289 final boolean hasResizeChange = hasResizeChange(changes & ~info.getRealConfigChanged());
3290 if (hasResizeChange) {
3291 final boolean isDragResizing =
Yunfan Chen0e7aff92018-12-05 16:35:32 -08003292 getTaskRecord().getTask().isDragResizing();
Garfield Tan2746ab52018-07-25 12:33:01 -07003293 mRelaunchReason = isDragResizing ? RELAUNCH_REASON_FREE_RESIZE
3294 : RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
3295 } else {
3296 mRelaunchReason = RELAUNCH_REASON_NONE;
3297 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003298 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003299 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3300 "Config is destroying non-running " + this);
3301 stack.destroyActivityLocked(this, true, "config");
Bryce Lee7ace3952018-02-16 14:34:32 -08003302 } else if (mState == PAUSING) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003303 // A little annoying: we are waiting for this activity to finish pausing. Let's not
3304 // do anything now, but just flag that it needs to be restarted when done pausing.
3305 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3306 "Config is skipping already pausing " + this);
3307 deferRelaunchUntilPaused = true;
3308 preserveWindowOnDeferredRelaunch = preserveWindow;
3309 return true;
Bryce Lee7ace3952018-02-16 14:34:32 -08003310 } else if (mState == RESUMED) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003311 // Try to optimize this case: the configuration is changing and we need to restart
3312 // the top, resumed activity. Instead of doing the normal handshaking, just say
3313 // "restart!".
3314 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3315 "Config is relaunching resumed " + this);
3316
3317 if (DEBUG_STATES && !visible) {
3318 Slog.v(TAG_STATES, "Config is relaunching resumed invisible activity " + this
3319 + " called by " + Debug.getCallers(4));
3320 }
3321
3322 relaunchActivityLocked(true /* andResume */, preserveWindow);
3323 } else {
3324 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3325 "Config is relaunching non-resumed " + this);
3326 relaunchActivityLocked(false /* andResume */, preserveWindow);
3327 }
3328
3329 // All done... tell the caller we weren't able to keep this activity around.
3330 return false;
3331 }
3332
3333 // Default case: the activity can handle this new configuration, so hand it over.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003334 // NOTE: We only forward the override configuration as the system level configuration
Andrii Kulian21713ac2016-10-12 22:05:05 -07003335 // changes is always sent to all processes when they happen so it can just use whatever
3336 // system level configuration it last got.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003337 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003338 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003339 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003340 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003341 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07003342 stopFreezingScreenLocked(false);
3343
3344 return true;
3345 }
3346
Zak Cohen90e7116742017-01-29 12:59:23 -08003347 /**
3348 * When assessing a configuration change, decide if the changes flags and the new configurations
3349 * should cause the Activity to relaunch.
Ruben Brunkf64af332017-03-22 22:03:25 -07003350 *
3351 * @param changes the changes due to the given configuration.
3352 * @param changesConfig the configuration that was used to calculate the given changes via a
3353 * call to getConfigurationChanges.
Zak Cohen90e7116742017-01-29 12:59:23 -08003354 */
Ruben Brunkf64af332017-03-22 22:03:25 -07003355 private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
Zak Cohen90e7116742017-01-29 12:59:23 -08003356 int configChanged = info.getRealConfigChanged();
Ruben Brunkf64af332017-03-22 22:03:25 -07003357 boolean onlyVrUiModeChanged = onlyVrUiModeChanged(changes, changesConfig);
Zak Cohen90e7116742017-01-29 12:59:23 -08003358
3359 // Override for apps targeting pre-O sdks
3360 // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
3361 // to the config change.
3362 // For O and later, apps will be required to add configChanges="uimode" to their manifest.
3363 if (appInfo.targetSdkVersion < O
3364 && requestedVrComponent != null
Ruben Brunkf64af332017-03-22 22:03:25 -07003365 && onlyVrUiModeChanged) {
Zak Cohen90e7116742017-01-29 12:59:23 -08003366 configChanged |= CONFIG_UI_MODE;
3367 }
3368
3369 return (changes&(~configChanged)) != 0;
3370 }
3371
Ruben Brunkf64af332017-03-22 22:03:25 -07003372 /**
3373 * Returns true if the configuration change is solely due to the UI mode switching into or out
3374 * of UI_MODE_TYPE_VR_HEADSET.
3375 */
3376 private boolean onlyVrUiModeChanged(int changes, Configuration lastReportedConfig) {
3377 final Configuration currentConfig = getConfiguration();
Ruben Brunkf53497c2017-03-27 20:26:17 -07003378 return changes == CONFIG_UI_MODE && (isInVrUiMode(currentConfig)
Ruben Brunkf64af332017-03-22 22:03:25 -07003379 != isInVrUiMode(lastReportedConfig));
3380 }
3381
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003382 private int getConfigurationChanges(Configuration lastReportedConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003383 // Determine what has changed. May be nothing, if this is a config that has come back from
3384 // the app after going idle. In that case we just want to leave the official config object
3385 // now in the activity and do nothing else.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003386 final Configuration currentConfig = getConfiguration();
3387 int changes = lastReportedConfig.diff(currentConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003388 // We don't want to use size changes if they don't cross boundaries that are important to
3389 // the app.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003390 if ((changes & CONFIG_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003391 final boolean crosses = crossesHorizontalSizeThreshold(lastReportedConfig.screenWidthDp,
3392 currentConfig.screenWidthDp)
3393 || crossesVerticalSizeThreshold(lastReportedConfig.screenHeightDp,
3394 currentConfig.screenHeightDp);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003395 if (!crosses) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003396 changes &= ~CONFIG_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003397 }
3398 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003399 if ((changes & CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003400 final int oldSmallest = lastReportedConfig.smallestScreenWidthDp;
3401 final int newSmallest = currentConfig.smallestScreenWidthDp;
3402 if (!crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003403 changes &= ~CONFIG_SMALLEST_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003404 }
3405 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07003406 // We don't want window configuration to cause relaunches.
3407 if ((changes & CONFIG_WINDOW_CONFIGURATION) != 0) {
3408 changes &= ~CONFIG_WINDOW_CONFIGURATION;
3409 }
Bryce Lee600dadd2017-07-25 10:48:42 -07003410
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003411 return changes;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003412 }
3413
3414 private static boolean isResizeOnlyChange(int change) {
3415 return (change & ~(CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
3416 | CONFIG_SCREEN_LAYOUT)) == 0;
3417 }
3418
Garfield Tan2746ab52018-07-25 12:33:01 -07003419 private static boolean hasResizeChange(int change) {
3420 return (change & (CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
3421 | CONFIG_SCREEN_LAYOUT)) != 0;
3422 }
3423
Andrii Kulian21713ac2016-10-12 22:05:05 -07003424 void relaunchActivityLocked(boolean andResume, boolean preserveWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003425 if (mAtmService.mSuppressResizeConfigChanges && preserveWindow) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003426 configChangeFlags = 0;
3427 return;
3428 }
3429
3430 List<ResultInfo> pendingResults = null;
3431 List<ReferrerIntent> pendingNewIntents = null;
3432 if (andResume) {
3433 pendingResults = results;
3434 pendingNewIntents = newIntents;
3435 }
3436 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
3437 "Relaunching: " + this + " with results=" + pendingResults
3438 + " newIntents=" + pendingNewIntents + " andResume=" + andResume
3439 + " preserveWindow=" + preserveWindow);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003440 EventLog.writeEvent(andResume ? AM_RELAUNCH_RESUME_ACTIVITY
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003441 : AM_RELAUNCH_ACTIVITY, mUserId, System.identityHashCode(this),
Andrii Kulian21713ac2016-10-12 22:05:05 -07003442 task.taskId, shortComponentName);
3443
3444 startFreezingScreenLocked(app, 0);
3445
Andrii Kulian21713ac2016-10-12 22:05:05 -07003446 try {
3447 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
3448 "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this
3449 + " callers=" + Debug.getCallers(6));
3450 forceNewConfig = false;
3451 mStackSupervisor.activityRelaunchingLocked(this);
Andrii Kulianb372da62018-01-18 10:46:24 -08003452 final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
3453 pendingNewIntents, configChangeFlags,
Andrii Kulianbeadacc2019-05-20 12:18:01 +00003454 new MergedConfiguration(mAtmService.getGlobalConfiguration(),
Andrii Kulianb372da62018-01-18 10:46:24 -08003455 getMergedOverrideConfiguration()),
3456 preserveWindow);
3457 final ActivityLifecycleItem lifecycleItem;
3458 if (andResume) {
lumark588a3e82018-07-20 18:53:54 +08003459 lifecycleItem = ResumeActivityItem.obtain(
Wale Ogunwale3a256e62018-12-06 14:41:18 -08003460 getDisplay().mDisplayContent.isNextTransitionForward());
Andrii Kulianb372da62018-01-18 10:46:24 -08003461 } else {
Bryce Lee1d0d5142018-04-12 10:35:07 -07003462 lifecycleItem = PauseActivityItem.obtain();
Andrii Kulianb372da62018-01-18 10:46:24 -08003463 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003464 final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), appToken);
Andrii Kulianb372da62018-01-18 10:46:24 -08003465 transaction.addCallback(callbackItem);
3466 transaction.setLifecycleStateRequest(lifecycleItem);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003467 mAtmService.getLifecycleManager().scheduleTransaction(transaction);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003468 // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
Andrii Kulianb372da62018-01-18 10:46:24 -08003469 // request resume if this activity is currently resumed, which implies we aren't
Andrii Kulian21713ac2016-10-12 22:05:05 -07003470 // sleeping.
3471 } catch (RemoteException e) {
3472 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
3473 }
3474
3475 if (andResume) {
3476 if (DEBUG_STATES) {
3477 Slog.d(TAG_STATES, "Resumed after relaunch " + this);
3478 }
3479 results = null;
3480 newIntents = null;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003481 mAtmService.getAppWarningsLocked().onResumeActivity(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003482 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003483 final ActivityStack stack = getActivityStack();
Wale Ogunwale008163e2018-07-23 23:11:08 -07003484 if (stack != null) {
3485 stack.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
3486 }
Bryce Lee7ace3952018-02-16 14:34:32 -08003487 setState(PAUSED, "relaunchActivityLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07003488 }
3489
3490 configChangeFlags = 0;
3491 deferRelaunchUntilPaused = false;
3492 preserveWindowOnDeferredRelaunch = false;
3493 }
3494
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003495 /**
3496 * Request the process of the activity to restart with its saved state (from
3497 * {@link android.app.Activity#onSaveInstanceState}) if possible. It also forces to recompute
3498 * the override configuration. Note if the activity is in background, the process will be killed
3499 * directly with keeping its record.
3500 */
3501 void restartProcessIfVisible() {
3502 Slog.i(TAG, "Request to restart process of " + this);
3503
Riddle Hsuaec55442019-03-12 17:25:35 +08003504 // Reset the existing override configuration so it can be updated according to the latest
3505 // configuration.
Riddle Hsu74826262019-04-17 14:57:42 +08003506 getRequestedOverrideConfiguration().unset();
3507 getResolvedOverrideConfiguration().unset();
Riddle Hsu61987bc2019-04-03 13:08:47 +08003508 mCompatDisplayInsets = null;
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003509 if (visible) {
3510 // Configuration will be ensured when becoming visible, so if it is already visible,
3511 // then the manual update is needed.
3512 updateOverrideConfiguration();
3513 }
3514
3515 if (!attachedToProcess()) {
3516 return;
3517 }
3518
3519 // The restarting state avoids removing this record when process is died.
3520 setState(RESTARTING_PROCESS, "restartActivityProcess");
3521
3522 if (!visible || haveState) {
3523 // Kill its process immediately because the activity should be in background.
3524 // The activity state will be update to {@link #DESTROYED} in
3525 // {@link ActivityStack#cleanUpActivityLocked} when handling process died.
Riddle Hsuaec55442019-03-12 17:25:35 +08003526 mAtmService.mH.post(() -> {
3527 final WindowProcessController wpc;
3528 synchronized (mAtmService.mGlobalLock) {
3529 if (!hasProcess()
3530 || app.getReportedProcState() <= PROCESS_STATE_IMPORTANT_FOREGROUND) {
3531 return;
3532 }
3533 wpc = app;
3534 }
3535 mAtmService.mAmInternal.killProcess(wpc.mName, wpc.mUid, "resetConfig");
3536 });
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003537 return;
3538 }
3539
3540 if (mAppWindowToken != null) {
3541 mAppWindowToken.startFreezingScreen();
3542 }
3543 // The process will be killed until the activity reports stopped with saved state (see
3544 // {@link ActivityTaskManagerService.activityStopped}).
3545 try {
3546 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
3547 StopActivityItem.obtain(false /* showWindow */, 0 /* configChanges */));
3548 } catch (RemoteException e) {
3549 Slog.w(TAG, "Exception thrown during restart " + this, e);
3550 }
3551 mStackSupervisor.scheduleRestartTimeout(this);
3552 }
3553
Jorim Jaggibae01b12017-04-11 16:29:10 -07003554 private boolean isProcessRunning() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003555 WindowProcessController proc = app;
Jorim Jaggi02886a82016-12-06 09:10:06 -08003556 if (proc == null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003557 proc = mAtmService.mProcessNames.get(processName, info.applicationInfo.uid);
Jorim Jaggi02886a82016-12-06 09:10:06 -08003558 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003559 return proc != null && proc.hasThread();
Jorim Jaggi02886a82016-12-06 09:10:06 -08003560 }
3561
Jorim Jaggibae01b12017-04-11 16:29:10 -07003562 /**
3563 * @return Whether a task snapshot starting window may be shown.
3564 */
3565 private boolean allowTaskSnapshot() {
3566 if (newIntents == null) {
3567 return true;
3568 }
3569
3570 // Restrict task snapshot starting window to launcher start, or there is no intent at all
3571 // (eg. task being brought to front). If the intent is something else, likely the app is
3572 // going to show some specific page or view, instead of what's left last time.
3573 for (int i = newIntents.size() - 1; i >= 0; i--) {
3574 final Intent intent = newIntents.get(i);
3575 if (intent != null && !ActivityRecord.isMainIntent(intent)) {
3576 return false;
3577 }
3578 }
3579 return true;
3580 }
3581
Bryce Leeb7c9b802017-05-02 14:20:24 -07003582 /**
3583 * Returns {@code true} if the associated activity has the no history flag set on it.
3584 * {@code false} otherwise.
3585 */
3586 boolean isNoHistory() {
3587 return (intent.getFlags() & FLAG_ACTIVITY_NO_HISTORY) != 0
3588 || (info.flags & FLAG_NO_HISTORY) != 0;
3589 }
3590
Craig Mautner21d24a22014-04-23 11:45:37 -07003591 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
3592 out.attribute(null, ATTR_ID, String.valueOf(createTime));
3593 out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
3594 if (launchedFromPackage != null) {
3595 out.attribute(null, ATTR_LAUNCHEDFROMPACKAGE, launchedFromPackage);
3596 }
3597 if (resolvedType != null) {
3598 out.attribute(null, ATTR_RESOLVEDTYPE, resolvedType);
3599 }
3600 out.attribute(null, ATTR_COMPONENTSPECIFIED, String.valueOf(componentSpecified));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003601 out.attribute(null, ATTR_USERID, String.valueOf(mUserId));
Winson Chung2cb86c72014-06-25 12:03:30 -07003602
Craig Mautner21d24a22014-04-23 11:45:37 -07003603 if (taskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003604 taskDescription.saveToXml(out);
Craig Mautner21d24a22014-04-23 11:45:37 -07003605 }
3606
3607 out.startTag(null, TAG_INTENT);
3608 intent.saveToXml(out);
3609 out.endTag(null, TAG_INTENT);
3610
3611 if (isPersistable() && persistentState != null) {
3612 out.startTag(null, TAG_PERSISTABLEBUNDLE);
3613 persistentState.saveToXml(out);
3614 out.endTag(null, TAG_PERSISTABLEBUNDLE);
3615 }
3616 }
3617
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07003618 static ActivityRecord restoreFromXml(XmlPullParser in,
3619 ActivityStackSupervisor stackSupervisor) throws IOException, XmlPullParserException {
Craig Mautner21d24a22014-04-23 11:45:37 -07003620 Intent intent = null;
3621 PersistableBundle persistentState = null;
3622 int launchedFromUid = 0;
3623 String launchedFromPackage = null;
3624 String resolvedType = null;
3625 boolean componentSpecified = false;
3626 int userId = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07003627 long createTime = -1;
3628 final int outerDepth = in.getDepth();
Winson Chung2cb86c72014-06-25 12:03:30 -07003629 TaskDescription taskDescription = new TaskDescription();
Craig Mautner21d24a22014-04-23 11:45:37 -07003630
3631 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
3632 final String attrName = in.getAttributeName(attrNdx);
3633 final String attrValue = in.getAttributeValue(attrNdx);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003634 if (DEBUG) Slog.d(TaskPersister.TAG,
Wale Ogunwale18795a22014-12-03 11:38:33 -08003635 "ActivityRecord: attribute name=" + attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003636 if (ATTR_ID.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01003637 createTime = Long.parseLong(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003638 } else if (ATTR_LAUNCHEDFROMUID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003639 launchedFromUid = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003640 } else if (ATTR_LAUNCHEDFROMPACKAGE.equals(attrName)) {
3641 launchedFromPackage = attrValue;
3642 } else if (ATTR_RESOLVEDTYPE.equals(attrName)) {
3643 resolvedType = attrValue;
3644 } else if (ATTR_COMPONENTSPECIFIED.equals(attrName)) {
Tobias Thiererb0800dc2016-04-21 17:51:41 +01003645 componentSpecified = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003646 } else if (ATTR_USERID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003647 userId = Integer.parseInt(attrValue);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003648 } else if (attrName.startsWith(ATTR_TASKDESCRIPTION_PREFIX)) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003649 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003650 } else {
3651 Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
3652 }
3653 }
3654
3655 int event;
Ruben Brunkf53497c2017-03-27 20:26:17 -07003656 while (((event = in.next()) != END_DOCUMENT) &&
3657 (event != END_TAG || in.getDepth() >= outerDepth)) {
3658 if (event == START_TAG) {
Craig Mautner21d24a22014-04-23 11:45:37 -07003659 final String name = in.getName();
Ruben Brunkf53497c2017-03-27 20:26:17 -07003660 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003661 Slog.d(TaskPersister.TAG, "ActivityRecord: START_TAG name=" + name);
Craig Mautner21d24a22014-04-23 11:45:37 -07003662 if (TAG_INTENT.equals(name)) {
3663 intent = Intent.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003664 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003665 Slog.d(TaskPersister.TAG, "ActivityRecord: intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003666 } else if (TAG_PERSISTABLEBUNDLE.equals(name)) {
3667 persistentState = PersistableBundle.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003668 if (DEBUG) Slog.d(TaskPersister.TAG,
Craig Mautner21d24a22014-04-23 11:45:37 -07003669 "ActivityRecord: persistentState=" + persistentState);
3670 } else {
3671 Slog.w(TAG, "restoreActivity: unexpected name=" + name);
3672 XmlUtils.skipCurrentTag(in);
3673 }
3674 }
3675 }
3676
3677 if (intent == null) {
Craig Mautnere0129b32014-05-25 16:41:09 -07003678 throw new XmlPullParserException("restoreActivity error intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003679 }
3680
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003681 final ActivityTaskManagerService service = stackSupervisor.mService;
Craig Mautner21d24a22014-04-23 11:45:37 -07003682 final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null,
Patrick Baumann78380272018-04-04 10:41:01 -07003683 userId, Binder.getCallingUid());
Craig Mautnere0129b32014-05-25 16:41:09 -07003684 if (aInfo == null) {
Craig Mautner77b04262014-06-27 15:22:12 -07003685 throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
3686 " resolvedType=" + resolvedType);
Craig Mautnere0129b32014-05-25 16:41:09 -07003687 }
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003688 final ActivityRecord r = new ActivityRecord(service, null /* caller */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003689 0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType,
Wale Ogunwalef6733932018-06-27 05:14:34 -07003690 aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003691 0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07003692 stackSupervisor, null /* options */, null /* sourceRecord */);
Craig Mautner21d24a22014-04-23 11:45:37 -07003693
3694 r.persistentState = persistentState;
Winson Chung2cb86c72014-06-25 12:03:30 -07003695 r.taskDescription = taskDescription;
Craig Mautner21d24a22014-04-23 11:45:37 -07003696 r.createTime = createTime;
3697
3698 return r;
3699 }
3700
Zak Cohen90e7116742017-01-29 12:59:23 -08003701 private static boolean isInVrUiMode(Configuration config) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07003702 return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
Zak Cohen90e7116742017-01-29 12:59:23 -08003703 }
3704
David Stevens82ea6cb2017-03-03 16:18:50 -08003705 int getUid() {
3706 return info.applicationInfo.uid;
3707 }
3708
chaviw59b98852017-06-13 12:05:44 -07003709 void setShowWhenLocked(boolean showWhenLocked) {
3710 mShowWhenLocked = showWhenLocked;
Wale Ogunwaled32da472018-11-16 07:19:28 -08003711 mRootActivityContainer.ensureActivitiesVisible(null, 0 /* configChanges */,
Kevin Chyn44639482017-10-09 18:34:41 -07003712 false /* preserveWindows */);
chaviw59b98852017-06-13 12:05:44 -07003713 }
3714
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003715 void setInheritShowWhenLocked(boolean inheritShowWhenLocked) {
3716 mInheritShownWhenLocked = inheritShowWhenLocked;
3717 mRootActivityContainer.ensureActivitiesVisible(null, 0, false);
3718 }
3719
chaviw59b98852017-06-13 12:05:44 -07003720 /**
chaviw2c500982018-01-04 17:05:05 -08003721 * @return true if the activity windowing mode is not
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003722 * {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and a) activity
3723 * contains windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the
3724 * activity has set {@link #mShowWhenLocked}, or b) if the activity has set
3725 * {@link #mInheritShownWhenLocked} and the activity behind this satisfies the
3726 * conditions a) above.
chaviw2c500982018-01-04 17:05:05 -08003727 * Multi-windowing mode will be exited if true is returned.
chaviw59b98852017-06-13 12:05:44 -07003728 */
3729 boolean canShowWhenLocked() {
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003730 if (!inPinnedWindowingMode() && (mShowWhenLocked
3731 || (mAppWindowToken != null && mAppWindowToken.containsShowWhenLockedWindow()))) {
3732 return true;
3733 } else if (mInheritShownWhenLocked) {
3734 ActivityRecord r = getActivityBelow();
3735 return r != null && !r.inPinnedWindowingMode() && (r.mShowWhenLocked
3736 || (r.mAppWindowToken != null
3737 && r.mAppWindowToken.containsShowWhenLockedWindow()));
3738 } else {
3739 return false;
3740 }
3741 }
3742
3743 /**
3744 * @return an {@link ActivityRecord} of the activity below this activity, or {@code null} if no
3745 * such activity exists.
3746 */
3747 @Nullable
3748 private ActivityRecord getActivityBelow() {
3749 final int pos = task.mActivities.indexOf(this);
3750 if (pos == -1) {
3751 throw new IllegalStateException("Activity not found in its task");
3752 }
3753 return pos == 0 ? null : task.getChildAt(pos - 1);
chaviw59b98852017-06-13 12:05:44 -07003754 }
3755
3756 void setTurnScreenOn(boolean turnScreenOn) {
3757 mTurnScreenOn = turnScreenOn;
3758 }
3759
3760 /**
3761 * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
3762 * {@link #mTurnScreenOn} is set and checks whether the ActivityRecord should be visible
3763 * depending on Keyguard state
3764 *
3765 * @return true if the screen can be turned on, false otherwise.
3766 */
3767 boolean canTurnScreenOn() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003768 final ActivityStack stack = getActivityStack();
chaviw59b98852017-06-13 12:05:44 -07003769 return mTurnScreenOn && stack != null &&
3770 stack.checkKeyguardVisibility(this, true /* shouldBeVisible */, true /* isTop */);
3771 }
3772
Louis Chang77ce34d2019-01-03 15:45:12 +08003773 /**
3774 * Check if this activity is able to resume. For pre-Q apps, only the topmost activities of each
3775 * process are allowed to be resumed.
3776 *
3777 * @return true if this activity can be resumed.
3778 */
3779 boolean canResumeByCompat() {
3780 return app == null || app.updateTopResumingActivityInProcessIfNeeded(this);
3781 }
3782
chaviw59b98852017-06-13 12:05:44 -07003783 boolean getTurnScreenOnFlag() {
3784 return mTurnScreenOn;
3785 }
3786
3787 boolean isTopRunningActivity() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003788 return mRootActivityContainer.topRunningActivity() == this;
chaviw59b98852017-06-13 12:05:44 -07003789 }
3790
Andrii Kulian52d255c2018-07-13 11:32:19 -07003791 /**
3792 * @return {@code true} if this is the resumed activity on its current display, {@code false}
3793 * otherwise.
3794 */
3795 boolean isResumedActivityOnDisplay() {
3796 final ActivityDisplay display = getDisplay();
3797 return display != null && this == display.getResumedActivity();
3798 }
3799
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003800 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003801 if (mAppWindowToken == null) {
3802 Slog.w(TAG_WM, "Attempted to register remote animations with non-existing app"
3803 + " token: " + appToken);
3804 return;
3805 }
3806 mAppWindowToken.registerRemoteAnimations(definition);
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003807 }
3808
Craig Mautnerf81b90872013-02-26 13:02:43 -08003809 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003810 public String toString() {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003811 if (stringName != null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08003812 return stringName + " t" + (task == null ? INVALID_TASK_ID : task.taskId) +
Craig Mautnerf3333272013-04-22 10:55:53 -07003813 (finishing ? " f}" : "}");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003814 }
3815 StringBuilder sb = new StringBuilder(128);
Dianne Hackborn30d71892010-12-11 10:37:55 -08003816 sb.append("ActivityRecord{");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003817 sb.append(Integer.toHexString(System.identityHashCode(this)));
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003818 sb.append(" u");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003819 sb.append(mUserId);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003820 sb.append(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003821 sb.append(intent.getComponent().flattenToShortString());
Craig Mautnerf81b90872013-02-26 13:02:43 -08003822 stringName = sb.toString();
3823 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003824 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07003825
3826 void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
3827 final long token = proto.start(fieldId);
3828 proto.write(HASH_CODE, System.identityHashCode(this));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003829 proto.write(USER_ID, mUserId);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003830 proto.write(TITLE, intent.getComponent().flattenToShortString());
3831 proto.end(token);
3832 }
3833
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003834 /**
3835 * Write all fields to an {@code ActivityRecordProto}. This assumes the
3836 * {@code ActivityRecordProto} is the outer-most proto data.
3837 */
3838 void writeToProto(ProtoOutputStream proto) {
Nataniel Borges023ecb52019-01-16 14:15:43 -08003839 super.writeToProto(proto, CONFIGURATION_CONTAINER, WindowTraceLogLevel.ALL);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003840 writeIdentifierToProto(proto, IDENTIFIER);
Bryce Lee7ace3952018-02-16 14:34:32 -08003841 proto.write(STATE, mState.toString());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003842 proto.write(VISIBLE, visible);
3843 proto.write(FRONT_OF_TASK, frontOfTask);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003844 if (hasProcess()) {
3845 proto.write(PROC_ID, app.getPid());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003846 }
Wale Ogunwale30eab1f2018-05-24 18:25:25 -07003847 proto.write(TRANSLUCENT, !fullscreen);
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003848 }
3849
3850 public void writeToProto(ProtoOutputStream proto, long fieldId) {
3851 final long token = proto.start(fieldId);
3852 writeToProto(proto);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003853 proto.end(token);
3854 }
Riddle Hsu61987bc2019-04-03 13:08:47 +08003855
3856 /**
3857 * The precomputed insets of the display in each rotation. This is used to make the size
3858 * compatibility mode activity compute the configuration without relying on its current display.
3859 */
3860 static class CompatDisplayInsets {
3861 final int mDisplayWidth;
3862 final int mDisplayHeight;
3863
Riddle Hsu74826262019-04-17 14:57:42 +08003864 /**
3865 * The nonDecorInsets for each rotation. Includes the navigation bar and cutout insets. It
3866 * is used to compute the appBounds.
3867 */
Riddle Hsu61987bc2019-04-03 13:08:47 +08003868 final Rect[] mNonDecorInsets = new Rect[4];
3869 /**
3870 * The stableInsets for each rotation. Includes the status bar inset and the
3871 * nonDecorInsets. It is used to compute {@link Configuration#screenWidthDp} and
3872 * {@link Configuration#screenHeightDp}.
3873 */
3874 final Rect[] mStableInsets = new Rect[4];
3875
3876 CompatDisplayInsets(DisplayContent display) {
3877 mDisplayWidth = display.mBaseDisplayWidth;
3878 mDisplayHeight = display.mBaseDisplayHeight;
3879 final DisplayPolicy policy = display.getDisplayPolicy();
Riddle Hsu61987bc2019-04-03 13:08:47 +08003880 for (int rotation = 0; rotation < 4; rotation++) {
3881 mNonDecorInsets[rotation] = new Rect();
3882 mStableInsets[rotation] = new Rect();
3883 final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
3884 final int dw = rotated ? mDisplayHeight : mDisplayWidth;
3885 final int dh = rotated ? mDisplayWidth : mDisplayHeight;
Riddle Hsu74826262019-04-17 14:57:42 +08003886 final DisplayCutout cutout = display.calculateDisplayCutoutForRotation(rotation)
3887 .getDisplayCutout();
Riddle Hsu61987bc2019-04-03 13:08:47 +08003888 policy.getNonDecorInsetsLw(rotation, dw, dh, cutout, mNonDecorInsets[rotation]);
3889 mStableInsets[rotation].set(mNonDecorInsets[rotation]);
3890 policy.convertNonDecorInsetsToStableInsets(mStableInsets[rotation], rotation);
3891 }
3892 }
3893
Riddle Hsu74826262019-04-17 14:57:42 +08003894 void getDisplayBoundsByRotation(Rect outBounds, int rotation) {
Riddle Hsu61987bc2019-04-03 13:08:47 +08003895 final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
3896 final int dw = rotated ? mDisplayHeight : mDisplayWidth;
3897 final int dh = rotated ? mDisplayWidth : mDisplayHeight;
3898 outBounds.set(0, 0, dw, dh);
3899 }
Riddle Hsu74826262019-04-17 14:57:42 +08003900
3901 void getDisplayBoundsByOrientation(Rect outBounds, int orientation) {
3902 final int longSide = Math.max(mDisplayWidth, mDisplayHeight);
3903 final int shortSide = Math.min(mDisplayWidth, mDisplayHeight);
3904 final boolean isLandscape = orientation == ORIENTATION_LANDSCAPE;
3905 outBounds.set(0, 0, isLandscape ? longSide : shortSide,
3906 isLandscape ? shortSide : longSide);
3907 }
Riddle Hsu61987bc2019-04-03 13:08:47 +08003908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003909}