blob: 087de69b6c12fdda90e3fef36bb18dc1616c96ec [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;
104import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
105import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
106import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
107import static com.android.server.wm.ActivityStack.LAUNCH_TICK;
108import static com.android.server.wm.ActivityStack.LAUNCH_TICK_MSG;
109import static com.android.server.wm.ActivityStack.PAUSE_TIMEOUT_MSG;
Andrii Kulian0c869cc2019-02-06 19:50:32 -0800110import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800111import static com.android.server.wm.ActivityStack.STOP_TIMEOUT_MSG;
Wale Ogunwale59507092018-10-29 09:00:30 -0700112import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
113import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
114import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
115import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
116import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
117import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
118import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
119import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
120import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SAVED_STATE;
121import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
122import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
123import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
124import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
125import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwale59507092018-10-29 09:00:30 -0700126import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
127import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
Hui Yu03d12402018-12-06 18:00:37 -0800128import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -0700129import static com.android.server.wm.IdentifierProto.HASH_CODE;
130import static com.android.server.wm.IdentifierProto.TITLE;
131import static com.android.server.wm.IdentifierProto.USER_ID;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800132import static com.android.server.wm.TaskPersister.DEBUG;
133import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800134import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
135import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
136import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
137import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
138import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700139
Ruben Brunkf53497c2017-03-27 20:26:17 -0700140import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
141import static org.xmlpull.v1.XmlPullParser.END_TAG;
142import static org.xmlpull.v1.XmlPullParser.START_TAG;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800143
Andrii Kulian21713ac2016-10-12 22:05:05 -0700144import android.annotation.NonNull;
Issei Suzuki74e1eb22018-12-20 17:42:52 +0100145import android.annotation.Nullable;
Craig Mautner21d24a22014-04-23 11:45:37 -0700146import android.app.ActivityManager.TaskDescription;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700147import android.app.ActivityOptions;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800148import android.app.PendingIntent;
Winson Chung709904f2017-04-25 11:00:48 -0700149import android.app.PictureInPictureParams;
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800150import android.app.ResultInfo;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -0800151import android.app.WaitResult.LaunchState;
Riddle Hsu16567132018-08-16 21:37:47 +0800152import android.app.servertransaction.ActivityConfigurationChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800153import android.app.servertransaction.ActivityLifecycleItem;
154import android.app.servertransaction.ActivityRelaunchItem;
155import android.app.servertransaction.ClientTransaction;
156import android.app.servertransaction.ClientTransactionItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700157import android.app.servertransaction.MoveToDisplayItem;
158import android.app.servertransaction.MultiWindowModeChangeItem;
159import android.app.servertransaction.NewIntentItem;
Bryce Lee0bd8d422018-01-09 09:45:57 -0800160import android.app.servertransaction.PauseActivityItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700161import android.app.servertransaction.PipModeChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800162import android.app.servertransaction.ResumeActivityItem;
Andrii Kuliand70cdb92019-01-08 15:03:50 -0800163import android.app.servertransaction.TopResumedActivityChangeItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700164import android.app.servertransaction.WindowVisibilityItem;
Hui Yu03d12402018-12-06 18:00:37 -0800165import android.app.usage.UsageEvents.Event;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166import android.content.ComponentName;
167import android.content.Intent;
168import android.content.pm.ActivityInfo;
169import android.content.pm.ApplicationInfo;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700170import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171import android.content.res.Configuration;
172import android.graphics.Bitmap;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800173import android.graphics.GraphicBuffer;
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700174import android.graphics.Rect;
Patrick Baumann78380272018-04-04 10:41:01 -0700175import android.os.Binder;
Bryce Lee39791592017-04-26 09:29:12 -0700176import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177import android.os.Bundle;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700178import android.os.Debug;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800179import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180import android.os.Message;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800181import android.os.PersistableBundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182import android.os.Process;
Dianne Hackborn39792d22010-08-19 18:01:52 -0700183import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700185import android.os.UserHandle;
Bryce Lee8558ec72017-08-17 15:37:26 -0700186import android.os.storage.StorageManager;
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800187import android.service.voice.IVoiceInteractionSession;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188import android.util.EventLog;
189import android.util.Log;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700190import android.util.MergedConfiguration;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700191import android.util.Slog;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700192import android.util.TimeUtils;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700193import android.util.proto.ProtoOutputStream;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800194import android.view.AppTransitionAnimationSpec;
195import android.view.IAppTransitionAnimationSpecsFuture;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196import android.view.IApplicationToken;
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100197import android.view.RemoteAnimationDefinition;
Jorim Jaggife762342016-10-13 14:33:27 +0200198import android.view.WindowManager.LayoutParams;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700199
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700200import com.android.internal.R;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800201import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800202import com.android.internal.app.ResolverActivity;
203import com.android.internal.content.ReferrerIntent;
204import com.android.internal.util.XmlUtils;
205import com.android.server.AttributeCache;
Ruben Brunkf53497c2017-03-27 20:26:17 -0700206import com.android.server.AttributeCache.Entry;
Wale Ogunwale59507092018-10-29 09:00:30 -0700207import com.android.server.am.AppTimeTracker;
208import com.android.server.am.PendingIntentRecord;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800209import com.android.server.uri.UriPermissionOwner;
Wale Ogunwale59507092018-10-29 09:00:30 -0700210import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
211import com.android.server.wm.ActivityStack.ActivityState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212
Jorim Jaggi02886a82016-12-06 09:10:06 -0800213import org.xmlpull.v1.XmlPullParser;
214import org.xmlpull.v1.XmlPullParserException;
215import org.xmlpull.v1.XmlSerializer;
216
Suprabh Shukla23593142015-11-03 17:31:15 -0800217import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -0700218import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219import java.io.PrintWriter;
220import java.lang.ref.WeakReference;
221import java.util.ArrayList;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800222import java.util.Arrays;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223import java.util.HashSet;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700224import java.util.List;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700225import java.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226
227/**
228 * An entry in the history stack, representing an activity.
229 */
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800230final class ActivityRecord extends ConfigurationContainer {
Wale Ogunwale98875612018-10-12 07:53:02 -0700231 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_ATM;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700232 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
233 private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700234 private static final String TAG_STATES = TAG + POSTFIX_STATES;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700235 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700236 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
Louis Chang19443452018-10-09 12:10:21 +0800237 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
Winson Chung16e185e2017-11-07 08:30:54 -0800238 // TODO(b/67864419): Remove once recents component is overridden
239 private static final String LEGACY_RECENTS_PACKAGE_NAME = "com.android.systemui.recents";
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800240
Wale Ogunwale3ab9a272015-03-16 09:55:45 -0700241 private static final boolean SHOW_ACTIVITY_START_TIME = true;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700242
Craig Mautner21d24a22014-04-23 11:45:37 -0700243 private static final String ATTR_ID = "id";
244 private static final String TAG_INTENT = "intent";
245 private static final String ATTR_USERID = "user_id";
246 private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle";
247 private static final String ATTR_LAUNCHEDFROMUID = "launched_from_uid";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700248 private static final String ATTR_LAUNCHEDFROMPACKAGE = "launched_from_package";
Craig Mautner21d24a22014-04-23 11:45:37 -0700249 private static final String ATTR_RESOLVEDTYPE = "resolved_type";
250 private static final String ATTR_COMPONENTSPECIFIED = "component_specified";
Dianne Hackborn337abb32014-09-24 12:44:29 -0700251 static final String ACTIVITY_ICON_SUFFIX = "_activity_icon_";
Craig Mautner21d24a22014-04-23 11:45:37 -0700252
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800253 final ActivityTaskManagerService mAtmService; // owner
Dianne Hackbornbe707852011-11-11 14:32:10 -0800254 final IApplicationToken.Stub appToken; // window manager token
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800255 // TODO: Remove after unification
256 AppWindowToken mAppWindowToken;
257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 final ActivityInfo info; // all about me
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700259 // TODO: This is duplicated state already contained in info.applicationInfo - remove
260 ApplicationInfo appInfo; // information about activity's app
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800261 final int launchedFromPid; // always the pid who started the activity.
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700262 final int launchedFromUid; // always the uid who started the activity.
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800263 final String launchedFromPackage; // always the package who started the activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800264 final int mUserId; // Which user is this running for?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 final Intent intent; // the original intent that generated us
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800266 final ComponentName mActivityComponent; // the intent component, or target of an alias.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 final String shortComponentName; // the short component name of the intent
268 final String resolvedType; // as per original caller;
269 final String packageName; // the package implementing intent's component
270 final String processName; // process where this component wants to run
271 final String taskAffinity; // as per ActivityInfo.taskAffinity
272 final boolean stateNotNeeded; // As per ActivityInfo.flags
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700273 boolean fullscreen; // The activity is opaque and fills the entire space of this task.
274 // TODO: See if it possible to combine this with the fullscreen field.
275 final boolean hasWallpaper; // Has a wallpaper window as a background.
Louis Changd58cb672018-12-24 17:45:16 +0800276 @VisibleForTesting
277 boolean noDisplay; // activity is not displayed?
278 @VisibleForTesting
279 int mHandoverLaunchDisplayId = INVALID_DISPLAY; // Handover launch display id to next activity.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800280 private final boolean componentSpecified; // did caller specify an explicit component?
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700281 final boolean rootVoiceInteraction; // was this the root activity of a voice interaction?
Craig Mautner86d67a42013-05-14 10:34:38 -0700282
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800283 private CharSequence nonLocalizedLabel; // the label information from the package mgr.
284 private int labelRes; // the label information from the package mgr.
285 private int icon; // resource identifier of activity's icon.
286 private int logo; // resource identifier of activity's logo.
287 private int theme; // resource identifier of activity's theme.
288 private int realTheme; // actual theme resource we will use, never 0.
289 private int windowFlags; // custom window flags for preview window.
Bryce Leeaf691c02017-03-20 14:20:22 -0700290 private TaskRecord task; // the task this is in.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800291 private long createTime = System.currentTimeMillis();
Dianne Hackborn50685602011-12-01 12:23:37 -0800292 long lastVisibleTime; // last time this activity became visible
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700293 long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700294 long pauseTime; // last time we started pausing the activity
295 long launchTickTime; // base time for launch tick messages
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700296 // Last configuration reported to the activity in the client process.
297 private MergedConfiguration mLastReportedConfiguration;
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800298 private int mLastReportedDisplayId;
Winson Chung609e1e92017-05-08 10:52:12 -0700299 private boolean mLastReportedMultiWindowMode;
300 private boolean mLastReportedPictureInPictureMode;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700301 CompatibilityInfo compat;// last used compatibility mode
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700302 ActivityRecord resultTo; // who started this entry, so will get our reply
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 final String resultWho; // additional identifier for use by resultTo.
304 final int requestCode; // code given by requester (resultTo)
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800305 ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
Dianne Hackborn85d558c2014-11-04 10:31:54 -0800307 ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700308 ActivityOptions pendingOptions; // most recently given options
George Mount6ba042b2014-07-28 11:12:28 -0700309 ActivityOptions returningOptions; // options that are coming back via convertToTranslucent
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700310 AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity
Wale Ogunwalec4e63a42018-10-02 13:19:54 -0700311 ActivityServiceConnectionsHolder mServiceConnectionsHolder; // Service connections.
Dianne Hackborn7e269642010-08-25 19:50:20 -0700312 UriPermissionOwner uriPermissions; // current special URI access perms.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700313 WindowProcessController app; // if non-null, hosting application
Bryce Lee7ace3952018-02-16 14:34:32 -0800314 private ActivityState mState; // current state we are in
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 Bundle icicle; // last saved activity state
Craig Mautnera0026042014-04-23 11:45:37 -0700316 PersistableBundle persistentState; // last persistently saved activity state
Wale Ogunwale66e16852017-10-19 13:35:52 -0700317 // TODO: See if this is still needed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 boolean frontOfTask; // is this the root activity of its task?
319 boolean launchFailed; // set if a launched failed, to abort on 2nd try
320 boolean haveState; // have we gotten the last activity state?
321 boolean stopped; // is activity pause finished?
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700322 boolean delayedResume; // not yet resumed because of stopped app switches?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 boolean finishing; // activity in pending finish list?
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800324 boolean deferRelaunchUntilPaused; // relaunch of activity is being deferred until pause is
325 // completed
326 boolean preserveWindowOnDeferredRelaunch; // activity windows are preserved on deferred relaunch
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 int configChangeFlags; // which config values have changed
Wale Ogunwaleec950642017-04-25 07:44:21 -0700328 private boolean keysPaused; // has key dispatching been paused for it?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 int launchMode; // the launch mode activity attribute.
Charles He2bf28322017-10-12 22:24:49 +0100330 int lockTaskLaunchMode; // the lockTaskMode manifest attribute, subject to override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 boolean visible; // does this activity's window need to be shown?
Jorim Jaggi241ae102016-11-02 21:57:33 -0700332 boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
333 // might hide this activity?
Wale Ogunwaleec950642017-04-25 07:44:21 -0700334 private boolean mDeferHidingClient; // If true we told WM to defer reporting to the client
335 // process that it is hidden.
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800336 boolean sleeping; // have we told the activity to sleep?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 boolean nowVisible; // is this activity's window visible?
Vishnu Nair9ba31652018-11-13 14:34:05 -0800338 boolean mDrawn; // is this activity's window drawn?
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700339 boolean mClientVisibilityDeferred;// was the visibility change message to client deferred?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 boolean idle; // has the activity gone idle?
341 boolean hasBeenLaunched;// has this activity ever been launched?
342 boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
Daniel Sandler69a48172010-06-23 16:29:36 -0400343 boolean immersive; // immersive mode (don't interrupt if possible)
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400344 boolean forceNewConfig; // force re-create with new config next time
Winson Chungf7e03e12017-08-22 11:32:16 -0700345 boolean supportsEnterPipOnTaskSwitch; // This flag is set by the system to indicate that the
346 // activity can enter picture in picture while pausing (only when switching to another task)
Winson Chung709904f2017-04-25 11:00:48 -0700347 PictureInPictureParams pictureInPictureArgs = new PictureInPictureParams.Builder().build();
348 // The PiP params used when deferring the entering of picture-in-picture.
Dianne Hackborn07981492013-01-28 11:36:23 -0800349 int launchCount; // count of launches since last state
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800350 long lastLaunchTime; // time of last launch of this activity
Ruben Brunke24b9a62016-02-16 21:38:24 -0800351 ComponentName requestedVrComponent; // the requested component for handling VR mode.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700353 String stringName; // for caching of toString().
Craig Mautnerde4ef022013-04-07 19:01:33 -0700354
Dianne Hackbornf26fd992011-04-08 18:14:09 -0700355 private boolean inHistory; // are we in the history stack?
Craig Mautnerde4ef022013-04-07 19:01:33 -0700356 final ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800357 final RootActivityContainer mRootActivityContainer;
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800358
359 static final int STARTING_WINDOW_NOT_SHOWN = 0;
360 static final int STARTING_WINDOW_SHOWN = 1;
361 static final int STARTING_WINDOW_REMOVED = 2;
362 int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;
Wale Ogunwale3b232392016-05-13 15:37:13 -0700363 boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800364
Garfield Tan2746ab52018-07-25 12:33:01 -0700365 // Marking the reason why this activity is being relaunched. Mainly used to track that this
366 // activity is being relaunched to fulfill a resize request due to compatibility issues, e.g. in
367 // pre-NYC apps that don't have a sense of being resized.
368 int mRelaunchReason = RELAUNCH_REASON_NONE;
369
Craig Mautner21d24a22014-04-23 11:45:37 -0700370 TaskDescription taskDescription; // the recents information for this activity
Craig Mautnerbb742462014-07-07 15:28:55 -0700371 boolean mLaunchTaskBehind; // this activity is actively being launched with
372 // ActivityOptions.setLaunchTaskBehind, will be cleared once launch is completed.
Craig Mautner2fbd7542014-03-21 09:34:07 -0700373
Filip Gruszczynski23493322015-07-29 17:02:59 -0700374 // These configurations are collected from application's resources based on size-sensitive
375 // qualifiers. For example, layout-w800dp will be added to mHorizontalSizeConfigurations as 800
376 // and drawable-sw400dp will be added to both as 400.
377 private int[] mVerticalSizeConfigurations;
378 private int[] mHorizontalSizeConfigurations;
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700379 private int[] mSmallestSizeConfigurations;
Filip Gruszczynski23493322015-07-29 17:02:59 -0700380
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800381 boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session
382 IVoiceInteractionSession voiceSession; // Voice interaction session for this activity
383
Robert Carrd2265122016-08-05 10:25:21 -0700384 // A hint to override the window specified rotation animation, or -1
385 // to use the window specified value. We use this so that
386 // we can select the right animation in the cases of starting
387 // windows, where the app hasn't had time to set a value
388 // on the window.
389 int mRotationAnimationHint = -1;
Robert Carrfd10cd12016-06-29 16:41:50 -0700390
chaviw59b98852017-06-13 12:05:44 -0700391 private boolean mShowWhenLocked;
Issei Suzuki74e1eb22018-12-20 17:42:52 +0100392 private boolean mInheritShownWhenLocked;
chaviw59b98852017-06-13 12:05:44 -0700393 private boolean mTurnScreenOn;
394
Andrii Kulian21713ac2016-10-12 22:05:05 -0700395 /**
Garfield Tan0443b372019-01-04 15:00:13 -0800396 * Current sequencing integer of the configuration, for skipping old activity configurations.
397 */
398 private int mConfigurationSeq;
399
400 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800401 * Temp configs used in {@link #ensureActivityConfiguration(int, boolean)}
Andrii Kulian21713ac2016-10-12 22:05:05 -0700402 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700403 private final Configuration mTmpConfig = new Configuration();
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700404 private final Rect mTmpBounds = new Rect();
Andrii Kulian21713ac2016-10-12 22:05:05 -0700405
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800406 private static String startingWindowStateToString(int state) {
407 switch (state) {
408 case STARTING_WINDOW_NOT_SHOWN:
409 return "STARTING_WINDOW_NOT_SHOWN";
410 case STARTING_WINDOW_SHOWN:
411 return "STARTING_WINDOW_SHOWN";
412 case STARTING_WINDOW_REMOVED:
413 return "STARTING_WINDOW_REMOVED";
414 default:
415 return "unknown state=" + state;
416 }
417 }
418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700420 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700421 pw.print(prefix); pw.print("packageName="); pw.print(packageName);
422 pw.print(" processName="); pw.println(processName);
423 pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
Craig Mautnere11f2b72013-04-01 12:37:17 -0700424 pw.print(" launchedFromPackage="); pw.print(launchedFromPackage);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800425 pw.print(" userId="); pw.println(mUserId);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800426 pw.print(prefix); pw.print("app="); pw.println(app);
427 pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700428 pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask);
429 pw.print(" task="); pw.println(task);
430 pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800431 pw.print(prefix); pw.print("mActivityComponent=");
432 pw.println(mActivityComponent.flattenToShortString());
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700433 if (appInfo != null) {
434 pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir);
435 if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) {
436 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir);
437 }
438 pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800439 if (appInfo.splitSourceDirs != null) {
440 pw.print(prefix); pw.print("splitDir=");
441 pw.println(Arrays.toString(appInfo.splitSourceDirs));
442 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800443 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700444 pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
445 pw.print(" componentSpecified="); pw.print(componentSpecified);
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700446 pw.print(" mActivityType="); pw.println(
447 activityTypeToString(getActivityType()));
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700448 if (rootVoiceInteraction) {
449 pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
450 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800451 pw.print(prefix); pw.print("compat="); pw.print(compat);
452 pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
453 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
454 pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700455 pw.println(prefix + "mLastReportedConfigurations:");
456 mLastReportedConfiguration.dump(pw, prefix + " ");
457
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700458 pw.print(prefix); pw.print("CurrentConfiguration="); pw.println(getConfiguration());
Evan Roskydfe3da72018-10-26 17:21:06 -0700459 if (!getRequestedOverrideConfiguration().equals(EMPTY)) {
460 pw.println(prefix + "RequestedOverrideConfiguration="
461 + getRequestedOverrideConfiguration());
462 }
463 if (!getResolvedOverrideConfiguration().equals(getRequestedOverrideConfiguration())) {
464 pw.println(prefix + "ResolvedOverrideConfiguration="
465 + getResolvedOverrideConfiguration());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700466 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800467 if (!matchParentBounds()) {
468 pw.println(prefix + "bounds=" + getBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700469 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700470 if (resultTo != null || resultWho != null) {
471 pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
472 pw.print(" resultWho="); pw.print(resultWho);
473 pw.print(" resultCode="); pw.println(requestCode);
474 }
Craig Mautner29c58ca2014-10-14 16:17:06 -0700475 if (taskDescription != null) {
476 final String iconFilename = taskDescription.getIconFilename();
477 if (iconFilename != null || taskDescription.getLabel() != null ||
478 taskDescription.getPrimaryColor() != 0) {
479 pw.print(prefix); pw.print("taskDescription:");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700480 pw.print(" label=\""); pw.print(taskDescription.getLabel());
481 pw.print("\"");
Matthew Ng54bc9422017-10-02 17:16:28 -0700482 pw.print(" icon="); pw.print(taskDescription.getInMemoryIcon() != null
483 ? taskDescription.getInMemoryIcon().getByteCount() + " bytes"
484 : "null");
485 pw.print(" iconResource="); pw.print(taskDescription.getIconResource());
486 pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200487 pw.print(" primaryColor=");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700488 pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700489 pw.print(prefix + " backgroundColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200490 pw.println(Integer.toHexString(taskDescription.getBackgroundColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700491 pw.print(prefix + " statusBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200492 pw.println(Integer.toHexString(taskDescription.getStatusBarColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700493 pw.print(prefix + " navigationBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200494 pw.println(Integer.toHexString(taskDescription.getNavigationBarColor()));
Craig Mautner29c58ca2014-10-14 16:17:06 -0700495 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700496 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700497 if (results != null) {
498 pw.print(prefix); pw.print("results="); pw.println(results);
499 }
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700500 if (pendingResults != null && pendingResults.size() > 0) {
501 pw.print(prefix); pw.println("Pending Results:");
502 for (WeakReference<PendingIntentRecord> wpir : pendingResults) {
503 PendingIntentRecord pir = wpir != null ? wpir.get() : null;
504 pw.print(prefix); pw.print(" - ");
505 if (pir == null) {
506 pw.println("null");
507 } else {
508 pw.println(pir);
509 pir.dump(pw, prefix + " ");
510 }
511 }
512 }
513 if (newIntents != null && newIntents.size() > 0) {
514 pw.print(prefix); pw.println("Pending New Intents:");
515 for (int i=0; i<newIntents.size(); i++) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800516 Intent intent = newIntents.get(i);
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700517 pw.print(prefix); pw.print(" - ");
518 if (intent == null) {
519 pw.println("null");
520 } else {
521 pw.println(intent.toShortString(false, true, false, true));
522 }
523 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700524 }
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700525 if (pendingOptions != null) {
526 pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions);
527 }
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700528 if (appTimeTracker != null) {
529 appTimeTracker.dumpWithHeader(pw, prefix, false);
530 }
Dianne Hackborn7e269642010-08-25 19:50:20 -0700531 if (uriPermissions != null) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700532 uriPermissions.dump(pw, prefix);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700533 }
534 pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed);
Dianne Hackborn07981492013-01-28 11:36:23 -0800535 pw.print(" launchCount="); pw.print(launchCount);
536 pw.print(" lastLaunchTime=");
537 if (lastLaunchTime == 0) pw.print("0");
538 else TimeUtils.formatDuration(lastLaunchTime, now, pw);
539 pw.println();
Dianne Hackborncfc837f2013-06-27 18:32:07 -0700540 pw.print(prefix); pw.print("haveState="); pw.print(haveState);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700541 pw.print(" icicle="); pw.println(icicle);
Bryce Lee7ace3952018-02-16 14:34:32 -0800542 pw.print(prefix); pw.print("state="); pw.print(mState);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700543 pw.print(" stopped="); pw.print(stopped);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700544 pw.print(" delayedResume="); pw.print(delayedResume);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700545 pw.print(" finishing="); pw.println(finishing);
546 pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
547 pw.print(" inHistory="); pw.print(inHistory);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700548 pw.print(" visible="); pw.print(visible);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800549 pw.print(" sleeping="); pw.print(sleeping);
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800550 pw.print(" idle="); pw.print(idle);
551 pw.print(" mStartingWindowState=");
552 pw.println(startingWindowStateToString(mStartingWindowState));
Dianne Hackbornff801ec2011-01-22 18:05:38 -0800553 pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
554 pw.print(" noDisplay="); pw.print(noDisplay);
555 pw.print(" immersive="); pw.print(immersive);
556 pw.print(" launchMode="); pw.println(launchMode);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800557 pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400558 pw.print(" forceNewConfig="); pw.println(forceNewConfig);
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700559 pw.print(prefix); pw.print("mActivityType=");
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700560 pw.println(activityTypeToString(getActivityType()));
Ruben Brunke24b9a62016-02-16 21:38:24 -0800561 if (requestedVrComponent != null) {
562 pw.print(prefix);
563 pw.print("requestedVrComponent=");
564 pw.println(requestedVrComponent);
565 }
Bryce Lee4a194382017-04-04 14:32:48 -0700566 final boolean waitingVisible =
567 mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800568 if (lastVisibleTime != 0 || waitingVisible || nowVisible) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700569 pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800570 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()) {
697 if (DEBUG_CONFIGURATION) {
698 Slog.w(TAG, "Can't report activity position update - client not running"
699 + ", activityRecord=" + this);
700 }
701 return;
702 }
703 try {
704 if (DEBUG_CONFIGURATION) {
705 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 }
2133 }
2134
2135 /**
2136 * Once we know that we have asked an application to put an activity in the resumed state
2137 * (either by launching it or explicitly telling it), this function updates the rest of our
2138 * state to match that fact.
2139 */
2140 void completeResumeLocked() {
2141 final boolean wasVisible = visible;
Jorim Jaggi8d062052017-08-22 14:55:17 +02002142 setVisible(true);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002143 if (!wasVisible) {
2144 // Visibility has changed, so take a note of it so we call the TaskStackChangedListener
2145 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
2146 }
2147 idle = false;
2148 results = null;
2149 newIntents = null;
2150 stopped = false;
2151
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002152 if (isActivityTypeHome()) {
Louis Changdcdde952018-12-04 15:38:44 +08002153 mStackSupervisor.updateHomeProcess(task.mActivities.get(0).app);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002154 }
2155
2156 if (nowVisible) {
2157 // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
2158 mStackSupervisor.reportActivityVisibleLocked(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002159 }
2160
2161 // Schedule an idle timeout in case the app doesn't do it for us.
2162 mStackSupervisor.scheduleIdleTimeoutLocked(this);
2163
2164 mStackSupervisor.reportResumedActivityLocked(this);
2165
2166 resumeKeyDispatchingLocked();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002167 final ActivityStack stack = getActivityStack();
Jorim Jaggifa9ed962018-01-25 00:16:49 +01002168 mStackSupervisor.mNoAnimActivities.clear();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002169
2170 // Mark the point when the activity is resuming
2171 // TODO: To be more accurate, the mark should be before the onCreate,
2172 // not after the onResume. But for subsequent starts, onResume is fine.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002173 if (hasProcess()) {
Wale Ogunwale86b74462018-07-02 08:42:43 -07002174 cpuTimeAtResume = app.getCpuTime();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002175 } else {
2176 cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2177 }
2178
2179 returningOptions = null;
chaviw59b98852017-06-13 12:05:44 -07002180
2181 if (canTurnScreenOn()) {
2182 mStackSupervisor.wakeUp("turnScreenOnFlag");
2183 } else {
2184 // If the screen is going to turn on because the caller explicitly requested it and
2185 // the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
2186 // pause and then resume again later, which will result in a double life-cycle event.
David Stevens9440dc82017-03-16 19:00:20 -07002187 stack.checkReadyForSleep();
chaviw59b98852017-06-13 12:05:44 -07002188 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002189 }
2190
2191 final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
2192 CharSequence description) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002193 final ActivityStack stack = getActivityStack();
Bryce Lee7ace3952018-02-16 14:34:32 -08002194 if (mState != STOPPING) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002195 Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
Ruben Brunkf53497c2017-03-27 20:26:17 -07002196 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002197 return;
2198 }
2199 if (newPersistentState != null) {
2200 persistentState = newPersistentState;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002201 mAtmService.notifyTaskPersisterLocked(task, false);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002202 }
2203 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + icicle);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002204
Andrii Kulian21713ac2016-10-12 22:05:05 -07002205 if (newIcicle != null) {
2206 // If icicle is null, this is happening due to a timeout, so we haven't really saved
2207 // the state.
2208 icicle = newIcicle;
2209 haveState = true;
2210 launchCount = 0;
Jorim Jaggie7d2b852017-08-28 17:55:15 +02002211 updateTaskDescription(description);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002212 }
2213 if (!stopped) {
2214 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
Ruben Brunkf53497c2017-03-27 20:26:17 -07002215 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002216 stopped = true;
Bryce Lee7ace3952018-02-16 14:34:32 -08002217 setState(STOPPED, "activityStoppedLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07002218
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002219 if (mAppWindowToken != null) {
2220 mAppWindowToken.notifyAppStopped();
2221 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002222
Andrii Kulian21713ac2016-10-12 22:05:05 -07002223 if (finishing) {
2224 clearOptionsLocked();
2225 } else {
2226 if (deferRelaunchUntilPaused) {
2227 stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002228 mRootActivityContainer.resumeFocusedStacksTopActivities();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002229 } else {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002230 mRootActivityContainer.updatePreviousProcess(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002231 }
2232 }
2233 }
2234 }
2235
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002236 void startLaunchTickingLocked() {
Jeff Sharkey5ab02432017-06-27 11:01:36 -06002237 if (Build.IS_USER) {
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002238 return;
2239 }
2240 if (launchTickTime == 0) {
2241 launchTickTime = SystemClock.uptimeMillis();
2242 continueLaunchTickingLocked();
2243 }
2244 }
2245
2246 boolean continueLaunchTickingLocked() {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002247 if (launchTickTime == 0) {
2248 return false;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002249 }
Wale Ogunwale7d701172015-03-11 15:36:30 -07002250
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002251 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002252 if (stack == null) {
2253 return false;
2254 }
2255
Ruben Brunkf53497c2017-03-27 20:26:17 -07002256 Message msg = stack.mHandler.obtainMessage(LAUNCH_TICK_MSG, this);
2257 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
2258 stack.mHandler.sendMessageDelayed(msg, LAUNCH_TICK);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002259 return true;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002260 }
2261
2262 void finishLaunchTickingLocked() {
2263 launchTickTime = 0;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002264 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002265 if (stack != null) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07002266 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002267 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002268 }
2269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002270 // IApplicationToken
2271
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002272 public boolean mayFreezeScreenLocked(WindowProcessController app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002273 // Only freeze the screen if this activity is currently attached to
2274 // an application, and that application is not blocked or unresponding.
2275 // In any other case, we can't count on getting the screen unfrozen,
2276 // so it is best to leave as-is.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002277 return hasProcess() && !app.isCrashing() && !app.isNotResponding();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002279
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002280 public void startFreezingScreenLocked(WindowProcessController app, int configChanges) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 if (mayFreezeScreenLocked(app)) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002282 if (mAppWindowToken == null) {
2283 Slog.w(TAG_WM,
2284 "Attempted to freeze screen with non-existing app token: " + appToken);
2285 return;
2286 }
2287
2288 if (configChanges == 0 && mAppWindowToken.okToDisplay()) {
2289 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + appToken);
2290 return;
2291 }
2292
2293 mAppWindowToken.startFreezingScreen();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 }
2295 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 public void stopFreezingScreenLocked(boolean force) {
2298 if (force || frozenBeforeDestroy) {
2299 frozenBeforeDestroy = false;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002300 if (mAppWindowToken == null) {
2301 return;
2302 }
2303 if (DEBUG_ORIENTATION) {
2304 Slog.v(TAG_WM, "Clear freezing of " + appToken + ": hidden="
2305 + mAppWindowToken.isHidden() + " freezing="
2306 + mAppWindowToken.isFreezingScreen());
2307 }
2308 mAppWindowToken.stopFreezingScreen(true, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 }
2310 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002311
Jorim Jaggi4d27b842017-08-17 17:22:26 +02002312 public void reportFullyDrawnLocked(boolean restoredFromBundle) {
Vishnu Nair132ee832018-09-28 15:00:05 -07002313 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2314 .getActivityMetricsLogger().logAppTransitionReportedDrawn(this, restoredFromBundle);
2315 if (info != null) {
2316 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002317 info.windowsFullyDrawnDelayMs, info.getLaunchState());
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002318 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002319 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002320
2321 /**
2322 * Called when the starting window for this container is drawn.
2323 */
Sudheer Shankac766db02017-06-12 10:37:29 -07002324 public void onStartingWindowDrawn(long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002325 synchronized (mAtmService.mGlobalLock) {
Bryce Lee2a3cc462017-10-27 10:57:35 -07002326 mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +01002327 getWindowingMode(), timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -08002328 }
2329 }
2330
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002331 /** Called when the windows associated app window container are drawn. */
Vishnu Nair9ba31652018-11-13 14:34:05 -08002332 public void onWindowsDrawn(boolean drawn, long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002333 synchronized (mAtmService.mGlobalLock) {
Vishnu Nair9ba31652018-11-13 14:34:05 -08002334 mDrawn = drawn;
2335 if (!drawn) {
2336 return;
2337 }
Vishnu Nair132ee832018-09-28 15:00:05 -07002338 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2339 .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
2340 final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002341 final @LaunchState int launchState = info != null ? info.getLaunchState() : -1;
Vishnu Nair132ee832018-09-28 15:00:05 -07002342 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002343 windowsDrawnDelayMs, launchState);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002344 mStackSupervisor.sendWaitingVisibleReportLocked(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002345 finishLaunchTickingLocked();
2346 if (task != null) {
2347 task.hasBeenVisible = true;
2348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 }
2350 }
2351
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002352 /** Called when the windows associated app window container are visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002353 public void onWindowsVisible() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002354 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002355 mStackSupervisor.reportActivityVisibleLocked(this);
2356 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
2357 if (!nowVisible) {
2358 nowVisible = true;
2359 lastVisibleTime = SystemClock.uptimeMillis();
Bryce Leeb7c9b802017-05-02 14:20:24 -07002360 if (idle || mStackSupervisor.isStoppingNoHistoryActivity()) {
2361 // If this activity was already idle or there is an activity that must be
2362 // stopped immediately after visible, then we now need to make sure we perform
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002363 // the full stop of any activities that are waiting to do so. This is because
2364 // we won't do that while they are still waiting for this one to become visible.
Bryce Lee4a194382017-04-04 14:32:48 -07002365 final int size = mStackSupervisor.mActivitiesWaitingForVisibleActivity.size();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002366 if (size > 0) {
2367 for (int i = 0; i < size; i++) {
Bryce Lee4a194382017-04-04 14:32:48 -07002368 final ActivityRecord r =
2369 mStackSupervisor.mActivitiesWaitingForVisibleActivity.get(i);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002370 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "Was waiting for visible: " + r);
2371 }
Bryce Lee4a194382017-04-04 14:32:48 -07002372 mStackSupervisor.mActivitiesWaitingForVisibleActivity.clear();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002373 mStackSupervisor.scheduleIdleLocked();
2374 }
Bryce Leeb7c9b802017-05-02 14:20:24 -07002375 } else {
2376 // Instead of doing the full stop routine here, let's just hide any activities
2377 // we now can, and let them stop when the normal idle happens.
2378 mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
2379 false /* remove */, true /* processPausingActivities */);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002380 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002381 mAtmService.scheduleAppGcsLocked();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002382 }
2383 }
2384 }
2385
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002386 /** Called when the windows associated app window container are no longer visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002387 public void onWindowsGone() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002388 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002389 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + this);
2390 nowVisible = false;
2391 }
2392 }
2393
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002394 /**
2395 * Called when the key dispatching to a window associated with the app window container
2396 * timed-out.
2397 *
2398 * @param reason The reason for the key dispatching time out.
2399 * @param windowPid The pid of the window key dispatching timed out on.
2400 * @return True if input dispatching should be aborted.
2401 */
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002402 public boolean keyDispatchingTimedOut(String reason, int windowPid) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002403 ActivityRecord anrActivity;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002404 WindowProcessController anrApp;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002405 boolean windowFromSameProcessAsActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002406 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002407 anrActivity = getWaitingHistoryRecordLocked();
2408 anrApp = app;
Brian Carlstrom7b0f2e82017-03-31 00:24:18 -07002409 windowFromSameProcessAsActivity =
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002410 !hasProcess() || app.getPid() == windowPid || windowPid == -1;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002411 }
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002412
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002413 if (windowFromSameProcessAsActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002414 return mAtmService.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner,
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002415 anrActivity.shortComponentName, anrActivity.appInfo, shortComponentName,
2416 app, false, reason);
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002417 } else {
2418 // In this case another process added windows using this activity token. So, we call the
2419 // generic service input dispatch timed out method so that the right process is blamed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002420 return mAtmService.mAmInternal.inputDispatchingTimedOut(
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002421 windowPid, false /* aboveSystem */, reason) < 0;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002422 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002423 }
2424
2425 private ActivityRecord getWaitingHistoryRecordLocked() {
riddle_hsudb46d6b2015-04-01 18:58:07 +08002426 // First find the real culprit... if this activity is waiting for
2427 // another activity to start or has stopped, then the key dispatching
2428 // timeout should not be caused by this.
Bryce Lee4a194382017-04-04 14:32:48 -07002429 if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this) || stopped) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002430 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
riddle_hsudb46d6b2015-04-01 18:58:07 +08002431 // Try to use the one which is closest to top.
Bryce Leec4ab62a2018-03-05 14:19:26 -08002432 ActivityRecord r = stack.getResumedActivity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002433 if (r == null) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002434 r = stack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002435 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002436 if (r != null) {
2437 return r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 }
2439 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002440 return this;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002441 }
2442
Chong Zhang87761972016-08-22 13:53:24 -07002443 /** Checks whether the activity should be shown for current user. */
2444 public boolean okToShowLocked() {
Bryce Lee8558ec72017-08-17 15:37:26 -07002445 // We cannot show activities when the device is locked and the application is not
2446 // encryption aware.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002447 if (!StorageManager.isUserKeyUnlocked(mUserId)
Bryce Lee8558ec72017-08-17 15:37:26 -07002448 && !info.applicationInfo.isEncryptionAware()) {
2449 return false;
2450 }
2451
Chong Zhang87761972016-08-22 13:53:24 -07002452 return (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002453 || (mStackSupervisor.isCurrentProfileLocked(mUserId)
2454 && mAtmService.mAmInternal.isUserRunning(mUserId, 0 /* flags */));
Chong Zhang87761972016-08-22 13:53:24 -07002455 }
2456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 /**
2458 * This method will return true if the activity is either visible, is becoming visible, is
2459 * currently pausing, or is resumed.
2460 */
2461 public boolean isInterestingToUserLocked() {
Bryce Lee7ace3952018-02-16 14:34:32 -08002462 return visible || nowVisible || mState == PAUSING || mState == RESUMED;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002463 }
2464
Wale Ogunwale3e997362016-09-06 10:37:56 -07002465 void setSleeping(boolean _sleeping) {
2466 setSleeping(_sleeping, false);
2467 }
2468
2469 void setSleeping(boolean _sleeping, boolean force) {
2470 if (!force && sleeping == _sleeping) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002471 return;
2472 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002473 if (attachedToProcess()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002474 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002475 app.getThread().scheduleSleeping(appToken, _sleeping);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002476 if (_sleeping && !mStackSupervisor.mGoingToSleepActivities.contains(this)) {
2477 mStackSupervisor.mGoingToSleepActivities.add(this);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002478 }
2479 sleeping = _sleeping;
2480 } catch (RemoteException e) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002481 Slog.w(TAG, "Exception thrown when sleeping: " + intent.getComponent(), e);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002482 }
2483 }
2484 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08002485
Craig Mautnerd2328952013-03-05 12:46:26 -08002486 static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002487 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Craig Mautnerd2328952013-03-05 12:46:26 -08002488 if (r == null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002489 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002490 }
2491 final TaskRecord task = r.task;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002492 final int activityNdx = task.mActivities.indexOf(r);
2493 if (activityNdx < 0 || (onlyRoot && activityNdx > task.findEffectiveRootIndex())) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002494 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002495 }
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002496 return task.taskId;
Craig Mautnerd2328952013-03-05 12:46:26 -08002497 }
2498
2499 static ActivityRecord isInStackLocked(IBinder token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002500 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002501 return (r != null) ? r.getActivityStack().isInStackLocked(r) : null;
Craig Mautnerd2328952013-03-05 12:46:26 -08002502 }
2503
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002504 static ActivityStack getStackLocked(IBinder token) {
Craig Mautnerd2328952013-03-05 12:46:26 -08002505 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2506 if (r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002507 return r.getActivityStack();
Craig Mautnerd2328952013-03-05 12:46:26 -08002508 }
2509 return null;
2510 }
2511
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002512 /**
Riddle Hsufd4a0502018-10-16 01:05:16 +08002513 * @return display id to which this record is attached,
2514 * {@link android.view.Display#INVALID_DISPLAY} if not attached.
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002515 */
2516 int getDisplayId() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002517 final ActivityStack stack = getActivityStack();
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002518 if (stack == null) {
Riddle Hsufd4a0502018-10-16 01:05:16 +08002519 return INVALID_DISPLAY;
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002520 }
2521 return stack.mDisplayId;
2522 }
2523
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002524 final boolean isDestroyable() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002525 if (finishing || !hasProcess()) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002526 // This would be redundant.
2527 return false;
2528 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002529 final ActivityStack stack = getActivityStack();
Bryce Leec4ab62a2018-03-05 14:19:26 -08002530 if (stack == null || this == stack.getResumedActivity() || this == stack.mPausingActivity
Andrii Kulian02b7a832016-10-06 23:11:56 -07002531 || !haveState || !stopped) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002532 // We're not ready for this kind of thing.
2533 return false;
2534 }
2535 if (visible) {
2536 // The user would notice this!
2537 return false;
2538 }
2539 return true;
2540 }
2541
Winson Chung3bad5cc02014-08-19 17:44:32 -07002542 private static String createImageFilename(long createTime, int taskId) {
2543 return String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX + createTime +
Ruben Brunkf53497c2017-03-27 20:26:17 -07002544 IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -07002545 }
2546
Craig Mautner648f69b2014-09-18 14:16:26 -07002547 void setTaskDescription(TaskDescription _taskDescription) {
2548 Bitmap icon;
2549 if (_taskDescription.getIconFilename() == null &&
2550 (icon = _taskDescription.getIcon()) != null) {
2551 final String iconFilename = createImageFilename(createTime, task.taskId);
Winson Chungc8408b82017-01-25 17:58:56 -08002552 final File iconFile = new File(TaskPersister.getUserImagesDir(task.userId),
2553 iconFilename);
Suprabh Shukla23593142015-11-03 17:31:15 -08002554 final String iconFilePath = iconFile.getAbsolutePath();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002555 mAtmService.getRecentTasks().saveImage(icon, iconFilePath);
Suprabh Shukla23593142015-11-03 17:31:15 -08002556 _taskDescription.setIconFilename(iconFilePath);
Craig Mautner648f69b2014-09-18 14:16:26 -07002557 }
2558 taskDescription = _taskDescription;
2559 }
2560
Amith Yamasani0af6fa72016-01-17 15:36:19 -08002561 void setVoiceSessionLocked(IVoiceInteractionSession session) {
2562 voiceSession = session;
2563 pendingVoiceInteractionStart = false;
2564 }
2565
2566 void clearVoiceSessionLocked() {
2567 voiceSession = null;
2568 pendingVoiceInteractionStart = false;
2569 }
2570
Jorim Jaggi02886a82016-12-06 09:10:06 -08002571 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch) {
Jorim Jaggi42befc62017-06-13 11:54:04 -07002572 showStartingWindow(prev, newTask, taskSwitch, false /* fromRecents */);
2573 }
2574
2575 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
2576 boolean fromRecents) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002577 if (mAppWindowToken == null) {
Jorim Jaggi70176432017-01-18 12:52:13 +01002578 return;
2579 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002580 if (mTaskOverlay) {
2581 // We don't show starting window for overlay activities.
2582 return;
2583 }
Sunny Goyald85bed52018-09-25 12:01:01 -07002584 if (pendingOptions != null
2585 && pendingOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
2586 // Don't show starting window when using shared element transition.
2587 return;
2588 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002589
Wale Ogunwale3b232392016-05-13 15:37:13 -07002590 final CompatibilityInfo compatInfo =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002591 mAtmService.compatibilityInfoForPackageLocked(info.applicationInfo);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002592 final boolean shown = addStartingWindow(packageName, theme,
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002593 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
Jorim Jaggibae01b12017-04-11 16:29:10 -07002594 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
Jorim Jaggi70aa4d12017-05-15 00:05:54 +02002595 allowTaskSnapshot(),
Bryce Lee7ace3952018-02-16 14:34:32 -08002596 mState.ordinal() >= RESUMED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
Jorim Jaggi42befc62017-06-13 11:54:04 -07002597 fromRecents);
Wale Ogunwale3b232392016-05-13 15:37:13 -07002598 if (shown) {
2599 mStartingWindowState = STARTING_WINDOW_SHOWN;
2600 }
2601 }
2602
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002603 void removeOrphanedStartingWindow(boolean behindFullscreenActivity) {
Jorim Jaggicb956052017-05-09 16:27:24 +02002604 if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002605 if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
2606 mStartingWindowState = STARTING_WINDOW_REMOVED;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002607 mAppWindowToken.removeStartingWindow();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002608 }
2609 }
2610
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002611 void setRequestedOrientation(int requestedOrientation) {
Garfield Tan90b04282018-12-11 14:04:42 -08002612 setOrientation(requestedOrientation, mayFreezeScreenLocked(app));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002613 mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
Yorke Leebd54c2a2016-10-25 13:49:23 -07002614 task.taskId, requestedOrientation);
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002615 }
2616
Garfield Tan90b04282018-12-11 14:04:42 -08002617 private void setOrientation(int requestedOrientation, boolean freezeScreenIfNeeded) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002618 if (mAppWindowToken == null) {
2619 Slog.w(TAG_WM,
2620 "Attempted to set orientation of non-existing app token: " + appToken);
Garfield Tan90b04282018-12-11 14:04:42 -08002621 return;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002622 }
2623
Evan Rosky730f6e82018-12-03 17:40:11 -08002624 final IBinder binder =
2625 (freezeScreenIfNeeded && appToken != null) ? appToken.asBinder() : null;
Garfield Tan90b04282018-12-11 14:04:42 -08002626 mAppWindowToken.setOrientation(requestedOrientation, binder, this);
Garfield Tan36a69ad2019-01-16 17:08:23 -08002627
2628 // Push the new configuration to the requested app in case where it's not pushed, e.g. when
2629 // the request is handled at task level with letterbox.
2630 if (!getMergedOverrideConfiguration().equals(
2631 mLastReportedConfiguration.getMergedConfiguration())) {
2632 ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
2633 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002634 }
2635
2636 int getOrientation() {
2637 if (mAppWindowToken == null) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002638 return info.screenOrientation;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002639 }
2640
2641 return mAppWindowToken.getOrientationIgnoreVisibility();
2642 }
2643
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002644 void setDisablePreviewScreenshots(boolean disable) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002645 if (mAppWindowToken == null) {
2646 Slog.w(TAG_WM, "Attempted to set disable screenshots of non-existing app"
2647 + " token: " + appToken);
2648 return;
2649 }
2650 mAppWindowToken.setDisablePreviewScreenshots(disable);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002651 }
2652
Bryce Leea163b762017-01-24 11:05:01 -08002653 /**
2654 * Set the last reported global configuration to the client. Should be called whenever a new
2655 * global configuration is sent to the client for this activity.
2656 */
2657 void setLastReportedGlobalConfiguration(@NonNull Configuration config) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002658 mLastReportedConfiguration.setGlobalConfiguration(config);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002659 }
2660
Bryce Leea163b762017-01-24 11:05:01 -08002661 /**
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002662 * Set the last reported configuration to the client. Should be called whenever
Bryce Leea163b762017-01-24 11:05:01 -08002663 * a new merged configuration is sent to the client for this activity.
2664 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002665 void setLastReportedConfiguration(@NonNull MergedConfiguration config) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002666 setLastReportedConfiguration(config.getGlobalConfiguration(),
2667 config.getOverrideConfiguration());
Bryce Leea163b762017-01-24 11:05:01 -08002668 }
2669
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002670 private void setLastReportedConfiguration(Configuration global, Configuration override) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002671 mLastReportedConfiguration.setConfiguration(global, override);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002672 }
2673
Riddle Hsu0a343c32018-12-21 00:40:48 +08002674 /**
2675 * Get the configuration orientation by the requested screen orientation
2676 * ({@link ActivityInfo.ScreenOrientation}) of this activity.
2677 *
Tiger Huang3d2b8982019-01-29 22:56:48 +08002678 * @return orientation in ({@link Configuration#ORIENTATION_LANDSCAPE},
2679 * {@link Configuration#ORIENTATION_PORTRAIT},
2680 * {@link Configuration#ORIENTATION_UNDEFINED}).
Riddle Hsu0a343c32018-12-21 00:40:48 +08002681 */
2682 int getRequestedConfigurationOrientation() {
2683 final int screenOrientation = getOrientation();
2684 if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
2685 // NOSENSOR means the display's "natural" orientation, so return that.
2686 final ActivityDisplay display = getDisplay();
2687 if (display != null && display.mDisplayContent != null) {
2688 return display.mDisplayContent.getNaturalOrientation();
2689 }
2690 } else if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
2691 // LOCKED means the activity's orientation remains unchanged, so return existing value.
2692 return getConfiguration().orientation;
2693 } else if (isFixedOrientationLandscape(screenOrientation)) {
2694 return ORIENTATION_LANDSCAPE;
2695 } else if (isFixedOrientationPortrait(screenOrientation)) {
2696 return ORIENTATION_PORTRAIT;
2697 }
2698 return ORIENTATION_UNDEFINED;
2699 }
2700
2701 /**
2702 * Indicates the activity will keep the bounds and screen configuration when it was first
2703 * launched, no matter how its parent changes.
2704 *
2705 * @return {@code true} if this activity is declared as non-resizable and fixed orientation or
2706 * aspect ratio.
2707 */
2708 private boolean inSizeCompatMode() {
2709 return !isResizeable() && (info.isFixedOrientation() || info.hasFixedAspectRatio())
2710 // The configuration of non-standard type should be enforced by system.
2711 && isActivityTypeStandard()
2712 && !mAtmService.mForceResizableActivities;
2713 }
2714
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002715 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002716 private void updateOverrideConfiguration() {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002717 final boolean inSizeCompatMode = inSizeCompatMode();
2718 if (inSizeCompatMode) {
2719 if (!matchParentBounds()) {
2720 // The override configuration is set only once in size compatible mode.
2721 return;
2722 }
2723 if (!hasProcess() && !isConfigurationCompatible(task.getConfiguration())) {
2724 // Don't compute when launching in fullscreen and the fixed orientation is not the
2725 // current orientation. It is more accurately to compute the override bounds from
2726 // the updated configuration after the fixed orientation is applied.
2727 return;
2728 }
2729 }
2730
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002731 computeBounds(mTmpBounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08002732
Riddle Hsu0a343c32018-12-21 00:40:48 +08002733 if (inSizeCompatMode && mTmpBounds.isEmpty()) {
2734 mTmpBounds.set(task.getWindowConfiguration().getBounds());
2735 }
Evan Roskydfe3da72018-10-26 17:21:06 -07002736 if (mTmpBounds.equals(getRequestedOverrideBounds())) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002737 // The bounds is not changed or the activity is resizable (both the 2 bounds are empty).
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002738 return;
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002739 }
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002740
Riddle Hsu0a343c32018-12-21 00:40:48 +08002741 final Configuration overrideConfig = mTmpConfig;
2742 overrideConfig.unset();
2743 if (!mTmpBounds.isEmpty()) {
2744 overrideConfig.windowConfiguration.setBounds(mTmpBounds);
2745 if (inSizeCompatMode) {
2746 // Ensure the screen related fields are set. It is used to prevent activity relaunch
2747 // when moving between displays. For screenWidthDp and screenWidthDp, because they
2748 // are relative to bounds and density, they will be calculated in
2749 // {@link TaskRecord#computeConfigResourceOverrides} and the result will also be
2750 // relatively fixed.
2751 final Configuration srcConfig = task.getConfiguration();
2752 overrideConfig.colorMode = srcConfig.colorMode;
2753 overrideConfig.densityDpi = srcConfig.densityDpi;
2754 overrideConfig.screenLayout = srcConfig.screenLayout;
2755 // The smallest screen width is the short side of screen bounds. Because the bounds
2756 // and density won't be changed, smallestScreenWidthDp is also fixed.
2757 overrideConfig.smallestScreenWidthDp = srcConfig.smallestScreenWidthDp;
2758 }
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002759 }
Riddle Hsu0a343c32018-12-21 00:40:48 +08002760 onRequestedOverrideConfigurationChanged(overrideConfig);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002761 }
2762
Garfield Tan0443b372019-01-04 15:00:13 -08002763 @Override
2764 void resolveOverrideConfiguration(Configuration newParentConfiguration) {
2765 super.resolveOverrideConfiguration(newParentConfiguration);
2766
2767 // Assign configuration sequence number into hierarchy because there is a different way than
2768 // ensureActivityConfiguration() in this class that uses configuration in WindowState during
2769 // layout traversals.
2770 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
2771 getResolvedOverrideConfiguration().seq = mConfigurationSeq;
Riddle Hsu0a343c32018-12-21 00:40:48 +08002772
2773 if (matchParentBounds()) {
2774 return;
2775 }
2776
2777 final Configuration resolvedConfig = getResolvedOverrideConfiguration();
2778 if (!inSizeCompatMode()) {
2779 computeConfigResourceOverrides(resolvedConfig, newParentConfiguration,
2780 ORIENTATION_UNDEFINED, true /* insideParentBounds */);
2781 return;
2782 }
2783
2784 final Configuration displayConfig = getDisplay().getConfiguration();
2785 int orientation = getConfiguration().orientation;
2786 if (orientation != displayConfig.orientation && isConfigurationCompatible(displayConfig)) {
2787 // The activity is compatible to apply the orientation change or it requests different
2788 // fixed orientation.
2789 orientation = displayConfig.orientation;
2790 } else {
2791 if (resolvedConfig.windowConfiguration.getAppBounds() != null) {
2792 // Keep the computed resolved override configuration.
2793 return;
2794 }
2795 final int requestedOrientation = getRequestedConfigurationOrientation();
2796 if (requestedOrientation != ORIENTATION_UNDEFINED) {
2797 orientation = requestedOrientation;
2798 }
2799 }
2800
2801 // Adjust the bounds to match the current orientation.
2802 if (orientation != ORIENTATION_UNDEFINED) {
2803 final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
2804 final int longSide = Math.max(resolvedBounds.height(), resolvedBounds.width());
2805 final int shortSide = Math.min(resolvedBounds.height(), resolvedBounds.width());
2806 final boolean toBeLandscape = orientation == ORIENTATION_LANDSCAPE;
2807 final int width = toBeLandscape ? longSide : shortSide;
2808 final int height = toBeLandscape ? shortSide : longSide;
2809 // Assume the bounds is always started from zero because the size may be bigger than its
2810 // parent (task ~ display). The actual letterboxing will be done by surface offset.
2811 resolvedBounds.set(0, 0, width, height);
2812 }
2813
2814 // In size compatible mode, activity is allowed to have larger bounds than its parent.
2815 computeConfigResourceOverrides(resolvedConfig, newParentConfiguration, orientation,
2816 false /* insideParentBounds */);
2817 }
2818
2819 private void computeConfigResourceOverrides(Configuration inOutConfig,
2820 Configuration parentConfig, int orientation, boolean insideParentBounds) {
2821 // Set the real orientation or undefined value to ensure the output orientation won't be the
2822 // old value. Also reset app bounds so it will be updated according to bounds.
2823 inOutConfig.orientation = orientation;
2824 final Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
2825 if (outAppBounds != null) {
2826 outAppBounds.setEmpty();
2827 }
2828
Riddle Hsu0a343c32018-12-21 00:40:48 +08002829 task.computeConfigResourceOverrides(inOutConfig, parentConfig, insideParentBounds);
Garfield Tan0443b372019-01-04 15:00:13 -08002830 }
2831
2832 @Override
2833 public void onConfigurationChanged(Configuration newParentConfig) {
2834 super.onConfigurationChanged(newParentConfig);
2835
2836 // Configuration's equality doesn't consider seq so if only seq number changes in resolved
2837 // override configuration. Therefore ConfigurationContainer doesn't change merged override
2838 // configuration, but it's used to push configuration changes so explicitly update that.
2839 if (getMergedOverrideConfiguration().seq != getResolvedOverrideConfiguration().seq) {
2840 onMergedOverrideConfigurationChanged();
2841 }
2842
2843 // TODO(b/80414790): Remove code below after unification.
2844 // Same as above it doesn't notify configuration listeners, and consequently AppWindowToken
2845 // can't get updated seq number. However WindowState's merged override configuration needs
2846 // to have this seq number because that's also used for activity config pushes during layout
2847 // traversal. Therefore explicitly update them here.
2848 if (mAppWindowToken == null) {
2849 return;
2850 }
2851 final Configuration appWindowTokenRequestedOverrideConfig =
2852 mAppWindowToken.getRequestedOverrideConfiguration();
2853 if (appWindowTokenRequestedOverrideConfig.seq != getResolvedOverrideConfiguration().seq) {
2854 appWindowTokenRequestedOverrideConfig.seq =
2855 getResolvedOverrideConfiguration().seq;
2856 mAppWindowToken.onMergedOverrideConfigurationChanged();
2857 }
2858 }
2859
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07002860 /** Returns true if the configuration is compatible with this activity. */
Wale Ogunwale42f07d92017-05-01 21:32:58 -07002861 boolean isConfigurationCompatible(Configuration config) {
Riddle Hsu0a343c32018-12-21 00:40:48 +08002862 final int orientation = getOrientation();
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07002863 if (isFixedOrientationPortrait(orientation)
2864 && config.orientation != ORIENTATION_PORTRAIT) {
2865 return false;
2866 }
2867 if (isFixedOrientationLandscape(orientation)
2868 && config.orientation != ORIENTATION_LANDSCAPE) {
2869 return false;
2870 }
2871 return true;
2872 }
2873
Bryce Lee7566d762017-03-30 09:34:15 -07002874 /**
2875 * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}.
2876 */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002877 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
2878 private void computeBounds(Rect outBounds) {
2879 outBounds.setEmpty();
2880 final float maxAspectRatio = info.maxAspectRatio;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002881 final ActivityStack stack = getActivityStack();
Adrian Roos917791e2018-11-28 16:30:44 +01002882 final float minAspectRatio = info.minAspectRatio;
2883
2884 if (task == null || stack == null || task.inMultiWindowMode()
2885 || (maxAspectRatio == 0 && minAspectRatio == 0)
Bryce Leee5ab4502017-07-11 08:58:05 -07002886 || isInVrUiMode(getConfiguration())) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002887 // We don't set override configuration if that activity task isn't fullscreen. I.e. the
2888 // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
Bryce Leee5ab4502017-07-11 08:58:05 -07002889 // the activity. This is indicated by an empty {@link outBounds}. We also don't set it
2890 // if we are in VR mode.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002891 return;
2892 }
2893
Bryce Lee7566d762017-03-30 09:34:15 -07002894 // We must base this on the parent configuration, because we set our override
2895 // configuration's appBounds based on the result of this method. If we used our own
2896 // configuration, it would be influenced by past invocations.
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002897 final Rect appBounds = getParent().getWindowConfiguration().getAppBounds();
Wale Ogunwale822e5122017-07-26 06:02:24 -07002898 final int containingAppWidth = appBounds.width();
2899 final int containingAppHeight = appBounds.height();
Adrian Roos917791e2018-11-28 16:30:44 +01002900 final float containingRatio = Math.max(containingAppWidth, containingAppHeight)
2901 / (float) Math.min(containingAppWidth, containingAppHeight);
Bryce Lee7566d762017-03-30 09:34:15 -07002902
Adrian Roos917791e2018-11-28 16:30:44 +01002903 int activityWidth = containingAppWidth;
2904 int activityHeight = containingAppHeight;
2905
2906 if (containingRatio > maxAspectRatio && maxAspectRatio != 0) {
2907 if (containingAppWidth < containingAppHeight) {
2908 // Width is the shorter side, so we use that to figure-out what the max. height
2909 // should be given the aspect ratio.
2910 activityHeight = (int) ((activityWidth * maxAspectRatio) + 0.5f);
2911 } else {
2912 // Height is the shorter side, so we use that to figure-out what the max. width
2913 // should be given the aspect ratio.
2914 activityWidth = (int) ((activityHeight * maxAspectRatio) + 0.5f);
2915 }
Tiger Huang3d2b8982019-01-29 22:56:48 +08002916 } else if (containingRatio < minAspectRatio) {
2917 boolean adjustWidth;
2918 switch (getRequestedConfigurationOrientation()) {
2919 case ORIENTATION_LANDSCAPE:
2920 // Width should be the longer side for this landscape app, so we use the width
2921 // to figure-out what the max. height should be given the aspect ratio.
2922 adjustWidth = false;
2923 break;
2924 case ORIENTATION_PORTRAIT:
2925 // Height should be the longer side for this portrait app, so we use the height
2926 // to figure-out what the max. width should be given the aspect ratio.
2927 adjustWidth = true;
2928 break;
2929 default:
2930 // This app doesn't have a preferred orientation, so we keep the length of the
2931 // longer side, and use it to figure-out the length of the shorter side.
2932 if (containingAppWidth < containingAppHeight) {
2933 // Width is the shorter side, so we use the height to figure-out what the
2934 // max. width should be given the aspect ratio.
2935 adjustWidth = true;
2936 } else {
2937 // Height is the shorter side, so we use the width to figure-out what the
2938 // max. height should be given the aspect ratio.
2939 adjustWidth = false;
2940 }
2941 break;
2942 }
2943 if (adjustWidth) {
Adrian Roos917791e2018-11-28 16:30:44 +01002944 activityWidth = (int) ((activityHeight / minAspectRatio) + 0.5f);
2945 } else {
Adrian Roos917791e2018-11-28 16:30:44 +01002946 activityHeight = (int) ((activityWidth / minAspectRatio) + 0.5f);
2947 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002948 }
2949
Adrian Roos917791e2018-11-28 16:30:44 +01002950 if (containingAppWidth <= activityWidth && containingAppHeight <= activityHeight) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002951 // The display matches or is less than the activity aspect ratio, so nothing else to do.
Bryce Lee7566d762017-03-30 09:34:15 -07002952 // Return the existing bounds. If this method is running for the first time,
Evan Roskydfe3da72018-10-26 17:21:06 -07002953 // {@link #getRequestedOverrideBounds()} will be empty (representing no override). If
2954 // the method has run before, then effect of {@link #getRequestedOverrideBounds()} will
2955 // already have been applied to the value returned from {@link getConfiguration}. Refer
2956 // to {@link TaskRecord#computeOverrideConfiguration}.
2957 outBounds.set(getRequestedOverrideBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002958 return;
2959 }
2960
2961 // Compute configuration based on max supported width and height.
Adrian Roos24be34d2018-05-28 18:55:38 +02002962 // Also account for the left / top insets (e.g. from display cutouts), which will be clipped
2963 // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app
2964 // bounds would end up too small.
Adrian Roos917791e2018-11-28 16:30:44 +01002965 outBounds.set(0, 0, activityWidth + appBounds.left, activityHeight + appBounds.top);
Andrii Kulian3a1619d2017-07-07 14:38:09 -07002966 }
2967
Riddle Hsu16567132018-08-16 21:37:47 +08002968 /**
2969 * @return {@code true} if this activity was reparented to another display but
2970 * {@link #ensureActivityConfiguration} is not called.
2971 */
2972 boolean shouldUpdateConfigForDisplayChanged() {
2973 return mLastReportedDisplayId != getDisplayId();
2974 }
2975
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002976 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
2977 return ensureActivityConfiguration(globalChanges, preserveWindow,
2978 false /* ignoreStopState */);
2979 }
2980
Andrii Kulian21713ac2016-10-12 22:05:05 -07002981 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002982 * Make sure the given activity matches the current configuration. Ensures the HistoryRecord
2983 * is updated with the correct configuration and all other bookkeeping is handled.
2984 *
2985 * @param globalChanges The changes to the global configuration.
2986 * @param preserveWindow If the activity window should be preserved on screen if the activity
2987 * is relaunched.
2988 * @param ignoreStopState If we should try to relaunch the activity even if it is in the stopped
2989 * state. This is useful for the case where we know the activity will be
2990 * visible soon and we want to ensure its configuration before we make it
2991 * visible.
2992 * @return True if the activity was relaunched and false if it wasn't relaunched because we
2993 * can't or the app handles the specific configuration that is changing.
Andrii Kulian21713ac2016-10-12 22:05:05 -07002994 */
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002995 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
2996 boolean ignoreStopState) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002997 final ActivityStack stack = getActivityStack();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002998 if (stack.mConfigWillChange) {
2999 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3000 "Skipping config check (will change): " + this);
3001 return true;
3002 }
3003
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003004 // We don't worry about activities that are finishing.
3005 if (finishing) {
3006 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3007 "Configuration doesn't matter in finishing " + this);
3008 stopFreezingScreenLocked(false);
3009 return true;
3010 }
3011
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08003012 if (!ignoreStopState && (mState == STOPPING || mState == STOPPED)) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07003013 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3014 "Skipping config check stopped or stopping: " + this);
3015 return true;
3016 }
3017
Garfield Tan47e576c2019-01-28 10:26:23 -08003018 if (!shouldBeVisible()) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07003019 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3020 "Skipping config check invisible stack: " + this);
3021 return true;
3022 }
3023
Andrii Kulian21713ac2016-10-12 22:05:05 -07003024 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3025 "Ensuring correct configuration: " + this);
3026
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003027 final int newDisplayId = getDisplayId();
3028 final boolean displayChanged = mLastReportedDisplayId != newDisplayId;
3029 if (displayChanged) {
3030 mLastReportedDisplayId = newDisplayId;
3031 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003032 // TODO(b/36505427): Is there a better place to do this?
3033 updateOverrideConfiguration();
3034
Winson Chungbdc646f2017-02-13 12:12:22 -08003035 // Short circuit: if the two full configurations are equal (the common case), then there is
3036 // nothing to do. We test the full configuration instead of the global and merged override
3037 // configurations because there are cases (like moving a task to the pinned stack) where
3038 // the combine configurations are equal, but would otherwise differ in the override config
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003039 mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
3040 if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003041 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003042 "Configuration & display unchanged in " + this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003043 return true;
3044 }
3045
3046 // Okay we now are going to make this activity have the new config.
3047 // But then we need to figure out how it needs to deal with that.
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003048
3049 // Find changes between last reported merged configuration and the current one. This is used
3050 // to decide whether to relaunch an activity or just report a configuration change.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003051 final int changes = getConfigurationChanges(mTmpConfig);
Ruben Brunkf64af332017-03-22 22:03:25 -07003052
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003053 // Update last reported values.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003054 final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
Bryce Lee8104e7a2017-08-17 09:16:03 -07003055
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003056 setLastReportedConfiguration(mAtmService.getGlobalConfiguration(), newMergedOverrideConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003057
Bryce Lee7ace3952018-02-16 14:34:32 -08003058 if (mState == INITIALIZING) {
Andrii Kulianb372da62018-01-18 10:46:24 -08003059 // No need to relaunch or schedule new config for activity that hasn't been launched
3060 // yet. We do, however, return after applying the config to activity record, so that
3061 // it will use it for launch transaction.
3062 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3063 "Skipping config check for initializing activity: " + this);
3064 return true;
3065 }
3066
Andrii Kulian21713ac2016-10-12 22:05:05 -07003067 if (changes == 0 && !forceNewConfig) {
3068 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3069 "Configuration no differences in " + this);
3070 // There are no significant differences, so we won't relaunch but should still deliver
3071 // the new configuration to the client process.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003072 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003073 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003074 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003075 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003076 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07003077 return true;
3078 }
3079
3080 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003081 "Configuration changes for " + this + ", allChanges="
Andrii Kulian21713ac2016-10-12 22:05:05 -07003082 + Configuration.configurationDiffToString(changes));
3083
3084 // If the activity isn't currently running, just leave the new configuration and it will
3085 // pick that up next time it starts.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003086 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003087 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3088 "Configuration doesn't matter not running " + this);
3089 stopFreezingScreenLocked(false);
3090 forceNewConfig = false;
3091 return true;
3092 }
3093
3094 // Figure out how to handle the changes between the configurations.
3095 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3096 "Checking to restart " + info.name + ": changed=0x"
3097 + Integer.toHexString(changes) + ", handles=0x"
3098 + Integer.toHexString(info.getRealConfigChanged())
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003099 + ", mLastReportedConfiguration=" + mLastReportedConfiguration);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003100
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07003101 if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003102 // Aha, the activity isn't handling the change, so DIE DIE DIE.
3103 configChangeFlags |= changes;
3104 startFreezingScreenLocked(app, globalChanges);
3105 forceNewConfig = false;
3106 preserveWindow &= isResizeOnlyChange(changes);
Garfield Tan2746ab52018-07-25 12:33:01 -07003107 final boolean hasResizeChange = hasResizeChange(changes & ~info.getRealConfigChanged());
3108 if (hasResizeChange) {
3109 final boolean isDragResizing =
Yunfan Chen0e7aff92018-12-05 16:35:32 -08003110 getTaskRecord().getTask().isDragResizing();
Garfield Tan2746ab52018-07-25 12:33:01 -07003111 mRelaunchReason = isDragResizing ? RELAUNCH_REASON_FREE_RESIZE
3112 : RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
3113 } else {
3114 mRelaunchReason = RELAUNCH_REASON_NONE;
3115 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003116 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003117 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3118 "Config is destroying non-running " + this);
3119 stack.destroyActivityLocked(this, true, "config");
Bryce Lee7ace3952018-02-16 14:34:32 -08003120 } else if (mState == PAUSING) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003121 // A little annoying: we are waiting for this activity to finish pausing. Let's not
3122 // do anything now, but just flag that it needs to be restarted when done pausing.
3123 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3124 "Config is skipping already pausing " + this);
3125 deferRelaunchUntilPaused = true;
3126 preserveWindowOnDeferredRelaunch = preserveWindow;
3127 return true;
Bryce Lee7ace3952018-02-16 14:34:32 -08003128 } else if (mState == RESUMED) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003129 // Try to optimize this case: the configuration is changing and we need to restart
3130 // the top, resumed activity. Instead of doing the normal handshaking, just say
3131 // "restart!".
3132 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3133 "Config is relaunching resumed " + this);
3134
3135 if (DEBUG_STATES && !visible) {
3136 Slog.v(TAG_STATES, "Config is relaunching resumed invisible activity " + this
3137 + " called by " + Debug.getCallers(4));
3138 }
3139
3140 relaunchActivityLocked(true /* andResume */, preserveWindow);
3141 } else {
3142 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3143 "Config is relaunching non-resumed " + this);
3144 relaunchActivityLocked(false /* andResume */, preserveWindow);
3145 }
3146
3147 // All done... tell the caller we weren't able to keep this activity around.
3148 return false;
3149 }
3150
3151 // Default case: the activity can handle this new configuration, so hand it over.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003152 // NOTE: We only forward the override configuration as the system level configuration
Andrii Kulian21713ac2016-10-12 22:05:05 -07003153 // changes is always sent to all processes when they happen so it can just use whatever
3154 // system level configuration it last got.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003155 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003156 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003157 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003158 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08003159 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07003160 stopFreezingScreenLocked(false);
3161
3162 return true;
3163 }
3164
Zak Cohen90e7116742017-01-29 12:59:23 -08003165 /**
3166 * When assessing a configuration change, decide if the changes flags and the new configurations
3167 * should cause the Activity to relaunch.
Ruben Brunkf64af332017-03-22 22:03:25 -07003168 *
3169 * @param changes the changes due to the given configuration.
3170 * @param changesConfig the configuration that was used to calculate the given changes via a
3171 * call to getConfigurationChanges.
Zak Cohen90e7116742017-01-29 12:59:23 -08003172 */
Ruben Brunkf64af332017-03-22 22:03:25 -07003173 private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
Zak Cohen90e7116742017-01-29 12:59:23 -08003174 int configChanged = info.getRealConfigChanged();
Ruben Brunkf64af332017-03-22 22:03:25 -07003175 boolean onlyVrUiModeChanged = onlyVrUiModeChanged(changes, changesConfig);
Zak Cohen90e7116742017-01-29 12:59:23 -08003176
3177 // Override for apps targeting pre-O sdks
3178 // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
3179 // to the config change.
3180 // For O and later, apps will be required to add configChanges="uimode" to their manifest.
3181 if (appInfo.targetSdkVersion < O
3182 && requestedVrComponent != null
Ruben Brunkf64af332017-03-22 22:03:25 -07003183 && onlyVrUiModeChanged) {
Zak Cohen90e7116742017-01-29 12:59:23 -08003184 configChanged |= CONFIG_UI_MODE;
3185 }
3186
3187 return (changes&(~configChanged)) != 0;
3188 }
3189
Ruben Brunkf64af332017-03-22 22:03:25 -07003190 /**
3191 * Returns true if the configuration change is solely due to the UI mode switching into or out
3192 * of UI_MODE_TYPE_VR_HEADSET.
3193 */
3194 private boolean onlyVrUiModeChanged(int changes, Configuration lastReportedConfig) {
3195 final Configuration currentConfig = getConfiguration();
Ruben Brunkf53497c2017-03-27 20:26:17 -07003196 return changes == CONFIG_UI_MODE && (isInVrUiMode(currentConfig)
Ruben Brunkf64af332017-03-22 22:03:25 -07003197 != isInVrUiMode(lastReportedConfig));
3198 }
3199
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003200 private int getConfigurationChanges(Configuration lastReportedConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003201 // Determine what has changed. May be nothing, if this is a config that has come back from
3202 // the app after going idle. In that case we just want to leave the official config object
3203 // now in the activity and do nothing else.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003204 final Configuration currentConfig = getConfiguration();
3205 int changes = lastReportedConfig.diff(currentConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003206 // We don't want to use size changes if they don't cross boundaries that are important to
3207 // the app.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003208 if ((changes & CONFIG_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003209 final boolean crosses = crossesHorizontalSizeThreshold(lastReportedConfig.screenWidthDp,
3210 currentConfig.screenWidthDp)
3211 || crossesVerticalSizeThreshold(lastReportedConfig.screenHeightDp,
3212 currentConfig.screenHeightDp);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003213 if (!crosses) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003214 changes &= ~CONFIG_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003215 }
3216 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003217 if ((changes & CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003218 final int oldSmallest = lastReportedConfig.smallestScreenWidthDp;
3219 final int newSmallest = currentConfig.smallestScreenWidthDp;
3220 if (!crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003221 changes &= ~CONFIG_SMALLEST_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003222 }
3223 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07003224 // We don't want window configuration to cause relaunches.
3225 if ((changes & CONFIG_WINDOW_CONFIGURATION) != 0) {
3226 changes &= ~CONFIG_WINDOW_CONFIGURATION;
3227 }
Bryce Lee600dadd2017-07-25 10:48:42 -07003228
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003229 return changes;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003230 }
3231
3232 private static boolean isResizeOnlyChange(int change) {
3233 return (change & ~(CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
3234 | CONFIG_SCREEN_LAYOUT)) == 0;
3235 }
3236
Garfield Tan2746ab52018-07-25 12:33:01 -07003237 private static boolean hasResizeChange(int change) {
3238 return (change & (CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
3239 | CONFIG_SCREEN_LAYOUT)) != 0;
3240 }
3241
Andrii Kulian21713ac2016-10-12 22:05:05 -07003242 void relaunchActivityLocked(boolean andResume, boolean preserveWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003243 if (mAtmService.mSuppressResizeConfigChanges && preserveWindow) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003244 configChangeFlags = 0;
3245 return;
3246 }
3247
3248 List<ResultInfo> pendingResults = null;
3249 List<ReferrerIntent> pendingNewIntents = null;
3250 if (andResume) {
3251 pendingResults = results;
3252 pendingNewIntents = newIntents;
3253 }
3254 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
3255 "Relaunching: " + this + " with results=" + pendingResults
3256 + " newIntents=" + pendingNewIntents + " andResume=" + andResume
3257 + " preserveWindow=" + preserveWindow);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003258 EventLog.writeEvent(andResume ? AM_RELAUNCH_RESUME_ACTIVITY
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003259 : AM_RELAUNCH_ACTIVITY, mUserId, System.identityHashCode(this),
Andrii Kulian21713ac2016-10-12 22:05:05 -07003260 task.taskId, shortComponentName);
3261
3262 startFreezingScreenLocked(app, 0);
3263
Andrii Kulian21713ac2016-10-12 22:05:05 -07003264 try {
3265 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
3266 "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this
3267 + " callers=" + Debug.getCallers(6));
3268 forceNewConfig = false;
3269 mStackSupervisor.activityRelaunchingLocked(this);
Andrii Kulianb372da62018-01-18 10:46:24 -08003270 final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
3271 pendingNewIntents, configChangeFlags,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003272 new MergedConfiguration(mAtmService.getGlobalConfiguration(),
Andrii Kulianb372da62018-01-18 10:46:24 -08003273 getMergedOverrideConfiguration()),
3274 preserveWindow);
3275 final ActivityLifecycleItem lifecycleItem;
3276 if (andResume) {
lumark588a3e82018-07-20 18:53:54 +08003277 lifecycleItem = ResumeActivityItem.obtain(
Wale Ogunwale3a256e62018-12-06 14:41:18 -08003278 getDisplay().mDisplayContent.isNextTransitionForward());
Andrii Kulianb372da62018-01-18 10:46:24 -08003279 } else {
Bryce Lee1d0d5142018-04-12 10:35:07 -07003280 lifecycleItem = PauseActivityItem.obtain();
Andrii Kulianb372da62018-01-18 10:46:24 -08003281 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003282 final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), appToken);
Andrii Kulianb372da62018-01-18 10:46:24 -08003283 transaction.addCallback(callbackItem);
3284 transaction.setLifecycleStateRequest(lifecycleItem);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003285 mAtmService.getLifecycleManager().scheduleTransaction(transaction);
Andrii Kuliand70cdb92019-01-08 15:03:50 -08003286 mRootActivityContainer.updateTopResumedActivityIfNeeded();
Andrii Kulian21713ac2016-10-12 22:05:05 -07003287 // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
Andrii Kulianb372da62018-01-18 10:46:24 -08003288 // request resume if this activity is currently resumed, which implies we aren't
Andrii Kulian21713ac2016-10-12 22:05:05 -07003289 // sleeping.
3290 } catch (RemoteException e) {
3291 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
3292 }
3293
3294 if (andResume) {
3295 if (DEBUG_STATES) {
3296 Slog.d(TAG_STATES, "Resumed after relaunch " + this);
3297 }
3298 results = null;
3299 newIntents = null;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003300 mAtmService.getAppWarningsLocked().onResumeActivity(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003301 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003302 final ActivityStack stack = getActivityStack();
Wale Ogunwale008163e2018-07-23 23:11:08 -07003303 if (stack != null) {
3304 stack.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
3305 }
Bryce Lee7ace3952018-02-16 14:34:32 -08003306 setState(PAUSED, "relaunchActivityLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07003307 }
3308
3309 configChangeFlags = 0;
3310 deferRelaunchUntilPaused = false;
3311 preserveWindowOnDeferredRelaunch = false;
3312 }
3313
Jorim Jaggibae01b12017-04-11 16:29:10 -07003314 private boolean isProcessRunning() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003315 WindowProcessController proc = app;
Jorim Jaggi02886a82016-12-06 09:10:06 -08003316 if (proc == null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003317 proc = mAtmService.mProcessNames.get(processName, info.applicationInfo.uid);
Jorim Jaggi02886a82016-12-06 09:10:06 -08003318 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003319 return proc != null && proc.hasThread();
Jorim Jaggi02886a82016-12-06 09:10:06 -08003320 }
3321
Jorim Jaggibae01b12017-04-11 16:29:10 -07003322 /**
3323 * @return Whether a task snapshot starting window may be shown.
3324 */
3325 private boolean allowTaskSnapshot() {
3326 if (newIntents == null) {
3327 return true;
3328 }
3329
3330 // Restrict task snapshot starting window to launcher start, or there is no intent at all
3331 // (eg. task being brought to front). If the intent is something else, likely the app is
3332 // going to show some specific page or view, instead of what's left last time.
3333 for (int i = newIntents.size() - 1; i >= 0; i--) {
3334 final Intent intent = newIntents.get(i);
3335 if (intent != null && !ActivityRecord.isMainIntent(intent)) {
3336 return false;
3337 }
3338 }
3339 return true;
3340 }
3341
Bryce Leeb7c9b802017-05-02 14:20:24 -07003342 /**
3343 * Returns {@code true} if the associated activity has the no history flag set on it.
3344 * {@code false} otherwise.
3345 */
3346 boolean isNoHistory() {
3347 return (intent.getFlags() & FLAG_ACTIVITY_NO_HISTORY) != 0
3348 || (info.flags & FLAG_NO_HISTORY) != 0;
3349 }
3350
Craig Mautner21d24a22014-04-23 11:45:37 -07003351 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
3352 out.attribute(null, ATTR_ID, String.valueOf(createTime));
3353 out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
3354 if (launchedFromPackage != null) {
3355 out.attribute(null, ATTR_LAUNCHEDFROMPACKAGE, launchedFromPackage);
3356 }
3357 if (resolvedType != null) {
3358 out.attribute(null, ATTR_RESOLVEDTYPE, resolvedType);
3359 }
3360 out.attribute(null, ATTR_COMPONENTSPECIFIED, String.valueOf(componentSpecified));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003361 out.attribute(null, ATTR_USERID, String.valueOf(mUserId));
Winson Chung2cb86c72014-06-25 12:03:30 -07003362
Craig Mautner21d24a22014-04-23 11:45:37 -07003363 if (taskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003364 taskDescription.saveToXml(out);
Craig Mautner21d24a22014-04-23 11:45:37 -07003365 }
3366
3367 out.startTag(null, TAG_INTENT);
3368 intent.saveToXml(out);
3369 out.endTag(null, TAG_INTENT);
3370
3371 if (isPersistable() && persistentState != null) {
3372 out.startTag(null, TAG_PERSISTABLEBUNDLE);
3373 persistentState.saveToXml(out);
3374 out.endTag(null, TAG_PERSISTABLEBUNDLE);
3375 }
3376 }
3377
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07003378 static ActivityRecord restoreFromXml(XmlPullParser in,
3379 ActivityStackSupervisor stackSupervisor) throws IOException, XmlPullParserException {
Craig Mautner21d24a22014-04-23 11:45:37 -07003380 Intent intent = null;
3381 PersistableBundle persistentState = null;
3382 int launchedFromUid = 0;
3383 String launchedFromPackage = null;
3384 String resolvedType = null;
3385 boolean componentSpecified = false;
3386 int userId = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07003387 long createTime = -1;
3388 final int outerDepth = in.getDepth();
Winson Chung2cb86c72014-06-25 12:03:30 -07003389 TaskDescription taskDescription = new TaskDescription();
Craig Mautner21d24a22014-04-23 11:45:37 -07003390
3391 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
3392 final String attrName = in.getAttributeName(attrNdx);
3393 final String attrValue = in.getAttributeValue(attrNdx);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003394 if (DEBUG) Slog.d(TaskPersister.TAG,
Wale Ogunwale18795a22014-12-03 11:38:33 -08003395 "ActivityRecord: attribute name=" + attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003396 if (ATTR_ID.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01003397 createTime = Long.parseLong(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003398 } else if (ATTR_LAUNCHEDFROMUID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003399 launchedFromUid = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003400 } else if (ATTR_LAUNCHEDFROMPACKAGE.equals(attrName)) {
3401 launchedFromPackage = attrValue;
3402 } else if (ATTR_RESOLVEDTYPE.equals(attrName)) {
3403 resolvedType = attrValue;
3404 } else if (ATTR_COMPONENTSPECIFIED.equals(attrName)) {
Tobias Thiererb0800dc2016-04-21 17:51:41 +01003405 componentSpecified = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003406 } else if (ATTR_USERID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003407 userId = Integer.parseInt(attrValue);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003408 } else if (attrName.startsWith(ATTR_TASKDESCRIPTION_PREFIX)) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003409 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003410 } else {
3411 Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
3412 }
3413 }
3414
3415 int event;
Ruben Brunkf53497c2017-03-27 20:26:17 -07003416 while (((event = in.next()) != END_DOCUMENT) &&
3417 (event != END_TAG || in.getDepth() >= outerDepth)) {
3418 if (event == START_TAG) {
Craig Mautner21d24a22014-04-23 11:45:37 -07003419 final String name = in.getName();
Ruben Brunkf53497c2017-03-27 20:26:17 -07003420 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003421 Slog.d(TaskPersister.TAG, "ActivityRecord: START_TAG name=" + name);
Craig Mautner21d24a22014-04-23 11:45:37 -07003422 if (TAG_INTENT.equals(name)) {
3423 intent = Intent.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003424 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003425 Slog.d(TaskPersister.TAG, "ActivityRecord: intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003426 } else if (TAG_PERSISTABLEBUNDLE.equals(name)) {
3427 persistentState = PersistableBundle.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003428 if (DEBUG) Slog.d(TaskPersister.TAG,
Craig Mautner21d24a22014-04-23 11:45:37 -07003429 "ActivityRecord: persistentState=" + persistentState);
3430 } else {
3431 Slog.w(TAG, "restoreActivity: unexpected name=" + name);
3432 XmlUtils.skipCurrentTag(in);
3433 }
3434 }
3435 }
3436
3437 if (intent == null) {
Craig Mautnere0129b32014-05-25 16:41:09 -07003438 throw new XmlPullParserException("restoreActivity error intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003439 }
3440
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003441 final ActivityTaskManagerService service = stackSupervisor.mService;
Craig Mautner21d24a22014-04-23 11:45:37 -07003442 final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null,
Patrick Baumann78380272018-04-04 10:41:01 -07003443 userId, Binder.getCallingUid());
Craig Mautnere0129b32014-05-25 16:41:09 -07003444 if (aInfo == null) {
Craig Mautner77b04262014-06-27 15:22:12 -07003445 throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
3446 " resolvedType=" + resolvedType);
Craig Mautnere0129b32014-05-25 16:41:09 -07003447 }
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003448 final ActivityRecord r = new ActivityRecord(service, null /* caller */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003449 0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType,
Wale Ogunwalef6733932018-06-27 05:14:34 -07003450 aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003451 0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07003452 stackSupervisor, null /* options */, null /* sourceRecord */);
Craig Mautner21d24a22014-04-23 11:45:37 -07003453
3454 r.persistentState = persistentState;
Winson Chung2cb86c72014-06-25 12:03:30 -07003455 r.taskDescription = taskDescription;
Craig Mautner21d24a22014-04-23 11:45:37 -07003456 r.createTime = createTime;
3457
3458 return r;
3459 }
3460
Zak Cohen90e7116742017-01-29 12:59:23 -08003461 private static boolean isInVrUiMode(Configuration config) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07003462 return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
Zak Cohen90e7116742017-01-29 12:59:23 -08003463 }
3464
David Stevens82ea6cb2017-03-03 16:18:50 -08003465 int getUid() {
3466 return info.applicationInfo.uid;
3467 }
3468
chaviw59b98852017-06-13 12:05:44 -07003469 void setShowWhenLocked(boolean showWhenLocked) {
3470 mShowWhenLocked = showWhenLocked;
Wale Ogunwaled32da472018-11-16 07:19:28 -08003471 mRootActivityContainer.ensureActivitiesVisible(null, 0 /* configChanges */,
Kevin Chyn44639482017-10-09 18:34:41 -07003472 false /* preserveWindows */);
chaviw59b98852017-06-13 12:05:44 -07003473 }
3474
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003475 void setInheritShowWhenLocked(boolean inheritShowWhenLocked) {
3476 mInheritShownWhenLocked = inheritShowWhenLocked;
3477 mRootActivityContainer.ensureActivitiesVisible(null, 0, false);
3478 }
3479
chaviw59b98852017-06-13 12:05:44 -07003480 /**
chaviw2c500982018-01-04 17:05:05 -08003481 * @return true if the activity windowing mode is not
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003482 * {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and a) activity
3483 * contains windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the
3484 * activity has set {@link #mShowWhenLocked}, or b) if the activity has set
3485 * {@link #mInheritShownWhenLocked} and the activity behind this satisfies the
3486 * conditions a) above.
chaviw2c500982018-01-04 17:05:05 -08003487 * Multi-windowing mode will be exited if true is returned.
chaviw59b98852017-06-13 12:05:44 -07003488 */
3489 boolean canShowWhenLocked() {
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003490 if (!inPinnedWindowingMode() && (mShowWhenLocked
3491 || (mAppWindowToken != null && mAppWindowToken.containsShowWhenLockedWindow()))) {
3492 return true;
3493 } else if (mInheritShownWhenLocked) {
3494 ActivityRecord r = getActivityBelow();
3495 return r != null && !r.inPinnedWindowingMode() && (r.mShowWhenLocked
3496 || (r.mAppWindowToken != null
3497 && r.mAppWindowToken.containsShowWhenLockedWindow()));
3498 } else {
3499 return false;
3500 }
3501 }
3502
3503 /**
3504 * @return an {@link ActivityRecord} of the activity below this activity, or {@code null} if no
3505 * such activity exists.
3506 */
3507 @Nullable
3508 private ActivityRecord getActivityBelow() {
3509 final int pos = task.mActivities.indexOf(this);
3510 if (pos == -1) {
3511 throw new IllegalStateException("Activity not found in its task");
3512 }
3513 return pos == 0 ? null : task.getChildAt(pos - 1);
chaviw59b98852017-06-13 12:05:44 -07003514 }
3515
3516 void setTurnScreenOn(boolean turnScreenOn) {
3517 mTurnScreenOn = turnScreenOn;
3518 }
3519
3520 /**
3521 * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
3522 * {@link #mTurnScreenOn} is set and checks whether the ActivityRecord should be visible
3523 * depending on Keyguard state
3524 *
3525 * @return true if the screen can be turned on, false otherwise.
3526 */
3527 boolean canTurnScreenOn() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003528 final ActivityStack stack = getActivityStack();
chaviw59b98852017-06-13 12:05:44 -07003529 return mTurnScreenOn && stack != null &&
3530 stack.checkKeyguardVisibility(this, true /* shouldBeVisible */, true /* isTop */);
3531 }
3532
Louis Chang77ce34d2019-01-03 15:45:12 +08003533 /**
3534 * Check if this activity is able to resume. For pre-Q apps, only the topmost activities of each
3535 * process are allowed to be resumed.
3536 *
3537 * @return true if this activity can be resumed.
3538 */
3539 boolean canResumeByCompat() {
3540 return app == null || app.updateTopResumingActivityInProcessIfNeeded(this);
3541 }
3542
chaviw59b98852017-06-13 12:05:44 -07003543 boolean getTurnScreenOnFlag() {
3544 return mTurnScreenOn;
3545 }
3546
3547 boolean isTopRunningActivity() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003548 return mRootActivityContainer.topRunningActivity() == this;
chaviw59b98852017-06-13 12:05:44 -07003549 }
3550
Andrii Kulian52d255c2018-07-13 11:32:19 -07003551 /**
3552 * @return {@code true} if this is the resumed activity on its current display, {@code false}
3553 * otherwise.
3554 */
3555 boolean isResumedActivityOnDisplay() {
3556 final ActivityDisplay display = getDisplay();
3557 return display != null && this == display.getResumedActivity();
3558 }
3559
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003560 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003561 if (mAppWindowToken == null) {
3562 Slog.w(TAG_WM, "Attempted to register remote animations with non-existing app"
3563 + " token: " + appToken);
3564 return;
3565 }
3566 mAppWindowToken.registerRemoteAnimations(definition);
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003567 }
3568
Craig Mautnerf81b90872013-02-26 13:02:43 -08003569 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003570 public String toString() {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003571 if (stringName != null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08003572 return stringName + " t" + (task == null ? INVALID_TASK_ID : task.taskId) +
Craig Mautnerf3333272013-04-22 10:55:53 -07003573 (finishing ? " f}" : "}");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003574 }
3575 StringBuilder sb = new StringBuilder(128);
Dianne Hackborn30d71892010-12-11 10:37:55 -08003576 sb.append("ActivityRecord{");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003577 sb.append(Integer.toHexString(System.identityHashCode(this)));
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003578 sb.append(" u");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003579 sb.append(mUserId);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003580 sb.append(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003581 sb.append(intent.getComponent().flattenToShortString());
Craig Mautnerf81b90872013-02-26 13:02:43 -08003582 stringName = sb.toString();
3583 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003584 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07003585
3586 void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
3587 final long token = proto.start(fieldId);
3588 proto.write(HASH_CODE, System.identityHashCode(this));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003589 proto.write(USER_ID, mUserId);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003590 proto.write(TITLE, intent.getComponent().flattenToShortString());
3591 proto.end(token);
3592 }
3593
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003594 /**
3595 * Write all fields to an {@code ActivityRecordProto}. This assumes the
3596 * {@code ActivityRecordProto} is the outer-most proto data.
3597 */
3598 void writeToProto(ProtoOutputStream proto) {
Nataniel Borges023ecb52019-01-16 14:15:43 -08003599 super.writeToProto(proto, CONFIGURATION_CONTAINER, WindowTraceLogLevel.ALL);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003600 writeIdentifierToProto(proto, IDENTIFIER);
Bryce Lee7ace3952018-02-16 14:34:32 -08003601 proto.write(STATE, mState.toString());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003602 proto.write(VISIBLE, visible);
3603 proto.write(FRONT_OF_TASK, frontOfTask);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003604 if (hasProcess()) {
3605 proto.write(PROC_ID, app.getPid());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003606 }
Wale Ogunwale30eab1f2018-05-24 18:25:25 -07003607 proto.write(TRANSLUCENT, !fullscreen);
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003608 }
3609
3610 public void writeToProto(ProtoOutputStream proto, long fieldId) {
3611 final long token = proto.start(fieldId);
3612 writeToProto(proto);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003613 proto.end(token);
3614 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615}