blob: 4706930928f45f38566a253737a1cb7f4e8b9ad2 [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;
Ruben Brunkf53497c2017-03-27 20:26:17 -070020import static android.app.ActivityManager.TaskDescription.ATTR_TASKDESCRIPTION_PREFIX;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080021import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
22import static android.app.ActivityOptions.ANIM_CUSTOM;
23import static android.app.ActivityOptions.ANIM_NONE;
24import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
25import static android.app.ActivityOptions.ANIM_REMOTE_ANIMATION;
26import static android.app.ActivityOptions.ANIM_SCALE_UP;
Ruben Brunkf53497c2017-03-27 20:26:17 -070027import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080028import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
29import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP;
30import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
31import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
Riddle Hsu16567132018-08-16 21:37:47 +080032import static android.app.ActivityTaskManager.INVALID_STACK_ID;
Vishnu Nair9ba31652018-11-13 14:34:05 -080033import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Winson Chung59fda9e2017-01-20 16:14:51 -080034import static android.app.AppOpsManager.MODE_ALLOWED;
Winson Chungf4ac0632017-03-17 12:34:12 -070035import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
Vishnu Nair132ee832018-09-28 15:00:05 -070036import static android.app.WaitResult.INVALID_DELAY;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070037import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
38import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
39import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070040import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
41import static android.app.WindowConfiguration.activityTypeToString;
Ruben Brunkf53497c2017-03-27 20:26:17 -070042import static android.content.Intent.ACTION_MAIN;
43import static android.content.Intent.CATEGORY_HOME;
44import static android.content.Intent.CATEGORY_LAUNCHER;
Chilun2ef71f72018-11-16 17:57:15 +080045import static android.content.Intent.CATEGORY_SECONDARY_HOME;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080046import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
Bryce Leeb7c9b802017-05-02 14:20:24 -070047import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY;
Andrii Kulian21713ac2016-10-12 22:05:05 -070048import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
49import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
50import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
51import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
Zak Cohen90e7116742017-01-29 12:59:23 -080052import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
Wale Ogunwale822e5122017-07-26 06:02:24 -070053import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
Jorim Jaggi02886a82016-12-06 09:10:06 -080054import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080055import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
56import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
Issei Suzuki74e1eb22018-12-20 17:42:52 +010057import static android.content.pm.ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080058import static android.content.pm.ActivityInfo.FLAG_MULTIPROCESS;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020059import static android.content.pm.ActivityInfo.FLAG_NO_HISTORY;
Chong Zhang87761972016-08-22 13:53:24 -070060import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020061import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080062import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
chaviw59b98852017-06-13 12:05:44 -070063import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080064import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -080065import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
66import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080067import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
Charles He2bf28322017-10-12 22:24:49 +010068import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
69import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
70import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
71import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
Ruben Brunkf53497c2017-03-27 20:26:17 -070072import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS;
73import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY;
Wale Ogunwaledf241e92016-10-13 15:14:21 -070074import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Jorim Jaggicd13d332016-04-27 15:40:20 -070075import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Wale Ogunwale72a73e32016-10-13 12:16:39 -070076import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Wale Ogunwaledf241e92016-10-13 15:14:21 -070077import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -070078import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
79import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -070080import static android.content.res.Configuration.EMPTY;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -070081import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
82import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
Riddle Hsu0a343c32018-12-21 00:40:48 +080083import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
Ruben Brunkf53497c2017-03-27 20:26:17 -070084import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
Zak Cohen90e7116742017-01-29 12:59:23 -080085import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080086import static android.os.Build.VERSION_CODES.HONEYCOMB;
Zak Cohen90e7116742017-01-29 12:59:23 -080087import static android.os.Build.VERSION_CODES.O;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080088import static android.os.Process.SYSTEM_UID;
Riddle Hsufd4a0502018-10-16 01:05:16 +080089import static android.view.Display.INVALID_DISPLAY;
Riddle Hsu16567132018-08-16 21:37:47 +080090
Vishnu Nair9ba31652018-11-13 14:34:05 -080091import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
92import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
93import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
94import static com.android.server.am.ActivityRecordProto.PROC_ID;
95import static com.android.server.am.ActivityRecordProto.STATE;
96import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
97import static com.android.server.am.ActivityRecordProto.VISIBLE;
98import static com.android.server.am.EventLogTags.AM_RELAUNCH_ACTIVITY;
99import static com.android.server.am.EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY;
Hui Yu03d12402018-12-06 18:00:37 -0800100import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800101import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
102import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
103import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
Riddle Hsu7b766fd2019-01-28 21:14:59 +0800104import static com.android.server.wm.ActivityStack.ActivityState.RESTARTING_PROCESS;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800105import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
106import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
107import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
108import static com.android.server.wm.ActivityStack.LAUNCH_TICK;
109import static com.android.server.wm.ActivityStack.LAUNCH_TICK_MSG;
110import static com.android.server.wm.ActivityStack.PAUSE_TIMEOUT_MSG;
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800111import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800112import static com.android.server.wm.ActivityStack.STOP_TIMEOUT_MSG;
Wale Ogunwale59507092018-10-29 09:00:30 -0700113import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
114import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
115import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
116import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
117import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
118import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
119import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
120import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
121import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SAVED_STATE;
122import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
123import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
124import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
125import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
126import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwale59507092018-10-29 09:00:30 -0700127import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
128import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
Hui Yu03d12402018-12-06 18:00:37 -0800129import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -0700130import static com.android.server.wm.IdentifierProto.HASH_CODE;
131import static com.android.server.wm.IdentifierProto.TITLE;
132import static com.android.server.wm.IdentifierProto.USER_ID;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800133import static com.android.server.wm.TaskPersister.DEBUG;
134import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800135import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
136import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
137import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
138import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
139import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700140
Ruben Brunkf53497c2017-03-27 20:26:17 -0700141import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
142import static org.xmlpull.v1.XmlPullParser.END_TAG;
143import static org.xmlpull.v1.XmlPullParser.START_TAG;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800144
Andrii Kulian21713ac2016-10-12 22:05:05 -0700145import android.annotation.NonNull;
Issei Suzuki74e1eb22018-12-20 17:42:52 +0100146import android.annotation.Nullable;
Craig Mautner21d24a22014-04-23 11:45:37 -0700147import android.app.ActivityManager.TaskDescription;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700148import android.app.ActivityOptions;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800149import android.app.PendingIntent;
Winson Chung709904f2017-04-25 11:00:48 -0700150import android.app.PictureInPictureParams;
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800151import android.app.ResultInfo;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -0800152import android.app.WaitResult.LaunchState;
Riddle Hsu16567132018-08-16 21:37:47 +0800153import android.app.servertransaction.ActivityConfigurationChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800154import android.app.servertransaction.ActivityLifecycleItem;
155import android.app.servertransaction.ActivityRelaunchItem;
156import android.app.servertransaction.ClientTransaction;
157import android.app.servertransaction.ClientTransactionItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700158import android.app.servertransaction.MoveToDisplayItem;
159import android.app.servertransaction.MultiWindowModeChangeItem;
160import android.app.servertransaction.NewIntentItem;
Bryce Lee0bd8d422018-01-09 09:45:57 -0800161import android.app.servertransaction.PauseActivityItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700162import android.app.servertransaction.PipModeChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800163import android.app.servertransaction.ResumeActivityItem;
Riddle Hsu7b766fd2019-01-28 21:14:59 +0800164import android.app.servertransaction.StopActivityItem;
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800165import android.app.servertransaction.TopResumedActivityChangeItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700166import android.app.servertransaction.WindowVisibilityItem;
Hui Yu03d12402018-12-06 18:00:37 -0800167import android.app.usage.UsageEvents.Event;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168import android.content.ComponentName;
169import android.content.Intent;
170import android.content.pm.ActivityInfo;
171import android.content.pm.ApplicationInfo;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700172import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173import android.content.res.Configuration;
174import android.graphics.Bitmap;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800175import android.graphics.GraphicBuffer;
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700176import android.graphics.Rect;
Patrick Baumann78380272018-04-04 10:41:01 -0700177import android.os.Binder;
Bryce Lee39791592017-04-26 09:29:12 -0700178import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179import android.os.Bundle;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700180import android.os.Debug;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800181import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182import android.os.Message;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800183import android.os.PersistableBundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184import android.os.Process;
Dianne Hackborn39792d22010-08-19 18:01:52 -0700185import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700187import android.os.UserHandle;
Bryce Lee8558ec72017-08-17 15:37:26 -0700188import android.os.storage.StorageManager;
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800189import android.service.voice.IVoiceInteractionSession;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190import android.util.EventLog;
191import android.util.Log;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700192import android.util.MergedConfiguration;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700193import android.util.Slog;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700194import android.util.TimeUtils;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700195import android.util.proto.ProtoOutputStream;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800196import android.view.AppTransitionAnimationSpec;
197import android.view.IAppTransitionAnimationSpecsFuture;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198import android.view.IApplicationToken;
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100199import android.view.RemoteAnimationDefinition;
Jorim Jaggife762342016-10-13 14:33:27 +0200200import android.view.WindowManager.LayoutParams;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700201
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700202import com.android.internal.R;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800203import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800204import com.android.internal.app.ResolverActivity;
205import com.android.internal.content.ReferrerIntent;
206import com.android.internal.util.XmlUtils;
207import com.android.server.AttributeCache;
Ruben Brunkf53497c2017-03-27 20:26:17 -0700208import com.android.server.AttributeCache.Entry;
Wale Ogunwale59507092018-10-29 09:00:30 -0700209import com.android.server.am.AppTimeTracker;
210import com.android.server.am.PendingIntentRecord;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800211import com.android.server.uri.UriPermissionOwner;
Wale Ogunwale59507092018-10-29 09:00:30 -0700212import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
213import com.android.server.wm.ActivityStack.ActivityState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214
Jorim Jaggi02886a82016-12-06 09:10:06 -0800215import org.xmlpull.v1.XmlPullParser;
216import org.xmlpull.v1.XmlPullParserException;
217import org.xmlpull.v1.XmlSerializer;
218
Suprabh Shukla23593142015-11-03 17:31:15 -0800219import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -0700220import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221import java.io.PrintWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800224import java.util.Arrays;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225import java.util.HashSet;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700226import java.util.List;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700227import java.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228
229/**
230 * An entry in the history stack, representing an activity.
231 */
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800232final class ActivityRecord extends ConfigurationContainer {
Wale Ogunwale98875612018-10-12 07:53:02 -0700233 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_ATM;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700234 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
235 private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700236 private static final String TAG_STATES = TAG + POSTFIX_STATES;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700237 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700238 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
Louis Chang19443452018-10-09 12:10:21 +0800239 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
Winson Chung16e185e2017-11-07 08:30:54 -0800240 // TODO(b/67864419): Remove once recents component is overridden
241 private static final String LEGACY_RECENTS_PACKAGE_NAME = "com.android.systemui.recents";
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800242
Wale Ogunwale3ab9a272015-03-16 09:55:45 -0700243 private static final boolean SHOW_ACTIVITY_START_TIME = true;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700244
Craig Mautner21d24a22014-04-23 11:45:37 -0700245 private static final String ATTR_ID = "id";
246 private static final String TAG_INTENT = "intent";
247 private static final String ATTR_USERID = "user_id";
248 private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle";
249 private static final String ATTR_LAUNCHEDFROMUID = "launched_from_uid";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700250 private static final String ATTR_LAUNCHEDFROMPACKAGE = "launched_from_package";
Craig Mautner21d24a22014-04-23 11:45:37 -0700251 private static final String ATTR_RESOLVEDTYPE = "resolved_type";
252 private static final String ATTR_COMPONENTSPECIFIED = "component_specified";
Dianne Hackborn337abb32014-09-24 12:44:29 -0700253 static final String ACTIVITY_ICON_SUFFIX = "_activity_icon_";
Craig Mautner21d24a22014-04-23 11:45:37 -0700254
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800255 final ActivityTaskManagerService mAtmService; // owner
Dianne Hackbornbe707852011-11-11 14:32:10 -0800256 final IApplicationToken.Stub appToken; // window manager token
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800257 // TODO: Remove after unification
258 AppWindowToken mAppWindowToken;
259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 final ActivityInfo info; // all about me
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700261 // TODO: This is duplicated state already contained in info.applicationInfo - remove
262 ApplicationInfo appInfo; // information about activity's app
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800263 final int launchedFromPid; // always the pid who started the activity.
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700264 final int launchedFromUid; // always the uid who started the activity.
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800265 final String launchedFromPackage; // always the package who started the activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800266 final int mUserId; // Which user is this running for?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 final Intent intent; // the original intent that generated us
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800268 final ComponentName mActivityComponent; // the intent component, or target of an alias.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 final String shortComponentName; // the short component name of the intent
270 final String resolvedType; // as per original caller;
271 final String packageName; // the package implementing intent's component
272 final String processName; // process where this component wants to run
273 final String taskAffinity; // as per ActivityInfo.taskAffinity
274 final boolean stateNotNeeded; // As per ActivityInfo.flags
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700275 boolean fullscreen; // The activity is opaque and fills the entire space of this task.
276 // TODO: See if it possible to combine this with the fullscreen field.
277 final boolean hasWallpaper; // Has a wallpaper window as a background.
Louis Changd58cb672018-12-24 17:45:16 +0800278 @VisibleForTesting
279 boolean noDisplay; // activity is not displayed?
280 @VisibleForTesting
281 int mHandoverLaunchDisplayId = INVALID_DISPLAY; // Handover launch display id to next activity.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800282 private final boolean componentSpecified; // did caller specify an explicit component?
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700283 final boolean rootVoiceInteraction; // was this the root activity of a voice interaction?
Craig Mautner86d67a42013-05-14 10:34:38 -0700284
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800285 private CharSequence nonLocalizedLabel; // the label information from the package mgr.
286 private int labelRes; // the label information from the package mgr.
287 private int icon; // resource identifier of activity's icon.
288 private int logo; // resource identifier of activity's logo.
289 private int theme; // resource identifier of activity's theme.
290 private int realTheme; // actual theme resource we will use, never 0.
291 private int windowFlags; // custom window flags for preview window.
Bryce Leeaf691c02017-03-20 14:20:22 -0700292 private TaskRecord task; // the task this is in.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800293 private long createTime = System.currentTimeMillis();
Andrii Kulian86e70fc2019-02-12 11:04:10 +0000294 long lastVisibleTime; // last time this activity became visible
295 long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity
296 long pauseTime; // last time we started pausing the activity
297 long launchTickTime; // base time for launch tick messages
298 long topResumedStateLossTime; // last time we reported top resumed state loss to an activity
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700299 // Last configuration reported to the activity in the client process.
300 private MergedConfiguration mLastReportedConfiguration;
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800301 private int mLastReportedDisplayId;
Winson Chung609e1e92017-05-08 10:52:12 -0700302 private boolean mLastReportedMultiWindowMode;
303 private boolean mLastReportedPictureInPictureMode;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700304 CompatibilityInfo compat;// last used compatibility mode
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700305 ActivityRecord resultTo; // who started this entry, so will get our reply
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 final String resultWho; // additional identifier for use by resultTo.
307 final int requestCode; // code given by requester (resultTo)
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800308 ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
Dianne Hackborn85d558c2014-11-04 10:31:54 -0800310 ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700311 ActivityOptions pendingOptions; // most recently given options
George Mount6ba042b2014-07-28 11:12:28 -0700312 ActivityOptions returningOptions; // options that are coming back via convertToTranslucent
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700313 AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity
Wale Ogunwalec4e63a42018-10-02 13:19:54 -0700314 ActivityServiceConnectionsHolder mServiceConnectionsHolder; // Service connections.
Dianne Hackborn7e269642010-08-25 19:50:20 -0700315 UriPermissionOwner uriPermissions; // current special URI access perms.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700316 WindowProcessController app; // if non-null, hosting application
Bryce Lee7ace3952018-02-16 14:34:32 -0800317 private ActivityState mState; // current state we are in
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 Bundle icicle; // last saved activity state
Craig Mautnera0026042014-04-23 11:45:37 -0700319 PersistableBundle persistentState; // last persistently saved activity state
Wale Ogunwale66e16852017-10-19 13:35:52 -0700320 // TODO: See if this is still needed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 boolean frontOfTask; // is this the root activity of its task?
322 boolean launchFailed; // set if a launched failed, to abort on 2nd try
323 boolean haveState; // have we gotten the last activity state?
324 boolean stopped; // is activity pause finished?
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700325 boolean delayedResume; // not yet resumed because of stopped app switches?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 boolean finishing; // activity in pending finish list?
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800327 boolean deferRelaunchUntilPaused; // relaunch of activity is being deferred until pause is
328 // completed
329 boolean preserveWindowOnDeferredRelaunch; // activity windows are preserved on deferred relaunch
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 int configChangeFlags; // which config values have changed
Wale Ogunwaleec950642017-04-25 07:44:21 -0700331 private boolean keysPaused; // has key dispatching been paused for it?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 int launchMode; // the launch mode activity attribute.
Charles He2bf28322017-10-12 22:24:49 +0100333 int lockTaskLaunchMode; // the lockTaskMode manifest attribute, subject to override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 boolean visible; // does this activity's window need to be shown?
Jorim Jaggi241ae102016-11-02 21:57:33 -0700335 boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
336 // might hide this activity?
Wale Ogunwaleec950642017-04-25 07:44:21 -0700337 private boolean mDeferHidingClient; // If true we told WM to defer reporting to the client
338 // process that it is hidden.
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800339 boolean sleeping; // have we told the activity to sleep?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 boolean nowVisible; // is this activity's window visible?
Vishnu Nair9ba31652018-11-13 14:34:05 -0800341 boolean mDrawn; // is this activity's window drawn?
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700342 boolean mClientVisibilityDeferred;// was the visibility change message to client deferred?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 boolean idle; // has the activity gone idle?
344 boolean hasBeenLaunched;// has this activity ever been launched?
345 boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
Daniel Sandler69a48172010-06-23 16:29:36 -0400346 boolean immersive; // immersive mode (don't interrupt if possible)
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400347 boolean forceNewConfig; // force re-create with new config next time
Winson Chungf7e03e12017-08-22 11:32:16 -0700348 boolean supportsEnterPipOnTaskSwitch; // This flag is set by the system to indicate that the
349 // activity can enter picture in picture while pausing (only when switching to another task)
Winson Chung709904f2017-04-25 11:00:48 -0700350 PictureInPictureParams pictureInPictureArgs = new PictureInPictureParams.Builder().build();
351 // The PiP params used when deferring the entering of picture-in-picture.
Dianne Hackborn07981492013-01-28 11:36:23 -0800352 int launchCount; // count of launches since last state
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800353 long lastLaunchTime; // time of last launch of this activity
Ruben Brunke24b9a62016-02-16 21:38:24 -0800354 ComponentName requestedVrComponent; // the requested component for handling VR mode.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700356 String stringName; // for caching of toString().
Craig Mautnerde4ef022013-04-07 19:01:33 -0700357
Dianne Hackbornf26fd992011-04-08 18:14:09 -0700358 private boolean inHistory; // are we in the history stack?
Craig Mautnerde4ef022013-04-07 19:01:33 -0700359 final ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800360 final RootActivityContainer mRootActivityContainer;
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800361
362 static final int STARTING_WINDOW_NOT_SHOWN = 0;
363 static final int STARTING_WINDOW_SHOWN = 1;
364 static final int STARTING_WINDOW_REMOVED = 2;
365 int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;
Wale Ogunwale3b232392016-05-13 15:37:13 -0700366 boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800367
Garfield Tan2746ab52018-07-25 12:33:01 -0700368 // Marking the reason why this activity is being relaunched. Mainly used to track that this
369 // activity is being relaunched to fulfill a resize request due to compatibility issues, e.g. in
370 // pre-NYC apps that don't have a sense of being resized.
371 int mRelaunchReason = RELAUNCH_REASON_NONE;
372
Craig Mautner21d24a22014-04-23 11:45:37 -0700373 TaskDescription taskDescription; // the recents information for this activity
Craig Mautnerbb742462014-07-07 15:28:55 -0700374 boolean mLaunchTaskBehind; // this activity is actively being launched with
375 // ActivityOptions.setLaunchTaskBehind, will be cleared once launch is completed.
Craig Mautner2fbd7542014-03-21 09:34:07 -0700376
Filip Gruszczynski23493322015-07-29 17:02:59 -0700377 // These configurations are collected from application's resources based on size-sensitive
378 // qualifiers. For example, layout-w800dp will be added to mHorizontalSizeConfigurations as 800
379 // and drawable-sw400dp will be added to both as 400.
380 private int[] mVerticalSizeConfigurations;
381 private int[] mHorizontalSizeConfigurations;
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700382 private int[] mSmallestSizeConfigurations;
Filip Gruszczynski23493322015-07-29 17:02:59 -0700383
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800384 boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session
385 IVoiceInteractionSession voiceSession; // Voice interaction session for this activity
386
Robert Carrd2265122016-08-05 10:25:21 -0700387 // A hint to override the window specified rotation animation, or -1
388 // to use the window specified value. We use this so that
389 // we can select the right animation in the cases of starting
390 // windows, where the app hasn't had time to set a value
391 // on the window.
392 int mRotationAnimationHint = -1;
Robert Carrfd10cd12016-06-29 16:41:50 -0700393
chaviw59b98852017-06-13 12:05:44 -0700394 private boolean mShowWhenLocked;
Issei Suzuki74e1eb22018-12-20 17:42:52 +0100395 private boolean mInheritShownWhenLocked;
chaviw59b98852017-06-13 12:05:44 -0700396 private boolean mTurnScreenOn;
397
Andrii Kulian21713ac2016-10-12 22:05:05 -0700398 /**
Garfield Tan0443b372019-01-04 15:00:13 -0800399 * Current sequencing integer of the configuration, for skipping old activity configurations.
400 */
401 private int mConfigurationSeq;
402
403 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800404 * Temp configs used in {@link #ensureActivityConfiguration(int, boolean)}
Andrii Kulian21713ac2016-10-12 22:05:05 -0700405 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700406 private final Configuration mTmpConfig = new Configuration();
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700407 private final Rect mTmpBounds = new Rect();
Andrii Kulian21713ac2016-10-12 22:05:05 -0700408
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800409 private static String startingWindowStateToString(int state) {
410 switch (state) {
411 case STARTING_WINDOW_NOT_SHOWN:
412 return "STARTING_WINDOW_NOT_SHOWN";
413 case STARTING_WINDOW_SHOWN:
414 return "STARTING_WINDOW_SHOWN";
415 case STARTING_WINDOW_REMOVED:
416 return "STARTING_WINDOW_REMOVED";
417 default:
418 return "unknown state=" + state;
419 }
420 }
421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700423 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700424 pw.print(prefix); pw.print("packageName="); pw.print(packageName);
425 pw.print(" processName="); pw.println(processName);
426 pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
Craig Mautnere11f2b72013-04-01 12:37:17 -0700427 pw.print(" launchedFromPackage="); pw.print(launchedFromPackage);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800428 pw.print(" userId="); pw.println(mUserId);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800429 pw.print(prefix); pw.print("app="); pw.println(app);
430 pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700431 pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask);
432 pw.print(" task="); pw.println(task);
433 pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800434 pw.print(prefix); pw.print("mActivityComponent=");
435 pw.println(mActivityComponent.flattenToShortString());
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700436 if (appInfo != null) {
437 pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir);
438 if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) {
439 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir);
440 }
441 pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800442 if (appInfo.splitSourceDirs != null) {
443 pw.print(prefix); pw.print("splitDir=");
444 pw.println(Arrays.toString(appInfo.splitSourceDirs));
445 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800446 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700447 pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
448 pw.print(" componentSpecified="); pw.print(componentSpecified);
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700449 pw.print(" mActivityType="); pw.println(
450 activityTypeToString(getActivityType()));
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700451 if (rootVoiceInteraction) {
452 pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
453 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800454 pw.print(prefix); pw.print("compat="); pw.print(compat);
455 pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
456 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
457 pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700458 pw.println(prefix + "mLastReportedConfigurations:");
459 mLastReportedConfiguration.dump(pw, prefix + " ");
460
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700461 pw.print(prefix); pw.print("CurrentConfiguration="); pw.println(getConfiguration());
Evan Roskydfe3da72018-10-26 17:21:06 -0700462 if (!getRequestedOverrideConfiguration().equals(EMPTY)) {
463 pw.println(prefix + "RequestedOverrideConfiguration="
464 + getRequestedOverrideConfiguration());
465 }
466 if (!getResolvedOverrideConfiguration().equals(getRequestedOverrideConfiguration())) {
467 pw.println(prefix + "ResolvedOverrideConfiguration="
468 + getResolvedOverrideConfiguration());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700469 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800470 if (!matchParentBounds()) {
471 pw.println(prefix + "bounds=" + getBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700472 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700473 if (resultTo != null || resultWho != null) {
474 pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
475 pw.print(" resultWho="); pw.print(resultWho);
476 pw.print(" resultCode="); pw.println(requestCode);
477 }
Craig Mautner29c58ca2014-10-14 16:17:06 -0700478 if (taskDescription != null) {
479 final String iconFilename = taskDescription.getIconFilename();
480 if (iconFilename != null || taskDescription.getLabel() != null ||
481 taskDescription.getPrimaryColor() != 0) {
482 pw.print(prefix); pw.print("taskDescription:");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700483 pw.print(" label=\""); pw.print(taskDescription.getLabel());
484 pw.print("\"");
Matthew Ng54bc9422017-10-02 17:16:28 -0700485 pw.print(" icon="); pw.print(taskDescription.getInMemoryIcon() != null
486 ? taskDescription.getInMemoryIcon().getByteCount() + " bytes"
487 : "null");
488 pw.print(" iconResource="); pw.print(taskDescription.getIconResource());
489 pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200490 pw.print(" primaryColor=");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700491 pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700492 pw.print(prefix + " backgroundColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200493 pw.println(Integer.toHexString(taskDescription.getBackgroundColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700494 pw.print(prefix + " statusBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200495 pw.println(Integer.toHexString(taskDescription.getStatusBarColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700496 pw.print(prefix + " navigationBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200497 pw.println(Integer.toHexString(taskDescription.getNavigationBarColor()));
Craig Mautner29c58ca2014-10-14 16:17:06 -0700498 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700499 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700500 if (results != null) {
501 pw.print(prefix); pw.print("results="); pw.println(results);
502 }
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700503 if (pendingResults != null && pendingResults.size() > 0) {
504 pw.print(prefix); pw.println("Pending Results:");
505 for (WeakReference<PendingIntentRecord> wpir : pendingResults) {
506 PendingIntentRecord pir = wpir != null ? wpir.get() : null;
507 pw.print(prefix); pw.print(" - ");
508 if (pir == null) {
509 pw.println("null");
510 } else {
511 pw.println(pir);
512 pir.dump(pw, prefix + " ");
513 }
514 }
515 }
516 if (newIntents != null && newIntents.size() > 0) {
517 pw.print(prefix); pw.println("Pending New Intents:");
518 for (int i=0; i<newIntents.size(); i++) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800519 Intent intent = newIntents.get(i);
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700520 pw.print(prefix); pw.print(" - ");
521 if (intent == null) {
522 pw.println("null");
523 } else {
524 pw.println(intent.toShortString(false, true, false, true));
525 }
526 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700527 }
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700528 if (pendingOptions != null) {
529 pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions);
530 }
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700531 if (appTimeTracker != null) {
532 appTimeTracker.dumpWithHeader(pw, prefix, false);
533 }
Dianne Hackborn7e269642010-08-25 19:50:20 -0700534 if (uriPermissions != null) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700535 uriPermissions.dump(pw, prefix);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700536 }
537 pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed);
Dianne Hackborn07981492013-01-28 11:36:23 -0800538 pw.print(" launchCount="); pw.print(launchCount);
539 pw.print(" lastLaunchTime=");
540 if (lastLaunchTime == 0) pw.print("0");
541 else TimeUtils.formatDuration(lastLaunchTime, now, pw);
542 pw.println();
Dianne Hackborncfc837f2013-06-27 18:32:07 -0700543 pw.print(prefix); pw.print("haveState="); pw.print(haveState);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700544 pw.print(" icicle="); pw.println(icicle);
Bryce Lee7ace3952018-02-16 14:34:32 -0800545 pw.print(prefix); pw.print("state="); pw.print(mState);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700546 pw.print(" stopped="); pw.print(stopped);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700547 pw.print(" delayedResume="); pw.print(delayedResume);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700548 pw.print(" finishing="); pw.println(finishing);
549 pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
550 pw.print(" inHistory="); pw.print(inHistory);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700551 pw.print(" visible="); pw.print(visible);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800552 pw.print(" sleeping="); pw.print(sleeping);
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800553 pw.print(" idle="); pw.print(idle);
554 pw.print(" mStartingWindowState=");
555 pw.println(startingWindowStateToString(mStartingWindowState));
Dianne Hackbornff801ec2011-01-22 18:05:38 -0800556 pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
557 pw.print(" noDisplay="); pw.print(noDisplay);
558 pw.print(" immersive="); pw.print(immersive);
559 pw.print(" launchMode="); pw.println(launchMode);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800560 pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400561 pw.print(" forceNewConfig="); pw.println(forceNewConfig);
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700562 pw.print(prefix); pw.print("mActivityType=");
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700563 pw.println(activityTypeToString(getActivityType()));
Ruben Brunke24b9a62016-02-16 21:38:24 -0800564 if (requestedVrComponent != null) {
565 pw.print(prefix);
566 pw.print("requestedVrComponent=");
567 pw.println(requestedVrComponent);
568 }
Jorim Jaggi9b5e3312019-03-01 18:08:00 +0100569 if (lastVisibleTime != 0 || nowVisible) {
570 pw.print(prefix); pw.print(" nowVisible="); pw.print(nowVisible);
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700571 pw.print(" lastVisibleTime=");
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700572 if (lastVisibleTime == 0) pw.print("0");
573 else TimeUtils.formatDuration(lastVisibleTime, now, pw);
574 pw.println();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700575 }
Wale Ogunwaleec950642017-04-25 07:44:21 -0700576 if (mDeferHidingClient) {
577 pw.println(prefix + "mDeferHidingClient=" + mDeferHidingClient);
578 }
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800579 if (deferRelaunchUntilPaused || configChangeFlags != 0) {
580 pw.print(prefix); pw.print("deferRelaunchUntilPaused="); pw.print(deferRelaunchUntilPaused);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700581 pw.print(" configChangeFlags=");
582 pw.println(Integer.toHexString(configChangeFlags));
583 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -0700584 if (mServiceConnectionsHolder != null) {
585 pw.print(prefix); pw.print("connections="); pw.println(mServiceConnectionsHolder);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700586 }
Wale Ogunwaled26176f2016-01-25 20:04:04 -0800587 if (info != null) {
588 pw.println(prefix + "resizeMode=" + ActivityInfo.resizeModeToString(info.resizeMode));
Winson Chung609e1e92017-05-08 10:52:12 -0700589 pw.println(prefix + "mLastReportedMultiWindowMode=" + mLastReportedMultiWindowMode
590 + " mLastReportedPictureInPictureMode=" + mLastReportedPictureInPictureMode);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700591 if (info.supportsPictureInPicture()) {
592 pw.println(prefix + "supportsPictureInPicture=" + info.supportsPictureInPicture());
Winson Chungf7e03e12017-08-22 11:32:16 -0700593 pw.println(prefix + "supportsEnterPipOnTaskSwitch: "
594 + supportsEnterPipOnTaskSwitch);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700595 }
596 if (info.maxAspectRatio != 0) {
597 pw.println(prefix + "maxAspectRatio=" + info.maxAspectRatio);
598 }
Adrian Roos917791e2018-11-28 16:30:44 +0100599 if (info.minAspectRatio != 0) {
600 pw.println(prefix + "minAspectRatio=" + info.minAspectRatio);
601 }
Wale Ogunwaled26176f2016-01-25 20:04:04 -0800602 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 }
604
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700605 void updateApplicationInfo(ApplicationInfo aInfo) {
606 appInfo = aInfo;
607 info.applicationInfo = aInfo;
608 }
609
Andrii Kulian21713ac2016-10-12 22:05:05 -0700610 private boolean crossesHorizontalSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700611 return crossesSizeThreshold(mHorizontalSizeConfigurations, firstDp, secondDp);
612 }
613
Andrii Kulian21713ac2016-10-12 22:05:05 -0700614 private boolean crossesVerticalSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700615 return crossesSizeThreshold(mVerticalSizeConfigurations, firstDp, secondDp);
616 }
617
Andrii Kulian21713ac2016-10-12 22:05:05 -0700618 private boolean crossesSmallestSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700619 return crossesSizeThreshold(mSmallestSizeConfigurations, firstDp, secondDp);
620 }
621
Filip Gruszczynski23493322015-07-29 17:02:59 -0700622 /**
623 * The purpose of this method is to decide whether the activity needs to be relaunched upon
624 * changing its size. In most cases the activities don't need to be relaunched, if the resize
625 * is small, all the activity content has to do is relayout itself within new bounds. There are
626 * cases however, where the activity's content would be completely changed in the new size and
627 * the full relaunch is required.
628 *
629 * The activity will report to us vertical and horizontal thresholds after which a relaunch is
630 * required. These thresholds are collected from the application resource qualifiers. For
631 * example, if application has layout-w600dp resource directory, then it needs a relaunch when
632 * we resize from width of 650dp to 550dp, as it crosses the 600dp threshold. However, if
633 * it resizes width from 620dp to 700dp, it won't be relaunched as it stays on the same side
634 * of the threshold.
635 */
636 private static boolean crossesSizeThreshold(int[] thresholds, int firstDp,
637 int secondDp) {
638 if (thresholds == null) {
639 return false;
640 }
641 for (int i = thresholds.length - 1; i >= 0; i--) {
642 final int threshold = thresholds[i];
643 if ((firstDp < threshold && secondDp >= threshold)
644 || (firstDp >= threshold && secondDp < threshold)) {
645 return true;
646 }
647 }
648 return false;
649 }
650
Andrii Kulian21713ac2016-10-12 22:05:05 -0700651 void setSizeConfigurations(int[] horizontalSizeConfiguration,
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700652 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700653 mHorizontalSizeConfigurations = horizontalSizeConfiguration;
654 mVerticalSizeConfigurations = verticalSizeConfigurations;
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700655 mSmallestSizeConfigurations = smallestSizeConfigurations;
Filip Gruszczynski23493322015-07-29 17:02:59 -0700656 }
657
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800658 private void scheduleActivityMovedToDisplay(int displayId, Configuration config) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700659 if (!attachedToProcess()) {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800660 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.w(TAG,
661 "Can't report activity moved to display - client not running, activityRecord="
662 + this + ", displayId=" + displayId);
Wale Ogunwale22e25262016-02-01 10:32:02 -0800663 return;
664 }
665 try {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800666 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
667 "Reporting activity moved to display" + ", activityRecord=" + this
668 + ", displayId=" + displayId + ", config=" + config);
Chong Zhang6be533e2016-06-17 16:24:21 -0700669
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800670 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800671 MoveToDisplayItem.obtain(displayId, config));
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800672 } catch (RemoteException e) {
673 // If process died, whatever.
674 }
675 }
676
677 private void scheduleConfigurationChanged(Configuration config) {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700678 if (!attachedToProcess()) {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800679 if (DEBUG_CONFIGURATION) Slog.w(TAG,
680 "Can't report activity configuration update - client not running"
681 + ", activityRecord=" + this);
682 return;
683 }
684 try {
685 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + this + ", config: "
686 + config);
687
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800688 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800689 ActivityConfigurationChangeItem.obtain(config));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800690 } catch (RemoteException e) {
691 // If process died, whatever.
692 }
693 }
694
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800695 void scheduleTopResumedActivityChanged(boolean onTop) {
696 if (!attachedToProcess()) {
Andrii Kulian86e70fc2019-02-12 11:04:10 +0000697 if (DEBUG_STATES) {
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800698 Slog.w(TAG, "Can't report activity position update - client not running"
699 + ", activityRecord=" + this);
700 }
701 return;
702 }
703 try {
Andrii Kulian86e70fc2019-02-12 11:04:10 +0000704 if (DEBUG_STATES) {
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800705 Slog.v(TAG, "Sending position change to " + this + ", onTop: " + onTop);
706 }
707
708 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
709 TopResumedActivityChangeItem.obtain(onTop));
710 } catch (RemoteException e) {
711 // If process died, whatever.
712 }
713 }
714
Winson Chung5af42fc2017-03-24 17:11:33 -0700715 void updateMultiWindowMode() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700716 if (task == null || task.getStack() == null || !attachedToProcess()) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800717 return;
718 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700719
Wale Ogunwaleeb76b762017-11-17 10:08:04 -0800720 if (task.getStack().deferScheduleMultiWindowModeChanged()) {
721 // Don't do anything if we are currently deferring multi-window mode change.
722 return;
723 }
724
Winson Chung5af42fc2017-03-24 17:11:33 -0700725 // An activity is considered to be in multi-window mode if its task isn't fullscreen.
Wale Ogunwaleeb76b762017-11-17 10:08:04 -0800726 final boolean inMultiWindowMode = inMultiWindowMode();
Winson Chung609e1e92017-05-08 10:52:12 -0700727 if (inMultiWindowMode != mLastReportedMultiWindowMode) {
728 mLastReportedMultiWindowMode = inMultiWindowMode;
Winson Chung5af42fc2017-03-24 17:11:33 -0700729 scheduleMultiWindowModeChanged(getConfiguration());
730 }
731 }
732
733 private void scheduleMultiWindowModeChanged(Configuration overrideConfig) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800734 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800735 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700736 MultiWindowModeChangeItem.obtain(mLastReportedMultiWindowMode, overrideConfig));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800737 } catch (Exception e) {
738 // If process died, I don't care.
739 }
740 }
741
Winson Chungab76bbc2017-08-14 13:33:51 -0700742 void updatePictureInPictureMode(Rect targetStackBounds, boolean forceUpdate) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700743 if (task == null || task.getStack() == null || !attachedToProcess()) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800744 return;
745 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700746
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700747 final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null;
Winson Chungab76bbc2017-08-14 13:33:51 -0700748 if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) {
Winson Chung5af42fc2017-03-24 17:11:33 -0700749 // Picture-in-picture mode changes also trigger a multi-window mode change as well, so
Winson Chung059955f2018-08-08 16:10:20 -0700750 // update that here in order. Set the last reported MW state to the same as the PiP
751 // state since we haven't yet actually resized the task (these callbacks need to
752 // preceed the configuration change from the resiez.
753 // TODO(110009072): Once we move these callbacks to the client, remove all logic related
754 // to forcing the update of the picture-in-picture mode as a part of the PiP animation.
Winson Chung609e1e92017-05-08 10:52:12 -0700755 mLastReportedPictureInPictureMode = inPictureInPictureMode;
Winson Chung059955f2018-08-08 16:10:20 -0700756 mLastReportedMultiWindowMode = inPictureInPictureMode;
Evan Rosky1ac84462018-11-13 11:25:30 -0800757 final Configuration newConfig = new Configuration();
758 if (targetStackBounds != null && !targetStackBounds.isEmpty()) {
Evan Rosky730f6e82018-12-03 17:40:11 -0800759 newConfig.setTo(task.getRequestedOverrideConfiguration());
760 Rect outBounds = newConfig.windowConfiguration.getBounds();
761 task.adjustForMinimalTaskDimensions(outBounds, outBounds);
762 task.computeConfigResourceOverrides(newConfig, task.getParent().getConfiguration());
Evan Rosky1ac84462018-11-13 11:25:30 -0800763 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700764 schedulePictureInPictureModeChanged(newConfig);
765 scheduleMultiWindowModeChanged(newConfig);
766 }
767 }
768
769 private void schedulePictureInPictureModeChanged(Configuration overrideConfig) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800770 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800771 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800772 PipModeChangeItem.obtain(mLastReportedPictureInPictureMode,
Andrii Kulian446e8242017-10-26 15:17:29 -0700773 overrideConfig));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800774 } catch (Exception e) {
775 // If process died, no one cares.
Filip Gruszczynskica664812015-12-04 12:43:36 -0800776 }
777 }
778
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700779 @Override
780 protected int getChildCount() {
781 // {@link ActivityRecord} is a leaf node and has no children.
782 return 0;
783 }
784
785 @Override
786 protected ConfigurationContainer getChildAt(int index) {
787 return null;
788 }
789
790 @Override
791 protected ConfigurationContainer getParent() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800792 return getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -0700793 }
794
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800795 TaskRecord getTaskRecord() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700796 return task;
797 }
798
Bryce Leeaf691c02017-03-20 14:20:22 -0700799 /**
800 * Sets reference to the {@link TaskRecord} the {@link ActivityRecord} will treat as its parent.
801 * Note that this does not actually add the {@link ActivityRecord} as a {@link TaskRecord}
802 * children. However, this method will clean up references to this {@link ActivityRecord} in
803 * {@link ActivityStack}.
804 * @param task The new parent {@link TaskRecord}.
805 */
806 void setTask(TaskRecord task) {
Bryce Lee84730a02018-04-03 14:10:04 -0700807 setTask(task /* task */, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -0700808 }
809
810 /**
811 * This method should only be called by {@link TaskRecord#removeActivity(ActivityRecord)}.
Bryce Lee84730a02018-04-03 14:10:04 -0700812 * @param task The new parent task.
813 * @param reparenting Whether we're in the middle of reparenting.
Bryce Leeaf691c02017-03-20 14:20:22 -0700814 */
815 void setTask(TaskRecord task, boolean reparenting) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800816 // Do nothing if the {@link TaskRecord} is the same as the current {@link getTaskRecord}.
817 if (task != null && task == getTaskRecord()) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700818 return;
819 }
820
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800821 final ActivityStack oldStack = getActivityStack();
Bryce Lee84730a02018-04-03 14:10:04 -0700822 final ActivityStack newStack = task != null ? task.getStack() : null;
Bryce Leeaf691c02017-03-20 14:20:22 -0700823
Bryce Lee84730a02018-04-03 14:10:04 -0700824 // Inform old stack (if present) of activity removal and new stack (if set) of activity
825 // addition.
826 if (oldStack != newStack) {
827 if (!reparenting && oldStack != null) {
828 oldStack.onActivityRemovedFromStack(this);
829 }
830
831 if (newStack != null) {
832 newStack.onActivityAddedToStack(this);
833 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700834 }
835
836 this.task = task;
837
838 if (!reparenting) {
839 onParentChanged();
840 }
841 }
842
chaviw4ad54912018-05-30 11:05:44 -0700843 /**
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800844 * Notifies AWT that this app is waiting to pause in order to determine if it will enter PIP.
845 * This information helps AWT know that the app is in the process of pausing before it gets the
846 * signal on the WM side.
chaviw4ad54912018-05-30 11:05:44 -0700847 */
848 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800849 if (mAppWindowToken == null) {
850 return;
851 }
852
853 mAppWindowToken.setWillCloseOrEnterPip(willCloseOrEnterPip);
chaviw4ad54912018-05-30 11:05:44 -0700854 }
855
Dianne Hackbornbe707852011-11-11 14:32:10 -0800856 static class Token extends IApplicationToken.Stub {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700857 private final WeakReference<ActivityRecord> weakActivity;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700858 private final String name;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800859
Steven Timotiusaf03df62017-07-18 16:56:43 -0700860 Token(ActivityRecord activity, Intent intent) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800861 weakActivity = new WeakReference<>(activity);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700862 name = intent.getComponent().flattenToShortString();
Wale Ogunwale7d701172015-03-11 15:36:30 -0700863 }
864
Andrii Kulian21713ac2016-10-12 22:05:05 -0700865 private static ActivityRecord tokenToActivityRecordLocked(Token token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700866 if (token == null) {
867 return null;
868 }
869 ActivityRecord r = token.weakActivity.get();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800870 if (r == null || r.getActivityStack() == null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700871 return null;
872 }
873 return r;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800874 }
875
Craig Mautnerde4ef022013-04-07 19:01:33 -0700876 @Override
Dianne Hackbornbe707852011-11-11 14:32:10 -0800877 public String toString() {
878 StringBuilder sb = new StringBuilder(128);
879 sb.append("Token{");
880 sb.append(Integer.toHexString(System.identityHashCode(this)));
881 sb.append(' ');
882 sb.append(weakActivity.get());
883 sb.append('}');
884 return sb.toString();
885 }
Steven Timotiusaf03df62017-07-18 16:56:43 -0700886
887 @Override
888 public String getName() {
889 return name;
890 }
Dianne Hackbornbe707852011-11-11 14:32:10 -0800891 }
892
Wale Ogunwale7d701172015-03-11 15:36:30 -0700893 static ActivityRecord forTokenLocked(IBinder token) {
Dianne Hackbornbe707852011-11-11 14:32:10 -0800894 try {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700895 return Token.tokenToActivityRecordLocked((Token)token);
Dianne Hackbornbe707852011-11-11 14:32:10 -0800896 } catch (ClassCastException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800897 Slog.w(TAG, "Bad activity token: " + token, e);
Dianne Hackbornbe707852011-11-11 14:32:10 -0800898 return null;
899 }
900 }
901
Chong Zhang85ee6542015-10-02 13:36:38 -0700902 boolean isResolverActivity() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800903 return ResolverActivity.class.getName().equals(mActivityComponent.getClassName());
Craig Mautnerac6f8432013-07-17 13:24:59 -0700904 }
905
Patrick Baumann31426b22018-05-21 13:46:40 -0700906 boolean isResolverOrChildActivity() {
907 if (!"android".equals(packageName)) {
908 return false;
909 }
910 try {
911 return ResolverActivity.class.isAssignableFrom(
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800912 Object.class.getClassLoader().loadClass(mActivityComponent.getClassName()));
Patrick Baumann31426b22018-05-21 13:46:40 -0700913 } catch (ClassNotFoundException e) {
914 return false;
915 }
916 }
917
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700918 ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
919 int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage, Intent _intent,
920 String _resolvedType, ActivityInfo aInfo, Configuration _configuration,
921 ActivityRecord _resultTo, String _resultWho, int _reqCode, boolean _componentSpecified,
922 boolean _rootVoiceInteraction, ActivityStackSupervisor supervisor,
923 ActivityOptions options, ActivityRecord sourceRecord) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800924 mAtmService = _service;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800925 mRootActivityContainer = _service.mRootActivityContainer;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700926 appToken = new Token(this, _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 info = aInfo;
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800928 launchedFromPid = _launchedFromPid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 launchedFromUid = _launchedFromUid;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800930 launchedFromPackage = _launchedFromPackage;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800931 mUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 intent = _intent;
933 shortComponentName = _intent.getComponent().flattenToShortString();
934 resolvedType = _resolvedType;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800935 componentSpecified = _componentSpecified;
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700936 rootVoiceInteraction = _rootVoiceInteraction;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700937 mLastReportedConfiguration = new MergedConfiguration(_configuration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 resultTo = _resultTo;
939 resultWho = _resultWho;
940 requestCode = _reqCode;
Bryce Lee7ace3952018-02-16 14:34:32 -0800941 setState(INITIALIZING, "ActivityRecord ctor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942 frontOfTask = false;
943 launchFailed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 stopped = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700945 delayedResume = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 finishing = false;
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800947 deferRelaunchUntilPaused = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 keysPaused = false;
949 inHistory = false;
Chong Zhanga48ef662015-08-18 19:21:47 -0700950 visible = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 nowVisible = false;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800952 mDrawn = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 idle = false;
954 hasBeenLaunched = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700955 mStackSupervisor = supervisor;
Robert Carr0f5d7532016-10-17 16:39:17 -0700956
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800957 // This starts out true, since the initial state of an activity is that we have everything,
958 // and we shouldn't never consider it lacking in state to be removed if it dies.
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700959 haveState = true;
960
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800961 // If the class name in the intent doesn't match that of the target, this is
962 // probably an alias. We have to create a new ComponentName object to keep track
963 // of the real activity name, so that FLAG_ACTIVITY_CLEAR_TOP is handled properly.
964 if (aInfo.targetActivity == null
965 || (aInfo.targetActivity.equals(_intent.getComponent().getClassName())
966 && (aInfo.launchMode == LAUNCH_MULTIPLE
967 || aInfo.launchMode == LAUNCH_SINGLE_TOP))) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800968 mActivityComponent = _intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800970 mActivityComponent = new ComponentName(aInfo.packageName, aInfo.targetActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800972 taskAffinity = aInfo.taskAffinity;
973 stateNotNeeded = (aInfo.flags & FLAG_STATE_NOT_NEEDED) != 0;
974 appInfo = aInfo.applicationInfo;
975 nonLocalizedLabel = aInfo.nonLocalizedLabel;
976 labelRes = aInfo.labelRes;
977 if (nonLocalizedLabel == null && labelRes == 0) {
978 ApplicationInfo app = aInfo.applicationInfo;
979 nonLocalizedLabel = app.nonLocalizedLabel;
980 labelRes = app.labelRes;
981 }
982 icon = aInfo.getIconResource();
983 logo = aInfo.getLogoResource();
984 theme = aInfo.getThemeResource();
985 realTheme = theme;
986 if (realTheme == 0) {
987 realTheme = aInfo.applicationInfo.targetSdkVersion < HONEYCOMB
988 ? android.R.style.Theme : android.R.style.Theme_Holo;
989 }
990 if ((aInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
991 windowFlags |= LayoutParams.FLAG_HARDWARE_ACCELERATED;
992 }
993 if ((aInfo.flags & FLAG_MULTIPROCESS) != 0 && _caller != null
994 && (aInfo.applicationInfo.uid == SYSTEM_UID
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700995 || aInfo.applicationInfo.uid == _caller.mInfo.uid)) {
996 processName = _caller.mName;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800997 } else {
998 processName = aInfo.processName;
999 }
1000
1001 if ((aInfo.flags & FLAG_EXCLUDE_FROM_RECENTS) != 0) {
1002 intent.addFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
1003 }
1004
1005 packageName = aInfo.applicationInfo.packageName;
1006 launchMode = aInfo.launchMode;
1007
Ruben Brunkf53497c2017-03-27 20:26:17 -07001008 Entry ent = AttributeCache.instance().get(packageName,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001009 realTheme, com.android.internal.R.styleable.Window, mUserId);
Bryce Leee83f34cd2017-10-31 19:50:54 -07001010
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -07001011 if (ent != null) {
1012 fullscreen = !ActivityInfo.isTranslucentOrFloating(ent.array);
1013 hasWallpaper = ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
1014 noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
1015 } else {
1016 hasWallpaper = false;
1017 noDisplay = false;
1018 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001019
Winson Chung83471632016-12-13 11:02:12 -08001020 setActivityType(_componentSpecified, _launchedFromUid, _intent, options, sourceRecord);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001021
1022 immersive = (aInfo.flags & FLAG_IMMERSIVE) != 0;
1023
1024 requestedVrComponent = (aInfo.requestedVrComponent == null) ?
1025 null : ComponentName.unflattenFromString(aInfo.requestedVrComponent);
chaviw59b98852017-06-13 12:05:44 -07001026
1027 mShowWhenLocked = (aInfo.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
Issei Suzuki74e1eb22018-12-20 17:42:52 +01001028 mInheritShownWhenLocked = (aInfo.privateFlags & FLAG_INHERIT_SHOW_WHEN_LOCKED) != 0;
chaviw59b98852017-06-13 12:05:44 -07001029 mTurnScreenOn = (aInfo.flags & FLAG_TURN_SCREEN_ON) != 0;
Charles He2bf28322017-10-12 22:24:49 +01001030
1031 mRotationAnimationHint = aInfo.rotationAnimation;
1032 lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
1033 if (appInfo.isPrivilegedApp() && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
1034 || lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
1035 lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
1036 }
1037
1038 if (options != null) {
1039 pendingOptions = options;
1040 mLaunchTaskBehind = options.getLaunchTaskBehind();
1041
1042 final int rotationAnimation = pendingOptions.getRotationAnimationHint();
1043 // Only override manifest supplied option if set.
1044 if (rotationAnimation >= 0) {
1045 mRotationAnimationHint = rotationAnimation;
1046 }
1047 final PendingIntent usageReport = pendingOptions.getUsageTimeReport();
1048 if (usageReport != null) {
1049 appTimeTracker = new AppTimeTracker(usageReport);
1050 }
1051 final boolean useLockTask = pendingOptions.getLockTaskMode();
1052 if (useLockTask && lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_DEFAULT) {
1053 lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
1054 }
Louis Changd58cb672018-12-24 17:45:16 +08001055 // Gets launch display id from options. It returns INVALID_DISPLAY if not set.
1056 mHandoverLaunchDisplayId = options.getLaunchDisplayId();
Charles He2bf28322017-10-12 22:24:49 +01001057 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001058 }
1059
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001060 void setProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08001061 app = proc;
1062 final ActivityRecord root = task != null ? task.getRootActivity() : null;
1063 if (root == this) {
1064 task.setRootProcess(proc);
1065 }
1066 }
1067
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001068 boolean hasProcess() {
1069 return app != null;
1070 }
1071
1072 boolean attachedToProcess() {
1073 return hasProcess() && app.hasThread();
1074 }
1075
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001076 void createAppWindowToken() {
1077 if (mAppWindowToken != null) {
1078 throw new IllegalArgumentException("App Window Token=" + mAppWindowToken
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001079 + " already created for r=" + this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001080 }
1081
1082 inHistory = true;
1083
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001084 // TODO(b/36505427): Maybe this call should be moved inside updateOverrideConfiguration()
1085 task.updateOverrideConfigurationFromLaunchBounds();
1086 // Make sure override configuration is up-to-date before using to create window controller.
1087 updateOverrideConfiguration();
1088
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001089 // TODO: remove after unification
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001090 mAppWindowToken = mAtmService.mWindowManager.mRoot.getAppWindowToken(appToken.asBinder());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001091 if (mAppWindowToken != null) {
1092 // TODO: Should this throw an exception instead?
1093 Slog.w(TAG, "Attempted to add existing app token: " + appToken);
1094 } else {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001095 final Task container = task.getTask();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001096 if (container == null) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001097 throw new IllegalArgumentException("createAppWindowToken: invalid task =" + task);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001098 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001099 mAppWindowToken = createAppWindow(mAtmService.mWindowManager, appToken,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001100 task.voiceSession != null, container.getDisplayContent(),
1101 ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this)
1102 * 1000000L, fullscreen,
1103 (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, appInfo.targetSdkVersion,
1104 info.screenOrientation, mRotationAnimationHint, info.configChanges,
1105 mLaunchTaskBehind, isAlwaysFocusable());
1106 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) {
1107 Slog.v(TAG, "addAppToken: "
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001108 + mAppWindowToken + " task=" + container + " at "
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001109 + Integer.MAX_VALUE);
1110 }
1111 container.addChild(mAppWindowToken, Integer.MAX_VALUE /* add on top */);
1112 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001113
1114 task.addActivityToTop(this);
1115
Winson Chung609e1e92017-05-08 10:52:12 -07001116 // When an activity is started directly into a split-screen fullscreen stack, we need to
1117 // update the initial multi-window modes so that the callbacks are scheduled correctly when
1118 // the user leaves that mode.
Bryce Leef3c6a472017-11-14 14:53:06 -08001119 mLastReportedMultiWindowMode = inMultiWindowMode();
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001120 mLastReportedPictureInPictureMode = inPinnedWindowingMode();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001121 }
1122
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001123 boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
1124 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
1125 IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
1126 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
1127 if (DEBUG_STARTING_WINDOW) {
1128 Slog.v(TAG, "setAppStartingWindow: token=" + appToken
1129 + " pkg=" + pkg + " transferFrom=" + transferFrom + " newTask=" + newTask
1130 + " taskSwitch=" + taskSwitch + " processRunning=" + processRunning
1131 + " allowTaskSnapshot=" + allowTaskSnapshot);
1132 }
1133 if (mAppWindowToken == null) {
1134 Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + appToken);
1135 return false;
1136 }
Yunfan Chen48c0ed082018-12-05 18:15:35 -08001137 if (mAppWindowToken.getTask() == null) {
1138 // Can be removed after unification of Task and TaskRecord.
1139 Slog.w(TAG_WM, "Attempted to start a window to an app token not having attached to any"
1140 + " task: " + appToken);
1141 return false;
1142 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001143 return mAppWindowToken.addStartingWindow(pkg, theme, compatInfo, nonLocalizedLabel,
1144 labelRes, icon, logo, windowFlags, transferFrom, newTask, taskSwitch,
1145 processRunning, allowTaskSnapshot, activityCreated, fromRecents);
1146 }
1147
1148 // TODO: Remove after unification
1149 @VisibleForTesting
1150 AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
1151 boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
1152 boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
1153 int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
1154 boolean alwaysFocusable) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001155 return new AppWindowToken(service, token, mActivityComponent, voiceInteraction, dc,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001156 inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation,
1157 rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable,
1158 this);
1159 }
1160
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001161 void removeWindowContainer() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001162 if (mAtmService.mWindowManager.mRoot == null) return;
Yunfan Chend4ef3012018-11-28 21:14:32 -08001163
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001164 final DisplayContent dc = mAtmService.mWindowManager.mRoot.getDisplayContent(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001165 getDisplayId());
1166 if (dc == null) {
1167 Slog.w(TAG, "removeWindowContainer: Attempted to remove token: "
1168 + appToken + " from non-existing displayId=" + getDisplayId());
Bryce Lee7ace3952018-02-16 14:34:32 -08001169 return;
1170 }
Wale Ogunwalecc367f42017-02-01 08:12:14 -08001171 // Resume key dispatching if it is currently paused before we remove the container.
1172 resumeKeyDispatchingLocked();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001173 dc.removeAppToken(appToken.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001174 }
1175
Winson Chung30480042017-01-26 10:55:34 -08001176 /**
1177 * Reparents this activity into {@param newTask} at the provided {@param position}. The caller
1178 * should ensure that the {@param newTask} is not already the parent of this activity.
1179 */
1180 void reparent(TaskRecord newTask, int position, String reason) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001181 if (mAppWindowToken == null) {
1182 Slog.w(TAG, "reparent: Attempted to reparent non-existing app token: " + appToken);
1183 return;
1184 }
Winson Chung30480042017-01-26 10:55:34 -08001185 final TaskRecord prevTask = task;
1186 if (prevTask == newTask) {
1187 throw new IllegalArgumentException(reason + ": task=" + newTask
1188 + " is already the parent of r=" + this);
1189 }
1190
Winson Chung74666102017-02-22 17:49:24 -08001191 // TODO: Ensure that we do not directly reparent activities across stacks, as that may leave
1192 // the stacks in strange states. For now, we should use Task.reparent() to ensure that
1193 // the stack is left in an OK state.
1194 if (prevTask != null && newTask != null && prevTask.getStack() != newTask.getStack()) {
1195 throw new IllegalArgumentException(reason + ": task=" + newTask
1196 + " is in a different stack (" + newTask.getStackId() + ") than the parent of"
1197 + " r=" + this + " (" + prevTask.getStackId() + ")");
1198 }
1199
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001200 mAppWindowToken.reparent(newTask.getTask(), position);
Winson Chung30480042017-01-26 10:55:34 -08001201
Bryce Lee84730a02018-04-03 14:10:04 -07001202 // Reparenting prevents informing the parent stack of activity removal in the case that
1203 // the new stack has the same parent. we must manually signal here if this is not the case.
1204 final ActivityStack prevStack = prevTask.getStack();
1205
1206 if (prevStack != newTask.getStack()) {
1207 prevStack.onActivityRemovedFromStack(this);
1208 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001209 // Remove the activity from the old task and add it to the new task.
Bryce Lee84730a02018-04-03 14:10:04 -07001210 prevTask.removeActivity(this, true /* reparenting */);
Bryce Lee0f9bde82017-02-22 16:39:06 -08001211
Winson Chung30480042017-01-26 10:55:34 -08001212 newTask.addActivityAtIndex(position, this);
1213 }
1214
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001215 private boolean isHomeIntent(Intent intent) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001216 return ACTION_MAIN.equals(intent.getAction())
Chilun2ef71f72018-11-16 17:57:15 +08001217 && (intent.hasCategory(CATEGORY_HOME)
1218 || intent.hasCategory(CATEGORY_SECONDARY_HOME))
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001219 && intent.getCategories().size() == 1
1220 && intent.getData() == null
1221 && intent.getType() == null;
1222 }
1223
Chong Zhangad24f962016-08-25 12:12:33 -07001224 static boolean isMainIntent(Intent intent) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001225 return ACTION_MAIN.equals(intent.getAction())
1226 && intent.hasCategory(CATEGORY_LAUNCHER)
Chong Zhangad24f962016-08-25 12:12:33 -07001227 && intent.getCategories().size() == 1
1228 && intent.getData() == null
1229 && intent.getType() == null;
1230 }
1231
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001232 private boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
1233 if (uid == Process.myUid() || uid == 0) {
1234 // System process can launch home activity.
1235 return true;
1236 }
Winson Chung547afd22018-05-17 16:03:25 -07001237 // Allow the recents component to launch the home activity.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001238 final RecentTasks recentTasks = mStackSupervisor.mService.getRecentTasks();
Winson Chung547afd22018-05-17 16:03:25 -07001239 if (recentTasks != null && recentTasks.isCallerRecents(uid)) {
1240 return true;
1241 }
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001242 // Resolver activity can launch home activity.
1243 return sourceRecord != null && sourceRecord.isResolverActivity();
1244 }
1245
Winson Chung83471632016-12-13 11:02:12 -08001246 /**
1247 * @return whether the given package name can launch an assist activity.
1248 */
1249 private boolean canLaunchAssistActivity(String packageName) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001250 final ComponentName assistComponent =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001251 mAtmService.mActiveVoiceInteractionServiceComponent;
Winson Chung83471632016-12-13 11:02:12 -08001252 if (assistComponent != null) {
1253 return assistComponent.getPackageName().equals(packageName);
1254 }
1255 return false;
1256 }
1257
1258 private void setActivityType(boolean componentSpecified, int launchedFromUid, Intent intent,
1259 ActivityOptions options, ActivityRecord sourceRecord) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001260 int activityType = ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001261 if ((!componentSpecified || canLaunchHomeActivity(launchedFromUid, sourceRecord))
1262 && isHomeIntent(intent) && !isResolverActivity()) {
1263 // This sure looks like a home activity!
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001264 activityType = ACTIVITY_TYPE_HOME;
Wale Ogunwaledf241e92016-10-13 15:14:21 -07001265
1266 if (info.resizeMode == RESIZE_MODE_FORCE_RESIZEABLE
1267 || info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
1268 // We only allow home activities to be resizeable if they explicitly requested it.
1269 info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
1270 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001271 } else if (mActivityComponent.getClassName().contains(LEGACY_RECENTS_PACKAGE_NAME)
1272 || mAtmService.getRecentTasks().isRecentsComponent(mActivityComponent, appInfo.uid)) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001273 activityType = ACTIVITY_TYPE_RECENTS;
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001274 } else if (options != null && options.getLaunchActivityType() == ACTIVITY_TYPE_ASSISTANT
Winson Chung83471632016-12-13 11:02:12 -08001275 && canLaunchAssistActivity(launchedFromPackage)) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001276 activityType = ACTIVITY_TYPE_ASSISTANT;
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001277 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001278 setActivityType(activityType);
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001279 }
1280
Craig Mautnera228ae92014-07-09 05:44:55 -07001281 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001282 if (launchMode != LAUNCH_SINGLE_INSTANCE && launchMode != LAUNCH_SINGLE_TASK) {
Craig Mautnera228ae92014-07-09 05:44:55 -07001283 task.setTaskToAffiliateWith(taskToAffiliateWith);
1284 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001285 }
1286
Andrii Kulian02b7a832016-10-06 23:11:56 -07001287 /**
1288 * @return Stack value from current task, null if there is no task.
1289 */
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001290 <T extends ActivityStack> T getActivityStack() {
Winson Chung55893332017-02-17 17:13:10 -08001291 return task != null ? (T) task.getStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001292 }
1293
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001294 int getStackId() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001295 return getActivityStack() != null ? getActivityStack().mStackId : INVALID_STACK_ID;
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001296 }
1297
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001298 ActivityDisplay getDisplay() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001299 final ActivityStack stack = getActivityStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001300 return stack != null ? stack.getDisplay() : null;
1301 }
1302
Craig Mautner5eda9b32013-07-02 11:58:16 -07001303 boolean changeWindowTranslucency(boolean toOpaque) {
1304 if (fullscreen == toOpaque) {
1305 return false;
1306 }
Craig Mautner4addfc52013-06-25 08:05:45 -07001307
Craig Mautner5eda9b32013-07-02 11:58:16 -07001308 // Keep track of the number of fullscreen activities in this task.
1309 task.numFullscreen += toOpaque ? +1 : -1;
1310
1311 fullscreen = toOpaque;
1312 return true;
Craig Mautner4addfc52013-06-25 08:05:45 -07001313 }
1314
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001315 void takeFromHistory() {
1316 if (inHistory) {
1317 inHistory = false;
1318 if (task != null && !finishing) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001319 task = null;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001320 }
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -07001321 clearOptionsLocked();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001322 }
1323 }
1324
1325 boolean isInHistory() {
1326 return inHistory;
1327 }
1328
Wale Ogunwale7d701172015-03-11 15:36:30 -07001329 boolean isInStackLocked() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001330 final ActivityStack stack = getActivityStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001331 return stack != null && stack.isInStackLocked(this) != null;
Wale Ogunwale7d701172015-03-11 15:36:30 -07001332 }
1333
Craig Mautner21d24a22014-04-23 11:45:37 -07001334 boolean isPersistable() {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001335 return (info.persistableMode == PERSIST_ROOT_ONLY ||
1336 info.persistableMode == PERSIST_ACROSS_REBOOTS) &&
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001337 (intent == null || (intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
Craig Mautner21d24a22014-04-23 11:45:37 -07001338 }
1339
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08001340 boolean isFocusable() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001341 return mRootActivityContainer.isFocusable(this, isAlwaysFocusable());
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001342 }
1343
1344 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001345 return ActivityInfo.isResizeableMode(info.resizeMode) || info.supportsPictureInPicture();
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001346 }
1347
Winson Chungd3395382016-12-13 11:49:09 -08001348 /**
1349 * @return whether this activity is non-resizeable or forced to be resizeable
1350 */
1351 boolean isNonResizableOrForcedResizable() {
Wale Ogunwaledf241e92016-10-13 15:14:21 -07001352 return info.resizeMode != RESIZE_MODE_RESIZEABLE
Wale Ogunwale72a73e32016-10-13 12:16:39 -07001353 && info.resizeMode != RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Jorim Jaggicd13d332016-04-27 15:40:20 -07001354 }
1355
Winson Chunge6308042016-10-31 09:24:01 -07001356 /**
Winson Chungd3395382016-12-13 11:49:09 -08001357 * @return whether this activity supports PiP multi-window and can be put in the pinned stack.
Winson Chunge6308042016-10-31 09:24:01 -07001358 */
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001359 boolean supportsPictureInPicture() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001360 return mAtmService.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
Winson Chungd3395382016-12-13 11:49:09 -08001361 && info.supportsPictureInPicture();
1362 }
1363
1364 /**
1365 * @return whether this activity supports split-screen multi-window and can be put in the docked
1366 * stack.
1367 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001368 @Override
1369 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001370 // An activity can not be docked even if it is considered resizeable because it only
1371 // supports picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001372 return super.supportsSplitScreenWindowingMode()
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001373 && mAtmService.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow();
Winson Chungd3395382016-12-13 11:49:09 -08001374 }
1375
1376 /**
1377 * @return whether this activity supports freeform multi-window and can be put in the freeform
1378 * stack.
1379 */
1380 boolean supportsFreeform() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001381 return mAtmService.mSupportsFreeformWindowManagement && supportsResizeableMultiWindow();
Winson Chungd3395382016-12-13 11:49:09 -08001382 }
1383
1384 /**
1385 * @return whether this activity supports non-PiP multi-window.
1386 */
1387 private boolean supportsResizeableMultiWindow() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001388 return mAtmService.mSupportsMultiWindow && !isActivityTypeHome()
Winson Chungd3395382016-12-13 11:49:09 -08001389 && (ActivityInfo.isResizeableMode(info.resizeMode)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001390 || mAtmService.mForceResizableActivities);
Wale Ogunwaled26176f2016-01-25 20:04:04 -08001391 }
1392
Winson Chunge6308042016-10-31 09:24:01 -07001393 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001394 * Check whether this activity can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001395 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001396 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001397 * @return {@code true} if either it is the default display or this activity can be put on a
1398 * secondary screen.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001399 */
1400 boolean canBeLaunchedOnDisplay(int displayId) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001401 return mAtmService.mStackSupervisor.canPlaceEntityOnDisplay(displayId, launchedFromPid,
Riddle Hsu16567132018-08-16 21:37:47 +08001402 launchedFromUid, info);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001403 }
1404
1405 /**
Robert Carrc33658e2017-04-11 18:24:20 -07001406 * @param beforeStopping Whether this check is for an auto-enter-pip operation, that is to say
1407 * the activity has requested to enter PiP when it would otherwise be stopped.
1408 *
Winson Chung298f95b2017-08-10 15:57:18 -07001409 * @return whether this activity is currently allowed to enter PIP.
Winson Chunge6308042016-10-31 09:24:01 -07001410 */
Winson Chung298f95b2017-08-10 15:57:18 -07001411 boolean checkEnterPictureInPictureState(String caller, boolean beforeStopping) {
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07001412 if (!supportsPictureInPicture()) {
1413 return false;
1414 }
1415
Winson Chungf4ac0632017-03-17 12:34:12 -07001416 // Check app-ops and see if PiP is supported for this package
1417 if (!checkEnterPictureInPictureAppOpsState()) {
1418 return false;
1419 }
1420
Winson Chungf1bfee12017-03-24 17:11:33 -07001421 // Check to see if we are in VR mode, and disallow PiP if so
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001422 if (mAtmService.shouldDisableNonVrUiLocked()) {
Winson Chungf1bfee12017-03-24 17:11:33 -07001423 return false;
1424 }
1425
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001426 boolean isKeyguardLocked = mAtmService.isKeyguardLocked();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001427 boolean isCurrentAppLocked =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001428 mAtmService.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001429 final ActivityDisplay display = getDisplay();
1430 boolean hasPinnedStack = display != null && display.hasPinnedStack();
Winson Chungbb348802017-01-30 12:01:45 -08001431 // Don't return early if !isNotLocked, since we want to throw an exception if the activity
1432 // is in an incorrect state
Winson Chunge581ebf2017-02-21 08:25:03 -08001433 boolean isNotLockedOrOnKeyguard = !isKeyguardLocked && !isCurrentAppLocked;
Robert Carrc33658e2017-04-11 18:24:20 -07001434
1435 // We don't allow auto-PiP when something else is already pipped.
1436 if (beforeStopping && hasPinnedStack) {
1437 return false;
1438 }
1439
Bryce Lee7ace3952018-02-16 14:34:32 -08001440 switch (mState) {
Winson Chungc2baac02017-01-11 13:34:47 -08001441 case RESUMED:
Winson Chunge581ebf2017-02-21 08:25:03 -08001442 // When visible, allow entering PiP if the app is not locked. If it is over the
1443 // keyguard, then we will prompt to unlock in the caller before entering PiP.
Robert Carrc33658e2017-04-11 18:24:20 -07001444 return !isCurrentAppLocked &&
Winson Chungf7e03e12017-08-22 11:32:16 -07001445 (supportsEnterPipOnTaskSwitch || !beforeStopping);
Winson Chungc2baac02017-01-11 13:34:47 -08001446 case PAUSING:
1447 case PAUSED:
Winson Chungbb348802017-01-30 12:01:45 -08001448 // When pausing, then only allow enter PiP as in the resume state, and in addition,
1449 // require that there is not an existing PiP activity and that the current system
1450 // state supports entering PiP
Winson Chunge581ebf2017-02-21 08:25:03 -08001451 return isNotLockedOrOnKeyguard && !hasPinnedStack
Winson Chungf7e03e12017-08-22 11:32:16 -07001452 && supportsEnterPipOnTaskSwitch;
Winson Chungc2baac02017-01-11 13:34:47 -08001453 case STOPPING:
1454 // When stopping in a valid state, then only allow enter PiP as in the pause state.
1455 // Otherwise, fall through to throw an exception if the caller is trying to enter
1456 // PiP in an invalid stopping state.
Winson Chungf7e03e12017-08-22 11:32:16 -07001457 if (supportsEnterPipOnTaskSwitch) {
Winson Chungf4ac0632017-03-17 12:34:12 -07001458 return isNotLockedOrOnKeyguard && !hasPinnedStack;
Winson Chungc2baac02017-01-11 13:34:47 -08001459 }
1460 default:
Winson Chung298f95b2017-08-10 15:57:18 -07001461 return false;
Winson Chungb5c41b72016-12-07 15:00:47 -08001462 }
Winson Chunge6308042016-10-31 09:24:01 -07001463 }
1464
Winson Chung59fda9e2017-01-20 16:14:51 -08001465 /**
Winson Chungf4ac0632017-03-17 12:34:12 -07001466 * @return Whether AppOps allows this package to enter picture-in-picture.
Winson Chung59fda9e2017-01-20 16:14:51 -08001467 */
Winson Chungf4ac0632017-03-17 12:34:12 -07001468 private boolean checkEnterPictureInPictureAppOpsState() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001469 return mAtmService.getAppOpsService().checkOperation(
Wale Ogunwalef6733932018-06-27 05:14:34 -07001470 OP_PICTURE_IN_PICTURE, appInfo.uid, packageName) == MODE_ALLOWED;
Winson Chung59fda9e2017-01-20 16:14:51 -08001471 }
1472
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001473 boolean isAlwaysFocusable() {
1474 return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08001475 }
1476
Louis Chang19443452018-10-09 12:10:21 +08001477 /** Move activity with its stack to front and make the stack focused. */
1478 boolean moveFocusableActivityToTop(String reason) {
1479 if (!isFocusable()) {
1480 if (DEBUG_FOCUS) {
1481 Slog.d(TAG_FOCUS, "moveActivityStackToFront: unfocusable activity=" + this);
1482 }
1483 return false;
1484 }
1485
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001486 final TaskRecord task = getTaskRecord();
1487 final ActivityStack stack = getActivityStack();
Louis Chang19443452018-10-09 12:10:21 +08001488 if (stack == null) {
1489 Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: activity="
1490 + this + " task=" + task);
1491 return false;
1492 }
1493
Wale Ogunwaled32da472018-11-16 07:19:28 -08001494 if (mRootActivityContainer.getTopResumedActivity() == this) {
Louis Chang19443452018-10-09 12:10:21 +08001495 if (DEBUG_FOCUS) {
1496 Slog.d(TAG_FOCUS, "moveActivityStackToFront: already on top, activity=" + this);
1497 }
1498 return false;
1499 }
1500
1501 if (DEBUG_FOCUS) {
1502 Slog.d(TAG_FOCUS, "moveActivityStackToFront: activity=" + this);
1503 }
1504
1505 stack.moveToFront(reason, task);
1506 // Report top activity change to tracking services and WM
Wale Ogunwaled32da472018-11-16 07:19:28 -08001507 if (mRootActivityContainer.getTopResumedActivity() == this) {
Louis Chang19443452018-10-09 12:10:21 +08001508 // TODO(b/111361570): Support multiple focused apps in WM
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001509 mAtmService.setResumedActivityUncheckLocked(this, reason);
Louis Chang19443452018-10-09 12:10:21 +08001510 }
1511 return true;
1512 }
Jorim Jaggife762342016-10-13 14:33:27 +02001513
Wale Ogunwale7d701172015-03-11 15:36:30 -07001514 void makeFinishingLocked() {
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001515 if (finishing) {
1516 return;
1517 }
1518 finishing = true;
1519 if (stopped) {
1520 clearOptionsLocked();
1521 }
Yorke Leebd54c2a2016-10-25 13:49:23 -07001522
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001523 if (mAtmService != null) {
1524 mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08001525 }
1526 }
1527
Dianne Hackborn7e269642010-08-25 19:50:20 -07001528 UriPermissionOwner getUriPermissionsLocked() {
1529 if (uriPermissions == null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001530 uriPermissions = new UriPermissionOwner(mAtmService.mUgmInternal, this);
Dianne Hackborn7e269642010-08-25 19:50:20 -07001531 }
1532 return uriPermissions;
1533 }
1534
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001535 void addResultLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 int requestCode, int resultCode,
1537 Intent resultData) {
1538 ActivityResult r = new ActivityResult(from, resultWho,
John Spurlock8a985d22014-02-25 09:40:05 -05001539 requestCode, resultCode, resultData);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 if (results == null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001541 results = new ArrayList<ResultInfo>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 }
1543 results.add(r);
1544 }
1545
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001546 void removeResultsLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001547 int requestCode) {
1548 if (results != null) {
1549 for (int i=results.size()-1; i>=0; i--) {
1550 ActivityResult r = (ActivityResult)results.get(i);
1551 if (r.mFrom != from) continue;
1552 if (r.mResultWho == null) {
1553 if (resultWho != null) continue;
1554 } else {
1555 if (!r.mResultWho.equals(resultWho)) continue;
1556 }
1557 if (r.mRequestCode != requestCode) continue;
1558
1559 results.remove(i);
1560 }
1561 }
1562 }
1563
Andrii Kulian21713ac2016-10-12 22:05:05 -07001564 private void addNewIntentLocked(ReferrerIntent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 if (newIntents == null) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001566 newIntents = new ArrayList<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 }
1568 newIntents.add(intent);
1569 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001570
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001571 final boolean isSleeping() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001572 final ActivityStack stack = getActivityStack();
1573 return stack != null ? stack.shouldSleepActivities() : mAtmService.isSleepingLocked();
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001574 }
1575
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001576 /**
1577 * Deliver a new Intent to an existing activity, so that its onNewIntent()
1578 * method will be called at the proper time.
1579 */
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001580 final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
Dianne Hackborn514074f2013-02-11 10:52:46 -08001581 // The activity now gets access to the data associated with this Intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001582 mAtmService.mUgmInternal.grantUriPermissionFromIntent(callingUid, packageName,
1583 intent, getUriPermissionsLocked(), mUserId);
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001584 final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
Craig Mautner86d67a42013-05-14 10:34:38 -07001585 boolean unsent = true;
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001586 final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping();
Wale Ogunwale826c7062016-09-13 08:25:54 -07001587
1588 // We want to immediately deliver the intent to the activity if:
Wale Ogunwale03f7e9e2016-09-22 09:04:09 -07001589 // - It is currently resumed or paused. i.e. it is currently visible to the user and we want
1590 // the user to see the visual effects caused by the intent delivery now.
Wale Ogunwale826c7062016-09-13 08:25:54 -07001591 // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001592 if ((mState == RESUMED || mState == PAUSED || isTopActivityWhileSleeping)
1593 && attachedToProcess()) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001594 try {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001595 ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
1596 ar.add(rintent);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001597 mAtmService.getLifecycleManager().scheduleTransaction(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001598 app.getThread(), appToken, NewIntentItem.obtain(ar, mState == PAUSED));
Craig Mautner86d67a42013-05-14 10:34:38 -07001599 unsent = false;
Dianne Hackborn39792d22010-08-19 18:01:52 -07001600 } catch (RemoteException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001601 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
Dianne Hackborn39792d22010-08-19 18:01:52 -07001602 } catch (NullPointerException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001603 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001604 }
1605 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001606 if (unsent) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001607 addNewIntentLocked(rintent);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001608 }
1609 }
1610
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001611 void updateOptionsLocked(ActivityOptions options) {
1612 if (options != null) {
1613 if (pendingOptions != null) {
1614 pendingOptions.abort();
1615 }
1616 pendingOptions = options;
1617 }
1618 }
1619
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001620 void applyOptionsLocked() {
George Mount2c92c972014-03-20 09:38:23 -07001621 if (pendingOptions != null
Ruben Brunkf53497c2017-03-27 20:26:17 -07001622 && pendingOptions.getAnimationType() != ANIM_SCENE_TRANSITION) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001623 applyOptionsLocked(pendingOptions, intent);
chaviw82a0ba82018-03-15 14:26:29 -07001624 if (task == null) {
1625 clearOptionsLocked(false /* withAbort */);
1626 } else {
1627 // This will clear the options for all the ActivityRecords for this Task.
1628 task.clearAllPendingOptions();
1629 }
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001630 }
1631 }
1632
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001633 /**
1634 * Apply override app transition base on options & animation type.
1635 */
1636 void applyOptionsLocked(ActivityOptions pendingOptions, Intent intent) {
1637 final int animationType = pendingOptions.getAnimationType();
1638 final DisplayContent displayContent = mAppWindowToken.getDisplayContent();
1639 switch (animationType) {
1640 case ANIM_CUSTOM:
1641 displayContent.mAppTransition.overridePendingAppTransition(
1642 pendingOptions.getPackageName(),
1643 pendingOptions.getCustomEnterResId(),
1644 pendingOptions.getCustomExitResId(),
1645 pendingOptions.getOnAnimationStartListener());
1646 break;
1647 case ANIM_CLIP_REVEAL:
1648 displayContent.mAppTransition.overridePendingAppTransitionClipReveal(
1649 pendingOptions.getStartX(), pendingOptions.getStartY(),
1650 pendingOptions.getWidth(), pendingOptions.getHeight());
1651 if (intent.getSourceBounds() == null) {
1652 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1653 pendingOptions.getStartY(),
1654 pendingOptions.getStartX() + pendingOptions.getWidth(),
1655 pendingOptions.getStartY() + pendingOptions.getHeight()));
1656 }
1657 break;
1658 case ANIM_SCALE_UP:
1659 displayContent.mAppTransition.overridePendingAppTransitionScaleUp(
1660 pendingOptions.getStartX(), pendingOptions.getStartY(),
1661 pendingOptions.getWidth(), pendingOptions.getHeight());
1662 if (intent.getSourceBounds() == null) {
1663 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1664 pendingOptions.getStartY(),
1665 pendingOptions.getStartX() + pendingOptions.getWidth(),
1666 pendingOptions.getStartY() + pendingOptions.getHeight()));
1667 }
1668 break;
1669 case ANIM_THUMBNAIL_SCALE_UP:
1670 case ANIM_THUMBNAIL_SCALE_DOWN:
1671 final boolean scaleUp = (animationType == ANIM_THUMBNAIL_SCALE_UP);
1672 final GraphicBuffer buffer = pendingOptions.getThumbnail();
1673 displayContent.mAppTransition.overridePendingAppTransitionThumb(buffer,
1674 pendingOptions.getStartX(), pendingOptions.getStartY(),
1675 pendingOptions.getOnAnimationStartListener(),
1676 scaleUp);
1677 if (intent.getSourceBounds() == null && buffer != null) {
1678 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1679 pendingOptions.getStartY(),
1680 pendingOptions.getStartX() + buffer.getWidth(),
1681 pendingOptions.getStartY() + buffer.getHeight()));
1682 }
1683 break;
1684 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
1685 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
1686 final AppTransitionAnimationSpec[] specs = pendingOptions.getAnimSpecs();
1687 final IAppTransitionAnimationSpecsFuture specsFuture =
1688 pendingOptions.getSpecsFuture();
1689 if (specsFuture != null) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001690 displayContent.mAppTransition.overridePendingAppTransitionMultiThumbFuture(
1691 specsFuture, pendingOptions.getOnAnimationStartListener(),
1692 animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP);
1693 } else if (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
1694 && specs != null) {
1695 displayContent.mAppTransition.overridePendingAppTransitionMultiThumb(
1696 specs, pendingOptions.getOnAnimationStartListener(),
1697 pendingOptions.getAnimationFinishedListener(), false);
1698 } else {
1699 displayContent.mAppTransition.overridePendingAppTransitionAspectScaledThumb(
1700 pendingOptions.getThumbnail(),
1701 pendingOptions.getStartX(), pendingOptions.getStartY(),
1702 pendingOptions.getWidth(), pendingOptions.getHeight(),
1703 pendingOptions.getOnAnimationStartListener(),
1704 (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP));
1705 if (intent.getSourceBounds() == null) {
1706 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1707 pendingOptions.getStartY(),
1708 pendingOptions.getStartX() + pendingOptions.getWidth(),
1709 pendingOptions.getStartY() + pendingOptions.getHeight()));
1710 }
1711 }
1712 break;
1713 case ANIM_OPEN_CROSS_PROFILE_APPS:
1714 displayContent.mAppTransition
1715 .overridePendingAppTransitionStartCrossProfileApps();
1716 break;
1717 case ANIM_REMOTE_ANIMATION:
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001718 displayContent.mAppTransition.overridePendingAppTransitionRemote(
1719 pendingOptions.getRemoteAnimationAdapter());
1720 break;
1721 case ANIM_NONE:
1722 break;
1723 default:
1724 Slog.e(TAG_WM, "applyOptionsLocked: Unknown animationType=" + animationType);
1725 break;
1726 }
1727 }
1728
Adam Powellcfbe9be2013-11-06 14:58:58 -08001729 ActivityOptions getOptionsForTargetActivityLocked() {
1730 return pendingOptions != null ? pendingOptions.forTargetActivity() : null;
1731 }
1732
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001733 void clearOptionsLocked() {
chaviw82a0ba82018-03-15 14:26:29 -07001734 clearOptionsLocked(true /* withAbort */);
1735 }
1736
1737 void clearOptionsLocked(boolean withAbort) {
1738 if (withAbort && pendingOptions != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001739 pendingOptions.abort();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001740 }
chaviw82a0ba82018-03-15 14:26:29 -07001741 pendingOptions = null;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001742 }
1743
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001744 ActivityOptions takeOptionsLocked() {
1745 ActivityOptions opts = pendingOptions;
1746 pendingOptions = null;
1747 return opts;
1748 }
1749
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001750 void removeUriPermissionsLocked() {
Dianne Hackborn7e269642010-08-25 19:50:20 -07001751 if (uriPermissions != null) {
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07001752 uriPermissions.removeUriPermissions();
Dianne Hackborn7e269642010-08-25 19:50:20 -07001753 uriPermissions = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001754 }
1755 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756
1757 void pauseKeyDispatchingLocked() {
1758 if (!keysPaused) {
1759 keysPaused = true;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001760
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001761 // TODO: remove the check after unification with AppWindowToken. The DC check is not
1762 // needed after no mock mAppWindowToken in tests.
1763 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
1764 mAppWindowToken.getDisplayContent().getInputMonitor().pauseDispatchingLw(
1765 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07001766 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001767 }
1768 }
1769
1770 void resumeKeyDispatchingLocked() {
1771 if (keysPaused) {
1772 keysPaused = false;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001773
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001774 // TODO: remove the check after unification with AppWindowToken. The DC check is not
1775 // needed after no mock mAppWindowToken in tests.
1776 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
1777 mAppWindowToken.getDisplayContent().getInputMonitor().resumeDispatchingLw(
1778 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07001779 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 }
1781 }
1782
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001783 private void updateTaskDescription(CharSequence description) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001784 task.lastDescription = description;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001785 }
1786
Wale Ogunwaleec950642017-04-25 07:44:21 -07001787 void setDeferHidingClient(boolean deferHidingClient) {
1788 if (mDeferHidingClient == deferHidingClient) {
1789 return;
1790 }
1791 mDeferHidingClient = deferHidingClient;
1792 if (!mDeferHidingClient && !visible) {
1793 // Hiding the client is no longer deferred and the app isn't visible still, go ahead and
1794 // update the visibility.
1795 setVisibility(false);
1796 }
Wale Ogunwale89973222017-04-23 18:39:45 -07001797 }
1798
Wale Ogunwaleec950642017-04-25 07:44:21 -07001799 void setVisibility(boolean visible) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001800 if (mAppWindowToken == null) {
1801 Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: "
1802 + appToken);
1803 return;
1804 }
1805 mAppWindowToken.setVisibility(visible, mDeferHidingClient);
Bryce Lee2a3cc462017-10-27 10:57:35 -07001806 mStackSupervisor.getActivityMetricsLogger().notifyVisibilityChanged(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001807 }
1808
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001809 // TODO: Look into merging with #commitVisibility()
Wale Ogunwaleec950642017-04-25 07:44:21 -07001810 void setVisible(boolean newVisible) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001811 visible = newVisible;
Wale Ogunwaleec950642017-04-25 07:44:21 -07001812 mDeferHidingClient = !visible && mDeferHidingClient;
Wale Ogunwaleec950642017-04-25 07:44:21 -07001813 setVisibility(visible);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001814 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
1815 }
1816
Bryce Lee7ace3952018-02-16 14:34:32 -08001817 void setState(ActivityState state, String reason) {
1818 if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState()
1819 + " to:" + state + " reason:" + reason);
Bryce Lee6ff17072018-02-28 07:26:17 -08001820
Bryce Leeb0f993f2018-03-02 15:38:01 -08001821 if (state == mState) {
1822 // No need to do anything if state doesn't change.
1823 if (DEBUG_STATES) Slog.v(TAG_STATES, "State unchanged from:" + state);
1824 return;
1825 }
1826
Bryce Leeb0f993f2018-03-02 15:38:01 -08001827 mState = state;
1828
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001829 final TaskRecord parent = getTaskRecord();
Bryce Leec4ab62a2018-03-05 14:19:26 -08001830
1831 if (parent != null) {
1832 parent.onActivityStateChanged(this, state, reason);
1833 }
Robert Carr29daa922018-04-27 11:56:48 -07001834
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001835 // The WindowManager interprets the app stopping signal as
1836 // an indication that the Surface will eventually be destroyed.
1837 // This however isn't necessarily true if we are going to sleep.
1838 if (state == STOPPING && !isSleeping()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001839 if (mAppWindowToken == null) {
1840 Slog.w(TAG_WM, "Attempted to notify stopping on non-existing app token: "
1841 + appToken);
1842 return;
1843 }
1844 mAppWindowToken.detachChildren();
Robert Carr29daa922018-04-27 11:56:48 -07001845 }
Hui Yu03d12402018-12-06 18:00:37 -08001846
1847 if (state == RESUMED) {
1848 mAtmService.updateBatteryStats(this, true);
1849 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_RESUMED);
1850 } else if (state == PAUSED) {
1851 mAtmService.updateBatteryStats(this, false);
1852 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_PAUSED);
1853 } else if (state == STOPPED) {
1854 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_STOPPED);
1855 } else if (state == DESTROYED) {
1856 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_DESTROYED);
1857 }
Bryce Lee7ace3952018-02-16 14:34:32 -08001858 }
1859
1860 ActivityState getState() {
1861 return mState;
1862 }
1863
1864 /**
1865 * Returns {@code true} if the Activity is in the specified state.
1866 */
1867 boolean isState(ActivityState state) {
1868 return state == mState;
1869 }
1870
1871 /**
1872 * Returns {@code true} if the Activity is in one of the specified states.
1873 */
1874 boolean isState(ActivityState state1, ActivityState state2) {
1875 return state1 == mState || state2 == mState;
1876 }
1877
1878 /**
1879 * Returns {@code true} if the Activity is in one of the specified states.
1880 */
1881 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3) {
1882 return state1 == mState || state2 == mState || state3 == mState;
1883 }
1884
1885 /**
1886 * Returns {@code true} if the Activity is in one of the specified states.
1887 */
1888 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3,
1889 ActivityState state4) {
1890 return state1 == mState || state2 == mState || state3 == mState || state4 == mState;
1891 }
1892
Jorim Jaggibae01b12017-04-11 16:29:10 -07001893 void notifyAppResumed(boolean wasStopped) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001894 if (mAppWindowToken == null) {
1895 Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: "
1896 + appToken);
1897 return;
1898 }
1899 mAppWindowToken.notifyAppResumed(wasStopped);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001900 }
1901
1902 void notifyUnknownVisibilityLaunched() {
Jorim Jaggi838c2452017-08-28 15:44:43 +02001903
1904 // No display activities never add a window, so there is no point in waiting them for
1905 // relayout.
1906 if (!noDisplay) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001907 if (mAppWindowToken != null) {
1908 mAppWindowToken.getDisplayContent().mUnknownAppVisibilityController
1909 .notifyLaunched(mAppWindowToken);
1910 }
Jorim Jaggi838c2452017-08-28 15:44:43 +02001911 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001912 }
1913
Jorim Jaggi241ae102016-11-02 21:57:33 -07001914 /**
1915 * @return true if the input activity should be made visible, ignoring any effect Keyguard
1916 * might have on the visibility
1917 *
Garfield Tan47e576c2019-01-28 10:26:23 -08001918 * TODO(b/123540470): Combine this method and {@link #shouldBeVisible(boolean)}.
1919 *
Jorim Jaggi241ae102016-11-02 21:57:33 -07001920 * @see {@link ActivityStack#checkKeyguardVisibility}
1921 */
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001922 boolean shouldBeVisibleIgnoringKeyguard(boolean behindFullscreenActivity) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001923 if (!okToShowLocked()) {
1924 return false;
1925 }
1926
Winson Chung3f0e59a2017-10-25 10:19:05 -07001927 return !behindFullscreenActivity || mLaunchTaskBehind;
Andrii Kulian21713ac2016-10-12 22:05:05 -07001928 }
1929
Garfield Tan47e576c2019-01-28 10:26:23 -08001930 boolean shouldBeVisible(boolean behindFullscreenActivity) {
1931 // Check whether activity should be visible without Keyguard influence
1932 visibleIgnoringKeyguard = shouldBeVisibleIgnoringKeyguard(behindFullscreenActivity);
1933
1934 final ActivityStack stack = getActivityStack();
1935 if (stack == null) {
1936 return false;
1937 }
1938
1939 // Whether this activity is the top activity of this stack.
1940 final boolean isTop = this == stack.getTopActivity();
1941 // Exclude the case where this is the top activity in a pinned stack.
1942 final boolean isTopNotPinnedStack = stack.isAttached()
1943 && stack.getDisplay().isTopNotPinnedStack(stack);
1944 // Now check whether it's really visible depending on Keyguard state.
1945 return stack.checkKeyguardVisibility(this,
1946 visibleIgnoringKeyguard, isTop && isTopNotPinnedStack);
1947 }
1948
1949 boolean shouldBeVisible() {
1950 final ActivityStack stack = getActivityStack();
1951 if (stack == null) {
1952 return false;
1953 }
1954
1955 // TODO: Use real value of behindFullscreenActivity calculated using the same logic in
1956 // ActivityStack#ensureActivitiesVisibleLocked().
1957 return shouldBeVisible(!stack.shouldBeVisible(null /* starting */));
1958 }
1959
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001960 void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001961 // This activity is not currently visible, but is running. Tell it to become visible.
Bryce Lee7ace3952018-02-16 14:34:32 -08001962 if (mState == RESUMED || this == starting) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001963 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
Bryce Lee7ace3952018-02-16 14:34:32 -08001964 "Not making visible, r=" + this + " state=" + mState + " starting=" + starting);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001965 return;
1966 }
1967
1968 // If this activity is paused, tell it to now show its window.
1969 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1970 "Making visible and scheduling visibility: " + this);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001971 final ActivityStack stack = getActivityStack();
Andrii Kulian21713ac2016-10-12 22:05:05 -07001972 try {
1973 if (stack.mTranslucentActivityWaiting != null) {
1974 updateOptionsLocked(returningOptions);
1975 stack.mUndrawnActivitiesBelowTopTranslucent.add(this);
1976 }
1977 setVisible(true);
1978 sleeping = false;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001979 app.postPendingUiCleanMsg(true);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001980 if (reportToClient) {
1981 makeClientVisible();
1982 } else {
1983 mClientVisibilityDeferred = true;
1984 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07001985 // The activity may be waiting for stop, but that is no longer appropriate for it.
1986 mStackSupervisor.mStoppingActivities.remove(this);
1987 mStackSupervisor.mGoingToSleepActivities.remove(this);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001988 } catch (Exception e) {
1989 // Just skip on any failure; we'll make it visible when it next restarts.
1990 Slog.w(TAG, "Exception thrown making visible: " + intent.getComponent(), e);
1991 }
1992 handleAlreadyVisible();
1993 }
Andrii Kulian0d595f32018-02-21 15:47:33 -08001994
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001995 /** Send visibility change message to the client and pause if needed. */
1996 void makeClientVisible() {
1997 mClientVisibilityDeferred = false;
1998 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001999 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002000 WindowVisibilityItem.obtain(true /* showWindow */));
Andrii Kulian6b321512019-01-23 06:37:00 +00002001 makeActiveIfNeeded(null /* activeActivity*/);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002002 } catch (Exception e) {
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07002003 Slog.w(TAG, "Exception thrown sending visibility update: " + intent.getComponent(), e);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002004 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002005 }
2006
Andrii Kulian6b321512019-01-23 06:37:00 +00002007 /**
2008 * Make activity resumed or paused if needed.
2009 * @param activeActivity an activity that is resumed or just completed pause action.
2010 * We won't change the state of this activity.
2011 */
2012 boolean makeActiveIfNeeded(ActivityRecord activeActivity) {
2013 if (shouldResumeActivity(activeActivity)) {
2014 if (DEBUG_VISIBILITY) {
2015 Slog.v("TAG_VISIBILITY", "Resume visible activity, " + this);
2016 }
2017 return getActivityStack().resumeTopActivityUncheckedLocked(activeActivity /* prev */,
2018 null /* options */);
2019 } else if (shouldPauseActivity(activeActivity)) {
2020 if (DEBUG_VISIBILITY) {
2021 Slog.v("TAG_VISIBILITY", "Pause visible activity, " + this);
2022 }
2023 // An activity must be in the {@link PAUSING} state for the system to validate
2024 // the move to {@link PAUSED}.
2025 setState(PAUSING, "makeVisibleIfNeeded");
2026 try {
2027 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
2028 PauseActivityItem.obtain(finishing, false /* userLeaving */,
2029 configChangeFlags, false /* dontReport */));
2030 } catch (Exception e) {
2031 Slog.w(TAG, "Exception thrown sending pause: " + intent.getComponent(), e);
2032 }
2033 }
2034 return false;
2035 }
2036
2037 /**
2038 * Check if activity should be moved to PAUSED state. The activity:
2039 * - should be eligible to be made active (see {@link #shouldMakeActive(ActivityRecord)})
2040 * - should be non-focusable
2041 * - should not be currently pausing or paused
2042 * @param activeActivity the activity that is active or just completed pause action. We won't
2043 * resume if this activity is active.
2044 */
2045 private boolean shouldPauseActivity(ActivityRecord activeActivity) {
2046 return shouldMakeActive(activeActivity) && !isFocusable() && !isState(PAUSING, PAUSED);
2047 }
2048
2049 /**
2050 * Check if activity should be moved to RESUMED state. The activity:
2051 * - should be eligible to be made active (see {@link #shouldMakeActive(ActivityRecord)})
2052 * - should be focusable
2053 * @param activeActivity the activity that is active or just completed pause action. We won't
2054 * resume if this activity is active.
2055 */
Andrii Kulian0c869cc2019-02-06 19:50:32 -08002056 @VisibleForTesting
2057 boolean shouldResumeActivity(ActivityRecord activeActivity) {
2058 return shouldMakeActive(activeActivity) && isFocusable() && !isState(RESUMED)
2059 && getActivityStack().getVisibility(activeActivity) == STACK_VISIBILITY_VISIBLE;
Andrii Kulian6b321512019-01-23 06:37:00 +00002060 }
2061
2062 /**
2063 * Check if activity is eligible to be made active (resumed of paused). The activity:
2064 * - should be paused, stopped or stopping
Andrii Kulian996df0d2019-01-24 17:04:36 -08002065 * - should not be the currently active one or launching behind other tasks
Andrii Kulian6b321512019-01-23 06:37:00 +00002066 * - should be either the topmost in task, or right below the top activity that is finishing
2067 * If all of these conditions are not met at the same time, the activity cannot be made active.
2068 */
Andrii Kulianf2195362019-01-31 18:20:11 -08002069 @VisibleForTesting
2070 boolean shouldMakeActive(ActivityRecord activeActivity) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002071 // If the activity is stopped, stopping, cycle to an active state. We avoid doing
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002072 // this when there is an activity waiting to become translucent as the extra binder
2073 // calls will lead to noticeable jank. A later call to
Andrii Kulian6b321512019-01-23 06:37:00 +00002074 // ActivityStack#ensureActivitiesVisibleLocked will bring the activity to a proper
2075 // active state.
2076 if (!isState(RESUMED, PAUSED, STOPPED, STOPPING)
2077 || getActivityStack().mTranslucentActivityWaiting != null) {
2078 return false;
2079 }
2080
2081 if (this == activeActivity) {
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002082 return false;
2083 }
2084
Andrii Kulianf2195362019-01-31 18:20:11 -08002085 if (!mStackSupervisor.readyToResume()) {
2086 // Making active is currently deferred (e.g. because an activity launch is in progress).
2087 return false;
2088 }
2089
Andrii Kulian996df0d2019-01-24 17:04:36 -08002090 if (this.mLaunchTaskBehind) {
2091 // This activity is being launched from behind, which means that it's not intended to be
2092 // presented to user right now, even if it's set to be visible.
2093 return false;
2094 }
2095
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002096 // Check if position in task allows to become paused
2097 final int positionInTask = task.mActivities.indexOf(this);
2098 if (positionInTask == -1) {
2099 throw new IllegalStateException("Activity not found in its task");
2100 }
2101 if (positionInTask == task.mActivities.size() - 1) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002102 // It's the topmost activity in the task - should become resumed now
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002103 return true;
2104 }
2105 // Check if activity above is finishing now and this one becomes the topmost in task.
2106 final ActivityRecord activityAbove = task.mActivities.get(positionInTask + 1);
2107 if (activityAbove.finishing && results == null) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002108 // We will only allow making active if activity above wasn't launched for result.
2109 // Otherwise it will cause this activity to resume before getting result.
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002110 return true;
2111 }
2112 return false;
2113 }
2114
Andrii Kulian21713ac2016-10-12 22:05:05 -07002115 boolean handleAlreadyVisible() {
2116 stopFreezingScreenLocked(false);
2117 try {
2118 if (returningOptions != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002119 app.getThread().scheduleOnNewActivityOptions(appToken, returningOptions.toBundle());
Andrii Kulian21713ac2016-10-12 22:05:05 -07002120 }
2121 } catch(RemoteException e) {
2122 }
Bryce Lee7ace3952018-02-16 14:34:32 -08002123 return mState == RESUMED;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002124 }
2125
2126 static void activityResumedLocked(IBinder token) {
2127 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2128 if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
2129 if (r != null) {
2130 r.icicle = null;
2131 r.haveState = false;
2132 }
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002133
2134 final ActivityDisplay display = r.getDisplay();
2135 if (display != null) {
2136 display.handleActivitySizeCompatModeIfNeeded(r);
2137 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002138 }
2139
2140 /**
2141 * Once we know that we have asked an application to put an activity in the resumed state
2142 * (either by launching it or explicitly telling it), this function updates the rest of our
2143 * state to match that fact.
2144 */
2145 void completeResumeLocked() {
2146 final boolean wasVisible = visible;
Jorim Jaggi8d062052017-08-22 14:55:17 +02002147 setVisible(true);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002148 if (!wasVisible) {
2149 // Visibility has changed, so take a note of it so we call the TaskStackChangedListener
2150 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
2151 }
2152 idle = false;
2153 results = null;
2154 newIntents = null;
2155 stopped = false;
2156
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002157 if (isActivityTypeHome()) {
Louis Changdcdde952018-12-04 15:38:44 +08002158 mStackSupervisor.updateHomeProcess(task.mActivities.get(0).app);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002159 }
2160
2161 if (nowVisible) {
2162 // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
2163 mStackSupervisor.reportActivityVisibleLocked(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002164 }
2165
2166 // Schedule an idle timeout in case the app doesn't do it for us.
2167 mStackSupervisor.scheduleIdleTimeoutLocked(this);
2168
2169 mStackSupervisor.reportResumedActivityLocked(this);
2170
2171 resumeKeyDispatchingLocked();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002172 final ActivityStack stack = getActivityStack();
Jorim Jaggifa9ed962018-01-25 00:16:49 +01002173 mStackSupervisor.mNoAnimActivities.clear();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002174
2175 // Mark the point when the activity is resuming
2176 // TODO: To be more accurate, the mark should be before the onCreate,
2177 // not after the onResume. But for subsequent starts, onResume is fine.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002178 if (hasProcess()) {
Wale Ogunwale86b74462018-07-02 08:42:43 -07002179 cpuTimeAtResume = app.getCpuTime();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002180 } else {
2181 cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2182 }
2183
2184 returningOptions = null;
chaviw59b98852017-06-13 12:05:44 -07002185
2186 if (canTurnScreenOn()) {
2187 mStackSupervisor.wakeUp("turnScreenOnFlag");
2188 } else {
2189 // If the screen is going to turn on because the caller explicitly requested it and
2190 // the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
2191 // pause and then resume again later, which will result in a double life-cycle event.
David Stevens9440dc82017-03-16 19:00:20 -07002192 stack.checkReadyForSleep();
chaviw59b98852017-06-13 12:05:44 -07002193 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002194 }
2195
2196 final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
2197 CharSequence description) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002198 final ActivityStack stack = getActivityStack();
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002199 final boolean isStopping = mState == STOPPING;
2200 if (!isStopping && mState != RESTARTING_PROCESS) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002201 Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
Ruben Brunkf53497c2017-03-27 20:26:17 -07002202 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002203 return;
2204 }
2205 if (newPersistentState != null) {
2206 persistentState = newPersistentState;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002207 mAtmService.notifyTaskPersisterLocked(task, false);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002208 }
2209 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + icicle);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002210
Andrii Kulian21713ac2016-10-12 22:05:05 -07002211 if (newIcicle != null) {
2212 // If icicle is null, this is happening due to a timeout, so we haven't really saved
2213 // the state.
2214 icicle = newIcicle;
2215 haveState = true;
2216 launchCount = 0;
Jorim Jaggie7d2b852017-08-28 17:55:15 +02002217 updateTaskDescription(description);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002218 }
2219 if (!stopped) {
2220 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
Ruben Brunkf53497c2017-03-27 20:26:17 -07002221 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002222 stopped = true;
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002223 if (isStopping) {
2224 setState(STOPPED, "activityStoppedLocked");
2225 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002226
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002227 if (mAppWindowToken != null) {
2228 mAppWindowToken.notifyAppStopped();
2229 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002230
Andrii Kulian21713ac2016-10-12 22:05:05 -07002231 if (finishing) {
2232 clearOptionsLocked();
2233 } else {
2234 if (deferRelaunchUntilPaused) {
2235 stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002236 mRootActivityContainer.resumeFocusedStacksTopActivities();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002237 } else {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002238 mRootActivityContainer.updatePreviousProcess(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002239 }
2240 }
2241 }
2242 }
2243
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002244 void startLaunchTickingLocked() {
Jeff Sharkey5ab02432017-06-27 11:01:36 -06002245 if (Build.IS_USER) {
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002246 return;
2247 }
2248 if (launchTickTime == 0) {
2249 launchTickTime = SystemClock.uptimeMillis();
2250 continueLaunchTickingLocked();
2251 }
2252 }
2253
2254 boolean continueLaunchTickingLocked() {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002255 if (launchTickTime == 0) {
2256 return false;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002257 }
Wale Ogunwale7d701172015-03-11 15:36:30 -07002258
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002259 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002260 if (stack == null) {
2261 return false;
2262 }
2263
Ruben Brunkf53497c2017-03-27 20:26:17 -07002264 Message msg = stack.mHandler.obtainMessage(LAUNCH_TICK_MSG, this);
2265 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
2266 stack.mHandler.sendMessageDelayed(msg, LAUNCH_TICK);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002267 return true;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002268 }
2269
2270 void finishLaunchTickingLocked() {
2271 launchTickTime = 0;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002272 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002273 if (stack != null) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07002274 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002275 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002276 }
2277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 // IApplicationToken
2279
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002280 public boolean mayFreezeScreenLocked(WindowProcessController app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 // Only freeze the screen if this activity is currently attached to
2282 // an application, and that application is not blocked or unresponding.
2283 // In any other case, we can't count on getting the screen unfrozen,
2284 // so it is best to leave as-is.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002285 return hasProcess() && !app.isCrashing() && !app.isNotResponding();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002287
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002288 public void startFreezingScreenLocked(WindowProcessController app, int configChanges) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 if (mayFreezeScreenLocked(app)) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002290 if (mAppWindowToken == null) {
2291 Slog.w(TAG_WM,
2292 "Attempted to freeze screen with non-existing app token: " + appToken);
2293 return;
2294 }
2295
2296 if (configChanges == 0 && mAppWindowToken.okToDisplay()) {
2297 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + appToken);
2298 return;
2299 }
2300
2301 mAppWindowToken.startFreezingScreen();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 }
2303 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002305 public void stopFreezingScreenLocked(boolean force) {
2306 if (force || frozenBeforeDestroy) {
2307 frozenBeforeDestroy = false;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002308 if (mAppWindowToken == null) {
2309 return;
2310 }
2311 if (DEBUG_ORIENTATION) {
2312 Slog.v(TAG_WM, "Clear freezing of " + appToken + ": hidden="
2313 + mAppWindowToken.isHidden() + " freezing="
2314 + mAppWindowToken.isFreezingScreen());
2315 }
2316 mAppWindowToken.stopFreezingScreen(true, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 }
2318 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002319
Jorim Jaggi4d27b842017-08-17 17:22:26 +02002320 public void reportFullyDrawnLocked(boolean restoredFromBundle) {
Vishnu Nair132ee832018-09-28 15:00:05 -07002321 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2322 .getActivityMetricsLogger().logAppTransitionReportedDrawn(this, restoredFromBundle);
2323 if (info != null) {
2324 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002325 info.windowsFullyDrawnDelayMs, info.getLaunchState());
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002326 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002327 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002328
2329 /**
2330 * Called when the starting window for this container is drawn.
2331 */
Sudheer Shankac766db02017-06-12 10:37:29 -07002332 public void onStartingWindowDrawn(long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002333 synchronized (mAtmService.mGlobalLock) {
Bryce Lee2a3cc462017-10-27 10:57:35 -07002334 mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +01002335 getWindowingMode(), timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -08002336 }
2337 }
2338
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002339 /** Called when the windows associated app window container are drawn. */
Vishnu Nair9ba31652018-11-13 14:34:05 -08002340 public void onWindowsDrawn(boolean drawn, long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002341 synchronized (mAtmService.mGlobalLock) {
Vishnu Nair9ba31652018-11-13 14:34:05 -08002342 mDrawn = drawn;
2343 if (!drawn) {
2344 return;
2345 }
Vishnu Nair132ee832018-09-28 15:00:05 -07002346 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2347 .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
2348 final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002349 final @LaunchState int launchState = info != null ? info.getLaunchState() : -1;
Vishnu Nair132ee832018-09-28 15:00:05 -07002350 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002351 windowsDrawnDelayMs, launchState);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002352 mStackSupervisor.sendWaitingVisibleReportLocked(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002353 finishLaunchTickingLocked();
2354 if (task != null) {
2355 task.hasBeenVisible = true;
2356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357 }
2358 }
2359
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002360 /** Called when the windows associated app window container are visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002361 public void onWindowsVisible() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002362 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002363 mStackSupervisor.reportActivityVisibleLocked(this);
2364 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
2365 if (!nowVisible) {
2366 nowVisible = true;
2367 lastVisibleTime = SystemClock.uptimeMillis();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002368 mAtmService.scheduleAppGcsLocked();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002369 }
2370 }
2371 }
2372
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002373 /** Called when the windows associated app window container are no longer visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002374 public void onWindowsGone() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002375 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002376 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + this);
2377 nowVisible = false;
2378 }
2379 }
2380
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002381 void onAnimationFinished() {
2382 if (mRootActivityContainer.allResumedActivitiesIdle()
2383 || mStackSupervisor.isStoppingNoHistoryActivity()) {
2384 // If all activities are already idle or there is an activity that must be
2385 // stopped immediately after visible, then we now need to make sure we perform
2386 // the full stop of this activity. This is because we won't do that while they are still
2387 // waiting for the animation to finish.
2388 if (mStackSupervisor.mStoppingActivities.contains(this)) {
2389 mStackSupervisor.scheduleIdleLocked();
2390 }
2391 } else {
2392 // Instead of doing the full stop routine here, let's just hide any activities
2393 // we now can, and let them stop when the normal idle happens.
2394 mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
2395 false /* remove */, true /* processPausingActivities */);
2396 }
2397 }
2398
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002399 /**
2400 * Called when the key dispatching to a window associated with the app window container
2401 * timed-out.
2402 *
2403 * @param reason The reason for the key dispatching time out.
2404 * @param windowPid The pid of the window key dispatching timed out on.
2405 * @return True if input dispatching should be aborted.
2406 */
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002407 public boolean keyDispatchingTimedOut(String reason, int windowPid) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002408 ActivityRecord anrActivity;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002409 WindowProcessController anrApp;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002410 boolean windowFromSameProcessAsActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002411 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002412 anrActivity = getWaitingHistoryRecordLocked();
2413 anrApp = app;
Brian Carlstrom7b0f2e82017-03-31 00:24:18 -07002414 windowFromSameProcessAsActivity =
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002415 !hasProcess() || app.getPid() == windowPid || windowPid == -1;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002416 }
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002417
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002418 if (windowFromSameProcessAsActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002419 return mAtmService.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner,
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002420 anrActivity.shortComponentName, anrActivity.appInfo, shortComponentName,
2421 app, false, reason);
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002422 } else {
2423 // In this case another process added windows using this activity token. So, we call the
2424 // generic service input dispatch timed out method so that the right process is blamed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002425 return mAtmService.mAmInternal.inputDispatchingTimedOut(
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002426 windowPid, false /* aboveSystem */, reason) < 0;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002427 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002428 }
2429
2430 private ActivityRecord getWaitingHistoryRecordLocked() {
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002431 // First find the real culprit... if this activity has stopped, then the key dispatching
riddle_hsudb46d6b2015-04-01 18:58:07 +08002432 // timeout should not be caused by this.
Jorim Jaggi9b5e3312019-03-01 18:08:00 +01002433 if (stopped) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002434 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
riddle_hsudb46d6b2015-04-01 18:58:07 +08002435 // Try to use the one which is closest to top.
Bryce Leec4ab62a2018-03-05 14:19:26 -08002436 ActivityRecord r = stack.getResumedActivity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002437 if (r == null) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002438 r = stack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002440 if (r != null) {
2441 return r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 }
2443 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002444 return this;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002445 }
2446
Chong Zhang87761972016-08-22 13:53:24 -07002447 /** Checks whether the activity should be shown for current user. */
2448 public boolean okToShowLocked() {
Bryce Lee8558ec72017-08-17 15:37:26 -07002449 // We cannot show activities when the device is locked and the application is not
2450 // encryption aware.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002451 if (!StorageManager.isUserKeyUnlocked(mUserId)
Bryce Lee8558ec72017-08-17 15:37:26 -07002452 && !info.applicationInfo.isEncryptionAware()) {
2453 return false;
2454 }
2455
Chong Zhang87761972016-08-22 13:53:24 -07002456 return (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002457 || (mStackSupervisor.isCurrentProfileLocked(mUserId)
2458 && mAtmService.mAmInternal.isUserRunning(mUserId, 0 /* flags */));
Chong Zhang87761972016-08-22 13:53:24 -07002459 }
2460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002461 /**
2462 * This method will return true if the activity is either visible, is becoming visible, is
2463 * currently pausing, or is resumed.
2464 */
2465 public boolean isInterestingToUserLocked() {
Bryce Lee7ace3952018-02-16 14:34:32 -08002466 return visible || nowVisible || mState == PAUSING || mState == RESUMED;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002467 }
2468
Wale Ogunwale3e997362016-09-06 10:37:56 -07002469 void setSleeping(boolean _sleeping) {
2470 setSleeping(_sleeping, false);
2471 }
2472
2473 void setSleeping(boolean _sleeping, boolean force) {
2474 if (!force && sleeping == _sleeping) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002475 return;
2476 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002477 if (attachedToProcess()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002478 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002479 app.getThread().scheduleSleeping(appToken, _sleeping);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002480 if (_sleeping && !mStackSupervisor.mGoingToSleepActivities.contains(this)) {
2481 mStackSupervisor.mGoingToSleepActivities.add(this);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002482 }
2483 sleeping = _sleeping;
2484 } catch (RemoteException e) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002485 Slog.w(TAG, "Exception thrown when sleeping: " + intent.getComponent(), e);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002486 }
2487 }
2488 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08002489
Craig Mautnerd2328952013-03-05 12:46:26 -08002490 static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002491 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Craig Mautnerd2328952013-03-05 12:46:26 -08002492 if (r == null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002493 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002494 }
2495 final TaskRecord task = r.task;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002496 final int activityNdx = task.mActivities.indexOf(r);
2497 if (activityNdx < 0 || (onlyRoot && activityNdx > task.findEffectiveRootIndex())) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002498 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002499 }
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002500 return task.taskId;
Craig Mautnerd2328952013-03-05 12:46:26 -08002501 }
2502
2503 static ActivityRecord isInStackLocked(IBinder token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002504 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002505 return (r != null) ? r.getActivityStack().isInStackLocked(r) : null;
Craig Mautnerd2328952013-03-05 12:46:26 -08002506 }
2507
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002508 static ActivityStack getStackLocked(IBinder token) {
Craig Mautnerd2328952013-03-05 12:46:26 -08002509 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2510 if (r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002511 return r.getActivityStack();
Craig Mautnerd2328952013-03-05 12:46:26 -08002512 }
2513 return null;
2514 }
2515
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002516 /**
Riddle Hsufd4a0502018-10-16 01:05:16 +08002517 * @return display id to which this record is attached,
2518 * {@link android.view.Display#INVALID_DISPLAY} if not attached.
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002519 */
2520 int getDisplayId() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002521 final ActivityStack stack = getActivityStack();
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002522 if (stack == null) {
Riddle Hsufd4a0502018-10-16 01:05:16 +08002523 return INVALID_DISPLAY;
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002524 }
2525 return stack.mDisplayId;
2526 }
2527
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002528 final boolean isDestroyable() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002529 if (finishing || !hasProcess()) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002530 // This would be redundant.
2531 return false;
2532 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002533 final ActivityStack stack = getActivityStack();
Bryce Leec4ab62a2018-03-05 14:19:26 -08002534 if (stack == null || this == stack.getResumedActivity() || this == stack.mPausingActivity
Andrii Kulian02b7a832016-10-06 23:11:56 -07002535 || !haveState || !stopped) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002536 // We're not ready for this kind of thing.
2537 return false;
2538 }
2539 if (visible) {
2540 // The user would notice this!
2541 return false;
2542 }
2543 return true;
2544 }
2545
Winson Chung3bad5cc02014-08-19 17:44:32 -07002546 private static String createImageFilename(long createTime, int taskId) {
2547 return String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX + createTime +
Ruben Brunkf53497c2017-03-27 20:26:17 -07002548 IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -07002549 }
2550
Craig Mautner648f69b2014-09-18 14:16:26 -07002551 void setTaskDescription(TaskDescription _taskDescription) {
2552 Bitmap icon;
2553 if (_taskDescription.getIconFilename() == null &&
2554 (icon = _taskDescription.getIcon()) != null) {
2555 final String iconFilename = createImageFilename(createTime, task.taskId);
Winson Chungc8408b82017-01-25 17:58:56 -08002556 final File iconFile = new File(TaskPersister.getUserImagesDir(task.userId),
2557 iconFilename);
Suprabh Shukla23593142015-11-03 17:31:15 -08002558 final String iconFilePath = iconFile.getAbsolutePath();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002559 mAtmService.getRecentTasks().saveImage(icon, iconFilePath);
Suprabh Shukla23593142015-11-03 17:31:15 -08002560 _taskDescription.setIconFilename(iconFilePath);
Craig Mautner648f69b2014-09-18 14:16:26 -07002561 }
2562 taskDescription = _taskDescription;
2563 }
2564
Amith Yamasani0af6fa72016-01-17 15:36:19 -08002565 void setVoiceSessionLocked(IVoiceInteractionSession session) {
2566 voiceSession = session;
2567 pendingVoiceInteractionStart = false;
2568 }
2569
2570 void clearVoiceSessionLocked() {
2571 voiceSession = null;
2572 pendingVoiceInteractionStart = false;
2573 }
2574
Jorim Jaggi02886a82016-12-06 09:10:06 -08002575 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch) {
Jorim Jaggi42befc62017-06-13 11:54:04 -07002576 showStartingWindow(prev, newTask, taskSwitch, false /* fromRecents */);
2577 }
2578
2579 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
2580 boolean fromRecents) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002581 if (mAppWindowToken == null) {
Jorim Jaggi70176432017-01-18 12:52:13 +01002582 return;
2583 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002584 if (mTaskOverlay) {
2585 // We don't show starting window for overlay activities.
2586 return;
2587 }
Sunny Goyald85bed52018-09-25 12:01:01 -07002588 if (pendingOptions != null
2589 && pendingOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
2590 // Don't show starting window when using shared element transition.
2591 return;
2592 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002593
Wale Ogunwale3b232392016-05-13 15:37:13 -07002594 final CompatibilityInfo compatInfo =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002595 mAtmService.compatibilityInfoForPackageLocked(info.applicationInfo);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002596 final boolean shown = addStartingWindow(packageName, theme,
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002597 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
Jorim Jaggibae01b12017-04-11 16:29:10 -07002598 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
Jorim Jaggi70aa4d12017-05-15 00:05:54 +02002599 allowTaskSnapshot(),
Bryce Lee7ace3952018-02-16 14:34:32 -08002600 mState.ordinal() >= RESUMED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
Jorim Jaggi42befc62017-06-13 11:54:04 -07002601 fromRecents);
Wale Ogunwale3b232392016-05-13 15:37:13 -07002602 if (shown) {
2603 mStartingWindowState = STARTING_WINDOW_SHOWN;
2604 }
2605 }
2606
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002607 void removeOrphanedStartingWindow(boolean behindFullscreenActivity) {
Jorim Jaggicb956052017-05-09 16:27:24 +02002608 if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002609 if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
2610 mStartingWindowState = STARTING_WINDOW_REMOVED;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002611 mAppWindowToken.removeStartingWindow();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002612 }
2613 }
2614
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002615 void setRequestedOrientation(int requestedOrientation) {
Garfield Tan90b04282018-12-11 14:04:42 -08002616 setOrientation(requestedOrientation, mayFreezeScreenLocked(app));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002617 mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
Yorke Leebd54c2a2016-10-25 13:49:23 -07002618 task.taskId, requestedOrientation);
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002619 }
2620
Garfield Tan90b04282018-12-11 14:04:42 -08002621 private void setOrientation(int requestedOrientation, boolean freezeScreenIfNeeded) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002622 if (mAppWindowToken == null) {
2623 Slog.w(TAG_WM,
2624 "Attempted to set orientation of non-existing app token: " + appToken);
Garfield Tan90b04282018-12-11 14:04:42 -08002625 return;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002626 }
2627
Evan Rosky730f6e82018-12-03 17:40:11 -08002628 final IBinder binder =
2629 (freezeScreenIfNeeded && appToken != null) ? appToken.asBinder() : null;
Garfield Tan90b04282018-12-11 14:04:42 -08002630 mAppWindowToken.setOrientation(requestedOrientation, binder, this);
Garfield Tan36a69ad2019-01-16 17:08:23 -08002631
2632 // Push the new configuration to the requested app in case where it's not pushed, e.g. when
2633 // the request is handled at task level with letterbox.
2634 if (!getMergedOverrideConfiguration().equals(
2635 mLastReportedConfiguration.getMergedConfiguration())) {
2636 ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
2637 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002638 }
2639
2640 int getOrientation() {
2641 if (mAppWindowToken == null) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002642 return info.screenOrientation;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002643 }
2644
2645 return mAppWindowToken.getOrientationIgnoreVisibility();
2646 }
2647
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002648 void setDisablePreviewScreenshots(boolean disable) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002649 if (mAppWindowToken == null) {
2650 Slog.w(TAG_WM, "Attempted to set disable screenshots of non-existing app"
2651 + " token: " + appToken);
2652 return;
2653 }
2654 mAppWindowToken.setDisablePreviewScreenshots(disable);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002655 }
2656
Bryce Leea163b762017-01-24 11:05:01 -08002657 /**
2658 * Set the last reported global configuration to the client. Should be called whenever a new
2659 * global configuration is sent to the client for this activity.
2660 */
2661 void setLastReportedGlobalConfiguration(@NonNull Configuration config) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002662 mLastReportedConfiguration.setGlobalConfiguration(config);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002663 }
2664
Bryce Leea163b762017-01-24 11:05:01 -08002665 /**
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002666 * Set the last reported configuration to the client. Should be called whenever
Bryce Leea163b762017-01-24 11:05:01 -08002667 * a new merged configuration is sent to the client for this activity.
2668 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002669 void setLastReportedConfiguration(@NonNull MergedConfiguration config) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002670 setLastReportedConfiguration(config.getGlobalConfiguration(),
2671 config.getOverrideConfiguration());
Bryce Leea163b762017-01-24 11:05:01 -08002672 }
2673
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002674 private void setLastReportedConfiguration(Configuration global, Configuration override) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002675 mLastReportedConfiguration.setConfiguration(global, override);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002676 }
2677
Riddle Hsu0a343c32018-12-21 00:40:48 +08002678 /**
2679 * Get the configuration orientation by the requested screen orientation
2680 * ({@link ActivityInfo.ScreenOrientation}) of this activity.
2681 *
Tiger Huang3d2b8982019-01-29 22:56:48 +08002682 * @return orientation in ({@link Configuration#ORIENTATION_LANDSCAPE},
2683 * {@link Configuration#ORIENTATION_PORTRAIT},
2684 * {@link Configuration#ORIENTATION_UNDEFINED}).
Riddle Hsu0a343c32018-12-21 00:40:48 +08002685 */
2686 int getRequestedConfigurationOrientation() {
2687 final int screenOrientation = getOrientation();
2688 if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
2689 // NOSENSOR means the display's "natural" orientation, so return that.
2690 final ActivityDisplay display = getDisplay();
2691 if (display != null && display.mDisplayContent != null) {
2692 return display.mDisplayContent.getNaturalOrientation();
2693 }
2694 } else if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
2695 // LOCKED means the activity's orientation remains unchanged, so return existing value.
2696 return getConfiguration().orientation;
2697 } else if (isFixedOrientationLandscape(screenOrientation)) {
2698 return ORIENTATION_LANDSCAPE;
2699 } else if (isFixedOrientationPortrait(screenOrientation)) {
2700 return ORIENTATION_PORTRAIT;
2701 }
2702 return ORIENTATION_UNDEFINED;
2703 }
2704
2705 /**
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002706 * @return {@code true} if this activity is in size compatibility mode that uses the different
2707 * density or bounds from its parent.
2708 */
2709 boolean inSizeCompatMode() {
2710 if (!shouldUseSizeCompatMode()) {
2711 return false;
2712 }
2713 final Configuration parentConfig = getParent().getConfiguration();
2714 final Configuration resolvedConfig = getResolvedOverrideConfiguration();
2715 // Although colorMode, screenLayout, smallestScreenWidthDp are also fixed, generally these
2716 // fields should be changed with density and bounds, so here only compares the most
2717 // significant field.
2718 if (parentConfig.densityDpi != resolvedConfig.densityDpi) {
2719 return true;
2720 }
2721 final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds();
2722 final Rect parentBounds = parentAppBounds != null
2723 ? parentAppBounds : parentConfig.windowConfiguration.getBounds();
2724 final Rect overrideBounds = resolvedConfig.windowConfiguration.getBounds();
2725 // If the width or height is the same as parent, it is already the best fit of the override
2726 // bounds, therefore this condition is considered as not size compatibility mode.
2727 return parentBounds.width() != overrideBounds.width()
2728 && parentBounds.height() != overrideBounds.height();
2729 }
2730
2731 /**
Riddle Hsu0a343c32018-12-21 00:40:48 +08002732 * Indicates the activity will keep the bounds and screen configuration when it was first
2733 * launched, no matter how its parent changes.
2734 *
2735 * @return {@code true} if this activity is declared as non-resizable and fixed orientation or
2736 * aspect ratio.
2737 */
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002738 private boolean shouldUseSizeCompatMode() {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002739 return !isResizeable() && (info.isFixedOrientation() || info.hasFixedAspectRatio())
2740 // The configuration of non-standard type should be enforced by system.
2741 && isActivityTypeStandard()
2742 && !mAtmService.mForceResizableActivities;
2743 }
2744
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002745 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002746 private void updateOverrideConfiguration() {
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002747 final boolean shouldUseSizeCompatMode = shouldUseSizeCompatMode();
2748 if (shouldUseSizeCompatMode) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002749 if (!matchParentBounds()) {
2750 // The override configuration is set only once in size compatible mode.
2751 return;
2752 }
2753 if (!hasProcess() && !isConfigurationCompatible(task.getConfiguration())) {
2754 // Don't compute when launching in fullscreen and the fixed orientation is not the
2755 // current orientation. It is more accurately to compute the override bounds from
2756 // the updated configuration after the fixed orientation is applied.
2757 return;
2758 }
2759 }
2760
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002761 computeBounds(mTmpBounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08002762
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002763 if (shouldUseSizeCompatMode && mTmpBounds.isEmpty()) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002764 mTmpBounds.set(task.getWindowConfiguration().getBounds());
2765 }
Evan Roskydfe3da72018-10-26 17:21:06 -07002766 if (mTmpBounds.equals(getRequestedOverrideBounds())) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002767 // The bounds is not changed or the activity is resizable (both the 2 bounds are empty).
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002768 return;
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002769 }
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002770
Riddle Hsu0a343c32018-12-21 00:40:48 +08002771 final Configuration overrideConfig = mTmpConfig;
2772 overrideConfig.unset();
2773 if (!mTmpBounds.isEmpty()) {
2774 overrideConfig.windowConfiguration.setBounds(mTmpBounds);
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002775 if (shouldUseSizeCompatMode) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002776 // Ensure the screen related fields are set. It is used to prevent activity relaunch
2777 // when moving between displays. For screenWidthDp and screenWidthDp, because they
2778 // are relative to bounds and density, they will be calculated in
2779 // {@link TaskRecord#computeConfigResourceOverrides} and the result will also be
2780 // relatively fixed.
2781 final Configuration srcConfig = task.getConfiguration();
2782 overrideConfig.colorMode = srcConfig.colorMode;
2783 overrideConfig.densityDpi = srcConfig.densityDpi;
Riddle Hsu2560c3b2019-02-23 23:45:58 +08002784 overrideConfig.screenLayout = srcConfig.screenLayout
2785 & (Configuration.SCREENLAYOUT_LONG_MASK
2786 | Configuration.SCREENLAYOUT_SIZE_MASK);
Riddle Hsu0a343c32018-12-21 00:40:48 +08002787 // The smallest screen width is the short side of screen bounds. Because the bounds
2788 // and density won't be changed, smallestScreenWidthDp is also fixed.
2789 overrideConfig.smallestScreenWidthDp = srcConfig.smallestScreenWidthDp;
2790 }
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002791 }
Riddle Hsu0a343c32018-12-21 00:40:48 +08002792 onRequestedOverrideConfigurationChanged(overrideConfig);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002793 }
2794
Garfield Tan0443b372019-01-04 15:00:13 -08002795 @Override
2796 void resolveOverrideConfiguration(Configuration newParentConfiguration) {
2797 super.resolveOverrideConfiguration(newParentConfiguration);
2798
2799 // Assign configuration sequence number into hierarchy because there is a different way than
2800 // ensureActivityConfiguration() in this class that uses configuration in WindowState during
2801 // layout traversals.
2802 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
2803 getResolvedOverrideConfiguration().seq = mConfigurationSeq;
Riddle Hsu0a343c32018-12-21 00:40:48 +08002804
2805 if (matchParentBounds()) {
2806 return;
2807 }
2808
2809 final Configuration resolvedConfig = getResolvedOverrideConfiguration();
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002810 if (!shouldUseSizeCompatMode()) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002811 computeConfigResourceOverrides(resolvedConfig, newParentConfiguration,
2812 ORIENTATION_UNDEFINED, true /* insideParentBounds */);
2813 return;
2814 }
2815
2816 final Configuration displayConfig = getDisplay().getConfiguration();
2817 int orientation = getConfiguration().orientation;
2818 if (orientation != displayConfig.orientation && isConfigurationCompatible(displayConfig)) {
2819 // The activity is compatible to apply the orientation change or it requests different
2820 // fixed orientation.
2821 orientation = displayConfig.orientation;
2822 } else {
2823 if (resolvedConfig.windowConfiguration.getAppBounds() != null) {
2824 // Keep the computed resolved override configuration.
2825 return;
2826 }
2827 final int requestedOrientation = getRequestedConfigurationOrientation();
2828 if (requestedOrientation != ORIENTATION_UNDEFINED) {
2829 orientation = requestedOrientation;
2830 }
2831 }
2832
2833 // Adjust the bounds to match the current orientation.
2834 if (orientation != ORIENTATION_UNDEFINED) {
2835 final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
2836 final int longSide = Math.max(resolvedBounds.height(), resolvedBounds.width());
2837 final int shortSide = Math.min(resolvedBounds.height(), resolvedBounds.width());
2838 final boolean toBeLandscape = orientation == ORIENTATION_LANDSCAPE;
2839 final int width = toBeLandscape ? longSide : shortSide;
2840 final int height = toBeLandscape ? shortSide : longSide;
2841 // Assume the bounds is always started from zero because the size may be bigger than its
2842 // parent (task ~ display). The actual letterboxing will be done by surface offset.
2843 resolvedBounds.set(0, 0, width, height);
2844 }
2845
2846 // In size compatible mode, activity is allowed to have larger bounds than its parent.
2847 computeConfigResourceOverrides(resolvedConfig, newParentConfiguration, orientation,
2848 false /* insideParentBounds */);
2849 }
2850
2851 private void computeConfigResourceOverrides(Configuration inOutConfig,
2852 Configuration parentConfig, int orientation, boolean insideParentBounds) {
2853 // Set the real orientation or undefined value to ensure the output orientation won't be the
2854 // old value. Also reset app bounds so it will be updated according to bounds.
2855 inOutConfig.orientation = orientation;
2856 final Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
2857 if (outAppBounds != null) {
2858 outAppBounds.setEmpty();
2859 }
2860
Riddle Hsu0a343c32018-12-21 00:40:48 +08002861 task.computeConfigResourceOverrides(inOutConfig, parentConfig, insideParentBounds);
Garfield Tan0443b372019-01-04 15:00:13 -08002862 }
2863
2864 @Override
2865 public void onConfigurationChanged(Configuration newParentConfig) {
2866 super.onConfigurationChanged(newParentConfig);
2867
2868 // Configuration's equality doesn't consider seq so if only seq number changes in resolved
2869 // override configuration. Therefore ConfigurationContainer doesn't change merged override
2870 // configuration, but it's used to push configuration changes so explicitly update that.
2871 if (getMergedOverrideConfiguration().seq != getResolvedOverrideConfiguration().seq) {
2872 onMergedOverrideConfigurationChanged();
2873 }
2874
2875 // TODO(b/80414790): Remove code below after unification.
2876 // Same as above it doesn't notify configuration listeners, and consequently AppWindowToken
2877 // can't get updated seq number. However WindowState's merged override configuration needs
2878 // to have this seq number because that's also used for activity config pushes during layout
2879 // traversal. Therefore explicitly update them here.
2880 if (mAppWindowToken == null) {
2881 return;
2882 }
2883 final Configuration appWindowTokenRequestedOverrideConfig =
2884 mAppWindowToken.getRequestedOverrideConfiguration();
2885 if (appWindowTokenRequestedOverrideConfig.seq != getResolvedOverrideConfiguration().seq) {
2886 appWindowTokenRequestedOverrideConfig.seq =
2887 getResolvedOverrideConfiguration().seq;
2888 mAppWindowToken.onMergedOverrideConfigurationChanged();
2889 }
Riddle Hsu7b766fd2019-01-28 21:14:59 +08002890
2891 final ActivityDisplay display = getDisplay();
2892 if (display != null) {
2893 display.handleActivitySizeCompatModeIfNeeded(this);
2894 }
Garfield Tan0443b372019-01-04 15:00:13 -08002895 }
2896
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07002897 /** Returns true if the configuration is compatible with this activity. */
Wale Ogunwale42f07d92017-05-01 21:32:58 -07002898 boolean isConfigurationCompatible(Configuration config) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002899 final int orientation = getOrientation();
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07002900 if (isFixedOrientationPortrait(orientation)
2901 && config.orientation != ORIENTATION_PORTRAIT) {
2902 return false;
2903 }
2904 if (isFixedOrientationLandscape(orientation)
2905 && config.orientation != ORIENTATION_LANDSCAPE) {
2906 return false;
2907 }
2908 return true;
2909 }
2910
Bryce Lee7566d762017-03-30 09:34:15 -07002911 /**
2912 * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}.
2913 */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002914 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
2915 private void computeBounds(Rect outBounds) {
2916 outBounds.setEmpty();
2917 final float maxAspectRatio = info.maxAspectRatio;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002918 final ActivityStack stack = getActivityStack();
Adrian Roos917791e2018-11-28 16:30:44 +01002919 final float minAspectRatio = info.minAspectRatio;
2920
2921 if (task == null || stack == null || task.inMultiWindowMode()
2922 || (maxAspectRatio == 0 && minAspectRatio == 0)
Bryce Leee5ab4502017-07-11 08:58:05 -07002923 || isInVrUiMode(getConfiguration())) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002924 // We don't set override configuration if that activity task isn't fullscreen. I.e. the
2925 // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
Bryce Leee5ab4502017-07-11 08:58:05 -07002926 // the activity. This is indicated by an empty {@link outBounds}. We also don't set it
2927 // if we are in VR mode.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002928 return;
2929 }
2930
Bryce Lee7566d762017-03-30 09:34:15 -07002931 // We must base this on the parent configuration, because we set our override
2932 // configuration's appBounds based on the result of this method. If we used our own
2933 // configuration, it would be influenced by past invocations.
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002934 final Rect appBounds = getParent().getWindowConfiguration().getAppBounds();
Wale Ogunwale822e5122017-07-26 06:02:24 -07002935 final int containingAppWidth = appBounds.width();
2936 final int containingAppHeight = appBounds.height();
Adrian Roos917791e2018-11-28 16:30:44 +01002937 final float containingRatio = Math.max(containingAppWidth, containingAppHeight)
2938 / (float) Math.min(containingAppWidth, containingAppHeight);
Bryce Lee7566d762017-03-30 09:34:15 -07002939
Adrian Roos917791e2018-11-28 16:30:44 +01002940 int activityWidth = containingAppWidth;
2941 int activityHeight = containingAppHeight;
2942
2943 if (containingRatio > maxAspectRatio && maxAspectRatio != 0) {
2944 if (containingAppWidth < containingAppHeight) {
2945 // Width is the shorter side, so we use that to figure-out what the max. height
2946 // should be given the aspect ratio.
2947 activityHeight = (int) ((activityWidth * maxAspectRatio) + 0.5f);
2948 } else {
2949 // Height is the shorter side, so we use that to figure-out what the max. width
2950 // should be given the aspect ratio.
2951 activityWidth = (int) ((activityHeight * maxAspectRatio) + 0.5f);
2952 }
Tiger Huang3d2b8982019-01-29 22:56:48 +08002953 } else if (containingRatio < minAspectRatio) {
2954 boolean adjustWidth;
2955 switch (getRequestedConfigurationOrientation()) {
2956 case ORIENTATION_LANDSCAPE:
2957 // Width should be the longer side for this landscape app, so we use the width
2958 // to figure-out what the max. height should be given the aspect ratio.
2959 adjustWidth = false;
2960 break;
2961 case ORIENTATION_PORTRAIT:
2962 // Height should be the longer side for this portrait app, so we use the height
2963 // to figure-out what the max. width should be given the aspect ratio.
2964 adjustWidth = true;
2965 break;
2966 default:
2967 // This app doesn't have a preferred orientation, so we keep the length of the
2968 // longer side, and use it to figure-out the length of the shorter side.
2969 if (containingAppWidth < containingAppHeight) {
2970 // Width is the shorter side, so we use the height to figure-out what the
2971 // max. width should be given the aspect ratio.
2972 adjustWidth = true;
2973 } else {
2974 // Height is the shorter side, so we use the width to figure-out what the
2975 // max. height should be given the aspect ratio.
2976 adjustWidth = false;
2977 }
2978 break;
2979 }
2980 if (adjustWidth) {
Adrian Roos917791e2018-11-28 16:30:44 +01002981 activityWidth = (int) ((activityHeight / minAspectRatio) + 0.5f);
2982 } else {
Adrian Roos917791e2018-11-28 16:30:44 +01002983 activityHeight = (int) ((activityWidth / minAspectRatio) + 0.5f);
2984 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002985 }
2986
Adrian Roos917791e2018-11-28 16:30:44 +01002987 if (containingAppWidth <= activityWidth && containingAppHeight <= activityHeight) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002988 // The display matches or is less than the activity aspect ratio, so nothing else to do.
Bryce Lee7566d762017-03-30 09:34:15 -07002989 // Return the existing bounds. If this method is running for the first time,
Evan Roskydfe3da72018-10-26 17:21:06 -07002990 // {@link #getRequestedOverrideBounds()} will be empty (representing no override). If
2991 // the method has run before, then effect of {@link #getRequestedOverrideBounds()} will
2992 // already have been applied to the value returned from {@link getConfiguration}. Refer
2993 // to {@link TaskRecord#computeOverrideConfiguration}.
2994 outBounds.set(getRequestedOverrideBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002995 return;
2996 }
2997
2998 // Compute configuration based on max supported width and height.
Adrian Roos24be34d2018-05-28 18:55:38 +02002999 // Also account for the left / top insets (e.g. from display cutouts), which will be clipped
3000 // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app
3001 // bounds would end up too small.
Adrian Roos917791e2018-11-28 16:30:44 +01003002 outBounds.set(0, 0, activityWidth + appBounds.left, activityHeight + appBounds.top);
Andrii Kulian3a1619d2017-07-07 14:38:09 -07003003 }
3004
Riddle Hsu16567132018-08-16 21:37:47 +08003005 /**
3006 * @return {@code true} if this activity was reparented to another display but
3007 * {@link #ensureActivityConfiguration} is not called.
3008 */
3009 boolean shouldUpdateConfigForDisplayChanged() {
3010 return mLastReportedDisplayId != getDisplayId();
3011 }
3012
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003013 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
3014 return ensureActivityConfiguration(globalChanges, preserveWindow,
3015 false /* ignoreStopState */);
3016 }
3017
Andrii Kulian21713ac2016-10-12 22:05:05 -07003018 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003019 * Make sure the given activity matches the current configuration. Ensures the HistoryRecord
3020 * is updated with the correct configuration and all other bookkeeping is handled.
3021 *
3022 * @param globalChanges The changes to the global configuration.
3023 * @param preserveWindow If the activity window should be preserved on screen if the activity
3024 * is relaunched.
3025 * @param ignoreStopState If we should try to relaunch the activity even if it is in the stopped
3026 * state. This is useful for the case where we know the activity will be
3027 * visible soon and we want to ensure its configuration before we make it
3028 * visible.
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003029 * @return False if the activity was relaunched and true if it wasn't relaunched because we
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003030 * can't or the app handles the specific configuration that is changing.
Andrii Kulian21713ac2016-10-12 22:05:05 -07003031 */
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003032 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
3033 boolean ignoreStopState) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003034 final ActivityStack stack = getActivityStack();
Andrii Kulian21713ac2016-10-12 22:05:05 -07003035 if (stack.mConfigWillChange) {
3036 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3037 "Skipping config check (will change): " + this);
3038 return true;
3039 }
3040
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003041 // We don't worry about activities that are finishing.
3042 if (finishing) {
3043 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3044 "Configuration doesn't matter in finishing " + this);
3045 stopFreezingScreenLocked(false);
3046 return true;
3047 }
3048
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003049 if (!ignoreStopState && (mState == STOPPING || mState == STOPPED)) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07003050 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3051 "Skipping config check stopped or stopping: " + this);
3052 return true;
3053 }
3054
Garfield Tan47e576c2019-01-28 10:26:23 -08003055 if (!shouldBeVisible()) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07003056 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3057 "Skipping config check invisible stack: " + this);
3058 return true;
3059 }
3060
Andrii Kulian21713ac2016-10-12 22:05:05 -07003061 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3062 "Ensuring correct configuration: " + this);
3063
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003064 final int newDisplayId = getDisplayId();
3065 final boolean displayChanged = mLastReportedDisplayId != newDisplayId;
3066 if (displayChanged) {
3067 mLastReportedDisplayId = newDisplayId;
3068 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003069 // TODO(b/36505427): Is there a better place to do this?
3070 updateOverrideConfiguration();
3071
Winson Chungbdc646f2017-02-13 12:12:22 -08003072 // Short circuit: if the two full configurations are equal (the common case), then there is
3073 // nothing to do. We test the full configuration instead of the global and merged override
3074 // configurations because there are cases (like moving a task to the pinned stack) where
3075 // the combine configurations are equal, but would otherwise differ in the override config
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003076 mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
3077 if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003078 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003079 "Configuration & display unchanged in " + this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003080 return true;
3081 }
3082
3083 // Okay we now are going to make this activity have the new config.
3084 // But then we need to figure out how it needs to deal with that.
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003085
3086 // Find changes between last reported merged configuration and the current one. This is used
3087 // to decide whether to relaunch an activity or just report a configuration change.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003088 final int changes = getConfigurationChanges(mTmpConfig);
Ruben Brunkf64af332017-03-22 22:03:25 -07003089
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003090 // Update last reported values.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003091 final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
Bryce Lee8104e7a2017-08-17 09:16:03 -07003092
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003093 setLastReportedConfiguration(mAtmService.getGlobalConfiguration(), newMergedOverrideConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003094
Bryce Lee7ace3952018-02-16 14:34:32 -08003095 if (mState == INITIALIZING) {
Andrii Kulianb372da62018-01-18 10:46:24 -08003096 // No need to relaunch or schedule new config for activity that hasn't been launched
3097 // yet. We do, however, return after applying the config to activity record, so that
3098 // it will use it for launch transaction.
3099 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3100 "Skipping config check for initializing activity: " + this);
3101 return true;
3102 }
3103
Andrii Kulian21713ac2016-10-12 22:05:05 -07003104 if (changes == 0 && !forceNewConfig) {
3105 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3106 "Configuration no differences in " + this);
3107 // There are no significant differences, so we won't relaunch but should still deliver
3108 // the new configuration to the client process.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003109 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003110 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003111 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003112 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003113 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07003114 return true;
3115 }
3116
3117 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003118 "Configuration changes for " + this + ", allChanges="
Andrii Kulian21713ac2016-10-12 22:05:05 -07003119 + Configuration.configurationDiffToString(changes));
3120
3121 // If the activity isn't currently running, just leave the new configuration and it will
3122 // pick that up next time it starts.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003123 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003124 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3125 "Configuration doesn't matter not running " + this);
3126 stopFreezingScreenLocked(false);
3127 forceNewConfig = false;
3128 return true;
3129 }
3130
3131 // Figure out how to handle the changes between the configurations.
3132 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3133 "Checking to restart " + info.name + ": changed=0x"
3134 + Integer.toHexString(changes) + ", handles=0x"
3135 + Integer.toHexString(info.getRealConfigChanged())
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003136 + ", mLastReportedConfiguration=" + mLastReportedConfiguration);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003137
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003138 if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003139 // Aha, the activity isn't handling the change, so DIE DIE DIE.
3140 configChangeFlags |= changes;
3141 startFreezingScreenLocked(app, globalChanges);
3142 forceNewConfig = false;
3143 preserveWindow &= isResizeOnlyChange(changes);
Garfield Tan2746ab52018-07-25 12:33:01 -07003144 final boolean hasResizeChange = hasResizeChange(changes & ~info.getRealConfigChanged());
3145 if (hasResizeChange) {
3146 final boolean isDragResizing =
Yunfan Chen0e7aff92018-12-05 16:35:32 -08003147 getTaskRecord().getTask().isDragResizing();
Garfield Tan2746ab52018-07-25 12:33:01 -07003148 mRelaunchReason = isDragResizing ? RELAUNCH_REASON_FREE_RESIZE
3149 : RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
3150 } else {
3151 mRelaunchReason = RELAUNCH_REASON_NONE;
3152 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003153 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003154 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3155 "Config is destroying non-running " + this);
3156 stack.destroyActivityLocked(this, true, "config");
Bryce Lee7ace3952018-02-16 14:34:32 -08003157 } else if (mState == PAUSING) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003158 // A little annoying: we are waiting for this activity to finish pausing. Let's not
3159 // do anything now, but just flag that it needs to be restarted when done pausing.
3160 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3161 "Config is skipping already pausing " + this);
3162 deferRelaunchUntilPaused = true;
3163 preserveWindowOnDeferredRelaunch = preserveWindow;
3164 return true;
Bryce Lee7ace3952018-02-16 14:34:32 -08003165 } else if (mState == RESUMED) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003166 // Try to optimize this case: the configuration is changing and we need to restart
3167 // the top, resumed activity. Instead of doing the normal handshaking, just say
3168 // "restart!".
3169 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3170 "Config is relaunching resumed " + this);
3171
3172 if (DEBUG_STATES && !visible) {
3173 Slog.v(TAG_STATES, "Config is relaunching resumed invisible activity " + this
3174 + " called by " + Debug.getCallers(4));
3175 }
3176
3177 relaunchActivityLocked(true /* andResume */, preserveWindow);
3178 } else {
3179 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3180 "Config is relaunching non-resumed " + this);
3181 relaunchActivityLocked(false /* andResume */, preserveWindow);
3182 }
3183
3184 // All done... tell the caller we weren't able to keep this activity around.
3185 return false;
3186 }
3187
3188 // Default case: the activity can handle this new configuration, so hand it over.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003189 // NOTE: We only forward the override configuration as the system level configuration
Andrii Kulian21713ac2016-10-12 22:05:05 -07003190 // changes is always sent to all processes when they happen so it can just use whatever
3191 // system level configuration it last got.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003192 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003193 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003194 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003195 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003196 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07003197 stopFreezingScreenLocked(false);
3198
3199 return true;
3200 }
3201
Zak Cohen90e7116742017-01-29 12:59:23 -08003202 /**
3203 * When assessing a configuration change, decide if the changes flags and the new configurations
3204 * should cause the Activity to relaunch.
Ruben Brunkf64af332017-03-22 22:03:25 -07003205 *
3206 * @param changes the changes due to the given configuration.
3207 * @param changesConfig the configuration that was used to calculate the given changes via a
3208 * call to getConfigurationChanges.
Zak Cohen90e7116742017-01-29 12:59:23 -08003209 */
Ruben Brunkf64af332017-03-22 22:03:25 -07003210 private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
Zak Cohen90e7116742017-01-29 12:59:23 -08003211 int configChanged = info.getRealConfigChanged();
Ruben Brunkf64af332017-03-22 22:03:25 -07003212 boolean onlyVrUiModeChanged = onlyVrUiModeChanged(changes, changesConfig);
Zak Cohen90e7116742017-01-29 12:59:23 -08003213
3214 // Override for apps targeting pre-O sdks
3215 // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
3216 // to the config change.
3217 // For O and later, apps will be required to add configChanges="uimode" to their manifest.
3218 if (appInfo.targetSdkVersion < O
3219 && requestedVrComponent != null
Ruben Brunkf64af332017-03-22 22:03:25 -07003220 && onlyVrUiModeChanged) {
Zak Cohen90e7116742017-01-29 12:59:23 -08003221 configChanged |= CONFIG_UI_MODE;
3222 }
3223
3224 return (changes&(~configChanged)) != 0;
3225 }
3226
Ruben Brunkf64af332017-03-22 22:03:25 -07003227 /**
3228 * Returns true if the configuration change is solely due to the UI mode switching into or out
3229 * of UI_MODE_TYPE_VR_HEADSET.
3230 */
3231 private boolean onlyVrUiModeChanged(int changes, Configuration lastReportedConfig) {
3232 final Configuration currentConfig = getConfiguration();
Ruben Brunkf53497c2017-03-27 20:26:17 -07003233 return changes == CONFIG_UI_MODE && (isInVrUiMode(currentConfig)
Ruben Brunkf64af332017-03-22 22:03:25 -07003234 != isInVrUiMode(lastReportedConfig));
3235 }
3236
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003237 private int getConfigurationChanges(Configuration lastReportedConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003238 // Determine what has changed. May be nothing, if this is a config that has come back from
3239 // the app after going idle. In that case we just want to leave the official config object
3240 // now in the activity and do nothing else.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003241 final Configuration currentConfig = getConfiguration();
3242 int changes = lastReportedConfig.diff(currentConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003243 // We don't want to use size changes if they don't cross boundaries that are important to
3244 // the app.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003245 if ((changes & CONFIG_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003246 final boolean crosses = crossesHorizontalSizeThreshold(lastReportedConfig.screenWidthDp,
3247 currentConfig.screenWidthDp)
3248 || crossesVerticalSizeThreshold(lastReportedConfig.screenHeightDp,
3249 currentConfig.screenHeightDp);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003250 if (!crosses) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003251 changes &= ~CONFIG_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003252 }
3253 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003254 if ((changes & CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003255 final int oldSmallest = lastReportedConfig.smallestScreenWidthDp;
3256 final int newSmallest = currentConfig.smallestScreenWidthDp;
3257 if (!crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003258 changes &= ~CONFIG_SMALLEST_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003259 }
3260 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07003261 // We don't want window configuration to cause relaunches.
3262 if ((changes & CONFIG_WINDOW_CONFIGURATION) != 0) {
3263 changes &= ~CONFIG_WINDOW_CONFIGURATION;
3264 }
Bryce Lee600dadd2017-07-25 10:48:42 -07003265
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003266 return changes;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003267 }
3268
3269 private static boolean isResizeOnlyChange(int change) {
3270 return (change & ~(CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
3271 | CONFIG_SCREEN_LAYOUT)) == 0;
3272 }
3273
Garfield Tan2746ab52018-07-25 12:33:01 -07003274 private static boolean hasResizeChange(int change) {
3275 return (change & (CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
3276 | CONFIG_SCREEN_LAYOUT)) != 0;
3277 }
3278
Andrii Kulian21713ac2016-10-12 22:05:05 -07003279 void relaunchActivityLocked(boolean andResume, boolean preserveWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003280 if (mAtmService.mSuppressResizeConfigChanges && preserveWindow) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003281 configChangeFlags = 0;
3282 return;
3283 }
3284
3285 List<ResultInfo> pendingResults = null;
3286 List<ReferrerIntent> pendingNewIntents = null;
3287 if (andResume) {
3288 pendingResults = results;
3289 pendingNewIntents = newIntents;
3290 }
3291 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
3292 "Relaunching: " + this + " with results=" + pendingResults
3293 + " newIntents=" + pendingNewIntents + " andResume=" + andResume
3294 + " preserveWindow=" + preserveWindow);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003295 EventLog.writeEvent(andResume ? AM_RELAUNCH_RESUME_ACTIVITY
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003296 : AM_RELAUNCH_ACTIVITY, mUserId, System.identityHashCode(this),
Andrii Kulian21713ac2016-10-12 22:05:05 -07003297 task.taskId, shortComponentName);
3298
3299 startFreezingScreenLocked(app, 0);
3300
Andrii Kulian21713ac2016-10-12 22:05:05 -07003301 try {
3302 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
3303 "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this
3304 + " callers=" + Debug.getCallers(6));
3305 forceNewConfig = false;
3306 mStackSupervisor.activityRelaunchingLocked(this);
Andrii Kulianb372da62018-01-18 10:46:24 -08003307 final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
3308 pendingNewIntents, configChangeFlags,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003309 new MergedConfiguration(mAtmService.getGlobalConfiguration(),
Andrii Kulianb372da62018-01-18 10:46:24 -08003310 getMergedOverrideConfiguration()),
3311 preserveWindow);
3312 final ActivityLifecycleItem lifecycleItem;
3313 if (andResume) {
lumark588a3e82018-07-20 18:53:54 +08003314 lifecycleItem = ResumeActivityItem.obtain(
Wale Ogunwale3a256e62018-12-06 14:41:18 -08003315 getDisplay().mDisplayContent.isNextTransitionForward());
Andrii Kulianb372da62018-01-18 10:46:24 -08003316 } else {
Bryce Lee1d0d5142018-04-12 10:35:07 -07003317 lifecycleItem = PauseActivityItem.obtain();
Andrii Kulianb372da62018-01-18 10:46:24 -08003318 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003319 final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), appToken);
Andrii Kulianb372da62018-01-18 10:46:24 -08003320 transaction.addCallback(callbackItem);
3321 transaction.setLifecycleStateRequest(lifecycleItem);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003322 mAtmService.getLifecycleManager().scheduleTransaction(transaction);
Andrii Kulian86e70fc2019-02-12 11:04:10 +00003323 mStackSupervisor.updateTopResumedActivityIfNeeded();
Andrii Kulian21713ac2016-10-12 22:05:05 -07003324 // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
Andrii Kulianb372da62018-01-18 10:46:24 -08003325 // request resume if this activity is currently resumed, which implies we aren't
Andrii Kulian21713ac2016-10-12 22:05:05 -07003326 // sleeping.
3327 } catch (RemoteException e) {
3328 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
3329 }
3330
3331 if (andResume) {
3332 if (DEBUG_STATES) {
3333 Slog.d(TAG_STATES, "Resumed after relaunch " + this);
3334 }
3335 results = null;
3336 newIntents = null;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003337 mAtmService.getAppWarningsLocked().onResumeActivity(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003338 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003339 final ActivityStack stack = getActivityStack();
Wale Ogunwale008163e2018-07-23 23:11:08 -07003340 if (stack != null) {
3341 stack.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
3342 }
Bryce Lee7ace3952018-02-16 14:34:32 -08003343 setState(PAUSED, "relaunchActivityLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07003344 }
3345
3346 configChangeFlags = 0;
3347 deferRelaunchUntilPaused = false;
3348 preserveWindowOnDeferredRelaunch = false;
3349 }
3350
Riddle Hsu7b766fd2019-01-28 21:14:59 +08003351 /**
3352 * Request the process of the activity to restart with its saved state (from
3353 * {@link android.app.Activity#onSaveInstanceState}) if possible. It also forces to recompute
3354 * the override configuration. Note if the activity is in background, the process will be killed
3355 * directly with keeping its record.
3356 */
3357 void restartProcessIfVisible() {
3358 Slog.i(TAG, "Request to restart process of " + this);
3359
3360 // Reset the existing override configuration to the latest configuration.
3361 getRequestedOverrideConfiguration().setToDefaults();
3362 getResolvedOverrideConfiguration().setToDefaults();
3363 if (visible) {
3364 // Configuration will be ensured when becoming visible, so if it is already visible,
3365 // then the manual update is needed.
3366 updateOverrideConfiguration();
3367 }
3368
3369 if (!attachedToProcess()) {
3370 return;
3371 }
3372
3373 // The restarting state avoids removing this record when process is died.
3374 setState(RESTARTING_PROCESS, "restartActivityProcess");
3375
3376 if (!visible || haveState) {
3377 // Kill its process immediately because the activity should be in background.
3378 // The activity state will be update to {@link #DESTROYED} in
3379 // {@link ActivityStack#cleanUpActivityLocked} when handling process died.
3380 mAtmService.mH.post(() -> mAtmService.mAmInternal.killProcess(
3381 app.mName, app.mUid, "restartActivityProcess"));
3382 return;
3383 }
3384
3385 if (mAppWindowToken != null) {
3386 mAppWindowToken.startFreezingScreen();
3387 }
3388 // The process will be killed until the activity reports stopped with saved state (see
3389 // {@link ActivityTaskManagerService.activityStopped}).
3390 try {
3391 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
3392 StopActivityItem.obtain(false /* showWindow */, 0 /* configChanges */));
3393 } catch (RemoteException e) {
3394 Slog.w(TAG, "Exception thrown during restart " + this, e);
3395 }
3396 mStackSupervisor.scheduleRestartTimeout(this);
3397 }
3398
Jorim Jaggibae01b12017-04-11 16:29:10 -07003399 private boolean isProcessRunning() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003400 WindowProcessController proc = app;
Jorim Jaggi02886a82016-12-06 09:10:06 -08003401 if (proc == null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003402 proc = mAtmService.mProcessNames.get(processName, info.applicationInfo.uid);
Jorim Jaggi02886a82016-12-06 09:10:06 -08003403 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003404 return proc != null && proc.hasThread();
Jorim Jaggi02886a82016-12-06 09:10:06 -08003405 }
3406
Jorim Jaggibae01b12017-04-11 16:29:10 -07003407 /**
3408 * @return Whether a task snapshot starting window may be shown.
3409 */
3410 private boolean allowTaskSnapshot() {
3411 if (newIntents == null) {
3412 return true;
3413 }
3414
3415 // Restrict task snapshot starting window to launcher start, or there is no intent at all
3416 // (eg. task being brought to front). If the intent is something else, likely the app is
3417 // going to show some specific page or view, instead of what's left last time.
3418 for (int i = newIntents.size() - 1; i >= 0; i--) {
3419 final Intent intent = newIntents.get(i);
3420 if (intent != null && !ActivityRecord.isMainIntent(intent)) {
3421 return false;
3422 }
3423 }
3424 return true;
3425 }
3426
Bryce Leeb7c9b802017-05-02 14:20:24 -07003427 /**
3428 * Returns {@code true} if the associated activity has the no history flag set on it.
3429 * {@code false} otherwise.
3430 */
3431 boolean isNoHistory() {
3432 return (intent.getFlags() & FLAG_ACTIVITY_NO_HISTORY) != 0
3433 || (info.flags & FLAG_NO_HISTORY) != 0;
3434 }
3435
Craig Mautner21d24a22014-04-23 11:45:37 -07003436 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
3437 out.attribute(null, ATTR_ID, String.valueOf(createTime));
3438 out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
3439 if (launchedFromPackage != null) {
3440 out.attribute(null, ATTR_LAUNCHEDFROMPACKAGE, launchedFromPackage);
3441 }
3442 if (resolvedType != null) {
3443 out.attribute(null, ATTR_RESOLVEDTYPE, resolvedType);
3444 }
3445 out.attribute(null, ATTR_COMPONENTSPECIFIED, String.valueOf(componentSpecified));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003446 out.attribute(null, ATTR_USERID, String.valueOf(mUserId));
Winson Chung2cb86c72014-06-25 12:03:30 -07003447
Craig Mautner21d24a22014-04-23 11:45:37 -07003448 if (taskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003449 taskDescription.saveToXml(out);
Craig Mautner21d24a22014-04-23 11:45:37 -07003450 }
3451
3452 out.startTag(null, TAG_INTENT);
3453 intent.saveToXml(out);
3454 out.endTag(null, TAG_INTENT);
3455
3456 if (isPersistable() && persistentState != null) {
3457 out.startTag(null, TAG_PERSISTABLEBUNDLE);
3458 persistentState.saveToXml(out);
3459 out.endTag(null, TAG_PERSISTABLEBUNDLE);
3460 }
3461 }
3462
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07003463 static ActivityRecord restoreFromXml(XmlPullParser in,
3464 ActivityStackSupervisor stackSupervisor) throws IOException, XmlPullParserException {
Craig Mautner21d24a22014-04-23 11:45:37 -07003465 Intent intent = null;
3466 PersistableBundle persistentState = null;
3467 int launchedFromUid = 0;
3468 String launchedFromPackage = null;
3469 String resolvedType = null;
3470 boolean componentSpecified = false;
3471 int userId = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07003472 long createTime = -1;
3473 final int outerDepth = in.getDepth();
Winson Chung2cb86c72014-06-25 12:03:30 -07003474 TaskDescription taskDescription = new TaskDescription();
Craig Mautner21d24a22014-04-23 11:45:37 -07003475
3476 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
3477 final String attrName = in.getAttributeName(attrNdx);
3478 final String attrValue = in.getAttributeValue(attrNdx);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003479 if (DEBUG) Slog.d(TaskPersister.TAG,
Wale Ogunwale18795a22014-12-03 11:38:33 -08003480 "ActivityRecord: attribute name=" + attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003481 if (ATTR_ID.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01003482 createTime = Long.parseLong(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003483 } else if (ATTR_LAUNCHEDFROMUID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003484 launchedFromUid = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003485 } else if (ATTR_LAUNCHEDFROMPACKAGE.equals(attrName)) {
3486 launchedFromPackage = attrValue;
3487 } else if (ATTR_RESOLVEDTYPE.equals(attrName)) {
3488 resolvedType = attrValue;
3489 } else if (ATTR_COMPONENTSPECIFIED.equals(attrName)) {
Tobias Thiererb0800dc2016-04-21 17:51:41 +01003490 componentSpecified = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003491 } else if (ATTR_USERID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003492 userId = Integer.parseInt(attrValue);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003493 } else if (attrName.startsWith(ATTR_TASKDESCRIPTION_PREFIX)) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003494 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003495 } else {
3496 Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
3497 }
3498 }
3499
3500 int event;
Ruben Brunkf53497c2017-03-27 20:26:17 -07003501 while (((event = in.next()) != END_DOCUMENT) &&
3502 (event != END_TAG || in.getDepth() >= outerDepth)) {
3503 if (event == START_TAG) {
Craig Mautner21d24a22014-04-23 11:45:37 -07003504 final String name = in.getName();
Ruben Brunkf53497c2017-03-27 20:26:17 -07003505 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003506 Slog.d(TaskPersister.TAG, "ActivityRecord: START_TAG name=" + name);
Craig Mautner21d24a22014-04-23 11:45:37 -07003507 if (TAG_INTENT.equals(name)) {
3508 intent = Intent.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003509 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003510 Slog.d(TaskPersister.TAG, "ActivityRecord: intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003511 } else if (TAG_PERSISTABLEBUNDLE.equals(name)) {
3512 persistentState = PersistableBundle.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003513 if (DEBUG) Slog.d(TaskPersister.TAG,
Craig Mautner21d24a22014-04-23 11:45:37 -07003514 "ActivityRecord: persistentState=" + persistentState);
3515 } else {
3516 Slog.w(TAG, "restoreActivity: unexpected name=" + name);
3517 XmlUtils.skipCurrentTag(in);
3518 }
3519 }
3520 }
3521
3522 if (intent == null) {
Craig Mautnere0129b32014-05-25 16:41:09 -07003523 throw new XmlPullParserException("restoreActivity error intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003524 }
3525
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003526 final ActivityTaskManagerService service = stackSupervisor.mService;
Craig Mautner21d24a22014-04-23 11:45:37 -07003527 final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null,
Patrick Baumann78380272018-04-04 10:41:01 -07003528 userId, Binder.getCallingUid());
Craig Mautnere0129b32014-05-25 16:41:09 -07003529 if (aInfo == null) {
Craig Mautner77b04262014-06-27 15:22:12 -07003530 throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
3531 " resolvedType=" + resolvedType);
Craig Mautnere0129b32014-05-25 16:41:09 -07003532 }
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003533 final ActivityRecord r = new ActivityRecord(service, null /* caller */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003534 0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType,
Wale Ogunwalef6733932018-06-27 05:14:34 -07003535 aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003536 0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07003537 stackSupervisor, null /* options */, null /* sourceRecord */);
Craig Mautner21d24a22014-04-23 11:45:37 -07003538
3539 r.persistentState = persistentState;
Winson Chung2cb86c72014-06-25 12:03:30 -07003540 r.taskDescription = taskDescription;
Craig Mautner21d24a22014-04-23 11:45:37 -07003541 r.createTime = createTime;
3542
3543 return r;
3544 }
3545
Zak Cohen90e7116742017-01-29 12:59:23 -08003546 private static boolean isInVrUiMode(Configuration config) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07003547 return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
Zak Cohen90e7116742017-01-29 12:59:23 -08003548 }
3549
David Stevens82ea6cb2017-03-03 16:18:50 -08003550 int getUid() {
3551 return info.applicationInfo.uid;
3552 }
3553
chaviw59b98852017-06-13 12:05:44 -07003554 void setShowWhenLocked(boolean showWhenLocked) {
3555 mShowWhenLocked = showWhenLocked;
Wale Ogunwaled32da472018-11-16 07:19:28 -08003556 mRootActivityContainer.ensureActivitiesVisible(null, 0 /* configChanges */,
Kevin Chyn44639482017-10-09 18:34:41 -07003557 false /* preserveWindows */);
chaviw59b98852017-06-13 12:05:44 -07003558 }
3559
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003560 void setInheritShowWhenLocked(boolean inheritShowWhenLocked) {
3561 mInheritShownWhenLocked = inheritShowWhenLocked;
3562 mRootActivityContainer.ensureActivitiesVisible(null, 0, false);
3563 }
3564
chaviw59b98852017-06-13 12:05:44 -07003565 /**
chaviw2c500982018-01-04 17:05:05 -08003566 * @return true if the activity windowing mode is not
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003567 * {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and a) activity
3568 * contains windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the
3569 * activity has set {@link #mShowWhenLocked}, or b) if the activity has set
3570 * {@link #mInheritShownWhenLocked} and the activity behind this satisfies the
3571 * conditions a) above.
chaviw2c500982018-01-04 17:05:05 -08003572 * Multi-windowing mode will be exited if true is returned.
chaviw59b98852017-06-13 12:05:44 -07003573 */
3574 boolean canShowWhenLocked() {
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003575 if (!inPinnedWindowingMode() && (mShowWhenLocked
3576 || (mAppWindowToken != null && mAppWindowToken.containsShowWhenLockedWindow()))) {
3577 return true;
3578 } else if (mInheritShownWhenLocked) {
3579 ActivityRecord r = getActivityBelow();
3580 return r != null && !r.inPinnedWindowingMode() && (r.mShowWhenLocked
3581 || (r.mAppWindowToken != null
3582 && r.mAppWindowToken.containsShowWhenLockedWindow()));
3583 } else {
3584 return false;
3585 }
3586 }
3587
3588 /**
3589 * @return an {@link ActivityRecord} of the activity below this activity, or {@code null} if no
3590 * such activity exists.
3591 */
3592 @Nullable
3593 private ActivityRecord getActivityBelow() {
3594 final int pos = task.mActivities.indexOf(this);
3595 if (pos == -1) {
3596 throw new IllegalStateException("Activity not found in its task");
3597 }
3598 return pos == 0 ? null : task.getChildAt(pos - 1);
chaviw59b98852017-06-13 12:05:44 -07003599 }
3600
3601 void setTurnScreenOn(boolean turnScreenOn) {
3602 mTurnScreenOn = turnScreenOn;
3603 }
3604
3605 /**
3606 * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
3607 * {@link #mTurnScreenOn} is set and checks whether the ActivityRecord should be visible
3608 * depending on Keyguard state
3609 *
3610 * @return true if the screen can be turned on, false otherwise.
3611 */
3612 boolean canTurnScreenOn() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003613 final ActivityStack stack = getActivityStack();
chaviw59b98852017-06-13 12:05:44 -07003614 return mTurnScreenOn && stack != null &&
3615 stack.checkKeyguardVisibility(this, true /* shouldBeVisible */, true /* isTop */);
3616 }
3617
Louis Chang77ce34d2019-01-03 15:45:12 +08003618 /**
3619 * Check if this activity is able to resume. For pre-Q apps, only the topmost activities of each
3620 * process are allowed to be resumed.
3621 *
3622 * @return true if this activity can be resumed.
3623 */
3624 boolean canResumeByCompat() {
3625 return app == null || app.updateTopResumingActivityInProcessIfNeeded(this);
3626 }
3627
chaviw59b98852017-06-13 12:05:44 -07003628 boolean getTurnScreenOnFlag() {
3629 return mTurnScreenOn;
3630 }
3631
3632 boolean isTopRunningActivity() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003633 return mRootActivityContainer.topRunningActivity() == this;
chaviw59b98852017-06-13 12:05:44 -07003634 }
3635
Andrii Kulian52d255c2018-07-13 11:32:19 -07003636 /**
3637 * @return {@code true} if this is the resumed activity on its current display, {@code false}
3638 * otherwise.
3639 */
3640 boolean isResumedActivityOnDisplay() {
3641 final ActivityDisplay display = getDisplay();
3642 return display != null && this == display.getResumedActivity();
3643 }
3644
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003645 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003646 if (mAppWindowToken == null) {
3647 Slog.w(TAG_WM, "Attempted to register remote animations with non-existing app"
3648 + " token: " + appToken);
3649 return;
3650 }
3651 mAppWindowToken.registerRemoteAnimations(definition);
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003652 }
3653
Craig Mautnerf81b90872013-02-26 13:02:43 -08003654 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003655 public String toString() {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003656 if (stringName != null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08003657 return stringName + " t" + (task == null ? INVALID_TASK_ID : task.taskId) +
Craig Mautnerf3333272013-04-22 10:55:53 -07003658 (finishing ? " f}" : "}");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003659 }
3660 StringBuilder sb = new StringBuilder(128);
Dianne Hackborn30d71892010-12-11 10:37:55 -08003661 sb.append("ActivityRecord{");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003662 sb.append(Integer.toHexString(System.identityHashCode(this)));
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003663 sb.append(" u");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003664 sb.append(mUserId);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003665 sb.append(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003666 sb.append(intent.getComponent().flattenToShortString());
Craig Mautnerf81b90872013-02-26 13:02:43 -08003667 stringName = sb.toString();
3668 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07003670
3671 void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
3672 final long token = proto.start(fieldId);
3673 proto.write(HASH_CODE, System.identityHashCode(this));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003674 proto.write(USER_ID, mUserId);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003675 proto.write(TITLE, intent.getComponent().flattenToShortString());
3676 proto.end(token);
3677 }
3678
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003679 /**
3680 * Write all fields to an {@code ActivityRecordProto}. This assumes the
3681 * {@code ActivityRecordProto} is the outer-most proto data.
3682 */
3683 void writeToProto(ProtoOutputStream proto) {
Nataniel Borges023ecb52019-01-16 14:15:43 -08003684 super.writeToProto(proto, CONFIGURATION_CONTAINER, WindowTraceLogLevel.ALL);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003685 writeIdentifierToProto(proto, IDENTIFIER);
Bryce Lee7ace3952018-02-16 14:34:32 -08003686 proto.write(STATE, mState.toString());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003687 proto.write(VISIBLE, visible);
3688 proto.write(FRONT_OF_TASK, frontOfTask);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003689 if (hasProcess()) {
3690 proto.write(PROC_ID, app.getPid());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003691 }
Wale Ogunwale30eab1f2018-05-24 18:25:25 -07003692 proto.write(TRANSLUCENT, !fullscreen);
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003693 }
3694
3695 public void writeToProto(ProtoOutputStream proto, long fieldId) {
3696 final long token = proto.start(fieldId);
3697 writeToProto(proto);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003698 proto.end(token);
3699 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003700}