blob: 5da30d9fbda6df6364f9dbd6754e49056078c2f0 [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;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080045import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
Bryce Leeb7c9b802017-05-02 14:20:24 -070046import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY;
Andrii Kulian21713ac2016-10-12 22:05:05 -070047import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
48import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
49import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
50import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
Zak Cohen90e7116742017-01-29 12:59:23 -080051import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
Wale Ogunwale822e5122017-07-26 06:02:24 -070052import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
Jorim Jaggi02886a82016-12-06 09:10:06 -080053import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080054import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
55import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
56import static android.content.pm.ActivityInfo.FLAG_MULTIPROCESS;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020057import static android.content.pm.ActivityInfo.FLAG_NO_HISTORY;
Chong Zhang87761972016-08-22 13:53:24 -070058import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020059import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080060import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
chaviw59b98852017-06-13 12:05:44 -070061import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080062import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -080063import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
64import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080065import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
Charles He2bf28322017-10-12 22:24:49 +010066import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
67import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
68import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
69import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
Ruben Brunkf53497c2017-03-27 20:26:17 -070070import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS;
71import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY;
Wale Ogunwaledf241e92016-10-13 15:14:21 -070072import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Jorim Jaggicd13d332016-04-27 15:40:20 -070073import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Wale Ogunwale72a73e32016-10-13 12:16:39 -070074import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Wale Ogunwaledf241e92016-10-13 15:14:21 -070075import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080076import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -070077import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
78import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -070079import static android.content.res.Configuration.EMPTY;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -070080import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
81import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
Ruben Brunkf53497c2017-03-27 20:26:17 -070082import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
Zak Cohen90e7116742017-01-29 12:59:23 -080083import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080084import static android.os.Build.VERSION_CODES.HONEYCOMB;
Zak Cohen90e7116742017-01-29 12:59:23 -080085import static android.os.Build.VERSION_CODES.O;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080086import static android.os.Process.SYSTEM_UID;
Riddle Hsufd4a0502018-10-16 01:05:16 +080087import static android.view.Display.INVALID_DISPLAY;
Riddle Hsu16567132018-08-16 21:37:47 +080088import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
89
Vishnu Nair9ba31652018-11-13 14:34:05 -080090import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
91import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
92import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
93import static com.android.server.am.ActivityRecordProto.PROC_ID;
94import static com.android.server.am.ActivityRecordProto.STATE;
95import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
96import static com.android.server.am.ActivityRecordProto.VISIBLE;
97import static com.android.server.am.EventLogTags.AM_RELAUNCH_ACTIVITY;
98import static com.android.server.am.EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY;
99import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
100import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
101import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
102import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
103import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
104import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
105import static com.android.server.wm.ActivityStack.LAUNCH_TICK;
106import static com.android.server.wm.ActivityStack.LAUNCH_TICK_MSG;
107import static com.android.server.wm.ActivityStack.PAUSE_TIMEOUT_MSG;
108import static com.android.server.wm.ActivityStack.STOP_TIMEOUT_MSG;
Wale Ogunwale59507092018-10-29 09:00:30 -0700109import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
110import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
111import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
112import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
113import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
114import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
115import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
116import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
117import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SAVED_STATE;
118import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
119import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
120import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
121import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
122import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwale59507092018-10-29 09:00:30 -0700123import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
124import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800125import static com.android.server.wm.ActivityTaskManagerService
126 .RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -0700127import static com.android.server.wm.IdentifierProto.HASH_CODE;
128import static com.android.server.wm.IdentifierProto.TITLE;
129import static com.android.server.wm.IdentifierProto.USER_ID;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800130import static com.android.server.wm.TaskPersister.DEBUG;
131import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800132import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
133import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
134import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
135import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
136import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700137
Ruben Brunkf53497c2017-03-27 20:26:17 -0700138import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
139import static org.xmlpull.v1.XmlPullParser.END_TAG;
140import static org.xmlpull.v1.XmlPullParser.START_TAG;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800141
Andrii Kulian21713ac2016-10-12 22:05:05 -0700142import android.annotation.NonNull;
Craig Mautner21d24a22014-04-23 11:45:37 -0700143import android.app.ActivityManager.TaskDescription;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700144import android.app.ActivityOptions;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800145import android.app.PendingIntent;
Winson Chung709904f2017-04-25 11:00:48 -0700146import android.app.PictureInPictureParams;
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800147import android.app.ResultInfo;
Riddle Hsu16567132018-08-16 21:37:47 +0800148import android.app.servertransaction.ActivityConfigurationChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800149import android.app.servertransaction.ActivityLifecycleItem;
150import android.app.servertransaction.ActivityRelaunchItem;
151import android.app.servertransaction.ClientTransaction;
152import android.app.servertransaction.ClientTransactionItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700153import android.app.servertransaction.MoveToDisplayItem;
154import android.app.servertransaction.MultiWindowModeChangeItem;
155import android.app.servertransaction.NewIntentItem;
Bryce Lee0bd8d422018-01-09 09:45:57 -0800156import android.app.servertransaction.PauseActivityItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700157import android.app.servertransaction.PipModeChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800158import android.app.servertransaction.ResumeActivityItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700159import android.app.servertransaction.WindowVisibilityItem;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160import android.content.ComponentName;
161import android.content.Intent;
162import android.content.pm.ActivityInfo;
163import android.content.pm.ApplicationInfo;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700164import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165import android.content.res.Configuration;
166import android.graphics.Bitmap;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800167import android.graphics.GraphicBuffer;
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700168import android.graphics.Rect;
Patrick Baumann78380272018-04-04 10:41:01 -0700169import android.os.Binder;
Bryce Lee39791592017-04-26 09:29:12 -0700170import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171import android.os.Bundle;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700172import android.os.Debug;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800173import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174import android.os.Message;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800175import android.os.PersistableBundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176import android.os.Process;
Dianne Hackborn39792d22010-08-19 18:01:52 -0700177import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700179import android.os.UserHandle;
Bryce Lee8558ec72017-08-17 15:37:26 -0700180import android.os.storage.StorageManager;
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800181import android.service.voice.IVoiceInteractionSession;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182import android.util.EventLog;
183import android.util.Log;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700184import android.util.MergedConfiguration;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700185import android.util.Slog;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700186import android.util.TimeUtils;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700187import android.util.proto.ProtoOutputStream;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800188import android.view.AppTransitionAnimationSpec;
189import android.view.IAppTransitionAnimationSpecsFuture;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190import android.view.IApplicationToken;
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100191import android.view.RemoteAnimationDefinition;
Jorim Jaggife762342016-10-13 14:33:27 +0200192import android.view.WindowManager.LayoutParams;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700193
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700194import com.android.internal.R;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800195import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800196import com.android.internal.app.ResolverActivity;
197import com.android.internal.content.ReferrerIntent;
198import com.android.internal.util.XmlUtils;
199import com.android.server.AttributeCache;
Ruben Brunkf53497c2017-03-27 20:26:17 -0700200import com.android.server.AttributeCache.Entry;
Wale Ogunwale59507092018-10-29 09:00:30 -0700201import com.android.server.am.AppTimeTracker;
202import com.android.server.am.PendingIntentRecord;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800203import com.android.server.uri.UriPermissionOwner;
Wale Ogunwale59507092018-10-29 09:00:30 -0700204import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
205import com.android.server.wm.ActivityStack.ActivityState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206
Jorim Jaggi02886a82016-12-06 09:10:06 -0800207import org.xmlpull.v1.XmlPullParser;
208import org.xmlpull.v1.XmlPullParserException;
209import org.xmlpull.v1.XmlSerializer;
210
Suprabh Shukla23593142015-11-03 17:31:15 -0800211import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -0700212import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213import java.io.PrintWriter;
214import java.lang.ref.WeakReference;
215import java.util.ArrayList;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800216import java.util.Arrays;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217import java.util.HashSet;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700218import java.util.List;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700219import java.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220
221/**
222 * An entry in the history stack, representing an activity.
223 */
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800224final class ActivityRecord extends ConfigurationContainer {
Wale Ogunwale98875612018-10-12 07:53:02 -0700225 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_ATM;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700226 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
227 private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700228 private static final String TAG_STATES = TAG + POSTFIX_STATES;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700229 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700230 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
Louis Chang19443452018-10-09 12:10:21 +0800231 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
Winson Chung16e185e2017-11-07 08:30:54 -0800232 // TODO(b/67864419): Remove once recents component is overridden
233 private static final String LEGACY_RECENTS_PACKAGE_NAME = "com.android.systemui.recents";
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800234
Wale Ogunwale3ab9a272015-03-16 09:55:45 -0700235 private static final boolean SHOW_ACTIVITY_START_TIME = true;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700236
Craig Mautner21d24a22014-04-23 11:45:37 -0700237 private static final String ATTR_ID = "id";
238 private static final String TAG_INTENT = "intent";
239 private static final String ATTR_USERID = "user_id";
240 private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle";
241 private static final String ATTR_LAUNCHEDFROMUID = "launched_from_uid";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700242 private static final String ATTR_LAUNCHEDFROMPACKAGE = "launched_from_package";
Craig Mautner21d24a22014-04-23 11:45:37 -0700243 private static final String ATTR_RESOLVEDTYPE = "resolved_type";
244 private static final String ATTR_COMPONENTSPECIFIED = "component_specified";
Dianne Hackborn337abb32014-09-24 12:44:29 -0700245 static final String ACTIVITY_ICON_SUFFIX = "_activity_icon_";
Craig Mautner21d24a22014-04-23 11:45:37 -0700246
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800247 final ActivityTaskManagerService mAtmService; // owner
Dianne Hackbornbe707852011-11-11 14:32:10 -0800248 final IApplicationToken.Stub appToken; // window manager token
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800249 // TODO: Remove after unification
250 AppWindowToken mAppWindowToken;
251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 final ActivityInfo info; // all about me
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700253 // TODO: This is duplicated state already contained in info.applicationInfo - remove
254 ApplicationInfo appInfo; // information about activity's app
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800255 final int launchedFromPid; // always the pid who started the activity.
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700256 final int launchedFromUid; // always the uid who started the activity.
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800257 final String launchedFromPackage; // always the package who started the activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800258 final int mUserId; // Which user is this running for?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 final Intent intent; // the original intent that generated us
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800260 final ComponentName mActivityComponent; // the intent component, or target of an alias.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 final String shortComponentName; // the short component name of the intent
262 final String resolvedType; // as per original caller;
263 final String packageName; // the package implementing intent's component
264 final String processName; // process where this component wants to run
265 final String taskAffinity; // as per ActivityInfo.taskAffinity
266 final boolean stateNotNeeded; // As per ActivityInfo.flags
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700267 boolean fullscreen; // The activity is opaque and fills the entire space of this task.
268 // TODO: See if it possible to combine this with the fullscreen field.
269 final boolean hasWallpaper; // Has a wallpaper window as a background.
Dianne Hackbornff801ec2011-01-22 18:05:38 -0800270 final boolean noDisplay; // activity is not displayed?
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800271 private final boolean componentSpecified; // did caller specify an explicit component?
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700272 final boolean rootVoiceInteraction; // was this the root activity of a voice interaction?
Craig Mautner86d67a42013-05-14 10:34:38 -0700273
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800274 private CharSequence nonLocalizedLabel; // the label information from the package mgr.
275 private int labelRes; // the label information from the package mgr.
276 private int icon; // resource identifier of activity's icon.
277 private int logo; // resource identifier of activity's logo.
278 private int theme; // resource identifier of activity's theme.
279 private int realTheme; // actual theme resource we will use, never 0.
280 private int windowFlags; // custom window flags for preview window.
Bryce Leeaf691c02017-03-20 14:20:22 -0700281 private TaskRecord task; // the task this is in.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800282 private long createTime = System.currentTimeMillis();
Dianne Hackborn50685602011-12-01 12:23:37 -0800283 long lastVisibleTime; // last time this activity became visible
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700284 long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700285 long pauseTime; // last time we started pausing the activity
286 long launchTickTime; // base time for launch tick messages
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700287 // Last configuration reported to the activity in the client process.
288 private MergedConfiguration mLastReportedConfiguration;
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800289 private int mLastReportedDisplayId;
Winson Chung609e1e92017-05-08 10:52:12 -0700290 private boolean mLastReportedMultiWindowMode;
291 private boolean mLastReportedPictureInPictureMode;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700292 CompatibilityInfo compat;// last used compatibility mode
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700293 ActivityRecord resultTo; // who started this entry, so will get our reply
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 final String resultWho; // additional identifier for use by resultTo.
295 final int requestCode; // code given by requester (resultTo)
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800296 ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
Dianne Hackborn85d558c2014-11-04 10:31:54 -0800298 ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700299 ActivityOptions pendingOptions; // most recently given options
George Mount6ba042b2014-07-28 11:12:28 -0700300 ActivityOptions returningOptions; // options that are coming back via convertToTranslucent
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700301 AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity
Wale Ogunwalec4e63a42018-10-02 13:19:54 -0700302 ActivityServiceConnectionsHolder mServiceConnectionsHolder; // Service connections.
Dianne Hackborn7e269642010-08-25 19:50:20 -0700303 UriPermissionOwner uriPermissions; // current special URI access perms.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700304 WindowProcessController app; // if non-null, hosting application
Bryce Lee7ace3952018-02-16 14:34:32 -0800305 private ActivityState mState; // current state we are in
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 Bundle icicle; // last saved activity state
Craig Mautnera0026042014-04-23 11:45:37 -0700307 PersistableBundle persistentState; // last persistently saved activity state
Wale Ogunwale66e16852017-10-19 13:35:52 -0700308 // TODO: See if this is still needed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 boolean frontOfTask; // is this the root activity of its task?
310 boolean launchFailed; // set if a launched failed, to abort on 2nd try
311 boolean haveState; // have we gotten the last activity state?
312 boolean stopped; // is activity pause finished?
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700313 boolean delayedResume; // not yet resumed because of stopped app switches?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 boolean finishing; // activity in pending finish list?
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800315 boolean deferRelaunchUntilPaused; // relaunch of activity is being deferred until pause is
316 // completed
317 boolean preserveWindowOnDeferredRelaunch; // activity windows are preserved on deferred relaunch
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 int configChangeFlags; // which config values have changed
Wale Ogunwaleec950642017-04-25 07:44:21 -0700319 private boolean keysPaused; // has key dispatching been paused for it?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 int launchMode; // the launch mode activity attribute.
Charles He2bf28322017-10-12 22:24:49 +0100321 int lockTaskLaunchMode; // the lockTaskMode manifest attribute, subject to override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 boolean visible; // does this activity's window need to be shown?
Jorim Jaggi241ae102016-11-02 21:57:33 -0700323 boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
324 // might hide this activity?
Wale Ogunwaleec950642017-04-25 07:44:21 -0700325 private boolean mDeferHidingClient; // If true we told WM to defer reporting to the client
326 // process that it is hidden.
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800327 boolean sleeping; // have we told the activity to sleep?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 boolean nowVisible; // is this activity's window visible?
Vishnu Nair9ba31652018-11-13 14:34:05 -0800329 boolean mDrawn; // is this activity's window drawn?
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700330 boolean mClientVisibilityDeferred;// was the visibility change message to client deferred?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 boolean idle; // has the activity gone idle?
332 boolean hasBeenLaunched;// has this activity ever been launched?
333 boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
Daniel Sandler69a48172010-06-23 16:29:36 -0400334 boolean immersive; // immersive mode (don't interrupt if possible)
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400335 boolean forceNewConfig; // force re-create with new config next time
Winson Chungf7e03e12017-08-22 11:32:16 -0700336 boolean supportsEnterPipOnTaskSwitch; // This flag is set by the system to indicate that the
337 // activity can enter picture in picture while pausing (only when switching to another task)
Winson Chung709904f2017-04-25 11:00:48 -0700338 PictureInPictureParams pictureInPictureArgs = new PictureInPictureParams.Builder().build();
339 // The PiP params used when deferring the entering of picture-in-picture.
Dianne Hackborn07981492013-01-28 11:36:23 -0800340 int launchCount; // count of launches since last state
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800341 long lastLaunchTime; // time of last launch of this activity
Ruben Brunke24b9a62016-02-16 21:38:24 -0800342 ComponentName requestedVrComponent; // the requested component for handling VR mode.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700344 String stringName; // for caching of toString().
Craig Mautnerde4ef022013-04-07 19:01:33 -0700345
Dianne Hackbornf26fd992011-04-08 18:14:09 -0700346 private boolean inHistory; // are we in the history stack?
Craig Mautnerde4ef022013-04-07 19:01:33 -0700347 final ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800348 final RootActivityContainer mRootActivityContainer;
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800349
350 static final int STARTING_WINDOW_NOT_SHOWN = 0;
351 static final int STARTING_WINDOW_SHOWN = 1;
352 static final int STARTING_WINDOW_REMOVED = 2;
353 int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;
Wale Ogunwale3b232392016-05-13 15:37:13 -0700354 boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800355
Garfield Tan2746ab52018-07-25 12:33:01 -0700356 // Marking the reason why this activity is being relaunched. Mainly used to track that this
357 // activity is being relaunched to fulfill a resize request due to compatibility issues, e.g. in
358 // pre-NYC apps that don't have a sense of being resized.
359 int mRelaunchReason = RELAUNCH_REASON_NONE;
360
Craig Mautner21d24a22014-04-23 11:45:37 -0700361 TaskDescription taskDescription; // the recents information for this activity
Craig Mautnerbb742462014-07-07 15:28:55 -0700362 boolean mLaunchTaskBehind; // this activity is actively being launched with
363 // ActivityOptions.setLaunchTaskBehind, will be cleared once launch is completed.
Craig Mautner2fbd7542014-03-21 09:34:07 -0700364
Filip Gruszczynski23493322015-07-29 17:02:59 -0700365 // These configurations are collected from application's resources based on size-sensitive
366 // qualifiers. For example, layout-w800dp will be added to mHorizontalSizeConfigurations as 800
367 // and drawable-sw400dp will be added to both as 400.
368 private int[] mVerticalSizeConfigurations;
369 private int[] mHorizontalSizeConfigurations;
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700370 private int[] mSmallestSizeConfigurations;
Filip Gruszczynski23493322015-07-29 17:02:59 -0700371
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800372 boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session
373 IVoiceInteractionSession voiceSession; // Voice interaction session for this activity
374
Robert Carrd2265122016-08-05 10:25:21 -0700375 // A hint to override the window specified rotation animation, or -1
376 // to use the window specified value. We use this so that
377 // we can select the right animation in the cases of starting
378 // windows, where the app hasn't had time to set a value
379 // on the window.
380 int mRotationAnimationHint = -1;
Robert Carrfd10cd12016-06-29 16:41:50 -0700381
chaviw59b98852017-06-13 12:05:44 -0700382 private boolean mShowWhenLocked;
383 private boolean mTurnScreenOn;
384
Andrii Kulian21713ac2016-10-12 22:05:05 -0700385 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800386 * Temp configs used in {@link #ensureActivityConfiguration(int, boolean)}
Andrii Kulian21713ac2016-10-12 22:05:05 -0700387 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700388 private final Configuration mTmpConfig = new Configuration();
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700389 private final Rect mTmpBounds = new Rect();
Andrii Kulian21713ac2016-10-12 22:05:05 -0700390
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800391 private static String startingWindowStateToString(int state) {
392 switch (state) {
393 case STARTING_WINDOW_NOT_SHOWN:
394 return "STARTING_WINDOW_NOT_SHOWN";
395 case STARTING_WINDOW_SHOWN:
396 return "STARTING_WINDOW_SHOWN";
397 case STARTING_WINDOW_REMOVED:
398 return "STARTING_WINDOW_REMOVED";
399 default:
400 return "unknown state=" + state;
401 }
402 }
403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700405 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700406 pw.print(prefix); pw.print("packageName="); pw.print(packageName);
407 pw.print(" processName="); pw.println(processName);
408 pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
Craig Mautnere11f2b72013-04-01 12:37:17 -0700409 pw.print(" launchedFromPackage="); pw.print(launchedFromPackage);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800410 pw.print(" userId="); pw.println(mUserId);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800411 pw.print(prefix); pw.print("app="); pw.println(app);
412 pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700413 pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask);
414 pw.print(" task="); pw.println(task);
415 pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800416 pw.print(prefix); pw.print("mActivityComponent=");
417 pw.println(mActivityComponent.flattenToShortString());
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700418 if (appInfo != null) {
419 pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir);
420 if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) {
421 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir);
422 }
423 pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800424 if (appInfo.splitSourceDirs != null) {
425 pw.print(prefix); pw.print("splitDir=");
426 pw.println(Arrays.toString(appInfo.splitSourceDirs));
427 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800428 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700429 pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
430 pw.print(" componentSpecified="); pw.print(componentSpecified);
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700431 pw.print(" mActivityType="); pw.println(
432 activityTypeToString(getActivityType()));
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700433 if (rootVoiceInteraction) {
434 pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
435 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800436 pw.print(prefix); pw.print("compat="); pw.print(compat);
437 pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
438 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
439 pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700440 pw.println(prefix + "mLastReportedConfigurations:");
441 mLastReportedConfiguration.dump(pw, prefix + " ");
442
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700443 pw.print(prefix); pw.print("CurrentConfiguration="); pw.println(getConfiguration());
444 if (!getOverrideConfiguration().equals(EMPTY)) {
445 pw.println(prefix + "OverrideConfiguration=" + getOverrideConfiguration());
446 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800447 if (!matchParentBounds()) {
448 pw.println(prefix + "bounds=" + getBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700449 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700450 if (resultTo != null || resultWho != null) {
451 pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
452 pw.print(" resultWho="); pw.print(resultWho);
453 pw.print(" resultCode="); pw.println(requestCode);
454 }
Craig Mautner29c58ca2014-10-14 16:17:06 -0700455 if (taskDescription != null) {
456 final String iconFilename = taskDescription.getIconFilename();
457 if (iconFilename != null || taskDescription.getLabel() != null ||
458 taskDescription.getPrimaryColor() != 0) {
459 pw.print(prefix); pw.print("taskDescription:");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700460 pw.print(" label=\""); pw.print(taskDescription.getLabel());
461 pw.print("\"");
Matthew Ng54bc9422017-10-02 17:16:28 -0700462 pw.print(" icon="); pw.print(taskDescription.getInMemoryIcon() != null
463 ? taskDescription.getInMemoryIcon().getByteCount() + " bytes"
464 : "null");
465 pw.print(" iconResource="); pw.print(taskDescription.getIconResource());
466 pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200467 pw.print(" primaryColor=");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700468 pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700469 pw.print(prefix + " backgroundColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200470 pw.println(Integer.toHexString(taskDescription.getBackgroundColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700471 pw.print(prefix + " statusBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200472 pw.println(Integer.toHexString(taskDescription.getStatusBarColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700473 pw.print(prefix + " navigationBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200474 pw.println(Integer.toHexString(taskDescription.getNavigationBarColor()));
Craig Mautner29c58ca2014-10-14 16:17:06 -0700475 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700476 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700477 if (results != null) {
478 pw.print(prefix); pw.print("results="); pw.println(results);
479 }
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700480 if (pendingResults != null && pendingResults.size() > 0) {
481 pw.print(prefix); pw.println("Pending Results:");
482 for (WeakReference<PendingIntentRecord> wpir : pendingResults) {
483 PendingIntentRecord pir = wpir != null ? wpir.get() : null;
484 pw.print(prefix); pw.print(" - ");
485 if (pir == null) {
486 pw.println("null");
487 } else {
488 pw.println(pir);
489 pir.dump(pw, prefix + " ");
490 }
491 }
492 }
493 if (newIntents != null && newIntents.size() > 0) {
494 pw.print(prefix); pw.println("Pending New Intents:");
495 for (int i=0; i<newIntents.size(); i++) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800496 Intent intent = newIntents.get(i);
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700497 pw.print(prefix); pw.print(" - ");
498 if (intent == null) {
499 pw.println("null");
500 } else {
501 pw.println(intent.toShortString(false, true, false, true));
502 }
503 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700504 }
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700505 if (pendingOptions != null) {
506 pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions);
507 }
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700508 if (appTimeTracker != null) {
509 appTimeTracker.dumpWithHeader(pw, prefix, false);
510 }
Dianne Hackborn7e269642010-08-25 19:50:20 -0700511 if (uriPermissions != null) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700512 uriPermissions.dump(pw, prefix);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700513 }
514 pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed);
Dianne Hackborn07981492013-01-28 11:36:23 -0800515 pw.print(" launchCount="); pw.print(launchCount);
516 pw.print(" lastLaunchTime=");
517 if (lastLaunchTime == 0) pw.print("0");
518 else TimeUtils.formatDuration(lastLaunchTime, now, pw);
519 pw.println();
Dianne Hackborncfc837f2013-06-27 18:32:07 -0700520 pw.print(prefix); pw.print("haveState="); pw.print(haveState);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700521 pw.print(" icicle="); pw.println(icicle);
Bryce Lee7ace3952018-02-16 14:34:32 -0800522 pw.print(prefix); pw.print("state="); pw.print(mState);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700523 pw.print(" stopped="); pw.print(stopped);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700524 pw.print(" delayedResume="); pw.print(delayedResume);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700525 pw.print(" finishing="); pw.println(finishing);
526 pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
527 pw.print(" inHistory="); pw.print(inHistory);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700528 pw.print(" visible="); pw.print(visible);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800529 pw.print(" sleeping="); pw.print(sleeping);
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800530 pw.print(" idle="); pw.print(idle);
531 pw.print(" mStartingWindowState=");
532 pw.println(startingWindowStateToString(mStartingWindowState));
Dianne Hackbornff801ec2011-01-22 18:05:38 -0800533 pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
534 pw.print(" noDisplay="); pw.print(noDisplay);
535 pw.print(" immersive="); pw.print(immersive);
536 pw.print(" launchMode="); pw.println(launchMode);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800537 pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400538 pw.print(" forceNewConfig="); pw.println(forceNewConfig);
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700539 pw.print(prefix); pw.print("mActivityType=");
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700540 pw.println(activityTypeToString(getActivityType()));
Ruben Brunke24b9a62016-02-16 21:38:24 -0800541 if (requestedVrComponent != null) {
542 pw.print(prefix);
543 pw.print("requestedVrComponent=");
544 pw.println(requestedVrComponent);
545 }
Bryce Lee4a194382017-04-04 14:32:48 -0700546 final boolean waitingVisible =
547 mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800548 if (lastVisibleTime != 0 || waitingVisible || nowVisible) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700549 pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800550 pw.print(" nowVisible="); pw.print(nowVisible);
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700551 pw.print(" lastVisibleTime=");
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700552 if (lastVisibleTime == 0) pw.print("0");
553 else TimeUtils.formatDuration(lastVisibleTime, now, pw);
554 pw.println();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700555 }
Wale Ogunwaleec950642017-04-25 07:44:21 -0700556 if (mDeferHidingClient) {
557 pw.println(prefix + "mDeferHidingClient=" + mDeferHidingClient);
558 }
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800559 if (deferRelaunchUntilPaused || configChangeFlags != 0) {
560 pw.print(prefix); pw.print("deferRelaunchUntilPaused="); pw.print(deferRelaunchUntilPaused);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700561 pw.print(" configChangeFlags=");
562 pw.println(Integer.toHexString(configChangeFlags));
563 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -0700564 if (mServiceConnectionsHolder != null) {
565 pw.print(prefix); pw.print("connections="); pw.println(mServiceConnectionsHolder);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700566 }
Wale Ogunwaled26176f2016-01-25 20:04:04 -0800567 if (info != null) {
568 pw.println(prefix + "resizeMode=" + ActivityInfo.resizeModeToString(info.resizeMode));
Winson Chung609e1e92017-05-08 10:52:12 -0700569 pw.println(prefix + "mLastReportedMultiWindowMode=" + mLastReportedMultiWindowMode
570 + " mLastReportedPictureInPictureMode=" + mLastReportedPictureInPictureMode);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700571 if (info.supportsPictureInPicture()) {
572 pw.println(prefix + "supportsPictureInPicture=" + info.supportsPictureInPicture());
Winson Chungf7e03e12017-08-22 11:32:16 -0700573 pw.println(prefix + "supportsEnterPipOnTaskSwitch: "
574 + supportsEnterPipOnTaskSwitch);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700575 }
576 if (info.maxAspectRatio != 0) {
577 pw.println(prefix + "maxAspectRatio=" + info.maxAspectRatio);
578 }
Wale Ogunwaled26176f2016-01-25 20:04:04 -0800579 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580 }
581
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700582 void updateApplicationInfo(ApplicationInfo aInfo) {
583 appInfo = aInfo;
584 info.applicationInfo = aInfo;
585 }
586
Andrii Kulian21713ac2016-10-12 22:05:05 -0700587 private boolean crossesHorizontalSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700588 return crossesSizeThreshold(mHorizontalSizeConfigurations, firstDp, secondDp);
589 }
590
Andrii Kulian21713ac2016-10-12 22:05:05 -0700591 private boolean crossesVerticalSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700592 return crossesSizeThreshold(mVerticalSizeConfigurations, firstDp, secondDp);
593 }
594
Andrii Kulian21713ac2016-10-12 22:05:05 -0700595 private boolean crossesSmallestSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700596 return crossesSizeThreshold(mSmallestSizeConfigurations, firstDp, secondDp);
597 }
598
Filip Gruszczynski23493322015-07-29 17:02:59 -0700599 /**
600 * The purpose of this method is to decide whether the activity needs to be relaunched upon
601 * changing its size. In most cases the activities don't need to be relaunched, if the resize
602 * is small, all the activity content has to do is relayout itself within new bounds. There are
603 * cases however, where the activity's content would be completely changed in the new size and
604 * the full relaunch is required.
605 *
606 * The activity will report to us vertical and horizontal thresholds after which a relaunch is
607 * required. These thresholds are collected from the application resource qualifiers. For
608 * example, if application has layout-w600dp resource directory, then it needs a relaunch when
609 * we resize from width of 650dp to 550dp, as it crosses the 600dp threshold. However, if
610 * it resizes width from 620dp to 700dp, it won't be relaunched as it stays on the same side
611 * of the threshold.
612 */
613 private static boolean crossesSizeThreshold(int[] thresholds, int firstDp,
614 int secondDp) {
615 if (thresholds == null) {
616 return false;
617 }
618 for (int i = thresholds.length - 1; i >= 0; i--) {
619 final int threshold = thresholds[i];
620 if ((firstDp < threshold && secondDp >= threshold)
621 || (firstDp >= threshold && secondDp < threshold)) {
622 return true;
623 }
624 }
625 return false;
626 }
627
Andrii Kulian21713ac2016-10-12 22:05:05 -0700628 void setSizeConfigurations(int[] horizontalSizeConfiguration,
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700629 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700630 mHorizontalSizeConfigurations = horizontalSizeConfiguration;
631 mVerticalSizeConfigurations = verticalSizeConfigurations;
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700632 mSmallestSizeConfigurations = smallestSizeConfigurations;
Filip Gruszczynski23493322015-07-29 17:02:59 -0700633 }
634
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800635 private void scheduleActivityMovedToDisplay(int displayId, Configuration config) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700636 if (!attachedToProcess()) {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800637 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.w(TAG,
638 "Can't report activity moved to display - client not running, activityRecord="
639 + this + ", displayId=" + displayId);
Wale Ogunwale22e25262016-02-01 10:32:02 -0800640 return;
641 }
642 try {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800643 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
644 "Reporting activity moved to display" + ", activityRecord=" + this
645 + ", displayId=" + displayId + ", config=" + config);
Chong Zhang6be533e2016-06-17 16:24:21 -0700646
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800647 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800648 MoveToDisplayItem.obtain(displayId, config));
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800649 } catch (RemoteException e) {
650 // If process died, whatever.
651 }
652 }
653
654 private void scheduleConfigurationChanged(Configuration config) {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700655 if (!attachedToProcess()) {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800656 if (DEBUG_CONFIGURATION) Slog.w(TAG,
657 "Can't report activity configuration update - client not running"
658 + ", activityRecord=" + this);
659 return;
660 }
661 try {
662 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + this + ", config: "
663 + config);
664
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800665 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800666 ActivityConfigurationChangeItem.obtain(config));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800667 } catch (RemoteException e) {
668 // If process died, whatever.
669 }
670 }
671
Winson Chung5af42fc2017-03-24 17:11:33 -0700672 void updateMultiWindowMode() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700673 if (task == null || task.getStack() == null || !attachedToProcess()) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800674 return;
675 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700676
Wale Ogunwaleeb76b762017-11-17 10:08:04 -0800677 if (task.getStack().deferScheduleMultiWindowModeChanged()) {
678 // Don't do anything if we are currently deferring multi-window mode change.
679 return;
680 }
681
Winson Chung5af42fc2017-03-24 17:11:33 -0700682 // An activity is considered to be in multi-window mode if its task isn't fullscreen.
Wale Ogunwaleeb76b762017-11-17 10:08:04 -0800683 final boolean inMultiWindowMode = inMultiWindowMode();
Winson Chung609e1e92017-05-08 10:52:12 -0700684 if (inMultiWindowMode != mLastReportedMultiWindowMode) {
685 mLastReportedMultiWindowMode = inMultiWindowMode;
Winson Chung5af42fc2017-03-24 17:11:33 -0700686 scheduleMultiWindowModeChanged(getConfiguration());
687 }
688 }
689
690 private void scheduleMultiWindowModeChanged(Configuration overrideConfig) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800691 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800692 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700693 MultiWindowModeChangeItem.obtain(mLastReportedMultiWindowMode, overrideConfig));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800694 } catch (Exception e) {
695 // If process died, I don't care.
696 }
697 }
698
Winson Chungab76bbc2017-08-14 13:33:51 -0700699 void updatePictureInPictureMode(Rect targetStackBounds, boolean forceUpdate) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700700 if (task == null || task.getStack() == null || !attachedToProcess()) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800701 return;
702 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700703
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700704 final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null;
Winson Chungab76bbc2017-08-14 13:33:51 -0700705 if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) {
Winson Chung5af42fc2017-03-24 17:11:33 -0700706 // Picture-in-picture mode changes also trigger a multi-window mode change as well, so
Winson Chung059955f2018-08-08 16:10:20 -0700707 // update that here in order. Set the last reported MW state to the same as the PiP
708 // state since we haven't yet actually resized the task (these callbacks need to
709 // preceed the configuration change from the resiez.
710 // TODO(110009072): Once we move these callbacks to the client, remove all logic related
711 // to forcing the update of the picture-in-picture mode as a part of the PiP animation.
Winson Chung609e1e92017-05-08 10:52:12 -0700712 mLastReportedPictureInPictureMode = inPictureInPictureMode;
Winson Chung059955f2018-08-08 16:10:20 -0700713 mLastReportedMultiWindowMode = inPictureInPictureMode;
Winson Chung5af42fc2017-03-24 17:11:33 -0700714 final Configuration newConfig = task.computeNewOverrideConfigurationForBounds(
715 targetStackBounds, null);
716 schedulePictureInPictureModeChanged(newConfig);
717 scheduleMultiWindowModeChanged(newConfig);
718 }
719 }
720
721 private void schedulePictureInPictureModeChanged(Configuration overrideConfig) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800722 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800723 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800724 PipModeChangeItem.obtain(mLastReportedPictureInPictureMode,
Andrii Kulian446e8242017-10-26 15:17:29 -0700725 overrideConfig));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800726 } catch (Exception e) {
727 // If process died, no one cares.
Filip Gruszczynskica664812015-12-04 12:43:36 -0800728 }
729 }
730
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700731 @Override
732 protected int getChildCount() {
733 // {@link ActivityRecord} is a leaf node and has no children.
734 return 0;
735 }
736
737 @Override
738 protected ConfigurationContainer getChildAt(int index) {
739 return null;
740 }
741
742 @Override
743 protected ConfigurationContainer getParent() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800744 return getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -0700745 }
746
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800747 TaskRecord getTaskRecord() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700748 return task;
749 }
750
Bryce Leeaf691c02017-03-20 14:20:22 -0700751 /**
752 * Sets reference to the {@link TaskRecord} the {@link ActivityRecord} will treat as its parent.
753 * Note that this does not actually add the {@link ActivityRecord} as a {@link TaskRecord}
754 * children. However, this method will clean up references to this {@link ActivityRecord} in
755 * {@link ActivityStack}.
756 * @param task The new parent {@link TaskRecord}.
757 */
758 void setTask(TaskRecord task) {
Bryce Lee84730a02018-04-03 14:10:04 -0700759 setTask(task /* task */, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -0700760 }
761
762 /**
763 * This method should only be called by {@link TaskRecord#removeActivity(ActivityRecord)}.
Bryce Lee84730a02018-04-03 14:10:04 -0700764 * @param task The new parent task.
765 * @param reparenting Whether we're in the middle of reparenting.
Bryce Leeaf691c02017-03-20 14:20:22 -0700766 */
767 void setTask(TaskRecord task, boolean reparenting) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800768 // Do nothing if the {@link TaskRecord} is the same as the current {@link getTaskRecord}.
769 if (task != null && task == getTaskRecord()) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700770 return;
771 }
772
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800773 final ActivityStack oldStack = getActivityStack();
Bryce Lee84730a02018-04-03 14:10:04 -0700774 final ActivityStack newStack = task != null ? task.getStack() : null;
Bryce Leeaf691c02017-03-20 14:20:22 -0700775
Bryce Lee84730a02018-04-03 14:10:04 -0700776 // Inform old stack (if present) of activity removal and new stack (if set) of activity
777 // addition.
778 if (oldStack != newStack) {
779 if (!reparenting && oldStack != null) {
780 oldStack.onActivityRemovedFromStack(this);
781 }
782
783 if (newStack != null) {
784 newStack.onActivityAddedToStack(this);
785 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700786 }
787
788 this.task = task;
789
790 if (!reparenting) {
791 onParentChanged();
792 }
793 }
794
chaviw4ad54912018-05-30 11:05:44 -0700795 /**
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800796 * Notifies AWT that this app is waiting to pause in order to determine if it will enter PIP.
797 * This information helps AWT know that the app is in the process of pausing before it gets the
798 * signal on the WM side.
chaviw4ad54912018-05-30 11:05:44 -0700799 */
800 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800801 if (mAppWindowToken == null) {
802 return;
803 }
804
805 mAppWindowToken.setWillCloseOrEnterPip(willCloseOrEnterPip);
chaviw4ad54912018-05-30 11:05:44 -0700806 }
807
Dianne Hackbornbe707852011-11-11 14:32:10 -0800808 static class Token extends IApplicationToken.Stub {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700809 private final WeakReference<ActivityRecord> weakActivity;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700810 private final String name;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800811
Steven Timotiusaf03df62017-07-18 16:56:43 -0700812 Token(ActivityRecord activity, Intent intent) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800813 weakActivity = new WeakReference<>(activity);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700814 name = intent.getComponent().flattenToShortString();
Wale Ogunwale7d701172015-03-11 15:36:30 -0700815 }
816
Andrii Kulian21713ac2016-10-12 22:05:05 -0700817 private static ActivityRecord tokenToActivityRecordLocked(Token token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700818 if (token == null) {
819 return null;
820 }
821 ActivityRecord r = token.weakActivity.get();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800822 if (r == null || r.getActivityStack() == null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700823 return null;
824 }
825 return r;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800826 }
827
Craig Mautnerde4ef022013-04-07 19:01:33 -0700828 @Override
Dianne Hackbornbe707852011-11-11 14:32:10 -0800829 public String toString() {
830 StringBuilder sb = new StringBuilder(128);
831 sb.append("Token{");
832 sb.append(Integer.toHexString(System.identityHashCode(this)));
833 sb.append(' ');
834 sb.append(weakActivity.get());
835 sb.append('}');
836 return sb.toString();
837 }
Steven Timotiusaf03df62017-07-18 16:56:43 -0700838
839 @Override
840 public String getName() {
841 return name;
842 }
Dianne Hackbornbe707852011-11-11 14:32:10 -0800843 }
844
Wale Ogunwale7d701172015-03-11 15:36:30 -0700845 static ActivityRecord forTokenLocked(IBinder token) {
Dianne Hackbornbe707852011-11-11 14:32:10 -0800846 try {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700847 return Token.tokenToActivityRecordLocked((Token)token);
Dianne Hackbornbe707852011-11-11 14:32:10 -0800848 } catch (ClassCastException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800849 Slog.w(TAG, "Bad activity token: " + token, e);
Dianne Hackbornbe707852011-11-11 14:32:10 -0800850 return null;
851 }
852 }
853
Chong Zhang85ee6542015-10-02 13:36:38 -0700854 boolean isResolverActivity() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800855 return ResolverActivity.class.getName().equals(mActivityComponent.getClassName());
Craig Mautnerac6f8432013-07-17 13:24:59 -0700856 }
857
Patrick Baumann31426b22018-05-21 13:46:40 -0700858 boolean isResolverOrChildActivity() {
859 if (!"android".equals(packageName)) {
860 return false;
861 }
862 try {
863 return ResolverActivity.class.isAssignableFrom(
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800864 Object.class.getClassLoader().loadClass(mActivityComponent.getClassName()));
Patrick Baumann31426b22018-05-21 13:46:40 -0700865 } catch (ClassNotFoundException e) {
866 return false;
867 }
868 }
869
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700870 ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
871 int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage, Intent _intent,
872 String _resolvedType, ActivityInfo aInfo, Configuration _configuration,
873 ActivityRecord _resultTo, String _resultWho, int _reqCode, boolean _componentSpecified,
874 boolean _rootVoiceInteraction, ActivityStackSupervisor supervisor,
875 ActivityOptions options, ActivityRecord sourceRecord) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800876 mAtmService = _service;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800877 mRootActivityContainer = _service.mRootActivityContainer;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700878 appToken = new Token(this, _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 info = aInfo;
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800880 launchedFromPid = _launchedFromPid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 launchedFromUid = _launchedFromUid;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800882 launchedFromPackage = _launchedFromPackage;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800883 mUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 intent = _intent;
885 shortComponentName = _intent.getComponent().flattenToShortString();
886 resolvedType = _resolvedType;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800887 componentSpecified = _componentSpecified;
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700888 rootVoiceInteraction = _rootVoiceInteraction;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700889 mLastReportedConfiguration = new MergedConfiguration(_configuration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 resultTo = _resultTo;
891 resultWho = _resultWho;
892 requestCode = _reqCode;
Bryce Lee7ace3952018-02-16 14:34:32 -0800893 setState(INITIALIZING, "ActivityRecord ctor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800894 frontOfTask = false;
895 launchFailed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 stopped = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700897 delayedResume = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 finishing = false;
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800899 deferRelaunchUntilPaused = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900 keysPaused = false;
901 inHistory = false;
Chong Zhanga48ef662015-08-18 19:21:47 -0700902 visible = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 nowVisible = false;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800904 mDrawn = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800905 idle = false;
906 hasBeenLaunched = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700907 mStackSupervisor = supervisor;
Robert Carr0f5d7532016-10-17 16:39:17 -0700908
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800909 // This starts out true, since the initial state of an activity is that we have everything,
910 // and we shouldn't never consider it lacking in state to be removed if it dies.
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700911 haveState = true;
912
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800913 // If the class name in the intent doesn't match that of the target, this is
914 // probably an alias. We have to create a new ComponentName object to keep track
915 // of the real activity name, so that FLAG_ACTIVITY_CLEAR_TOP is handled properly.
916 if (aInfo.targetActivity == null
917 || (aInfo.targetActivity.equals(_intent.getComponent().getClassName())
918 && (aInfo.launchMode == LAUNCH_MULTIPLE
919 || aInfo.launchMode == LAUNCH_SINGLE_TOP))) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800920 mActivityComponent = _intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800922 mActivityComponent = new ComponentName(aInfo.packageName, aInfo.targetActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800923 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800924 taskAffinity = aInfo.taskAffinity;
925 stateNotNeeded = (aInfo.flags & FLAG_STATE_NOT_NEEDED) != 0;
926 appInfo = aInfo.applicationInfo;
927 nonLocalizedLabel = aInfo.nonLocalizedLabel;
928 labelRes = aInfo.labelRes;
929 if (nonLocalizedLabel == null && labelRes == 0) {
930 ApplicationInfo app = aInfo.applicationInfo;
931 nonLocalizedLabel = app.nonLocalizedLabel;
932 labelRes = app.labelRes;
933 }
934 icon = aInfo.getIconResource();
935 logo = aInfo.getLogoResource();
936 theme = aInfo.getThemeResource();
937 realTheme = theme;
938 if (realTheme == 0) {
939 realTheme = aInfo.applicationInfo.targetSdkVersion < HONEYCOMB
940 ? android.R.style.Theme : android.R.style.Theme_Holo;
941 }
942 if ((aInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
943 windowFlags |= LayoutParams.FLAG_HARDWARE_ACCELERATED;
944 }
945 if ((aInfo.flags & FLAG_MULTIPROCESS) != 0 && _caller != null
946 && (aInfo.applicationInfo.uid == SYSTEM_UID
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700947 || aInfo.applicationInfo.uid == _caller.mInfo.uid)) {
948 processName = _caller.mName;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800949 } else {
950 processName = aInfo.processName;
951 }
952
953 if ((aInfo.flags & FLAG_EXCLUDE_FROM_RECENTS) != 0) {
954 intent.addFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
955 }
956
957 packageName = aInfo.applicationInfo.packageName;
958 launchMode = aInfo.launchMode;
959
Ruben Brunkf53497c2017-03-27 20:26:17 -0700960 Entry ent = AttributeCache.instance().get(packageName,
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800961 realTheme, com.android.internal.R.styleable.Window, mUserId);
Bryce Leee83f34cd2017-10-31 19:50:54 -0700962
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700963 if (ent != null) {
964 fullscreen = !ActivityInfo.isTranslucentOrFloating(ent.array);
965 hasWallpaper = ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
966 noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
967 } else {
968 hasWallpaper = false;
969 noDisplay = false;
970 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800971
Winson Chung83471632016-12-13 11:02:12 -0800972 setActivityType(_componentSpecified, _launchedFromUid, _intent, options, sourceRecord);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800973
974 immersive = (aInfo.flags & FLAG_IMMERSIVE) != 0;
975
976 requestedVrComponent = (aInfo.requestedVrComponent == null) ?
977 null : ComponentName.unflattenFromString(aInfo.requestedVrComponent);
chaviw59b98852017-06-13 12:05:44 -0700978
979 mShowWhenLocked = (aInfo.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
980 mTurnScreenOn = (aInfo.flags & FLAG_TURN_SCREEN_ON) != 0;
Charles He2bf28322017-10-12 22:24:49 +0100981
982 mRotationAnimationHint = aInfo.rotationAnimation;
983 lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
984 if (appInfo.isPrivilegedApp() && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
985 || lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
986 lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
987 }
988
989 if (options != null) {
990 pendingOptions = options;
991 mLaunchTaskBehind = options.getLaunchTaskBehind();
992
993 final int rotationAnimation = pendingOptions.getRotationAnimationHint();
994 // Only override manifest supplied option if set.
995 if (rotationAnimation >= 0) {
996 mRotationAnimationHint = rotationAnimation;
997 }
998 final PendingIntent usageReport = pendingOptions.getUsageTimeReport();
999 if (usageReport != null) {
1000 appTimeTracker = new AppTimeTracker(usageReport);
1001 }
1002 final boolean useLockTask = pendingOptions.getLockTaskMode();
1003 if (useLockTask && lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_DEFAULT) {
1004 lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
1005 }
1006 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001007 }
1008
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001009 void setProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08001010 app = proc;
1011 final ActivityRecord root = task != null ? task.getRootActivity() : null;
1012 if (root == this) {
1013 task.setRootProcess(proc);
1014 }
1015 }
1016
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001017 boolean hasProcess() {
1018 return app != null;
1019 }
1020
1021 boolean attachedToProcess() {
1022 return hasProcess() && app.hasThread();
1023 }
1024
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001025 void createAppWindowToken() {
1026 if (mAppWindowToken != null) {
1027 throw new IllegalArgumentException("App Window Token=" + mAppWindowToken
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001028 + " already created for r=" + this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001029 }
1030
1031 inHistory = true;
1032
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -08001033 final TaskWindowContainerController taskController = task.getWindowContainerController();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001034
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001035 // TODO(b/36505427): Maybe this call should be moved inside updateOverrideConfiguration()
1036 task.updateOverrideConfigurationFromLaunchBounds();
1037 // Make sure override configuration is up-to-date before using to create window controller.
1038 updateOverrideConfiguration();
1039
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001040 // TODO: remove after unification
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001041 mAppWindowToken = mAtmService.mWindowManager.mRoot.getAppWindowToken(appToken.asBinder());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001042 if (mAppWindowToken != null) {
1043 // TODO: Should this throw an exception instead?
1044 Slog.w(TAG, "Attempted to add existing app token: " + appToken);
1045 } else {
1046 final Task container = taskController.mContainer;
1047 if (container == null) {
1048 throw new IllegalArgumentException("AppWindowContainerController: invalid "
1049 + " controller=" + taskController);
1050 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001051 mAppWindowToken = createAppWindow(mAtmService.mWindowManager, appToken,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001052 task.voiceSession != null, container.getDisplayContent(),
1053 ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this)
1054 * 1000000L, fullscreen,
1055 (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, appInfo.targetSdkVersion,
1056 info.screenOrientation, mRotationAnimationHint, info.configChanges,
1057 mLaunchTaskBehind, isAlwaysFocusable());
1058 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) {
1059 Slog.v(TAG, "addAppToken: "
1060 + mAppWindowToken + " controller=" + taskController + " at "
1061 + Integer.MAX_VALUE);
1062 }
1063 container.addChild(mAppWindowToken, Integer.MAX_VALUE /* add on top */);
1064 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001065
1066 task.addActivityToTop(this);
1067
Winson Chung609e1e92017-05-08 10:52:12 -07001068 // When an activity is started directly into a split-screen fullscreen stack, we need to
1069 // update the initial multi-window modes so that the callbacks are scheduled correctly when
1070 // the user leaves that mode.
Bryce Leef3c6a472017-11-14 14:53:06 -08001071 mLastReportedMultiWindowMode = inMultiWindowMode();
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001072 mLastReportedPictureInPictureMode = inPinnedWindowingMode();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001073 }
1074
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001075 boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
1076 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
1077 IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
1078 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
1079 if (DEBUG_STARTING_WINDOW) {
1080 Slog.v(TAG, "setAppStartingWindow: token=" + appToken
1081 + " pkg=" + pkg + " transferFrom=" + transferFrom + " newTask=" + newTask
1082 + " taskSwitch=" + taskSwitch + " processRunning=" + processRunning
1083 + " allowTaskSnapshot=" + allowTaskSnapshot);
1084 }
1085 if (mAppWindowToken == null) {
1086 Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + appToken);
1087 return false;
1088 }
1089 return mAppWindowToken.addStartingWindow(pkg, theme, compatInfo, nonLocalizedLabel,
1090 labelRes, icon, logo, windowFlags, transferFrom, newTask, taskSwitch,
1091 processRunning, allowTaskSnapshot, activityCreated, fromRecents);
1092 }
1093
1094 // TODO: Remove after unification
1095 @VisibleForTesting
1096 AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
1097 boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
1098 boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
1099 int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
1100 boolean alwaysFocusable) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001101 return new AppWindowToken(service, token, mActivityComponent, voiceInteraction, dc,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001102 inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation,
1103 rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable,
1104 this);
1105 }
1106
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001107 void removeWindowContainer() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001108 if (mAtmService.mWindowManager.mRoot == null) return;
Yunfan Chend4ef3012018-11-28 21:14:32 -08001109
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001110 final DisplayContent dc = mAtmService.mWindowManager.mRoot.getDisplayContent(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001111 getDisplayId());
1112 if (dc == null) {
1113 Slog.w(TAG, "removeWindowContainer: Attempted to remove token: "
1114 + appToken + " from non-existing displayId=" + getDisplayId());
Bryce Lee7ace3952018-02-16 14:34:32 -08001115 return;
1116 }
Wale Ogunwalecc367f42017-02-01 08:12:14 -08001117 // Resume key dispatching if it is currently paused before we remove the container.
1118 resumeKeyDispatchingLocked();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001119 dc.removeAppToken(appToken.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 }
1121
Winson Chung30480042017-01-26 10:55:34 -08001122 /**
1123 * Reparents this activity into {@param newTask} at the provided {@param position}. The caller
1124 * should ensure that the {@param newTask} is not already the parent of this activity.
1125 */
1126 void reparent(TaskRecord newTask, int position, String reason) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001127 if (mAppWindowToken == null) {
1128 Slog.w(TAG, "reparent: Attempted to reparent non-existing app token: " + appToken);
1129 return;
1130 }
Winson Chung30480042017-01-26 10:55:34 -08001131 final TaskRecord prevTask = task;
1132 if (prevTask == newTask) {
1133 throw new IllegalArgumentException(reason + ": task=" + newTask
1134 + " is already the parent of r=" + this);
1135 }
1136
Winson Chung74666102017-02-22 17:49:24 -08001137 // TODO: Ensure that we do not directly reparent activities across stacks, as that may leave
1138 // the stacks in strange states. For now, we should use Task.reparent() to ensure that
1139 // the stack is left in an OK state.
1140 if (prevTask != null && newTask != null && prevTask.getStack() != newTask.getStack()) {
1141 throw new IllegalArgumentException(reason + ": task=" + newTask
1142 + " is in a different stack (" + newTask.getStackId() + ") than the parent of"
1143 + " r=" + this + " (" + prevTask.getStackId() + ")");
1144 }
1145
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001146 mAppWindowToken.reparent(newTask.getWindowContainerController(), position);
Winson Chung30480042017-01-26 10:55:34 -08001147
Bryce Lee84730a02018-04-03 14:10:04 -07001148 // Reparenting prevents informing the parent stack of activity removal in the case that
1149 // the new stack has the same parent. we must manually signal here if this is not the case.
1150 final ActivityStack prevStack = prevTask.getStack();
1151
1152 if (prevStack != newTask.getStack()) {
1153 prevStack.onActivityRemovedFromStack(this);
1154 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001155 // Remove the activity from the old task and add it to the new task.
Bryce Lee84730a02018-04-03 14:10:04 -07001156 prevTask.removeActivity(this, true /* reparenting */);
Bryce Lee0f9bde82017-02-22 16:39:06 -08001157
Winson Chung30480042017-01-26 10:55:34 -08001158 newTask.addActivityAtIndex(position, this);
1159 }
1160
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001161 private boolean isHomeIntent(Intent intent) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001162 return ACTION_MAIN.equals(intent.getAction())
1163 && intent.hasCategory(CATEGORY_HOME)
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001164 && intent.getCategories().size() == 1
1165 && intent.getData() == null
1166 && intent.getType() == null;
1167 }
1168
Chong Zhangad24f962016-08-25 12:12:33 -07001169 static boolean isMainIntent(Intent intent) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001170 return ACTION_MAIN.equals(intent.getAction())
1171 && intent.hasCategory(CATEGORY_LAUNCHER)
Chong Zhangad24f962016-08-25 12:12:33 -07001172 && intent.getCategories().size() == 1
1173 && intent.getData() == null
1174 && intent.getType() == null;
1175 }
1176
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001177 private boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
1178 if (uid == Process.myUid() || uid == 0) {
1179 // System process can launch home activity.
1180 return true;
1181 }
Winson Chung547afd22018-05-17 16:03:25 -07001182 // Allow the recents component to launch the home activity.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001183 final RecentTasks recentTasks = mStackSupervisor.mService.getRecentTasks();
Winson Chung547afd22018-05-17 16:03:25 -07001184 if (recentTasks != null && recentTasks.isCallerRecents(uid)) {
1185 return true;
1186 }
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001187 // Resolver activity can launch home activity.
1188 return sourceRecord != null && sourceRecord.isResolverActivity();
1189 }
1190
Winson Chung83471632016-12-13 11:02:12 -08001191 /**
1192 * @return whether the given package name can launch an assist activity.
1193 */
1194 private boolean canLaunchAssistActivity(String packageName) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001195 final ComponentName assistComponent =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001196 mAtmService.mActiveVoiceInteractionServiceComponent;
Winson Chung83471632016-12-13 11:02:12 -08001197 if (assistComponent != null) {
1198 return assistComponent.getPackageName().equals(packageName);
1199 }
1200 return false;
1201 }
1202
1203 private void setActivityType(boolean componentSpecified, int launchedFromUid, Intent intent,
1204 ActivityOptions options, ActivityRecord sourceRecord) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001205 int activityType = ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001206 if ((!componentSpecified || canLaunchHomeActivity(launchedFromUid, sourceRecord))
1207 && isHomeIntent(intent) && !isResolverActivity()) {
1208 // This sure looks like a home activity!
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001209 activityType = ACTIVITY_TYPE_HOME;
Wale Ogunwaledf241e92016-10-13 15:14:21 -07001210
1211 if (info.resizeMode == RESIZE_MODE_FORCE_RESIZEABLE
1212 || info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
1213 // We only allow home activities to be resizeable if they explicitly requested it.
1214 info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
1215 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001216 } else if (mActivityComponent.getClassName().contains(LEGACY_RECENTS_PACKAGE_NAME)
1217 || mAtmService.getRecentTasks().isRecentsComponent(mActivityComponent, appInfo.uid)) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001218 activityType = ACTIVITY_TYPE_RECENTS;
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001219 } else if (options != null && options.getLaunchActivityType() == ACTIVITY_TYPE_ASSISTANT
Winson Chung83471632016-12-13 11:02:12 -08001220 && canLaunchAssistActivity(launchedFromPackage)) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001221 activityType = ACTIVITY_TYPE_ASSISTANT;
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001222 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001223 setActivityType(activityType);
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001224 }
1225
Craig Mautnera228ae92014-07-09 05:44:55 -07001226 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001227 if (launchMode != LAUNCH_SINGLE_INSTANCE && launchMode != LAUNCH_SINGLE_TASK) {
Craig Mautnera228ae92014-07-09 05:44:55 -07001228 task.setTaskToAffiliateWith(taskToAffiliateWith);
1229 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001230 }
1231
Andrii Kulian02b7a832016-10-06 23:11:56 -07001232 /**
1233 * @return Stack value from current task, null if there is no task.
1234 */
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001235 <T extends ActivityStack> T getActivityStack() {
Winson Chung55893332017-02-17 17:13:10 -08001236 return task != null ? (T) task.getStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001237 }
1238
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001239 int getStackId() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001240 return getActivityStack() != null ? getActivityStack().mStackId : INVALID_STACK_ID;
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001241 }
1242
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001243 ActivityDisplay getDisplay() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001244 final ActivityStack stack = getActivityStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001245 return stack != null ? stack.getDisplay() : null;
1246 }
1247
Craig Mautner5eda9b32013-07-02 11:58:16 -07001248 boolean changeWindowTranslucency(boolean toOpaque) {
1249 if (fullscreen == toOpaque) {
1250 return false;
1251 }
Craig Mautner4addfc52013-06-25 08:05:45 -07001252
Craig Mautner5eda9b32013-07-02 11:58:16 -07001253 // Keep track of the number of fullscreen activities in this task.
1254 task.numFullscreen += toOpaque ? +1 : -1;
1255
1256 fullscreen = toOpaque;
1257 return true;
Craig Mautner4addfc52013-06-25 08:05:45 -07001258 }
1259
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001260 void takeFromHistory() {
1261 if (inHistory) {
1262 inHistory = false;
1263 if (task != null && !finishing) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001264 task = null;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001265 }
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -07001266 clearOptionsLocked();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001267 }
1268 }
1269
1270 boolean isInHistory() {
1271 return inHistory;
1272 }
1273
Wale Ogunwale7d701172015-03-11 15:36:30 -07001274 boolean isInStackLocked() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001275 final ActivityStack stack = getActivityStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001276 return stack != null && stack.isInStackLocked(this) != null;
Wale Ogunwale7d701172015-03-11 15:36:30 -07001277 }
1278
Craig Mautner21d24a22014-04-23 11:45:37 -07001279 boolean isPersistable() {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001280 return (info.persistableMode == PERSIST_ROOT_ONLY ||
1281 info.persistableMode == PERSIST_ACROSS_REBOOTS) &&
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001282 (intent == null || (intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
Craig Mautner21d24a22014-04-23 11:45:37 -07001283 }
1284
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08001285 boolean isFocusable() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001286 return mRootActivityContainer.isFocusable(this, isAlwaysFocusable());
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001287 }
1288
1289 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001290 return ActivityInfo.isResizeableMode(info.resizeMode) || info.supportsPictureInPicture();
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001291 }
1292
Winson Chungd3395382016-12-13 11:49:09 -08001293 /**
1294 * @return whether this activity is non-resizeable or forced to be resizeable
1295 */
1296 boolean isNonResizableOrForcedResizable() {
Wale Ogunwaledf241e92016-10-13 15:14:21 -07001297 return info.resizeMode != RESIZE_MODE_RESIZEABLE
Wale Ogunwale72a73e32016-10-13 12:16:39 -07001298 && info.resizeMode != RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Jorim Jaggicd13d332016-04-27 15:40:20 -07001299 }
1300
Winson Chunge6308042016-10-31 09:24:01 -07001301 /**
Winson Chungd3395382016-12-13 11:49:09 -08001302 * @return whether this activity supports PiP multi-window and can be put in the pinned stack.
Winson Chunge6308042016-10-31 09:24:01 -07001303 */
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001304 boolean supportsPictureInPicture() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001305 return mAtmService.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
Winson Chungd3395382016-12-13 11:49:09 -08001306 && info.supportsPictureInPicture();
1307 }
1308
1309 /**
1310 * @return whether this activity supports split-screen multi-window and can be put in the docked
1311 * stack.
1312 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001313 @Override
1314 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001315 // An activity can not be docked even if it is considered resizeable because it only
1316 // supports picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001317 return super.supportsSplitScreenWindowingMode()
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001318 && mAtmService.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow();
Winson Chungd3395382016-12-13 11:49:09 -08001319 }
1320
1321 /**
1322 * @return whether this activity supports freeform multi-window and can be put in the freeform
1323 * stack.
1324 */
1325 boolean supportsFreeform() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001326 return mAtmService.mSupportsFreeformWindowManagement && supportsResizeableMultiWindow();
Winson Chungd3395382016-12-13 11:49:09 -08001327 }
1328
1329 /**
1330 * @return whether this activity supports non-PiP multi-window.
1331 */
1332 private boolean supportsResizeableMultiWindow() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001333 return mAtmService.mSupportsMultiWindow && !isActivityTypeHome()
Winson Chungd3395382016-12-13 11:49:09 -08001334 && (ActivityInfo.isResizeableMode(info.resizeMode)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001335 || mAtmService.mForceResizableActivities);
Wale Ogunwaled26176f2016-01-25 20:04:04 -08001336 }
1337
Winson Chunge6308042016-10-31 09:24:01 -07001338 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001339 * Check whether this activity can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001340 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001341 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001342 * @return {@code true} if either it is the default display or this activity can be put on a
1343 * secondary screen.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001344 */
1345 boolean canBeLaunchedOnDisplay(int displayId) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001346 return mAtmService.mStackSupervisor.canPlaceEntityOnDisplay(displayId, launchedFromPid,
Riddle Hsu16567132018-08-16 21:37:47 +08001347 launchedFromUid, info);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001348 }
1349
1350 /**
Robert Carrc33658e2017-04-11 18:24:20 -07001351 * @param beforeStopping Whether this check is for an auto-enter-pip operation, that is to say
1352 * the activity has requested to enter PiP when it would otherwise be stopped.
1353 *
Winson Chung298f95b2017-08-10 15:57:18 -07001354 * @return whether this activity is currently allowed to enter PIP.
Winson Chunge6308042016-10-31 09:24:01 -07001355 */
Winson Chung298f95b2017-08-10 15:57:18 -07001356 boolean checkEnterPictureInPictureState(String caller, boolean beforeStopping) {
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07001357 if (!supportsPictureInPicture()) {
1358 return false;
1359 }
1360
Winson Chungf4ac0632017-03-17 12:34:12 -07001361 // Check app-ops and see if PiP is supported for this package
1362 if (!checkEnterPictureInPictureAppOpsState()) {
1363 return false;
1364 }
1365
Winson Chungf1bfee12017-03-24 17:11:33 -07001366 // Check to see if we are in VR mode, and disallow PiP if so
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001367 if (mAtmService.shouldDisableNonVrUiLocked()) {
Winson Chungf1bfee12017-03-24 17:11:33 -07001368 return false;
1369 }
1370
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001371 boolean isKeyguardLocked = mAtmService.isKeyguardLocked();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001372 boolean isCurrentAppLocked =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001373 mAtmService.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001374 final ActivityDisplay display = getDisplay();
1375 boolean hasPinnedStack = display != null && display.hasPinnedStack();
Winson Chungbb348802017-01-30 12:01:45 -08001376 // Don't return early if !isNotLocked, since we want to throw an exception if the activity
1377 // is in an incorrect state
Winson Chunge581ebf2017-02-21 08:25:03 -08001378 boolean isNotLockedOrOnKeyguard = !isKeyguardLocked && !isCurrentAppLocked;
Robert Carrc33658e2017-04-11 18:24:20 -07001379
1380 // We don't allow auto-PiP when something else is already pipped.
1381 if (beforeStopping && hasPinnedStack) {
1382 return false;
1383 }
1384
Bryce Lee7ace3952018-02-16 14:34:32 -08001385 switch (mState) {
Winson Chungc2baac02017-01-11 13:34:47 -08001386 case RESUMED:
Winson Chunge581ebf2017-02-21 08:25:03 -08001387 // When visible, allow entering PiP if the app is not locked. If it is over the
1388 // keyguard, then we will prompt to unlock in the caller before entering PiP.
Robert Carrc33658e2017-04-11 18:24:20 -07001389 return !isCurrentAppLocked &&
Winson Chungf7e03e12017-08-22 11:32:16 -07001390 (supportsEnterPipOnTaskSwitch || !beforeStopping);
Winson Chungc2baac02017-01-11 13:34:47 -08001391 case PAUSING:
1392 case PAUSED:
Winson Chungbb348802017-01-30 12:01:45 -08001393 // When pausing, then only allow enter PiP as in the resume state, and in addition,
1394 // require that there is not an existing PiP activity and that the current system
1395 // state supports entering PiP
Winson Chunge581ebf2017-02-21 08:25:03 -08001396 return isNotLockedOrOnKeyguard && !hasPinnedStack
Winson Chungf7e03e12017-08-22 11:32:16 -07001397 && supportsEnterPipOnTaskSwitch;
Winson Chungc2baac02017-01-11 13:34:47 -08001398 case STOPPING:
1399 // When stopping in a valid state, then only allow enter PiP as in the pause state.
1400 // Otherwise, fall through to throw an exception if the caller is trying to enter
1401 // PiP in an invalid stopping state.
Winson Chungf7e03e12017-08-22 11:32:16 -07001402 if (supportsEnterPipOnTaskSwitch) {
Winson Chungf4ac0632017-03-17 12:34:12 -07001403 return isNotLockedOrOnKeyguard && !hasPinnedStack;
Winson Chungc2baac02017-01-11 13:34:47 -08001404 }
1405 default:
Winson Chung298f95b2017-08-10 15:57:18 -07001406 return false;
Winson Chungb5c41b72016-12-07 15:00:47 -08001407 }
Winson Chunge6308042016-10-31 09:24:01 -07001408 }
1409
Winson Chung59fda9e2017-01-20 16:14:51 -08001410 /**
Winson Chungf4ac0632017-03-17 12:34:12 -07001411 * @return Whether AppOps allows this package to enter picture-in-picture.
Winson Chung59fda9e2017-01-20 16:14:51 -08001412 */
Winson Chungf4ac0632017-03-17 12:34:12 -07001413 private boolean checkEnterPictureInPictureAppOpsState() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001414 return mAtmService.getAppOpsService().checkOperation(
Wale Ogunwalef6733932018-06-27 05:14:34 -07001415 OP_PICTURE_IN_PICTURE, appInfo.uid, packageName) == MODE_ALLOWED;
Winson Chung59fda9e2017-01-20 16:14:51 -08001416 }
1417
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001418 boolean isAlwaysFocusable() {
1419 return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08001420 }
1421
Louis Chang19443452018-10-09 12:10:21 +08001422 /** Move activity with its stack to front and make the stack focused. */
1423 boolean moveFocusableActivityToTop(String reason) {
1424 if (!isFocusable()) {
1425 if (DEBUG_FOCUS) {
1426 Slog.d(TAG_FOCUS, "moveActivityStackToFront: unfocusable activity=" + this);
1427 }
1428 return false;
1429 }
1430
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001431 final TaskRecord task = getTaskRecord();
1432 final ActivityStack stack = getActivityStack();
Louis Chang19443452018-10-09 12:10:21 +08001433 if (stack == null) {
1434 Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: activity="
1435 + this + " task=" + task);
1436 return false;
1437 }
1438
Wale Ogunwaled32da472018-11-16 07:19:28 -08001439 if (mRootActivityContainer.getTopResumedActivity() == this) {
Louis Chang19443452018-10-09 12:10:21 +08001440 if (DEBUG_FOCUS) {
1441 Slog.d(TAG_FOCUS, "moveActivityStackToFront: already on top, activity=" + this);
1442 }
1443 return false;
1444 }
1445
1446 if (DEBUG_FOCUS) {
1447 Slog.d(TAG_FOCUS, "moveActivityStackToFront: activity=" + this);
1448 }
1449
1450 stack.moveToFront(reason, task);
1451 // Report top activity change to tracking services and WM
Wale Ogunwaled32da472018-11-16 07:19:28 -08001452 if (mRootActivityContainer.getTopResumedActivity() == this) {
Louis Chang19443452018-10-09 12:10:21 +08001453 // TODO(b/111361570): Support multiple focused apps in WM
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001454 mAtmService.setResumedActivityUncheckLocked(this, reason);
Louis Chang19443452018-10-09 12:10:21 +08001455 }
1456 return true;
1457 }
Jorim Jaggife762342016-10-13 14:33:27 +02001458
1459 /**
1460 * @return true if the activity contains windows that have
1461 * {@link LayoutParams#FLAG_DISMISS_KEYGUARD} set
1462 */
1463 boolean hasDismissKeyguardWindows() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001464 return mAtmService.mWindowManager.containsDismissKeyguardWindow(appToken);
Jorim Jaggife762342016-10-13 14:33:27 +02001465 }
1466
Wale Ogunwale7d701172015-03-11 15:36:30 -07001467 void makeFinishingLocked() {
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001468 if (finishing) {
1469 return;
1470 }
1471 finishing = true;
1472 if (stopped) {
1473 clearOptionsLocked();
1474 }
Yorke Leebd54c2a2016-10-25 13:49:23 -07001475
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001476 if (mAtmService != null) {
1477 mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08001478 }
1479 }
1480
Dianne Hackborn7e269642010-08-25 19:50:20 -07001481 UriPermissionOwner getUriPermissionsLocked() {
1482 if (uriPermissions == null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001483 uriPermissions = new UriPermissionOwner(mAtmService.mUgmInternal, this);
Dianne Hackborn7e269642010-08-25 19:50:20 -07001484 }
1485 return uriPermissions;
1486 }
1487
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001488 void addResultLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001489 int requestCode, int resultCode,
1490 Intent resultData) {
1491 ActivityResult r = new ActivityResult(from, resultWho,
John Spurlock8a985d22014-02-25 09:40:05 -05001492 requestCode, resultCode, resultData);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 if (results == null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001494 results = new ArrayList<ResultInfo>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 }
1496 results.add(r);
1497 }
1498
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001499 void removeResultsLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 int requestCode) {
1501 if (results != null) {
1502 for (int i=results.size()-1; i>=0; i--) {
1503 ActivityResult r = (ActivityResult)results.get(i);
1504 if (r.mFrom != from) continue;
1505 if (r.mResultWho == null) {
1506 if (resultWho != null) continue;
1507 } else {
1508 if (!r.mResultWho.equals(resultWho)) continue;
1509 }
1510 if (r.mRequestCode != requestCode) continue;
1511
1512 results.remove(i);
1513 }
1514 }
1515 }
1516
Andrii Kulian21713ac2016-10-12 22:05:05 -07001517 private void addNewIntentLocked(ReferrerIntent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 if (newIntents == null) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001519 newIntents = new ArrayList<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 }
1521 newIntents.add(intent);
1522 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001523
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001524 final boolean isSleeping() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001525 final ActivityStack stack = getActivityStack();
1526 return stack != null ? stack.shouldSleepActivities() : mAtmService.isSleepingLocked();
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001527 }
1528
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001529 /**
1530 * Deliver a new Intent to an existing activity, so that its onNewIntent()
1531 * method will be called at the proper time.
1532 */
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001533 final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
Dianne Hackborn514074f2013-02-11 10:52:46 -08001534 // The activity now gets access to the data associated with this Intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001535 mAtmService.mUgmInternal.grantUriPermissionFromIntent(callingUid, packageName,
1536 intent, getUriPermissionsLocked(), mUserId);
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001537 final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
Craig Mautner86d67a42013-05-14 10:34:38 -07001538 boolean unsent = true;
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001539 final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping();
Wale Ogunwale826c7062016-09-13 08:25:54 -07001540
1541 // We want to immediately deliver the intent to the activity if:
Wale Ogunwale03f7e9e2016-09-22 09:04:09 -07001542 // - It is currently resumed or paused. i.e. it is currently visible to the user and we want
1543 // the user to see the visual effects caused by the intent delivery now.
Wale Ogunwale826c7062016-09-13 08:25:54 -07001544 // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001545 if ((mState == RESUMED || mState == PAUSED || isTopActivityWhileSleeping)
1546 && attachedToProcess()) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001547 try {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001548 ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
1549 ar.add(rintent);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001550 mAtmService.getLifecycleManager().scheduleTransaction(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001551 app.getThread(), appToken, NewIntentItem.obtain(ar, mState == PAUSED));
Craig Mautner86d67a42013-05-14 10:34:38 -07001552 unsent = false;
Dianne Hackborn39792d22010-08-19 18:01:52 -07001553 } catch (RemoteException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001554 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
Dianne Hackborn39792d22010-08-19 18:01:52 -07001555 } catch (NullPointerException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001556 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001557 }
1558 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001559 if (unsent) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001560 addNewIntentLocked(rintent);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001561 }
1562 }
1563
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001564 void updateOptionsLocked(ActivityOptions options) {
1565 if (options != null) {
1566 if (pendingOptions != null) {
1567 pendingOptions.abort();
1568 }
1569 pendingOptions = options;
1570 }
1571 }
1572
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001573 void applyOptionsLocked() {
George Mount2c92c972014-03-20 09:38:23 -07001574 if (pendingOptions != null
Ruben Brunkf53497c2017-03-27 20:26:17 -07001575 && pendingOptions.getAnimationType() != ANIM_SCENE_TRANSITION) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001576 applyOptionsLocked(pendingOptions, intent);
chaviw82a0ba82018-03-15 14:26:29 -07001577 if (task == null) {
1578 clearOptionsLocked(false /* withAbort */);
1579 } else {
1580 // This will clear the options for all the ActivityRecords for this Task.
1581 task.clearAllPendingOptions();
1582 }
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001583 }
1584 }
1585
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001586 /**
1587 * Apply override app transition base on options & animation type.
1588 */
1589 void applyOptionsLocked(ActivityOptions pendingOptions, Intent intent) {
1590 final int animationType = pendingOptions.getAnimationType();
1591 final DisplayContent displayContent = mAppWindowToken.getDisplayContent();
1592 switch (animationType) {
1593 case ANIM_CUSTOM:
1594 displayContent.mAppTransition.overridePendingAppTransition(
1595 pendingOptions.getPackageName(),
1596 pendingOptions.getCustomEnterResId(),
1597 pendingOptions.getCustomExitResId(),
1598 pendingOptions.getOnAnimationStartListener());
1599 break;
1600 case ANIM_CLIP_REVEAL:
1601 displayContent.mAppTransition.overridePendingAppTransitionClipReveal(
1602 pendingOptions.getStartX(), pendingOptions.getStartY(),
1603 pendingOptions.getWidth(), pendingOptions.getHeight());
1604 if (intent.getSourceBounds() == null) {
1605 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1606 pendingOptions.getStartY(),
1607 pendingOptions.getStartX() + pendingOptions.getWidth(),
1608 pendingOptions.getStartY() + pendingOptions.getHeight()));
1609 }
1610 break;
1611 case ANIM_SCALE_UP:
1612 displayContent.mAppTransition.overridePendingAppTransitionScaleUp(
1613 pendingOptions.getStartX(), pendingOptions.getStartY(),
1614 pendingOptions.getWidth(), pendingOptions.getHeight());
1615 if (intent.getSourceBounds() == null) {
1616 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1617 pendingOptions.getStartY(),
1618 pendingOptions.getStartX() + pendingOptions.getWidth(),
1619 pendingOptions.getStartY() + pendingOptions.getHeight()));
1620 }
1621 break;
1622 case ANIM_THUMBNAIL_SCALE_UP:
1623 case ANIM_THUMBNAIL_SCALE_DOWN:
1624 final boolean scaleUp = (animationType == ANIM_THUMBNAIL_SCALE_UP);
1625 final GraphicBuffer buffer = pendingOptions.getThumbnail();
1626 displayContent.mAppTransition.overridePendingAppTransitionThumb(buffer,
1627 pendingOptions.getStartX(), pendingOptions.getStartY(),
1628 pendingOptions.getOnAnimationStartListener(),
1629 scaleUp);
1630 if (intent.getSourceBounds() == null && buffer != null) {
1631 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1632 pendingOptions.getStartY(),
1633 pendingOptions.getStartX() + buffer.getWidth(),
1634 pendingOptions.getStartY() + buffer.getHeight()));
1635 }
1636 break;
1637 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
1638 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
1639 final AppTransitionAnimationSpec[] specs = pendingOptions.getAnimSpecs();
1640 final IAppTransitionAnimationSpecsFuture specsFuture =
1641 pendingOptions.getSpecsFuture();
1642 if (specsFuture != null) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001643 displayContent.mAppTransition.overridePendingAppTransitionMultiThumbFuture(
1644 specsFuture, pendingOptions.getOnAnimationStartListener(),
1645 animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP);
1646 } else if (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
1647 && specs != null) {
1648 displayContent.mAppTransition.overridePendingAppTransitionMultiThumb(
1649 specs, pendingOptions.getOnAnimationStartListener(),
1650 pendingOptions.getAnimationFinishedListener(), false);
1651 } else {
1652 displayContent.mAppTransition.overridePendingAppTransitionAspectScaledThumb(
1653 pendingOptions.getThumbnail(),
1654 pendingOptions.getStartX(), pendingOptions.getStartY(),
1655 pendingOptions.getWidth(), pendingOptions.getHeight(),
1656 pendingOptions.getOnAnimationStartListener(),
1657 (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP));
1658 if (intent.getSourceBounds() == null) {
1659 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1660 pendingOptions.getStartY(),
1661 pendingOptions.getStartX() + pendingOptions.getWidth(),
1662 pendingOptions.getStartY() + pendingOptions.getHeight()));
1663 }
1664 }
1665 break;
1666 case ANIM_OPEN_CROSS_PROFILE_APPS:
1667 displayContent.mAppTransition
1668 .overridePendingAppTransitionStartCrossProfileApps();
1669 break;
1670 case ANIM_REMOTE_ANIMATION:
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001671 displayContent.mAppTransition.overridePendingAppTransitionRemote(
1672 pendingOptions.getRemoteAnimationAdapter());
1673 break;
1674 case ANIM_NONE:
1675 break;
1676 default:
1677 Slog.e(TAG_WM, "applyOptionsLocked: Unknown animationType=" + animationType);
1678 break;
1679 }
1680 }
1681
Adam Powellcfbe9be2013-11-06 14:58:58 -08001682 ActivityOptions getOptionsForTargetActivityLocked() {
1683 return pendingOptions != null ? pendingOptions.forTargetActivity() : null;
1684 }
1685
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001686 void clearOptionsLocked() {
chaviw82a0ba82018-03-15 14:26:29 -07001687 clearOptionsLocked(true /* withAbort */);
1688 }
1689
1690 void clearOptionsLocked(boolean withAbort) {
1691 if (withAbort && pendingOptions != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001692 pendingOptions.abort();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001693 }
chaviw82a0ba82018-03-15 14:26:29 -07001694 pendingOptions = null;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001695 }
1696
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001697 ActivityOptions takeOptionsLocked() {
1698 ActivityOptions opts = pendingOptions;
1699 pendingOptions = null;
1700 return opts;
1701 }
1702
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001703 void removeUriPermissionsLocked() {
Dianne Hackborn7e269642010-08-25 19:50:20 -07001704 if (uriPermissions != null) {
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07001705 uriPermissions.removeUriPermissions();
Dianne Hackborn7e269642010-08-25 19:50:20 -07001706 uriPermissions = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001707 }
1708 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709
1710 void pauseKeyDispatchingLocked() {
1711 if (!keysPaused) {
1712 keysPaused = true;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001713
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001714 // TODO: remove the check after unification with AppWindowToken. The DC check is not
1715 // needed after no mock mAppWindowToken in tests.
1716 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
1717 mAppWindowToken.getDisplayContent().getInputMonitor().pauseDispatchingLw(
1718 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07001719 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001720 }
1721 }
1722
1723 void resumeKeyDispatchingLocked() {
1724 if (keysPaused) {
1725 keysPaused = false;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001726
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001727 // TODO: remove the check after unification with AppWindowToken. The DC check is not
1728 // needed after no mock mAppWindowToken in tests.
1729 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
1730 mAppWindowToken.getDisplayContent().getInputMonitor().resumeDispatchingLw(
1731 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07001732 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001733 }
1734 }
1735
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001736 private void updateTaskDescription(CharSequence description) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001737 task.lastDescription = description;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001738 }
1739
Wale Ogunwaleec950642017-04-25 07:44:21 -07001740 void setDeferHidingClient(boolean deferHidingClient) {
1741 if (mDeferHidingClient == deferHidingClient) {
1742 return;
1743 }
1744 mDeferHidingClient = deferHidingClient;
1745 if (!mDeferHidingClient && !visible) {
1746 // Hiding the client is no longer deferred and the app isn't visible still, go ahead and
1747 // update the visibility.
1748 setVisibility(false);
1749 }
Wale Ogunwale89973222017-04-23 18:39:45 -07001750 }
1751
Wale Ogunwaleec950642017-04-25 07:44:21 -07001752 void setVisibility(boolean visible) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001753 if (mAppWindowToken == null) {
1754 Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: "
1755 + appToken);
1756 return;
1757 }
1758 mAppWindowToken.setVisibility(visible, mDeferHidingClient);
Bryce Lee2a3cc462017-10-27 10:57:35 -07001759 mStackSupervisor.getActivityMetricsLogger().notifyVisibilityChanged(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001760 }
1761
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001762 // TODO: Look into merging with #commitVisibility()
Wale Ogunwaleec950642017-04-25 07:44:21 -07001763 void setVisible(boolean newVisible) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001764 visible = newVisible;
Wale Ogunwaleec950642017-04-25 07:44:21 -07001765 mDeferHidingClient = !visible && mDeferHidingClient;
Wale Ogunwaleec950642017-04-25 07:44:21 -07001766 setVisibility(visible);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001767 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
1768 }
1769
Bryce Lee7ace3952018-02-16 14:34:32 -08001770 void setState(ActivityState state, String reason) {
1771 if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState()
1772 + " to:" + state + " reason:" + reason);
Bryce Lee6ff17072018-02-28 07:26:17 -08001773
Bryce Leeb0f993f2018-03-02 15:38:01 -08001774 if (state == mState) {
1775 // No need to do anything if state doesn't change.
1776 if (DEBUG_STATES) Slog.v(TAG_STATES, "State unchanged from:" + state);
1777 return;
1778 }
1779
Bryce Leeb0f993f2018-03-02 15:38:01 -08001780 mState = state;
1781
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001782 final TaskRecord parent = getTaskRecord();
Bryce Leec4ab62a2018-03-05 14:19:26 -08001783
1784 if (parent != null) {
1785 parent.onActivityStateChanged(this, state, reason);
1786 }
Robert Carr29daa922018-04-27 11:56:48 -07001787
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001788 // The WindowManager interprets the app stopping signal as
1789 // an indication that the Surface will eventually be destroyed.
1790 // This however isn't necessarily true if we are going to sleep.
1791 if (state == STOPPING && !isSleeping()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001792 if (mAppWindowToken == null) {
1793 Slog.w(TAG_WM, "Attempted to notify stopping on non-existing app token: "
1794 + appToken);
1795 return;
1796 }
1797 mAppWindowToken.detachChildren();
Robert Carr29daa922018-04-27 11:56:48 -07001798 }
Bryce Lee7ace3952018-02-16 14:34:32 -08001799 }
1800
1801 ActivityState getState() {
1802 return mState;
1803 }
1804
1805 /**
1806 * Returns {@code true} if the Activity is in the specified state.
1807 */
1808 boolean isState(ActivityState state) {
1809 return state == mState;
1810 }
1811
1812 /**
1813 * Returns {@code true} if the Activity is in one of the specified states.
1814 */
1815 boolean isState(ActivityState state1, ActivityState state2) {
1816 return state1 == mState || state2 == mState;
1817 }
1818
1819 /**
1820 * Returns {@code true} if the Activity is in one of the specified states.
1821 */
1822 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3) {
1823 return state1 == mState || state2 == mState || state3 == mState;
1824 }
1825
1826 /**
1827 * Returns {@code true} if the Activity is in one of the specified states.
1828 */
1829 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3,
1830 ActivityState state4) {
1831 return state1 == mState || state2 == mState || state3 == mState || state4 == mState;
1832 }
1833
Jorim Jaggibae01b12017-04-11 16:29:10 -07001834 void notifyAppResumed(boolean wasStopped) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001835 if (mAppWindowToken == null) {
1836 Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: "
1837 + appToken);
1838 return;
1839 }
1840 mAppWindowToken.notifyAppResumed(wasStopped);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001841 }
1842
1843 void notifyUnknownVisibilityLaunched() {
Jorim Jaggi838c2452017-08-28 15:44:43 +02001844
1845 // No display activities never add a window, so there is no point in waiting them for
1846 // relayout.
1847 if (!noDisplay) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001848 if (mAppWindowToken != null) {
1849 mAppWindowToken.getDisplayContent().mUnknownAppVisibilityController
1850 .notifyLaunched(mAppWindowToken);
1851 }
Jorim Jaggi838c2452017-08-28 15:44:43 +02001852 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001853 }
1854
Jorim Jaggi241ae102016-11-02 21:57:33 -07001855 /**
1856 * @return true if the input activity should be made visible, ignoring any effect Keyguard
1857 * might have on the visibility
1858 *
1859 * @see {@link ActivityStack#checkKeyguardVisibility}
1860 */
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001861 boolean shouldBeVisibleIgnoringKeyguard(boolean behindFullscreenActivity) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001862 if (!okToShowLocked()) {
1863 return false;
1864 }
1865
Winson Chung3f0e59a2017-10-25 10:19:05 -07001866 return !behindFullscreenActivity || mLaunchTaskBehind;
Andrii Kulian21713ac2016-10-12 22:05:05 -07001867 }
1868
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001869 void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001870 // This activity is not currently visible, but is running. Tell it to become visible.
Bryce Lee7ace3952018-02-16 14:34:32 -08001871 if (mState == RESUMED || this == starting) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001872 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
Bryce Lee7ace3952018-02-16 14:34:32 -08001873 "Not making visible, r=" + this + " state=" + mState + " starting=" + starting);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001874 return;
1875 }
1876
1877 // If this activity is paused, tell it to now show its window.
1878 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1879 "Making visible and scheduling visibility: " + this);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001880 final ActivityStack stack = getActivityStack();
Andrii Kulian21713ac2016-10-12 22:05:05 -07001881 try {
1882 if (stack.mTranslucentActivityWaiting != null) {
1883 updateOptionsLocked(returningOptions);
1884 stack.mUndrawnActivitiesBelowTopTranslucent.add(this);
1885 }
1886 setVisible(true);
1887 sleeping = false;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001888 app.postPendingUiCleanMsg(true);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001889 if (reportToClient) {
1890 makeClientVisible();
1891 } else {
1892 mClientVisibilityDeferred = true;
1893 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07001894 // The activity may be waiting for stop, but that is no longer appropriate for it.
1895 mStackSupervisor.mStoppingActivities.remove(this);
1896 mStackSupervisor.mGoingToSleepActivities.remove(this);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001897 } catch (Exception e) {
1898 // Just skip on any failure; we'll make it visible when it next restarts.
1899 Slog.w(TAG, "Exception thrown making visible: " + intent.getComponent(), e);
1900 }
1901 handleAlreadyVisible();
1902 }
Andrii Kulian0d595f32018-02-21 15:47:33 -08001903
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001904 /** Send visibility change message to the client and pause if needed. */
1905 void makeClientVisible() {
1906 mClientVisibilityDeferred = false;
1907 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001908 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001909 WindowVisibilityItem.obtain(true /* showWindow */));
Andrii Kulian09e1afa2018-05-16 21:29:34 -07001910 if (shouldPauseWhenBecomingVisible()) {
Andrii Kulian0d595f32018-02-21 15:47:33 -08001911 // An activity must be in the {@link PAUSING} state for the system to validate
1912 // the move to {@link PAUSED}.
Bryce Lee7ace3952018-02-16 14:34:32 -08001913 setState(PAUSING, "makeVisibleIfNeeded");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001914 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian0d595f32018-02-21 15:47:33 -08001915 PauseActivityItem.obtain(finishing, false /* userLeaving */,
Bryce Lee1d0d5142018-04-12 10:35:07 -07001916 configChangeFlags, false /* dontReport */));
Andrii Kulian0d595f32018-02-21 15:47:33 -08001917 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07001918 } catch (Exception e) {
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001919 Slog.w(TAG, "Exception thrown sending visibility update: " + intent.getComponent(), e);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001920 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07001921 }
1922
Andrii Kulian09e1afa2018-05-16 21:29:34 -07001923 /** Check if activity should be moved to PAUSED state when it becomes visible. */
1924 private boolean shouldPauseWhenBecomingVisible() {
1925 // If the activity is stopped or stopping, cycle to the paused state. We avoid doing
1926 // this when there is an activity waiting to become translucent as the extra binder
1927 // calls will lead to noticeable jank. A later call to
1928 // ActivityStack#ensureActivitiesVisibleLocked will bring the activity to the proper
1929 // paused state. We also avoid doing this for the activity the stack supervisor
1930 // considers the resumed activity, as normal means will bring the activity from STOPPED
1931 // to RESUMED. Adding PAUSING in this scenario will lead to double lifecycles.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001932 if (!isState(STOPPED, STOPPING) || getActivityStack().mTranslucentActivityWaiting != null
Andrii Kulian52d255c2018-07-13 11:32:19 -07001933 || isResumedActivityOnDisplay()) {
Andrii Kulian09e1afa2018-05-16 21:29:34 -07001934 return false;
1935 }
1936
1937 // Check if position in task allows to become paused
1938 final int positionInTask = task.mActivities.indexOf(this);
1939 if (positionInTask == -1) {
1940 throw new IllegalStateException("Activity not found in its task");
1941 }
1942 if (positionInTask == task.mActivities.size() - 1) {
1943 // It's the topmost activity in the task - should become paused now
1944 return true;
1945 }
1946 // Check if activity above is finishing now and this one becomes the topmost in task.
1947 final ActivityRecord activityAbove = task.mActivities.get(positionInTask + 1);
1948 if (activityAbove.finishing && results == null) {
1949 // We will only allow pausing if activity above wasn't launched for result. Otherwise it
1950 // will cause this activity to resume before getting result.
1951 return true;
1952 }
1953 return false;
1954 }
1955
Andrii Kulian21713ac2016-10-12 22:05:05 -07001956 boolean handleAlreadyVisible() {
1957 stopFreezingScreenLocked(false);
1958 try {
1959 if (returningOptions != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001960 app.getThread().scheduleOnNewActivityOptions(appToken, returningOptions.toBundle());
Andrii Kulian21713ac2016-10-12 22:05:05 -07001961 }
1962 } catch(RemoteException e) {
1963 }
Bryce Lee7ace3952018-02-16 14:34:32 -08001964 return mState == RESUMED;
Andrii Kulian21713ac2016-10-12 22:05:05 -07001965 }
1966
1967 static void activityResumedLocked(IBinder token) {
1968 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1969 if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
1970 if (r != null) {
1971 r.icicle = null;
1972 r.haveState = false;
1973 }
1974 }
1975
1976 /**
1977 * Once we know that we have asked an application to put an activity in the resumed state
1978 * (either by launching it or explicitly telling it), this function updates the rest of our
1979 * state to match that fact.
1980 */
1981 void completeResumeLocked() {
1982 final boolean wasVisible = visible;
Jorim Jaggi8d062052017-08-22 14:55:17 +02001983 setVisible(true);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001984 if (!wasVisible) {
1985 // Visibility has changed, so take a note of it so we call the TaskStackChangedListener
1986 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
1987 }
1988 idle = false;
1989 results = null;
1990 newIntents = null;
1991 stopped = false;
1992
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001993 if (isActivityTypeHome()) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001994 WindowProcessController app = task.mActivities.get(0).app;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001995 if (hasProcess() && app != mAtmService.mHomeProcess) {
1996 mAtmService.mHomeProcess = app;
Andrii Kulian21713ac2016-10-12 22:05:05 -07001997 }
1998 }
1999
2000 if (nowVisible) {
2001 // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
2002 mStackSupervisor.reportActivityVisibleLocked(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002003 }
2004
2005 // Schedule an idle timeout in case the app doesn't do it for us.
2006 mStackSupervisor.scheduleIdleTimeoutLocked(this);
2007
2008 mStackSupervisor.reportResumedActivityLocked(this);
2009
2010 resumeKeyDispatchingLocked();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002011 final ActivityStack stack = getActivityStack();
Jorim Jaggifa9ed962018-01-25 00:16:49 +01002012 mStackSupervisor.mNoAnimActivities.clear();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002013
2014 // Mark the point when the activity is resuming
2015 // TODO: To be more accurate, the mark should be before the onCreate,
2016 // not after the onResume. But for subsequent starts, onResume is fine.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002017 if (hasProcess()) {
Wale Ogunwale86b74462018-07-02 08:42:43 -07002018 cpuTimeAtResume = app.getCpuTime();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002019 } else {
2020 cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2021 }
2022
2023 returningOptions = null;
chaviw59b98852017-06-13 12:05:44 -07002024
2025 if (canTurnScreenOn()) {
2026 mStackSupervisor.wakeUp("turnScreenOnFlag");
2027 } else {
2028 // If the screen is going to turn on because the caller explicitly requested it and
2029 // the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
2030 // pause and then resume again later, which will result in a double life-cycle event.
David Stevens9440dc82017-03-16 19:00:20 -07002031 stack.checkReadyForSleep();
chaviw59b98852017-06-13 12:05:44 -07002032 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002033 }
2034
2035 final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
2036 CharSequence description) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002037 final ActivityStack stack = getActivityStack();
Bryce Lee7ace3952018-02-16 14:34:32 -08002038 if (mState != STOPPING) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002039 Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
Ruben Brunkf53497c2017-03-27 20:26:17 -07002040 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002041 return;
2042 }
2043 if (newPersistentState != null) {
2044 persistentState = newPersistentState;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002045 mAtmService.notifyTaskPersisterLocked(task, false);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002046 }
2047 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + icicle);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002048
Andrii Kulian21713ac2016-10-12 22:05:05 -07002049 if (newIcicle != null) {
2050 // If icicle is null, this is happening due to a timeout, so we haven't really saved
2051 // the state.
2052 icicle = newIcicle;
2053 haveState = true;
2054 launchCount = 0;
Jorim Jaggie7d2b852017-08-28 17:55:15 +02002055 updateTaskDescription(description);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002056 }
2057 if (!stopped) {
2058 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
Ruben Brunkf53497c2017-03-27 20:26:17 -07002059 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002060 stopped = true;
Bryce Lee7ace3952018-02-16 14:34:32 -08002061 setState(STOPPED, "activityStoppedLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07002062
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002063 if (mAppWindowToken != null) {
2064 mAppWindowToken.notifyAppStopped();
2065 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002066
Andrii Kulian21713ac2016-10-12 22:05:05 -07002067 if (finishing) {
2068 clearOptionsLocked();
2069 } else {
2070 if (deferRelaunchUntilPaused) {
2071 stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002072 mRootActivityContainer.resumeFocusedStacksTopActivities();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002073 } else {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002074 mRootActivityContainer.updatePreviousProcess(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002075 }
2076 }
2077 }
2078 }
2079
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002080 void startLaunchTickingLocked() {
Jeff Sharkey5ab02432017-06-27 11:01:36 -06002081 if (Build.IS_USER) {
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002082 return;
2083 }
2084 if (launchTickTime == 0) {
2085 launchTickTime = SystemClock.uptimeMillis();
2086 continueLaunchTickingLocked();
2087 }
2088 }
2089
2090 boolean continueLaunchTickingLocked() {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002091 if (launchTickTime == 0) {
2092 return false;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002093 }
Wale Ogunwale7d701172015-03-11 15:36:30 -07002094
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002095 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002096 if (stack == null) {
2097 return false;
2098 }
2099
Ruben Brunkf53497c2017-03-27 20:26:17 -07002100 Message msg = stack.mHandler.obtainMessage(LAUNCH_TICK_MSG, this);
2101 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
2102 stack.mHandler.sendMessageDelayed(msg, LAUNCH_TICK);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002103 return true;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002104 }
2105
2106 void finishLaunchTickingLocked() {
2107 launchTickTime = 0;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002108 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002109 if (stack != null) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07002110 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002111 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002112 }
2113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 // IApplicationToken
2115
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002116 public boolean mayFreezeScreenLocked(WindowProcessController app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002117 // Only freeze the screen if this activity is currently attached to
2118 // an application, and that application is not blocked or unresponding.
2119 // In any other case, we can't count on getting the screen unfrozen,
2120 // so it is best to leave as-is.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002121 return hasProcess() && !app.isCrashing() && !app.isNotResponding();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002122 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002123
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002124 public void startFreezingScreenLocked(WindowProcessController app, int configChanges) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002125 if (mayFreezeScreenLocked(app)) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002126 if (mAppWindowToken == null) {
2127 Slog.w(TAG_WM,
2128 "Attempted to freeze screen with non-existing app token: " + appToken);
2129 return;
2130 }
2131
2132 if (configChanges == 0 && mAppWindowToken.okToDisplay()) {
2133 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + appToken);
2134 return;
2135 }
2136
2137 mAppWindowToken.startFreezingScreen();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002138 }
2139 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002141 public void stopFreezingScreenLocked(boolean force) {
2142 if (force || frozenBeforeDestroy) {
2143 frozenBeforeDestroy = false;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002144 if (mAppWindowToken == null) {
2145 return;
2146 }
2147 if (DEBUG_ORIENTATION) {
2148 Slog.v(TAG_WM, "Clear freezing of " + appToken + ": hidden="
2149 + mAppWindowToken.isHidden() + " freezing="
2150 + mAppWindowToken.isFreezingScreen());
2151 }
2152 mAppWindowToken.stopFreezingScreen(true, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002153 }
2154 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002155
Jorim Jaggi4d27b842017-08-17 17:22:26 +02002156 public void reportFullyDrawnLocked(boolean restoredFromBundle) {
Vishnu Nair132ee832018-09-28 15:00:05 -07002157 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2158 .getActivityMetricsLogger().logAppTransitionReportedDrawn(this, restoredFromBundle);
2159 if (info != null) {
2160 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
2161 info.windowsFullyDrawnDelayMs);
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002162 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002163 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002164
2165 /**
2166 * Called when the starting window for this container is drawn.
2167 */
Sudheer Shankac766db02017-06-12 10:37:29 -07002168 public void onStartingWindowDrawn(long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002169 synchronized (mAtmService.mGlobalLock) {
Bryce Lee2a3cc462017-10-27 10:57:35 -07002170 mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +01002171 getWindowingMode(), timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -08002172 }
2173 }
2174
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002175 /** Called when the windows associated app window container are drawn. */
Vishnu Nair9ba31652018-11-13 14:34:05 -08002176 public void onWindowsDrawn(boolean drawn, long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002177 synchronized (mAtmService.mGlobalLock) {
Vishnu Nair9ba31652018-11-13 14:34:05 -08002178 mDrawn = drawn;
2179 if (!drawn) {
2180 return;
2181 }
Vishnu Nair132ee832018-09-28 15:00:05 -07002182 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2183 .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
2184 final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
2185 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
2186 windowsDrawnDelayMs);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002187 mStackSupervisor.sendWaitingVisibleReportLocked(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002188 finishLaunchTickingLocked();
2189 if (task != null) {
2190 task.hasBeenVisible = true;
2191 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002192 }
2193 }
2194
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002195 /** Called when the windows associated app window container are visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002196 public void onWindowsVisible() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002197 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002198 mStackSupervisor.reportActivityVisibleLocked(this);
2199 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
2200 if (!nowVisible) {
2201 nowVisible = true;
2202 lastVisibleTime = SystemClock.uptimeMillis();
Bryce Leeb7c9b802017-05-02 14:20:24 -07002203 if (idle || mStackSupervisor.isStoppingNoHistoryActivity()) {
2204 // If this activity was already idle or there is an activity that must be
2205 // stopped immediately after visible, then we now need to make sure we perform
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002206 // the full stop of any activities that are waiting to do so. This is because
2207 // we won't do that while they are still waiting for this one to become visible.
Bryce Lee4a194382017-04-04 14:32:48 -07002208 final int size = mStackSupervisor.mActivitiesWaitingForVisibleActivity.size();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002209 if (size > 0) {
2210 for (int i = 0; i < size; i++) {
Bryce Lee4a194382017-04-04 14:32:48 -07002211 final ActivityRecord r =
2212 mStackSupervisor.mActivitiesWaitingForVisibleActivity.get(i);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002213 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "Was waiting for visible: " + r);
2214 }
Bryce Lee4a194382017-04-04 14:32:48 -07002215 mStackSupervisor.mActivitiesWaitingForVisibleActivity.clear();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002216 mStackSupervisor.scheduleIdleLocked();
2217 }
Bryce Leeb7c9b802017-05-02 14:20:24 -07002218 } else {
2219 // Instead of doing the full stop routine here, let's just hide any activities
2220 // we now can, and let them stop when the normal idle happens.
2221 mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
2222 false /* remove */, true /* processPausingActivities */);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002223 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002224 mAtmService.scheduleAppGcsLocked();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002225 }
2226 }
2227 }
2228
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002229 /** Called when the windows associated app window container are no longer visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002230 public void onWindowsGone() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002231 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002232 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + this);
2233 nowVisible = false;
2234 }
2235 }
2236
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002237 /**
2238 * Called when the key dispatching to a window associated with the app window container
2239 * timed-out.
2240 *
2241 * @param reason The reason for the key dispatching time out.
2242 * @param windowPid The pid of the window key dispatching timed out on.
2243 * @return True if input dispatching should be aborted.
2244 */
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002245 public boolean keyDispatchingTimedOut(String reason, int windowPid) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002246 ActivityRecord anrActivity;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002247 WindowProcessController anrApp;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002248 boolean windowFromSameProcessAsActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002249 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002250 anrActivity = getWaitingHistoryRecordLocked();
2251 anrApp = app;
Brian Carlstrom7b0f2e82017-03-31 00:24:18 -07002252 windowFromSameProcessAsActivity =
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002253 !hasProcess() || app.getPid() == windowPid || windowPid == -1;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002254 }
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002255
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002256 if (windowFromSameProcessAsActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002257 return mAtmService.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner,
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002258 anrActivity.shortComponentName, anrActivity.appInfo, shortComponentName,
2259 app, false, reason);
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002260 } else {
2261 // In this case another process added windows using this activity token. So, we call the
2262 // generic service input dispatch timed out method so that the right process is blamed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002263 return mAtmService.mAmInternal.inputDispatchingTimedOut(
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002264 windowPid, false /* aboveSystem */, reason) < 0;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002265 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002266 }
2267
2268 private ActivityRecord getWaitingHistoryRecordLocked() {
riddle_hsudb46d6b2015-04-01 18:58:07 +08002269 // First find the real culprit... if this activity is waiting for
2270 // another activity to start or has stopped, then the key dispatching
2271 // timeout should not be caused by this.
Bryce Lee4a194382017-04-04 14:32:48 -07002272 if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this) || stopped) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002273 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
riddle_hsudb46d6b2015-04-01 18:58:07 +08002274 // Try to use the one which is closest to top.
Bryce Leec4ab62a2018-03-05 14:19:26 -08002275 ActivityRecord r = stack.getResumedActivity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 if (r == null) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002277 r = stack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002279 if (r != null) {
2280 return r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 }
2282 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002283 return this;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 }
2285
Chong Zhang87761972016-08-22 13:53:24 -07002286 /** Checks whether the activity should be shown for current user. */
2287 public boolean okToShowLocked() {
Bryce Lee8558ec72017-08-17 15:37:26 -07002288 // We cannot show activities when the device is locked and the application is not
2289 // encryption aware.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002290 if (!StorageManager.isUserKeyUnlocked(mUserId)
Bryce Lee8558ec72017-08-17 15:37:26 -07002291 && !info.applicationInfo.isEncryptionAware()) {
2292 return false;
2293 }
2294
Chong Zhang87761972016-08-22 13:53:24 -07002295 return (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002296 || (mStackSupervisor.isCurrentProfileLocked(mUserId)
2297 && mAtmService.mAmInternal.isUserRunning(mUserId, 0 /* flags */));
Chong Zhang87761972016-08-22 13:53:24 -07002298 }
2299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002300 /**
2301 * This method will return true if the activity is either visible, is becoming visible, is
2302 * currently pausing, or is resumed.
2303 */
2304 public boolean isInterestingToUserLocked() {
Bryce Lee7ace3952018-02-16 14:34:32 -08002305 return visible || nowVisible || mState == PAUSING || mState == RESUMED;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002306 }
2307
Wale Ogunwale3e997362016-09-06 10:37:56 -07002308 void setSleeping(boolean _sleeping) {
2309 setSleeping(_sleeping, false);
2310 }
2311
2312 void setSleeping(boolean _sleeping, boolean force) {
2313 if (!force && sleeping == _sleeping) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002314 return;
2315 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002316 if (attachedToProcess()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002317 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002318 app.getThread().scheduleSleeping(appToken, _sleeping);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002319 if (_sleeping && !mStackSupervisor.mGoingToSleepActivities.contains(this)) {
2320 mStackSupervisor.mGoingToSleepActivities.add(this);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002321 }
2322 sleeping = _sleeping;
2323 } catch (RemoteException e) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002324 Slog.w(TAG, "Exception thrown when sleeping: " + intent.getComponent(), e);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002325 }
2326 }
2327 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08002328
Craig Mautnerd2328952013-03-05 12:46:26 -08002329 static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002330 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Craig Mautnerd2328952013-03-05 12:46:26 -08002331 if (r == null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002332 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002333 }
2334 final TaskRecord task = r.task;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002335 final int activityNdx = task.mActivities.indexOf(r);
2336 if (activityNdx < 0 || (onlyRoot && activityNdx > task.findEffectiveRootIndex())) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002337 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002338 }
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002339 return task.taskId;
Craig Mautnerd2328952013-03-05 12:46:26 -08002340 }
2341
2342 static ActivityRecord isInStackLocked(IBinder token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002343 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002344 return (r != null) ? r.getActivityStack().isInStackLocked(r) : null;
Craig Mautnerd2328952013-03-05 12:46:26 -08002345 }
2346
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002347 static ActivityStack getStackLocked(IBinder token) {
Craig Mautnerd2328952013-03-05 12:46:26 -08002348 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2349 if (r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002350 return r.getActivityStack();
Craig Mautnerd2328952013-03-05 12:46:26 -08002351 }
2352 return null;
2353 }
2354
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002355 /**
Riddle Hsufd4a0502018-10-16 01:05:16 +08002356 * @return display id to which this record is attached,
2357 * {@link android.view.Display#INVALID_DISPLAY} if not attached.
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002358 */
2359 int getDisplayId() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002360 final ActivityStack stack = getActivityStack();
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002361 if (stack == null) {
Riddle Hsufd4a0502018-10-16 01:05:16 +08002362 return INVALID_DISPLAY;
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002363 }
2364 return stack.mDisplayId;
2365 }
2366
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002367 final boolean isDestroyable() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002368 if (finishing || !hasProcess()) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002369 // This would be redundant.
2370 return false;
2371 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002372 final ActivityStack stack = getActivityStack();
Bryce Leec4ab62a2018-03-05 14:19:26 -08002373 if (stack == null || this == stack.getResumedActivity() || this == stack.mPausingActivity
Andrii Kulian02b7a832016-10-06 23:11:56 -07002374 || !haveState || !stopped) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002375 // We're not ready for this kind of thing.
2376 return false;
2377 }
2378 if (visible) {
2379 // The user would notice this!
2380 return false;
2381 }
2382 return true;
2383 }
2384
Winson Chung3bad5cc02014-08-19 17:44:32 -07002385 private static String createImageFilename(long createTime, int taskId) {
2386 return String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX + createTime +
Ruben Brunkf53497c2017-03-27 20:26:17 -07002387 IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -07002388 }
2389
Craig Mautner648f69b2014-09-18 14:16:26 -07002390 void setTaskDescription(TaskDescription _taskDescription) {
2391 Bitmap icon;
2392 if (_taskDescription.getIconFilename() == null &&
2393 (icon = _taskDescription.getIcon()) != null) {
2394 final String iconFilename = createImageFilename(createTime, task.taskId);
Winson Chungc8408b82017-01-25 17:58:56 -08002395 final File iconFile = new File(TaskPersister.getUserImagesDir(task.userId),
2396 iconFilename);
Suprabh Shukla23593142015-11-03 17:31:15 -08002397 final String iconFilePath = iconFile.getAbsolutePath();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002398 mAtmService.getRecentTasks().saveImage(icon, iconFilePath);
Suprabh Shukla23593142015-11-03 17:31:15 -08002399 _taskDescription.setIconFilename(iconFilePath);
Craig Mautner648f69b2014-09-18 14:16:26 -07002400 }
2401 taskDescription = _taskDescription;
2402 }
2403
Amith Yamasani0af6fa72016-01-17 15:36:19 -08002404 void setVoiceSessionLocked(IVoiceInteractionSession session) {
2405 voiceSession = session;
2406 pendingVoiceInteractionStart = false;
2407 }
2408
2409 void clearVoiceSessionLocked() {
2410 voiceSession = null;
2411 pendingVoiceInteractionStart = false;
2412 }
2413
Jorim Jaggi02886a82016-12-06 09:10:06 -08002414 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch) {
Jorim Jaggi42befc62017-06-13 11:54:04 -07002415 showStartingWindow(prev, newTask, taskSwitch, false /* fromRecents */);
2416 }
2417
2418 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
2419 boolean fromRecents) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002420 if (mAppWindowToken == null) {
Jorim Jaggi70176432017-01-18 12:52:13 +01002421 return;
2422 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002423 if (mTaskOverlay) {
2424 // We don't show starting window for overlay activities.
2425 return;
2426 }
Sunny Goyald85bed52018-09-25 12:01:01 -07002427 if (pendingOptions != null
2428 && pendingOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
2429 // Don't show starting window when using shared element transition.
2430 return;
2431 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002432
Wale Ogunwale3b232392016-05-13 15:37:13 -07002433 final CompatibilityInfo compatInfo =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002434 mAtmService.compatibilityInfoForPackageLocked(info.applicationInfo);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002435 final boolean shown = addStartingWindow(packageName, theme,
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002436 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
Jorim Jaggibae01b12017-04-11 16:29:10 -07002437 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
Jorim Jaggi70aa4d12017-05-15 00:05:54 +02002438 allowTaskSnapshot(),
Bryce Lee7ace3952018-02-16 14:34:32 -08002439 mState.ordinal() >= RESUMED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
Jorim Jaggi42befc62017-06-13 11:54:04 -07002440 fromRecents);
Wale Ogunwale3b232392016-05-13 15:37:13 -07002441 if (shown) {
2442 mStartingWindowState = STARTING_WINDOW_SHOWN;
2443 }
2444 }
2445
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002446 void removeOrphanedStartingWindow(boolean behindFullscreenActivity) {
Jorim Jaggicb956052017-05-09 16:27:24 +02002447 if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002448 if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
2449 mStartingWindowState = STARTING_WINDOW_REMOVED;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002450 mAppWindowToken.removeStartingWindow();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002451 }
2452 }
2453
2454 int getRequestedOrientation() {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002455 return getOrientation();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002456 }
2457
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002458 void setRequestedOrientation(int requestedOrientation) {
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002459 final int displayId = getDisplayId();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002460 final Configuration displayConfig =
Wale Ogunwaled32da472018-11-16 07:19:28 -08002461 mRootActivityContainer.getDisplayOverrideConfiguration(displayId);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002462
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002463 final Configuration config = setOrientation(requestedOrientation,
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002464 displayId, displayConfig, mayFreezeScreenLocked(app));
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002465 if (config != null) {
2466 frozenBeforeDestroy = true;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002467 if (!mAtmService.updateDisplayOverrideConfigurationLocked(config, this,
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002468 false /* deferResume */, displayId)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002469 mRootActivityContainer.resumeFocusedStacksTopActivities();
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002470 }
2471 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002472 mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
Yorke Leebd54c2a2016-10-25 13:49:23 -07002473 task.taskId, requestedOrientation);
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002474 }
2475
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002476 Configuration setOrientation(int requestedOrientation, int displayId,
2477 Configuration displayConfig, boolean freezeScreenIfNeeded) {
2478 if (mAppWindowToken == null) {
2479 Slog.w(TAG_WM,
2480 "Attempted to set orientation of non-existing app token: " + appToken);
2481 return null;
2482 }
2483
2484 mAppWindowToken.setOrientation(requestedOrientation);
2485
2486 final IBinder binder = freezeScreenIfNeeded ? appToken.asBinder() : null;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002487 return mAtmService.mWindowManager.updateOrientationFromAppTokens(displayConfig, binder,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002488 displayId);
2489 }
2490
2491 int getOrientation() {
2492 if (mAppWindowToken == null) {
2493 return SCREEN_ORIENTATION_UNSPECIFIED;
2494 }
2495
2496 return mAppWindowToken.getOrientationIgnoreVisibility();
2497 }
2498
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002499 void setDisablePreviewScreenshots(boolean disable) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002500 if (mAppWindowToken == null) {
2501 Slog.w(TAG_WM, "Attempted to set disable screenshots of non-existing app"
2502 + " token: " + appToken);
2503 return;
2504 }
2505 mAppWindowToken.setDisablePreviewScreenshots(disable);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002506 }
2507
Bryce Leea163b762017-01-24 11:05:01 -08002508 /**
2509 * Set the last reported global configuration to the client. Should be called whenever a new
2510 * global configuration is sent to the client for this activity.
2511 */
2512 void setLastReportedGlobalConfiguration(@NonNull Configuration config) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002513 mLastReportedConfiguration.setGlobalConfiguration(config);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002514 }
2515
Bryce Leea163b762017-01-24 11:05:01 -08002516 /**
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002517 * Set the last reported configuration to the client. Should be called whenever
Bryce Leea163b762017-01-24 11:05:01 -08002518 * a new merged configuration is sent to the client for this activity.
2519 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002520 void setLastReportedConfiguration(@NonNull MergedConfiguration config) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002521 setLastReportedConfiguration(config.getGlobalConfiguration(),
2522 config.getOverrideConfiguration());
Bryce Leea163b762017-01-24 11:05:01 -08002523 }
2524
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002525 private void setLastReportedConfiguration(Configuration global, Configuration override) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002526 mLastReportedConfiguration.setConfiguration(global, override);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002527 }
2528
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002529 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002530 private void updateOverrideConfiguration() {
2531 mTmpConfig.unset();
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002532 computeBounds(mTmpBounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08002533
2534 if (mTmpBounds.equals(getOverrideBounds())) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002535 return;
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002536 }
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002537
Bryce Leef3c6a472017-11-14 14:53:06 -08002538 setBounds(mTmpBounds);
2539
2540 final Rect updatedBounds = getOverrideBounds();
2541
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002542 // Bounds changed...update configuration to match.
Bryce Leef3c6a472017-11-14 14:53:06 -08002543 if (!matchParentBounds()) {
2544 task.computeOverrideConfiguration(mTmpConfig, updatedBounds, null /* insetBounds */,
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002545 false /* overrideWidth */, false /* overrideHeight */);
2546 }
Bryce Leef3c6a472017-11-14 14:53:06 -08002547
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002548 onOverrideConfigurationChanged(mTmpConfig);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002549 }
2550
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07002551 /** Returns true if the configuration is compatible with this activity. */
Wale Ogunwale42f07d92017-05-01 21:32:58 -07002552 boolean isConfigurationCompatible(Configuration config) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002553 final int orientation = mAppWindowToken != null
2554 ? getOrientation() : info.screenOrientation;
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07002555 if (isFixedOrientationPortrait(orientation)
2556 && config.orientation != ORIENTATION_PORTRAIT) {
2557 return false;
2558 }
2559 if (isFixedOrientationLandscape(orientation)
2560 && config.orientation != ORIENTATION_LANDSCAPE) {
2561 return false;
2562 }
2563 return true;
2564 }
2565
Bryce Lee7566d762017-03-30 09:34:15 -07002566 /**
2567 * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}.
2568 */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002569 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
2570 private void computeBounds(Rect outBounds) {
2571 outBounds.setEmpty();
2572 final float maxAspectRatio = info.maxAspectRatio;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002573 final ActivityStack stack = getActivityStack();
Bryce Leef3c6a472017-11-14 14:53:06 -08002574 if (task == null || stack == null || task.inMultiWindowMode() || maxAspectRatio == 0
Bryce Leee5ab4502017-07-11 08:58:05 -07002575 || isInVrUiMode(getConfiguration())) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002576 // We don't set override configuration if that activity task isn't fullscreen. I.e. the
2577 // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
Bryce Leee5ab4502017-07-11 08:58:05 -07002578 // the activity. This is indicated by an empty {@link outBounds}. We also don't set it
2579 // if we are in VR mode.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002580 return;
2581 }
2582
Bryce Lee7566d762017-03-30 09:34:15 -07002583 // We must base this on the parent configuration, because we set our override
2584 // configuration's appBounds based on the result of this method. If we used our own
2585 // configuration, it would be influenced by past invocations.
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002586 final Rect appBounds = getParent().getWindowConfiguration().getAppBounds();
Wale Ogunwale822e5122017-07-26 06:02:24 -07002587 final int containingAppWidth = appBounds.width();
2588 final int containingAppHeight = appBounds.height();
Bryce Lee7566d762017-03-30 09:34:15 -07002589 int maxActivityWidth = containingAppWidth;
2590 int maxActivityHeight = containingAppHeight;
2591
2592 if (containingAppWidth < containingAppHeight) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002593 // Width is the shorter side, so we use that to figure-out what the max. height
2594 // should be given the aspect ratio.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002595 maxActivityHeight = (int) ((maxActivityWidth * maxAspectRatio) + 0.5f);
2596 } else {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002597 // Height is the shorter side, so we use that to figure-out what the max. width
2598 // should be given the aspect ratio.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002599 maxActivityWidth = (int) ((maxActivityHeight * maxAspectRatio) + 0.5f);
2600 }
2601
Bryce Lee7566d762017-03-30 09:34:15 -07002602 if (containingAppWidth <= maxActivityWidth && containingAppHeight <= maxActivityHeight) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002603 // The display matches or is less than the activity aspect ratio, so nothing else to do.
Bryce Lee7566d762017-03-30 09:34:15 -07002604 // Return the existing bounds. If this method is running for the first time,
Bryce Leef3c6a472017-11-14 14:53:06 -08002605 // {@link #getOverrideBounds()} will be empty (representing no override). If the method has run
2606 // before, then effect of {@link #getOverrideBounds()} will already have been applied to the
Bryce Lee7566d762017-03-30 09:34:15 -07002607 // value returned from {@link getConfiguration}. Refer to
2608 // {@link TaskRecord#computeOverrideConfiguration}.
Bryce Leef3c6a472017-11-14 14:53:06 -08002609 outBounds.set(getOverrideBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002610 return;
2611 }
2612
2613 // Compute configuration based on max supported width and height.
Adrian Roos24be34d2018-05-28 18:55:38 +02002614 // Also account for the left / top insets (e.g. from display cutouts), which will be clipped
2615 // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app
2616 // bounds would end up too small.
2617 outBounds.set(0, 0, maxActivityWidth + appBounds.left, maxActivityHeight + appBounds.top);
2618
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002619 if (mAtmService.mWindowManager.getNavBarPosition(getDisplayId()) == NAV_BAR_LEFT) {
Adrian Roos24be34d2018-05-28 18:55:38 +02002620 // Position the activity frame on the opposite side of the nav bar.
2621 outBounds.left = appBounds.right - maxActivityWidth;
2622 outBounds.right = appBounds.right;
2623 }
Andrii Kulian3a1619d2017-07-07 14:38:09 -07002624 }
2625
Riddle Hsu16567132018-08-16 21:37:47 +08002626 /**
2627 * @return {@code true} if this activity was reparented to another display but
2628 * {@link #ensureActivityConfiguration} is not called.
2629 */
2630 boolean shouldUpdateConfigForDisplayChanged() {
2631 return mLastReportedDisplayId != getDisplayId();
2632 }
2633
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002634 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
2635 return ensureActivityConfiguration(globalChanges, preserveWindow,
2636 false /* ignoreStopState */);
2637 }
2638
Andrii Kulian21713ac2016-10-12 22:05:05 -07002639 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002640 * Make sure the given activity matches the current configuration. Ensures the HistoryRecord
2641 * is updated with the correct configuration and all other bookkeeping is handled.
2642 *
2643 * @param globalChanges The changes to the global configuration.
2644 * @param preserveWindow If the activity window should be preserved on screen if the activity
2645 * is relaunched.
2646 * @param ignoreStopState If we should try to relaunch the activity even if it is in the stopped
2647 * state. This is useful for the case where we know the activity will be
2648 * visible soon and we want to ensure its configuration before we make it
2649 * visible.
2650 * @return True if the activity was relaunched and false if it wasn't relaunched because we
2651 * can't or the app handles the specific configuration that is changing.
Andrii Kulian21713ac2016-10-12 22:05:05 -07002652 */
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002653 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
2654 boolean ignoreStopState) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002655 final ActivityStack stack = getActivityStack();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002656 if (stack.mConfigWillChange) {
2657 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2658 "Skipping config check (will change): " + this);
2659 return true;
2660 }
2661
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002662 // We don't worry about activities that are finishing.
2663 if (finishing) {
2664 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2665 "Configuration doesn't matter in finishing " + this);
2666 stopFreezingScreenLocked(false);
2667 return true;
2668 }
2669
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002670 if (!ignoreStopState && (mState == STOPPING || mState == STOPPED)) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07002671 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2672 "Skipping config check stopped or stopping: " + this);
2673 return true;
2674 }
2675
Wale Ogunwaleea3d3fd2017-05-01 07:41:08 -07002676 // TODO: We should add ActivityRecord.shouldBeVisible() that checks if the activity should
2677 // be visible based on the stack, task, and lockscreen state and use that here instead. The
2678 // method should be based on the logic in ActivityStack.ensureActivitiesVisibleLocked().
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07002679 // Skip updating configuration for activity is a stack that shouldn't be visible.
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002680 if (!stack.shouldBeVisible(null /* starting */)) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07002681 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2682 "Skipping config check invisible stack: " + this);
2683 return true;
2684 }
2685
Andrii Kulian21713ac2016-10-12 22:05:05 -07002686 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2687 "Ensuring correct configuration: " + this);
2688
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002689 final int newDisplayId = getDisplayId();
2690 final boolean displayChanged = mLastReportedDisplayId != newDisplayId;
2691 if (displayChanged) {
2692 mLastReportedDisplayId = newDisplayId;
2693 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002694 // TODO(b/36505427): Is there a better place to do this?
2695 updateOverrideConfiguration();
2696
Winson Chungbdc646f2017-02-13 12:12:22 -08002697 // Short circuit: if the two full configurations are equal (the common case), then there is
2698 // nothing to do. We test the full configuration instead of the global and merged override
2699 // configurations because there are cases (like moving a task to the pinned stack) where
2700 // the combine configurations are equal, but would otherwise differ in the override config
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002701 mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
2702 if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002703 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002704 "Configuration & display unchanged in " + this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002705 return true;
2706 }
2707
2708 // Okay we now are going to make this activity have the new config.
2709 // But then we need to figure out how it needs to deal with that.
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002710
2711 // Find changes between last reported merged configuration and the current one. This is used
2712 // to decide whether to relaunch an activity or just report a configuration change.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002713 final int changes = getConfigurationChanges(mTmpConfig);
Ruben Brunkf64af332017-03-22 22:03:25 -07002714
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002715 // Update last reported values.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002716 final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
Bryce Lee8104e7a2017-08-17 09:16:03 -07002717
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002718 setLastReportedConfiguration(mAtmService.getGlobalConfiguration(), newMergedOverrideConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002719
Bryce Lee7ace3952018-02-16 14:34:32 -08002720 if (mState == INITIALIZING) {
Andrii Kulianb372da62018-01-18 10:46:24 -08002721 // No need to relaunch or schedule new config for activity that hasn't been launched
2722 // yet. We do, however, return after applying the config to activity record, so that
2723 // it will use it for launch transaction.
2724 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2725 "Skipping config check for initializing activity: " + this);
2726 return true;
2727 }
2728
Andrii Kulian21713ac2016-10-12 22:05:05 -07002729 if (changes == 0 && !forceNewConfig) {
2730 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2731 "Configuration no differences in " + this);
2732 // There are no significant differences, so we won't relaunch but should still deliver
2733 // the new configuration to the client process.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002734 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002735 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002736 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002737 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002738 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002739 return true;
2740 }
2741
2742 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002743 "Configuration changes for " + this + ", allChanges="
Andrii Kulian21713ac2016-10-12 22:05:05 -07002744 + Configuration.configurationDiffToString(changes));
2745
2746 // If the activity isn't currently running, just leave the new configuration and it will
2747 // pick that up next time it starts.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002748 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002749 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2750 "Configuration doesn't matter not running " + this);
2751 stopFreezingScreenLocked(false);
2752 forceNewConfig = false;
2753 return true;
2754 }
2755
2756 // Figure out how to handle the changes between the configurations.
2757 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2758 "Checking to restart " + info.name + ": changed=0x"
2759 + Integer.toHexString(changes) + ", handles=0x"
2760 + Integer.toHexString(info.getRealConfigChanged())
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002761 + ", mLastReportedConfiguration=" + mLastReportedConfiguration);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002762
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002763 if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002764 // Aha, the activity isn't handling the change, so DIE DIE DIE.
2765 configChangeFlags |= changes;
2766 startFreezingScreenLocked(app, globalChanges);
2767 forceNewConfig = false;
2768 preserveWindow &= isResizeOnlyChange(changes);
Garfield Tan2746ab52018-07-25 12:33:01 -07002769 final boolean hasResizeChange = hasResizeChange(changes & ~info.getRealConfigChanged());
2770 if (hasResizeChange) {
2771 final boolean isDragResizing =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002772 getTaskRecord().getWindowContainerController().isDragResizing();
Garfield Tan2746ab52018-07-25 12:33:01 -07002773 mRelaunchReason = isDragResizing ? RELAUNCH_REASON_FREE_RESIZE
2774 : RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
2775 } else {
2776 mRelaunchReason = RELAUNCH_REASON_NONE;
2777 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002778 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002779 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2780 "Config is destroying non-running " + this);
2781 stack.destroyActivityLocked(this, true, "config");
Bryce Lee7ace3952018-02-16 14:34:32 -08002782 } else if (mState == PAUSING) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002783 // A little annoying: we are waiting for this activity to finish pausing. Let's not
2784 // do anything now, but just flag that it needs to be restarted when done pausing.
2785 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2786 "Config is skipping already pausing " + this);
2787 deferRelaunchUntilPaused = true;
2788 preserveWindowOnDeferredRelaunch = preserveWindow;
2789 return true;
Bryce Lee7ace3952018-02-16 14:34:32 -08002790 } else if (mState == RESUMED) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002791 // Try to optimize this case: the configuration is changing and we need to restart
2792 // the top, resumed activity. Instead of doing the normal handshaking, just say
2793 // "restart!".
2794 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2795 "Config is relaunching resumed " + this);
2796
2797 if (DEBUG_STATES && !visible) {
2798 Slog.v(TAG_STATES, "Config is relaunching resumed invisible activity " + this
2799 + " called by " + Debug.getCallers(4));
2800 }
2801
2802 relaunchActivityLocked(true /* andResume */, preserveWindow);
2803 } else {
2804 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2805 "Config is relaunching non-resumed " + this);
2806 relaunchActivityLocked(false /* andResume */, preserveWindow);
2807 }
2808
2809 // All done... tell the caller we weren't able to keep this activity around.
2810 return false;
2811 }
2812
2813 // Default case: the activity can handle this new configuration, so hand it over.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002814 // NOTE: We only forward the override configuration as the system level configuration
Andrii Kulian21713ac2016-10-12 22:05:05 -07002815 // changes is always sent to all processes when they happen so it can just use whatever
2816 // system level configuration it last got.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002817 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002818 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002819 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002820 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002821 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002822 stopFreezingScreenLocked(false);
2823
2824 return true;
2825 }
2826
Zak Cohen90e7116742017-01-29 12:59:23 -08002827 /**
2828 * When assessing a configuration change, decide if the changes flags and the new configurations
2829 * should cause the Activity to relaunch.
Ruben Brunkf64af332017-03-22 22:03:25 -07002830 *
2831 * @param changes the changes due to the given configuration.
2832 * @param changesConfig the configuration that was used to calculate the given changes via a
2833 * call to getConfigurationChanges.
Zak Cohen90e7116742017-01-29 12:59:23 -08002834 */
Ruben Brunkf64af332017-03-22 22:03:25 -07002835 private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
Zak Cohen90e7116742017-01-29 12:59:23 -08002836 int configChanged = info.getRealConfigChanged();
Ruben Brunkf64af332017-03-22 22:03:25 -07002837 boolean onlyVrUiModeChanged = onlyVrUiModeChanged(changes, changesConfig);
Zak Cohen90e7116742017-01-29 12:59:23 -08002838
2839 // Override for apps targeting pre-O sdks
2840 // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
2841 // to the config change.
2842 // For O and later, apps will be required to add configChanges="uimode" to their manifest.
2843 if (appInfo.targetSdkVersion < O
2844 && requestedVrComponent != null
Ruben Brunkf64af332017-03-22 22:03:25 -07002845 && onlyVrUiModeChanged) {
Zak Cohen90e7116742017-01-29 12:59:23 -08002846 configChanged |= CONFIG_UI_MODE;
2847 }
2848
2849 return (changes&(~configChanged)) != 0;
2850 }
2851
Ruben Brunkf64af332017-03-22 22:03:25 -07002852 /**
2853 * Returns true if the configuration change is solely due to the UI mode switching into or out
2854 * of UI_MODE_TYPE_VR_HEADSET.
2855 */
2856 private boolean onlyVrUiModeChanged(int changes, Configuration lastReportedConfig) {
2857 final Configuration currentConfig = getConfiguration();
Ruben Brunkf53497c2017-03-27 20:26:17 -07002858 return changes == CONFIG_UI_MODE && (isInVrUiMode(currentConfig)
Ruben Brunkf64af332017-03-22 22:03:25 -07002859 != isInVrUiMode(lastReportedConfig));
2860 }
2861
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002862 private int getConfigurationChanges(Configuration lastReportedConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002863 // Determine what has changed. May be nothing, if this is a config that has come back from
2864 // the app after going idle. In that case we just want to leave the official config object
2865 // now in the activity and do nothing else.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002866 final Configuration currentConfig = getConfiguration();
2867 int changes = lastReportedConfig.diff(currentConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002868 // We don't want to use size changes if they don't cross boundaries that are important to
2869 // the app.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002870 if ((changes & CONFIG_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002871 final boolean crosses = crossesHorizontalSizeThreshold(lastReportedConfig.screenWidthDp,
2872 currentConfig.screenWidthDp)
2873 || crossesVerticalSizeThreshold(lastReportedConfig.screenHeightDp,
2874 currentConfig.screenHeightDp);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002875 if (!crosses) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002876 changes &= ~CONFIG_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002877 }
2878 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002879 if ((changes & CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002880 final int oldSmallest = lastReportedConfig.smallestScreenWidthDp;
2881 final int newSmallest = currentConfig.smallestScreenWidthDp;
2882 if (!crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002883 changes &= ~CONFIG_SMALLEST_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002884 }
2885 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07002886 // We don't want window configuration to cause relaunches.
2887 if ((changes & CONFIG_WINDOW_CONFIGURATION) != 0) {
2888 changes &= ~CONFIG_WINDOW_CONFIGURATION;
2889 }
Bryce Lee600dadd2017-07-25 10:48:42 -07002890
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002891 return changes;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002892 }
2893
2894 private static boolean isResizeOnlyChange(int change) {
2895 return (change & ~(CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
2896 | CONFIG_SCREEN_LAYOUT)) == 0;
2897 }
2898
Garfield Tan2746ab52018-07-25 12:33:01 -07002899 private static boolean hasResizeChange(int change) {
2900 return (change & (CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
2901 | CONFIG_SCREEN_LAYOUT)) != 0;
2902 }
2903
Andrii Kulian21713ac2016-10-12 22:05:05 -07002904 void relaunchActivityLocked(boolean andResume, boolean preserveWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002905 if (mAtmService.mSuppressResizeConfigChanges && preserveWindow) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002906 configChangeFlags = 0;
2907 return;
2908 }
2909
2910 List<ResultInfo> pendingResults = null;
2911 List<ReferrerIntent> pendingNewIntents = null;
2912 if (andResume) {
2913 pendingResults = results;
2914 pendingNewIntents = newIntents;
2915 }
2916 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2917 "Relaunching: " + this + " with results=" + pendingResults
2918 + " newIntents=" + pendingNewIntents + " andResume=" + andResume
2919 + " preserveWindow=" + preserveWindow);
Ruben Brunkf53497c2017-03-27 20:26:17 -07002920 EventLog.writeEvent(andResume ? AM_RELAUNCH_RESUME_ACTIVITY
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002921 : AM_RELAUNCH_ACTIVITY, mUserId, System.identityHashCode(this),
Andrii Kulian21713ac2016-10-12 22:05:05 -07002922 task.taskId, shortComponentName);
2923
2924 startFreezingScreenLocked(app, 0);
2925
Andrii Kulian21713ac2016-10-12 22:05:05 -07002926 try {
2927 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
2928 "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this
2929 + " callers=" + Debug.getCallers(6));
2930 forceNewConfig = false;
2931 mStackSupervisor.activityRelaunchingLocked(this);
Andrii Kulianb372da62018-01-18 10:46:24 -08002932 final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
2933 pendingNewIntents, configChangeFlags,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002934 new MergedConfiguration(mAtmService.getGlobalConfiguration(),
Andrii Kulianb372da62018-01-18 10:46:24 -08002935 getMergedOverrideConfiguration()),
2936 preserveWindow);
2937 final ActivityLifecycleItem lifecycleItem;
2938 if (andResume) {
lumark588a3e82018-07-20 18:53:54 +08002939 lifecycleItem = ResumeActivityItem.obtain(
2940 getDisplay().getWindowContainerController().isNextTransitionForward());
Andrii Kulianb372da62018-01-18 10:46:24 -08002941 } else {
Bryce Lee1d0d5142018-04-12 10:35:07 -07002942 lifecycleItem = PauseActivityItem.obtain();
Andrii Kulianb372da62018-01-18 10:46:24 -08002943 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002944 final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), appToken);
Andrii Kulianb372da62018-01-18 10:46:24 -08002945 transaction.addCallback(callbackItem);
2946 transaction.setLifecycleStateRequest(lifecycleItem);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002947 mAtmService.getLifecycleManager().scheduleTransaction(transaction);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002948 // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
Andrii Kulianb372da62018-01-18 10:46:24 -08002949 // request resume if this activity is currently resumed, which implies we aren't
Andrii Kulian21713ac2016-10-12 22:05:05 -07002950 // sleeping.
2951 } catch (RemoteException e) {
2952 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
2953 }
2954
2955 if (andResume) {
2956 if (DEBUG_STATES) {
2957 Slog.d(TAG_STATES, "Resumed after relaunch " + this);
2958 }
2959 results = null;
2960 newIntents = null;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002961 mAtmService.getAppWarningsLocked().onResumeActivity(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002962 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002963 final ActivityStack stack = getActivityStack();
Wale Ogunwale008163e2018-07-23 23:11:08 -07002964 if (stack != null) {
2965 stack.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
2966 }
Bryce Lee7ace3952018-02-16 14:34:32 -08002967 setState(PAUSED, "relaunchActivityLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07002968 }
2969
2970 configChangeFlags = 0;
2971 deferRelaunchUntilPaused = false;
2972 preserveWindowOnDeferredRelaunch = false;
2973 }
2974
Jorim Jaggibae01b12017-04-11 16:29:10 -07002975 private boolean isProcessRunning() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002976 WindowProcessController proc = app;
Jorim Jaggi02886a82016-12-06 09:10:06 -08002977 if (proc == null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002978 proc = mAtmService.mProcessNames.get(processName, info.applicationInfo.uid);
Jorim Jaggi02886a82016-12-06 09:10:06 -08002979 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002980 return proc != null && proc.hasThread();
Jorim Jaggi02886a82016-12-06 09:10:06 -08002981 }
2982
Jorim Jaggibae01b12017-04-11 16:29:10 -07002983 /**
2984 * @return Whether a task snapshot starting window may be shown.
2985 */
2986 private boolean allowTaskSnapshot() {
2987 if (newIntents == null) {
2988 return true;
2989 }
2990
2991 // Restrict task snapshot starting window to launcher start, or there is no intent at all
2992 // (eg. task being brought to front). If the intent is something else, likely the app is
2993 // going to show some specific page or view, instead of what's left last time.
2994 for (int i = newIntents.size() - 1; i >= 0; i--) {
2995 final Intent intent = newIntents.get(i);
2996 if (intent != null && !ActivityRecord.isMainIntent(intent)) {
2997 return false;
2998 }
2999 }
3000 return true;
3001 }
3002
Bryce Leeb7c9b802017-05-02 14:20:24 -07003003 /**
3004 * Returns {@code true} if the associated activity has the no history flag set on it.
3005 * {@code false} otherwise.
3006 */
3007 boolean isNoHistory() {
3008 return (intent.getFlags() & FLAG_ACTIVITY_NO_HISTORY) != 0
3009 || (info.flags & FLAG_NO_HISTORY) != 0;
3010 }
3011
Craig Mautner21d24a22014-04-23 11:45:37 -07003012 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
3013 out.attribute(null, ATTR_ID, String.valueOf(createTime));
3014 out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
3015 if (launchedFromPackage != null) {
3016 out.attribute(null, ATTR_LAUNCHEDFROMPACKAGE, launchedFromPackage);
3017 }
3018 if (resolvedType != null) {
3019 out.attribute(null, ATTR_RESOLVEDTYPE, resolvedType);
3020 }
3021 out.attribute(null, ATTR_COMPONENTSPECIFIED, String.valueOf(componentSpecified));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003022 out.attribute(null, ATTR_USERID, String.valueOf(mUserId));
Winson Chung2cb86c72014-06-25 12:03:30 -07003023
Craig Mautner21d24a22014-04-23 11:45:37 -07003024 if (taskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003025 taskDescription.saveToXml(out);
Craig Mautner21d24a22014-04-23 11:45:37 -07003026 }
3027
3028 out.startTag(null, TAG_INTENT);
3029 intent.saveToXml(out);
3030 out.endTag(null, TAG_INTENT);
3031
3032 if (isPersistable() && persistentState != null) {
3033 out.startTag(null, TAG_PERSISTABLEBUNDLE);
3034 persistentState.saveToXml(out);
3035 out.endTag(null, TAG_PERSISTABLEBUNDLE);
3036 }
3037 }
3038
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07003039 static ActivityRecord restoreFromXml(XmlPullParser in,
3040 ActivityStackSupervisor stackSupervisor) throws IOException, XmlPullParserException {
Craig Mautner21d24a22014-04-23 11:45:37 -07003041 Intent intent = null;
3042 PersistableBundle persistentState = null;
3043 int launchedFromUid = 0;
3044 String launchedFromPackage = null;
3045 String resolvedType = null;
3046 boolean componentSpecified = false;
3047 int userId = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07003048 long createTime = -1;
3049 final int outerDepth = in.getDepth();
Winson Chung2cb86c72014-06-25 12:03:30 -07003050 TaskDescription taskDescription = new TaskDescription();
Craig Mautner21d24a22014-04-23 11:45:37 -07003051
3052 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
3053 final String attrName = in.getAttributeName(attrNdx);
3054 final String attrValue = in.getAttributeValue(attrNdx);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003055 if (DEBUG) Slog.d(TaskPersister.TAG,
Wale Ogunwale18795a22014-12-03 11:38:33 -08003056 "ActivityRecord: attribute name=" + attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003057 if (ATTR_ID.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01003058 createTime = Long.parseLong(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003059 } else if (ATTR_LAUNCHEDFROMUID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003060 launchedFromUid = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003061 } else if (ATTR_LAUNCHEDFROMPACKAGE.equals(attrName)) {
3062 launchedFromPackage = attrValue;
3063 } else if (ATTR_RESOLVEDTYPE.equals(attrName)) {
3064 resolvedType = attrValue;
3065 } else if (ATTR_COMPONENTSPECIFIED.equals(attrName)) {
Tobias Thiererb0800dc2016-04-21 17:51:41 +01003066 componentSpecified = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003067 } else if (ATTR_USERID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003068 userId = Integer.parseInt(attrValue);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003069 } else if (attrName.startsWith(ATTR_TASKDESCRIPTION_PREFIX)) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003070 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003071 } else {
3072 Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
3073 }
3074 }
3075
3076 int event;
Ruben Brunkf53497c2017-03-27 20:26:17 -07003077 while (((event = in.next()) != END_DOCUMENT) &&
3078 (event != END_TAG || in.getDepth() >= outerDepth)) {
3079 if (event == START_TAG) {
Craig Mautner21d24a22014-04-23 11:45:37 -07003080 final String name = in.getName();
Ruben Brunkf53497c2017-03-27 20:26:17 -07003081 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003082 Slog.d(TaskPersister.TAG, "ActivityRecord: START_TAG name=" + name);
Craig Mautner21d24a22014-04-23 11:45:37 -07003083 if (TAG_INTENT.equals(name)) {
3084 intent = Intent.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003085 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003086 Slog.d(TaskPersister.TAG, "ActivityRecord: intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003087 } else if (TAG_PERSISTABLEBUNDLE.equals(name)) {
3088 persistentState = PersistableBundle.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003089 if (DEBUG) Slog.d(TaskPersister.TAG,
Craig Mautner21d24a22014-04-23 11:45:37 -07003090 "ActivityRecord: persistentState=" + persistentState);
3091 } else {
3092 Slog.w(TAG, "restoreActivity: unexpected name=" + name);
3093 XmlUtils.skipCurrentTag(in);
3094 }
3095 }
3096 }
3097
3098 if (intent == null) {
Craig Mautnere0129b32014-05-25 16:41:09 -07003099 throw new XmlPullParserException("restoreActivity error intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003100 }
3101
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003102 final ActivityTaskManagerService service = stackSupervisor.mService;
Craig Mautner21d24a22014-04-23 11:45:37 -07003103 final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null,
Patrick Baumann78380272018-04-04 10:41:01 -07003104 userId, Binder.getCallingUid());
Craig Mautnere0129b32014-05-25 16:41:09 -07003105 if (aInfo == null) {
Craig Mautner77b04262014-06-27 15:22:12 -07003106 throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
3107 " resolvedType=" + resolvedType);
Craig Mautnere0129b32014-05-25 16:41:09 -07003108 }
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003109 final ActivityRecord r = new ActivityRecord(service, null /* caller */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003110 0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType,
Wale Ogunwalef6733932018-06-27 05:14:34 -07003111 aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003112 0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07003113 stackSupervisor, null /* options */, null /* sourceRecord */);
Craig Mautner21d24a22014-04-23 11:45:37 -07003114
3115 r.persistentState = persistentState;
Winson Chung2cb86c72014-06-25 12:03:30 -07003116 r.taskDescription = taskDescription;
Craig Mautner21d24a22014-04-23 11:45:37 -07003117 r.createTime = createTime;
3118
3119 return r;
3120 }
3121
Zak Cohen90e7116742017-01-29 12:59:23 -08003122 private static boolean isInVrUiMode(Configuration config) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07003123 return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
Zak Cohen90e7116742017-01-29 12:59:23 -08003124 }
3125
David Stevens82ea6cb2017-03-03 16:18:50 -08003126 int getUid() {
3127 return info.applicationInfo.uid;
3128 }
3129
chaviw59b98852017-06-13 12:05:44 -07003130 void setShowWhenLocked(boolean showWhenLocked) {
3131 mShowWhenLocked = showWhenLocked;
Wale Ogunwaled32da472018-11-16 07:19:28 -08003132 mRootActivityContainer.ensureActivitiesVisible(null, 0 /* configChanges */,
Kevin Chyn44639482017-10-09 18:34:41 -07003133 false /* preserveWindows */);
chaviw59b98852017-06-13 12:05:44 -07003134 }
3135
3136 /**
chaviw2c500982018-01-04 17:05:05 -08003137 * @return true if the activity windowing mode is not
3138 * {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and activity contains
3139 * windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the activity
3140 * has set {@link #mShowWhenLocked}.
3141 * Multi-windowing mode will be exited if true is returned.
chaviw59b98852017-06-13 12:05:44 -07003142 */
3143 boolean canShowWhenLocked() {
chaviw2c500982018-01-04 17:05:05 -08003144 return !inPinnedWindowingMode() && (mShowWhenLocked
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003145 || mAtmService.mWindowManager.containsShowWhenLockedWindow(appToken));
chaviw59b98852017-06-13 12:05:44 -07003146 }
3147
3148 void setTurnScreenOn(boolean turnScreenOn) {
3149 mTurnScreenOn = turnScreenOn;
3150 }
3151
3152 /**
3153 * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
3154 * {@link #mTurnScreenOn} is set and checks whether the ActivityRecord should be visible
3155 * depending on Keyguard state
3156 *
3157 * @return true if the screen can be turned on, false otherwise.
3158 */
3159 boolean canTurnScreenOn() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003160 final ActivityStack stack = getActivityStack();
chaviw59b98852017-06-13 12:05:44 -07003161 return mTurnScreenOn && stack != null &&
3162 stack.checkKeyguardVisibility(this, true /* shouldBeVisible */, true /* isTop */);
3163 }
3164
3165 boolean getTurnScreenOnFlag() {
3166 return mTurnScreenOn;
3167 }
3168
3169 boolean isTopRunningActivity() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003170 return mRootActivityContainer.topRunningActivity() == this;
chaviw59b98852017-06-13 12:05:44 -07003171 }
3172
Andrii Kulian52d255c2018-07-13 11:32:19 -07003173 /**
3174 * @return {@code true} if this is the resumed activity on its current display, {@code false}
3175 * otherwise.
3176 */
3177 boolean isResumedActivityOnDisplay() {
3178 final ActivityDisplay display = getDisplay();
3179 return display != null && this == display.getResumedActivity();
3180 }
3181
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003182 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003183 if (mAppWindowToken == null) {
3184 Slog.w(TAG_WM, "Attempted to register remote animations with non-existing app"
3185 + " token: " + appToken);
3186 return;
3187 }
3188 mAppWindowToken.registerRemoteAnimations(definition);
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003189 }
3190
Craig Mautnerf81b90872013-02-26 13:02:43 -08003191 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003192 public String toString() {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003193 if (stringName != null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08003194 return stringName + " t" + (task == null ? INVALID_TASK_ID : task.taskId) +
Craig Mautnerf3333272013-04-22 10:55:53 -07003195 (finishing ? " f}" : "}");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003196 }
3197 StringBuilder sb = new StringBuilder(128);
Dianne Hackborn30d71892010-12-11 10:37:55 -08003198 sb.append("ActivityRecord{");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003199 sb.append(Integer.toHexString(System.identityHashCode(this)));
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003200 sb.append(" u");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003201 sb.append(mUserId);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003202 sb.append(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003203 sb.append(intent.getComponent().flattenToShortString());
Craig Mautnerf81b90872013-02-26 13:02:43 -08003204 stringName = sb.toString();
3205 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003206 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07003207
3208 void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
3209 final long token = proto.start(fieldId);
3210 proto.write(HASH_CODE, System.identityHashCode(this));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003211 proto.write(USER_ID, mUserId);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003212 proto.write(TITLE, intent.getComponent().flattenToShortString());
3213 proto.end(token);
3214 }
3215
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003216 /**
3217 * Write all fields to an {@code ActivityRecordProto}. This assumes the
3218 * {@code ActivityRecordProto} is the outer-most proto data.
3219 */
3220 void writeToProto(ProtoOutputStream proto) {
Adrian Roos4921ccf2017-09-28 16:54:06 +02003221 super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003222 writeIdentifierToProto(proto, IDENTIFIER);
Bryce Lee7ace3952018-02-16 14:34:32 -08003223 proto.write(STATE, mState.toString());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003224 proto.write(VISIBLE, visible);
3225 proto.write(FRONT_OF_TASK, frontOfTask);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003226 if (hasProcess()) {
3227 proto.write(PROC_ID, app.getPid());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003228 }
Wale Ogunwale30eab1f2018-05-24 18:25:25 -07003229 proto.write(TRANSLUCENT, !fullscreen);
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003230 }
3231
3232 public void writeToProto(ProtoOutputStream proto, long fieldId) {
3233 final long token = proto.start(fieldId);
3234 writeToProto(proto);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003235 proto.end(token);
3236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003237}