blob: 6f2461bd84891bfc573189990d414e9c4f43a572 [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 Ogunwaled0412b32018-05-08 09:25:50 -0700247 final ActivityTaskManagerService service; // 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.
Amith Yamasani742a6712011-05-04 14:49:28 -0700258 final int userId; // 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
260 final ComponentName realActivity; // the intent component, or target of an alias.
261 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);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800410 pw.print(" userId="); pw.println(userId);
411 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);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700416 pw.print(prefix); pw.print("realActivity=");
417 pw.println(realActivity.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 Ogunwale9e4f3e02018-05-17 09:35:39 -0700647 service.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 Ogunwale9e4f3e02018-05-17 09:35:39 -0700665 service.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 Ogunwale9e4f3e02018-05-17 09:35:39 -0700692 service.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 Ogunwale9e4f3e02018-05-17 09:35:39 -0700723 service.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() {
Bryce Leeaf691c02017-03-20 14:20:22 -0700744 return getTask();
745 }
746
747 TaskRecord getTask() {
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) {
768 // Do nothing if the {@link TaskRecord} is the same as the current {@link getTask}.
769 if (task != null && task == getTask()) {
770 return;
771 }
772
Bryce Lee84730a02018-04-03 14:10:04 -0700773 final ActivityStack oldStack = getStack();
774 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();
Andrii Kulian02b7a832016-10-06 23:11:56 -0700822 if (r == null || r.getStack() == 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() {
855 return ResolverActivity.class.getName().equals(realActivity.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(
864 Object.class.getClassLoader().loadClass(realActivity.getClassName()));
865 } 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) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 service = _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;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700883 userId = 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))) {
920 realActivity = _intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 } else {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800922 realActivity = 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 Ogunwale26c0dfe2016-12-14 14:42:30 -0800961 realTheme, com.android.internal.R.styleable.Window, userId);
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
1041 mAppWindowToken = service.mWindowManager.mRoot.getAppWindowToken(appToken.asBinder());
1042 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 }
1051 mAppWindowToken = createAppWindow(service.mWindowManager, appToken,
1052 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) {
1101 return new AppWindowToken(service, token, realActivity, voiceInteraction, dc,
1102 inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation,
1103 rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable,
1104 this);
1105 }
1106
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001107 void removeWindowContainer() {
Yunfan Chend4ef3012018-11-28 21:14:32 -08001108 if (service.mWindowManager.mRoot == null) return;
1109
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001110 final DisplayContent dc = service.mWindowManager.mRoot.getDisplayContent(
1111 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 =
1196 service.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 Ogunwale16e505a2018-05-07 15:00:49 -07001216 } else if (realActivity.getClassName().contains(LEGACY_RECENTS_PACKAGE_NAME)
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001217 || service.getRecentTasks().isRecentsComponent(realActivity, 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 */
Winson Chung55893332017-02-17 17:13:10 -08001235 <T extends ActivityStack> T getStack() {
1236 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() {
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001240 return getStack() != null ? getStack().mStackId : INVALID_STACK_ID;
1241 }
1242
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001243 ActivityDisplay getDisplay() {
1244 final ActivityStack stack = getStack();
1245 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() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001275 final ActivityStack stack = getStack();
1276 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 Ogunwalea6191b42018-05-09 07:41:32 -07001305 return service.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 Ogunwalea6191b42018-05-09 07:41:32 -07001318 && service.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 Ogunwalea6191b42018-05-09 07:41:32 -07001326 return service.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 Ogunwalea6191b42018-05-09 07:41:32 -07001333 return service.mSupportsMultiWindow && !isActivityTypeHome()
Winson Chungd3395382016-12-13 11:49:09 -08001334 && (ActivityInfo.isResizeableMode(info.resizeMode)
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001335 || service.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) {
Riddle Hsu16567132018-08-16 21:37:47 +08001346 return service.mStackSupervisor.canPlaceEntityOnDisplay(displayId, launchedFromPid,
1347 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
1367 if (service.shouldDisableNonVrUiLocked()) {
1368 return false;
1369 }
1370
Winson Chungc2baac02017-01-11 13:34:47 -08001371 boolean isKeyguardLocked = service.isKeyguardLocked();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001372 boolean isCurrentAppLocked =
1373 service.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 Ogunwalef6733932018-06-27 05:14:34 -07001414 return service.getAppOpsService().checkOperation(
1415 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
1431 final TaskRecord task = getTask();
1432 final ActivityStack stack = getStack();
1433 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
1454 service.setResumedActivityUncheckLocked(this, reason);
1455 }
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() {
1464 return service.mWindowManager.containsDismissKeyguardWindow(appToken);
1465 }
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 Ogunwale9e4f3e02018-05-17 09:35:39 -07001476 if (service != null) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001477 service.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 Ogunwale6d50dcc2018-07-21 23:00:40 -07001483 uriPermissions = new UriPermissionOwner(service.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() {
1525 final ActivityStack stack = getStack();
Wale Ogunwalef6733932018-06-27 05:14:34 -07001526 return stack != null ? stack.shouldSleepActivities() : service.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 Ogunwale6d50dcc2018-07-21 23:00:40 -07001535 service.mUgmInternal.grantUriPermissionFromIntent(callingUid, packageName,
Nicolas Prevotc6cf95c2014-05-29 11:30:36 +01001536 intent, getUriPermissionsLocked(), userId);
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 Ogunwaled0412b32018-05-08 09:25:50 -07001550 service.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) {
1643 // TODO(multidisplay): Shouldn't be really used anymore from next CL.
1644 displayContent.mAppTransition.overridePendingAppTransitionMultiThumbFuture(
1645 specsFuture, pendingOptions.getOnAnimationStartListener(),
1646 animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP);
1647 } else if (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
1648 && specs != null) {
1649 displayContent.mAppTransition.overridePendingAppTransitionMultiThumb(
1650 specs, pendingOptions.getOnAnimationStartListener(),
1651 pendingOptions.getAnimationFinishedListener(), false);
1652 } else {
1653 displayContent.mAppTransition.overridePendingAppTransitionAspectScaledThumb(
1654 pendingOptions.getThumbnail(),
1655 pendingOptions.getStartX(), pendingOptions.getStartY(),
1656 pendingOptions.getWidth(), pendingOptions.getHeight(),
1657 pendingOptions.getOnAnimationStartListener(),
1658 (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP));
1659 if (intent.getSourceBounds() == null) {
1660 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1661 pendingOptions.getStartY(),
1662 pendingOptions.getStartX() + pendingOptions.getWidth(),
1663 pendingOptions.getStartY() + pendingOptions.getHeight()));
1664 }
1665 }
1666 break;
1667 case ANIM_OPEN_CROSS_PROFILE_APPS:
1668 displayContent.mAppTransition
1669 .overridePendingAppTransitionStartCrossProfileApps();
1670 break;
1671 case ANIM_REMOTE_ANIMATION:
1672 // TODO(multidisplay): Will pass displayId and adjust dependencies from next CL.
1673 displayContent.mAppTransition.overridePendingAppTransitionRemote(
1674 pendingOptions.getRemoteAnimationAdapter());
1675 break;
1676 case ANIM_NONE:
1677 break;
1678 default:
1679 Slog.e(TAG_WM, "applyOptionsLocked: Unknown animationType=" + animationType);
1680 break;
1681 }
1682 }
1683
Adam Powellcfbe9be2013-11-06 14:58:58 -08001684 ActivityOptions getOptionsForTargetActivityLocked() {
1685 return pendingOptions != null ? pendingOptions.forTargetActivity() : null;
1686 }
1687
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001688 void clearOptionsLocked() {
chaviw82a0ba82018-03-15 14:26:29 -07001689 clearOptionsLocked(true /* withAbort */);
1690 }
1691
1692 void clearOptionsLocked(boolean withAbort) {
1693 if (withAbort && pendingOptions != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001694 pendingOptions.abort();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001695 }
chaviw82a0ba82018-03-15 14:26:29 -07001696 pendingOptions = null;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001697 }
1698
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001699 ActivityOptions takeOptionsLocked() {
1700 ActivityOptions opts = pendingOptions;
1701 pendingOptions = null;
1702 return opts;
1703 }
1704
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001705 void removeUriPermissionsLocked() {
Dianne Hackborn7e269642010-08-25 19:50:20 -07001706 if (uriPermissions != null) {
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07001707 uriPermissions.removeUriPermissions();
Dianne Hackborn7e269642010-08-25 19:50:20 -07001708 uriPermissions = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001709 }
1710 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711
1712 void pauseKeyDispatchingLocked() {
1713 if (!keysPaused) {
1714 keysPaused = true;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001715
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001716 // TODO: remove the check after unification with AppWindowToken. The DC check is not
1717 // needed after no mock mAppWindowToken in tests.
1718 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
1719 mAppWindowToken.getDisplayContent().getInputMonitor().pauseDispatchingLw(
1720 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07001721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 }
1723 }
1724
1725 void resumeKeyDispatchingLocked() {
1726 if (keysPaused) {
1727 keysPaused = false;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001728
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001729 // TODO: remove the check after unification with AppWindowToken. The DC check is not
1730 // needed after no mock mAppWindowToken in tests.
1731 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
1732 mAppWindowToken.getDisplayContent().getInputMonitor().resumeDispatchingLw(
1733 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07001734 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001735 }
1736 }
1737
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001738 private void updateTaskDescription(CharSequence description) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001739 task.lastDescription = description;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001740 }
1741
Wale Ogunwaleec950642017-04-25 07:44:21 -07001742 void setDeferHidingClient(boolean deferHidingClient) {
1743 if (mDeferHidingClient == deferHidingClient) {
1744 return;
1745 }
1746 mDeferHidingClient = deferHidingClient;
1747 if (!mDeferHidingClient && !visible) {
1748 // Hiding the client is no longer deferred and the app isn't visible still, go ahead and
1749 // update the visibility.
1750 setVisibility(false);
1751 }
Wale Ogunwale89973222017-04-23 18:39:45 -07001752 }
1753
Wale Ogunwaleec950642017-04-25 07:44:21 -07001754 void setVisibility(boolean visible) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001755 if (mAppWindowToken == null) {
1756 Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: "
1757 + appToken);
1758 return;
1759 }
1760 mAppWindowToken.setVisibility(visible, mDeferHidingClient);
Bryce Lee2a3cc462017-10-27 10:57:35 -07001761 mStackSupervisor.getActivityMetricsLogger().notifyVisibilityChanged(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001762 }
1763
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001764 // TODO: Look into merging with #commitVisibility()
Wale Ogunwaleec950642017-04-25 07:44:21 -07001765 void setVisible(boolean newVisible) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001766 visible = newVisible;
Wale Ogunwaleec950642017-04-25 07:44:21 -07001767 mDeferHidingClient = !visible && mDeferHidingClient;
Wale Ogunwaleec950642017-04-25 07:44:21 -07001768 setVisibility(visible);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001769 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
1770 }
1771
Bryce Lee7ace3952018-02-16 14:34:32 -08001772 void setState(ActivityState state, String reason) {
1773 if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState()
1774 + " to:" + state + " reason:" + reason);
Bryce Lee6ff17072018-02-28 07:26:17 -08001775
Bryce Leeb0f993f2018-03-02 15:38:01 -08001776 if (state == mState) {
1777 // No need to do anything if state doesn't change.
1778 if (DEBUG_STATES) Slog.v(TAG_STATES, "State unchanged from:" + state);
1779 return;
1780 }
1781
Bryce Leeb0f993f2018-03-02 15:38:01 -08001782 mState = state;
1783
Bryce Leec4ab62a2018-03-05 14:19:26 -08001784 final TaskRecord parent = getTask();
1785
1786 if (parent != null) {
1787 parent.onActivityStateChanged(this, state, reason);
1788 }
Robert Carr29daa922018-04-27 11:56:48 -07001789
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001790 // The WindowManager interprets the app stopping signal as
1791 // an indication that the Surface will eventually be destroyed.
1792 // This however isn't necessarily true if we are going to sleep.
1793 if (state == STOPPING && !isSleeping()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001794 if (mAppWindowToken == null) {
1795 Slog.w(TAG_WM, "Attempted to notify stopping on non-existing app token: "
1796 + appToken);
1797 return;
1798 }
1799 mAppWindowToken.detachChildren();
Robert Carr29daa922018-04-27 11:56:48 -07001800 }
Bryce Lee7ace3952018-02-16 14:34:32 -08001801 }
1802
1803 ActivityState getState() {
1804 return mState;
1805 }
1806
1807 /**
1808 * Returns {@code true} if the Activity is in the specified state.
1809 */
1810 boolean isState(ActivityState state) {
1811 return state == mState;
1812 }
1813
1814 /**
1815 * Returns {@code true} if the Activity is in one of the specified states.
1816 */
1817 boolean isState(ActivityState state1, ActivityState state2) {
1818 return state1 == mState || state2 == mState;
1819 }
1820
1821 /**
1822 * Returns {@code true} if the Activity is in one of the specified states.
1823 */
1824 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3) {
1825 return state1 == mState || state2 == mState || state3 == mState;
1826 }
1827
1828 /**
1829 * Returns {@code true} if the Activity is in one of the specified states.
1830 */
1831 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3,
1832 ActivityState state4) {
1833 return state1 == mState || state2 == mState || state3 == mState || state4 == mState;
1834 }
1835
Jorim Jaggibae01b12017-04-11 16:29:10 -07001836 void notifyAppResumed(boolean wasStopped) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001837 if (mAppWindowToken == null) {
1838 Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: "
1839 + appToken);
1840 return;
1841 }
1842 mAppWindowToken.notifyAppResumed(wasStopped);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001843 }
1844
1845 void notifyUnknownVisibilityLaunched() {
Jorim Jaggi838c2452017-08-28 15:44:43 +02001846
1847 // No display activities never add a window, so there is no point in waiting them for
1848 // relayout.
1849 if (!noDisplay) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001850 if (mAppWindowToken != null) {
1851 mAppWindowToken.getDisplayContent().mUnknownAppVisibilityController
1852 .notifyLaunched(mAppWindowToken);
1853 }
Jorim Jaggi838c2452017-08-28 15:44:43 +02001854 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001855 }
1856
Jorim Jaggi241ae102016-11-02 21:57:33 -07001857 /**
1858 * @return true if the input activity should be made visible, ignoring any effect Keyguard
1859 * might have on the visibility
1860 *
1861 * @see {@link ActivityStack#checkKeyguardVisibility}
1862 */
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001863 boolean shouldBeVisibleIgnoringKeyguard(boolean behindFullscreenActivity) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001864 if (!okToShowLocked()) {
1865 return false;
1866 }
1867
Winson Chung3f0e59a2017-10-25 10:19:05 -07001868 return !behindFullscreenActivity || mLaunchTaskBehind;
Andrii Kulian21713ac2016-10-12 22:05:05 -07001869 }
1870
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001871 void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001872 // This activity is not currently visible, but is running. Tell it to become visible.
Bryce Lee7ace3952018-02-16 14:34:32 -08001873 if (mState == RESUMED || this == starting) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001874 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
Bryce Lee7ace3952018-02-16 14:34:32 -08001875 "Not making visible, r=" + this + " state=" + mState + " starting=" + starting);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001876 return;
1877 }
1878
1879 // If this activity is paused, tell it to now show its window.
1880 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1881 "Making visible and scheduling visibility: " + this);
1882 final ActivityStack stack = getStack();
1883 try {
1884 if (stack.mTranslucentActivityWaiting != null) {
1885 updateOptionsLocked(returningOptions);
1886 stack.mUndrawnActivitiesBelowTopTranslucent.add(this);
1887 }
1888 setVisible(true);
1889 sleeping = false;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001890 app.postPendingUiCleanMsg(true);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001891 if (reportToClient) {
1892 makeClientVisible();
1893 } else {
1894 mClientVisibilityDeferred = true;
1895 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07001896 // The activity may be waiting for stop, but that is no longer appropriate for it.
1897 mStackSupervisor.mStoppingActivities.remove(this);
1898 mStackSupervisor.mGoingToSleepActivities.remove(this);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001899 } catch (Exception e) {
1900 // Just skip on any failure; we'll make it visible when it next restarts.
1901 Slog.w(TAG, "Exception thrown making visible: " + intent.getComponent(), e);
1902 }
1903 handleAlreadyVisible();
1904 }
Andrii Kulian0d595f32018-02-21 15:47:33 -08001905
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001906 /** Send visibility change message to the client and pause if needed. */
1907 void makeClientVisible() {
1908 mClientVisibilityDeferred = false;
1909 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001910 service.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001911 WindowVisibilityItem.obtain(true /* showWindow */));
Andrii Kulian09e1afa2018-05-16 21:29:34 -07001912 if (shouldPauseWhenBecomingVisible()) {
Andrii Kulian0d595f32018-02-21 15:47:33 -08001913 // An activity must be in the {@link PAUSING} state for the system to validate
1914 // the move to {@link PAUSED}.
Bryce Lee7ace3952018-02-16 14:34:32 -08001915 setState(PAUSING, "makeVisibleIfNeeded");
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001916 service.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian0d595f32018-02-21 15:47:33 -08001917 PauseActivityItem.obtain(finishing, false /* userLeaving */,
Bryce Lee1d0d5142018-04-12 10:35:07 -07001918 configChangeFlags, false /* dontReport */));
Andrii Kulian0d595f32018-02-21 15:47:33 -08001919 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07001920 } catch (Exception e) {
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001921 Slog.w(TAG, "Exception thrown sending visibility update: " + intent.getComponent(), e);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001922 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07001923 }
1924
Andrii Kulian09e1afa2018-05-16 21:29:34 -07001925 /** Check if activity should be moved to PAUSED state when it becomes visible. */
1926 private boolean shouldPauseWhenBecomingVisible() {
1927 // If the activity is stopped or stopping, cycle to the paused state. We avoid doing
1928 // this when there is an activity waiting to become translucent as the extra binder
1929 // calls will lead to noticeable jank. A later call to
1930 // ActivityStack#ensureActivitiesVisibleLocked will bring the activity to the proper
1931 // paused state. We also avoid doing this for the activity the stack supervisor
1932 // considers the resumed activity, as normal means will bring the activity from STOPPED
1933 // to RESUMED. Adding PAUSING in this scenario will lead to double lifecycles.
1934 if (!isState(STOPPED, STOPPING) || getStack().mTranslucentActivityWaiting != null
Andrii Kulian52d255c2018-07-13 11:32:19 -07001935 || isResumedActivityOnDisplay()) {
Andrii Kulian09e1afa2018-05-16 21:29:34 -07001936 return false;
1937 }
1938
1939 // Check if position in task allows to become paused
1940 final int positionInTask = task.mActivities.indexOf(this);
1941 if (positionInTask == -1) {
1942 throw new IllegalStateException("Activity not found in its task");
1943 }
1944 if (positionInTask == task.mActivities.size() - 1) {
1945 // It's the topmost activity in the task - should become paused now
1946 return true;
1947 }
1948 // Check if activity above is finishing now and this one becomes the topmost in task.
1949 final ActivityRecord activityAbove = task.mActivities.get(positionInTask + 1);
1950 if (activityAbove.finishing && results == null) {
1951 // We will only allow pausing if activity above wasn't launched for result. Otherwise it
1952 // will cause this activity to resume before getting result.
1953 return true;
1954 }
1955 return false;
1956 }
1957
Andrii Kulian21713ac2016-10-12 22:05:05 -07001958 boolean handleAlreadyVisible() {
1959 stopFreezingScreenLocked(false);
1960 try {
1961 if (returningOptions != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001962 app.getThread().scheduleOnNewActivityOptions(appToken, returningOptions.toBundle());
Andrii Kulian21713ac2016-10-12 22:05:05 -07001963 }
1964 } catch(RemoteException e) {
1965 }
Bryce Lee7ace3952018-02-16 14:34:32 -08001966 return mState == RESUMED;
Andrii Kulian21713ac2016-10-12 22:05:05 -07001967 }
1968
1969 static void activityResumedLocked(IBinder token) {
1970 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
1971 if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
1972 if (r != null) {
1973 r.icicle = null;
1974 r.haveState = false;
1975 }
1976 }
1977
1978 /**
1979 * Once we know that we have asked an application to put an activity in the resumed state
1980 * (either by launching it or explicitly telling it), this function updates the rest of our
1981 * state to match that fact.
1982 */
1983 void completeResumeLocked() {
1984 final boolean wasVisible = visible;
Jorim Jaggi8d062052017-08-22 14:55:17 +02001985 setVisible(true);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001986 if (!wasVisible) {
1987 // Visibility has changed, so take a note of it so we call the TaskStackChangedListener
1988 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
1989 }
1990 idle = false;
1991 results = null;
1992 newIntents = null;
1993 stopped = false;
1994
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001995 if (isActivityTypeHome()) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001996 WindowProcessController app = task.mActivities.get(0).app;
1997 if (hasProcess() && app != service.mHomeProcess) {
1998 service.mHomeProcess = app;
Andrii Kulian21713ac2016-10-12 22:05:05 -07001999 }
2000 }
2001
2002 if (nowVisible) {
2003 // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
2004 mStackSupervisor.reportActivityVisibleLocked(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002005 }
2006
2007 // Schedule an idle timeout in case the app doesn't do it for us.
2008 mStackSupervisor.scheduleIdleTimeoutLocked(this);
2009
2010 mStackSupervisor.reportResumedActivityLocked(this);
2011
2012 resumeKeyDispatchingLocked();
2013 final ActivityStack stack = getStack();
Jorim Jaggifa9ed962018-01-25 00:16:49 +01002014 mStackSupervisor.mNoAnimActivities.clear();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002015
2016 // Mark the point when the activity is resuming
2017 // TODO: To be more accurate, the mark should be before the onCreate,
2018 // not after the onResume. But for subsequent starts, onResume is fine.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002019 if (hasProcess()) {
Wale Ogunwale86b74462018-07-02 08:42:43 -07002020 cpuTimeAtResume = app.getCpuTime();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002021 } else {
2022 cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2023 }
2024
2025 returningOptions = null;
chaviw59b98852017-06-13 12:05:44 -07002026
2027 if (canTurnScreenOn()) {
2028 mStackSupervisor.wakeUp("turnScreenOnFlag");
2029 } else {
2030 // If the screen is going to turn on because the caller explicitly requested it and
2031 // the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
2032 // pause and then resume again later, which will result in a double life-cycle event.
David Stevens9440dc82017-03-16 19:00:20 -07002033 stack.checkReadyForSleep();
chaviw59b98852017-06-13 12:05:44 -07002034 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002035 }
2036
2037 final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
2038 CharSequence description) {
2039 final ActivityStack stack = getStack();
Bryce Lee7ace3952018-02-16 14:34:32 -08002040 if (mState != STOPPING) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002041 Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
Ruben Brunkf53497c2017-03-27 20:26:17 -07002042 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002043 return;
2044 }
2045 if (newPersistentState != null) {
2046 persistentState = newPersistentState;
2047 service.notifyTaskPersisterLocked(task, false);
2048 }
2049 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + icicle);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002050
Andrii Kulian21713ac2016-10-12 22:05:05 -07002051 if (newIcicle != null) {
2052 // If icicle is null, this is happening due to a timeout, so we haven't really saved
2053 // the state.
2054 icicle = newIcicle;
2055 haveState = true;
2056 launchCount = 0;
Jorim Jaggie7d2b852017-08-28 17:55:15 +02002057 updateTaskDescription(description);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002058 }
2059 if (!stopped) {
2060 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
Ruben Brunkf53497c2017-03-27 20:26:17 -07002061 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002062 stopped = true;
Bryce Lee7ace3952018-02-16 14:34:32 -08002063 setState(STOPPED, "activityStoppedLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07002064
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002065 if (mAppWindowToken != null) {
2066 mAppWindowToken.notifyAppStopped();
2067 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002068
Andrii Kulian21713ac2016-10-12 22:05:05 -07002069 if (finishing) {
2070 clearOptionsLocked();
2071 } else {
2072 if (deferRelaunchUntilPaused) {
2073 stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002074 mRootActivityContainer.resumeFocusedStacksTopActivities();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002075 } else {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002076 mRootActivityContainer.updatePreviousProcess(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002077 }
2078 }
2079 }
2080 }
2081
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002082 void startLaunchTickingLocked() {
Jeff Sharkey5ab02432017-06-27 11:01:36 -06002083 if (Build.IS_USER) {
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002084 return;
2085 }
2086 if (launchTickTime == 0) {
2087 launchTickTime = SystemClock.uptimeMillis();
2088 continueLaunchTickingLocked();
2089 }
2090 }
2091
2092 boolean continueLaunchTickingLocked() {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002093 if (launchTickTime == 0) {
2094 return false;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002095 }
Wale Ogunwale7d701172015-03-11 15:36:30 -07002096
Andrii Kulian02b7a832016-10-06 23:11:56 -07002097 final ActivityStack stack = getStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002098 if (stack == null) {
2099 return false;
2100 }
2101
Ruben Brunkf53497c2017-03-27 20:26:17 -07002102 Message msg = stack.mHandler.obtainMessage(LAUNCH_TICK_MSG, this);
2103 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
2104 stack.mHandler.sendMessageDelayed(msg, LAUNCH_TICK);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002105 return true;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002106 }
2107
2108 void finishLaunchTickingLocked() {
2109 launchTickTime = 0;
Andrii Kulian02b7a832016-10-06 23:11:56 -07002110 final ActivityStack stack = getStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002111 if (stack != null) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07002112 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002113 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002114 }
2115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116 // IApplicationToken
2117
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002118 public boolean mayFreezeScreenLocked(WindowProcessController app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002119 // Only freeze the screen if this activity is currently attached to
2120 // an application, and that application is not blocked or unresponding.
2121 // In any other case, we can't count on getting the screen unfrozen,
2122 // so it is best to leave as-is.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002123 return hasProcess() && !app.isCrashing() && !app.isNotResponding();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002124 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002125
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002126 public void startFreezingScreenLocked(WindowProcessController app, int configChanges) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002127 if (mayFreezeScreenLocked(app)) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002128 if (mAppWindowToken == null) {
2129 Slog.w(TAG_WM,
2130 "Attempted to freeze screen with non-existing app token: " + appToken);
2131 return;
2132 }
2133
2134 if (configChanges == 0 && mAppWindowToken.okToDisplay()) {
2135 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + appToken);
2136 return;
2137 }
2138
2139 mAppWindowToken.startFreezingScreen();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002140 }
2141 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002143 public void stopFreezingScreenLocked(boolean force) {
2144 if (force || frozenBeforeDestroy) {
2145 frozenBeforeDestroy = false;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002146 if (mAppWindowToken == null) {
2147 return;
2148 }
2149 if (DEBUG_ORIENTATION) {
2150 Slog.v(TAG_WM, "Clear freezing of " + appToken + ": hidden="
2151 + mAppWindowToken.isHidden() + " freezing="
2152 + mAppWindowToken.isFreezingScreen());
2153 }
2154 mAppWindowToken.stopFreezingScreen(true, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155 }
2156 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002157
Jorim Jaggi4d27b842017-08-17 17:22:26 +02002158 public void reportFullyDrawnLocked(boolean restoredFromBundle) {
Vishnu Nair132ee832018-09-28 15:00:05 -07002159 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2160 .getActivityMetricsLogger().logAppTransitionReportedDrawn(this, restoredFromBundle);
2161 if (info != null) {
2162 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
2163 info.windowsFullyDrawnDelayMs);
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002164 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002165 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002166
2167 /**
2168 * Called when the starting window for this container is drawn.
2169 */
Sudheer Shankac766db02017-06-12 10:37:29 -07002170 public void onStartingWindowDrawn(long timestamp) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002171 synchronized (service.mGlobalLock) {
Bryce Lee2a3cc462017-10-27 10:57:35 -07002172 mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +01002173 getWindowingMode(), timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -08002174 }
2175 }
2176
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002177 /** Called when the windows associated app window container are drawn. */
Vishnu Nair9ba31652018-11-13 14:34:05 -08002178 public void onWindowsDrawn(boolean drawn, long timestamp) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002179 synchronized (service.mGlobalLock) {
Vishnu Nair9ba31652018-11-13 14:34:05 -08002180 mDrawn = drawn;
2181 if (!drawn) {
2182 return;
2183 }
Vishnu Nair132ee832018-09-28 15:00:05 -07002184 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2185 .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
2186 final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
2187 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
2188 windowsDrawnDelayMs);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002189 mStackSupervisor.sendWaitingVisibleReportLocked(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002190 finishLaunchTickingLocked();
2191 if (task != null) {
2192 task.hasBeenVisible = true;
2193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002194 }
2195 }
2196
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002197 /** Called when the windows associated app window container are visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002198 public void onWindowsVisible() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002199 synchronized (service.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002200 mStackSupervisor.reportActivityVisibleLocked(this);
2201 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
2202 if (!nowVisible) {
2203 nowVisible = true;
2204 lastVisibleTime = SystemClock.uptimeMillis();
Bryce Leeb7c9b802017-05-02 14:20:24 -07002205 if (idle || mStackSupervisor.isStoppingNoHistoryActivity()) {
2206 // If this activity was already idle or there is an activity that must be
2207 // stopped immediately after visible, then we now need to make sure we perform
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002208 // the full stop of any activities that are waiting to do so. This is because
2209 // we won't do that while they are still waiting for this one to become visible.
Bryce Lee4a194382017-04-04 14:32:48 -07002210 final int size = mStackSupervisor.mActivitiesWaitingForVisibleActivity.size();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002211 if (size > 0) {
2212 for (int i = 0; i < size; i++) {
Bryce Lee4a194382017-04-04 14:32:48 -07002213 final ActivityRecord r =
2214 mStackSupervisor.mActivitiesWaitingForVisibleActivity.get(i);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002215 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "Was waiting for visible: " + r);
2216 }
Bryce Lee4a194382017-04-04 14:32:48 -07002217 mStackSupervisor.mActivitiesWaitingForVisibleActivity.clear();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002218 mStackSupervisor.scheduleIdleLocked();
2219 }
Bryce Leeb7c9b802017-05-02 14:20:24 -07002220 } else {
2221 // Instead of doing the full stop routine here, let's just hide any activities
2222 // we now can, and let them stop when the normal idle happens.
2223 mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
2224 false /* remove */, true /* processPausingActivities */);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002225 }
Wale Ogunwale906f9c62018-07-23 11:23:44 -07002226 service.scheduleAppGcsLocked();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002227 }
2228 }
2229 }
2230
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002231 /** Called when the windows associated app window container are no longer visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002232 public void onWindowsGone() {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002233 synchronized (service.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002234 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + this);
2235 nowVisible = false;
2236 }
2237 }
2238
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002239 /**
2240 * Called when the key dispatching to a window associated with the app window container
2241 * timed-out.
2242 *
2243 * @param reason The reason for the key dispatching time out.
2244 * @param windowPid The pid of the window key dispatching timed out on.
2245 * @return True if input dispatching should be aborted.
2246 */
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002247 public boolean keyDispatchingTimedOut(String reason, int windowPid) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002248 ActivityRecord anrActivity;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002249 WindowProcessController anrApp;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002250 boolean windowFromSameProcessAsActivity;
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002251 synchronized (service.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002252 anrActivity = getWaitingHistoryRecordLocked();
2253 anrApp = app;
Brian Carlstrom7b0f2e82017-03-31 00:24:18 -07002254 windowFromSameProcessAsActivity =
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002255 !hasProcess() || app.getPid() == windowPid || windowPid == -1;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002256 }
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002257
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002258 if (windowFromSameProcessAsActivity) {
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002259 return service.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner,
2260 anrActivity.shortComponentName, anrActivity.appInfo, shortComponentName,
2261 app, false, reason);
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002262 } else {
2263 // In this case another process added windows using this activity token. So, we call the
2264 // generic service input dispatch timed out method so that the right process is blamed.
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002265 return service.mAmInternal.inputDispatchingTimedOut(
2266 windowPid, false /* aboveSystem */, reason) < 0;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002267 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002268 }
2269
2270 private ActivityRecord getWaitingHistoryRecordLocked() {
riddle_hsudb46d6b2015-04-01 18:58:07 +08002271 // First find the real culprit... if this activity is waiting for
2272 // another activity to start or has stopped, then the key dispatching
2273 // timeout should not be caused by this.
Bryce Lee4a194382017-04-04 14:32:48 -07002274 if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this) || stopped) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002275 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
riddle_hsudb46d6b2015-04-01 18:58:07 +08002276 // Try to use the one which is closest to top.
Bryce Leec4ab62a2018-03-05 14:19:26 -08002277 ActivityRecord r = stack.getResumedActivity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 if (r == null) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002279 r = stack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002280 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002281 if (r != null) {
2282 return r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002283 }
2284 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002285 return this;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 }
2287
Chong Zhang87761972016-08-22 13:53:24 -07002288 /** Checks whether the activity should be shown for current user. */
2289 public boolean okToShowLocked() {
Bryce Lee8558ec72017-08-17 15:37:26 -07002290 // We cannot show activities when the device is locked and the application is not
2291 // encryption aware.
2292 if (!StorageManager.isUserKeyUnlocked(userId)
2293 && !info.applicationInfo.isEncryptionAware()) {
2294 return false;
2295 }
2296
Chong Zhang87761972016-08-22 13:53:24 -07002297 return (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0
2298 || (mStackSupervisor.isCurrentProfileLocked(userId)
Wale Ogunwale86b74462018-07-02 08:42:43 -07002299 && service.mAmInternal.isUserRunning(userId, 0 /* flags */));
Chong Zhang87761972016-08-22 13:53:24 -07002300 }
2301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 /**
2303 * This method will return true if the activity is either visible, is becoming visible, is
2304 * currently pausing, or is resumed.
2305 */
2306 public boolean isInterestingToUserLocked() {
Bryce Lee7ace3952018-02-16 14:34:32 -08002307 return visible || nowVisible || mState == PAUSING || mState == RESUMED;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002308 }
2309
Wale Ogunwale3e997362016-09-06 10:37:56 -07002310 void setSleeping(boolean _sleeping) {
2311 setSleeping(_sleeping, false);
2312 }
2313
2314 void setSleeping(boolean _sleeping, boolean force) {
2315 if (!force && sleeping == _sleeping) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002316 return;
2317 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002318 if (attachedToProcess()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002319 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002320 app.getThread().scheduleSleeping(appToken, _sleeping);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002321 if (_sleeping && !mStackSupervisor.mGoingToSleepActivities.contains(this)) {
2322 mStackSupervisor.mGoingToSleepActivities.add(this);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002323 }
2324 sleeping = _sleeping;
2325 } catch (RemoteException e) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002326 Slog.w(TAG, "Exception thrown when sleeping: " + intent.getComponent(), e);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002327 }
2328 }
2329 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08002330
Craig Mautnerd2328952013-03-05 12:46:26 -08002331 static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002332 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Craig Mautnerd2328952013-03-05 12:46:26 -08002333 if (r == null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002334 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002335 }
2336 final TaskRecord task = r.task;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002337 final int activityNdx = task.mActivities.indexOf(r);
2338 if (activityNdx < 0 || (onlyRoot && activityNdx > task.findEffectiveRootIndex())) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002339 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002340 }
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002341 return task.taskId;
Craig Mautnerd2328952013-03-05 12:46:26 -08002342 }
2343
2344 static ActivityRecord isInStackLocked(IBinder token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002345 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Andrii Kulian02b7a832016-10-06 23:11:56 -07002346 return (r != null) ? r.getStack().isInStackLocked(r) : null;
Craig Mautnerd2328952013-03-05 12:46:26 -08002347 }
2348
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002349 static ActivityStack getStackLocked(IBinder token) {
Craig Mautnerd2328952013-03-05 12:46:26 -08002350 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2351 if (r != null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002352 return r.getStack();
Craig Mautnerd2328952013-03-05 12:46:26 -08002353 }
2354 return null;
2355 }
2356
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002357 /**
Riddle Hsufd4a0502018-10-16 01:05:16 +08002358 * @return display id to which this record is attached,
2359 * {@link android.view.Display#INVALID_DISPLAY} if not attached.
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002360 */
2361 int getDisplayId() {
2362 final ActivityStack stack = getStack();
2363 if (stack == null) {
Riddle Hsufd4a0502018-10-16 01:05:16 +08002364 return INVALID_DISPLAY;
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002365 }
2366 return stack.mDisplayId;
2367 }
2368
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002369 final boolean isDestroyable() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002370 if (finishing || !hasProcess()) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002371 // This would be redundant.
2372 return false;
2373 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002374 final ActivityStack stack = getStack();
Bryce Leec4ab62a2018-03-05 14:19:26 -08002375 if (stack == null || this == stack.getResumedActivity() || this == stack.mPausingActivity
Andrii Kulian02b7a832016-10-06 23:11:56 -07002376 || !haveState || !stopped) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002377 // We're not ready for this kind of thing.
2378 return false;
2379 }
2380 if (visible) {
2381 // The user would notice this!
2382 return false;
2383 }
2384 return true;
2385 }
2386
Winson Chung3bad5cc02014-08-19 17:44:32 -07002387 private static String createImageFilename(long createTime, int taskId) {
2388 return String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX + createTime +
Ruben Brunkf53497c2017-03-27 20:26:17 -07002389 IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -07002390 }
2391
Craig Mautner648f69b2014-09-18 14:16:26 -07002392 void setTaskDescription(TaskDescription _taskDescription) {
2393 Bitmap icon;
2394 if (_taskDescription.getIconFilename() == null &&
2395 (icon = _taskDescription.getIcon()) != null) {
2396 final String iconFilename = createImageFilename(createTime, task.taskId);
Winson Chungc8408b82017-01-25 17:58:56 -08002397 final File iconFile = new File(TaskPersister.getUserImagesDir(task.userId),
2398 iconFilename);
Suprabh Shukla23593142015-11-03 17:31:15 -08002399 final String iconFilePath = iconFile.getAbsolutePath();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002400 service.getRecentTasks().saveImage(icon, iconFilePath);
Suprabh Shukla23593142015-11-03 17:31:15 -08002401 _taskDescription.setIconFilename(iconFilePath);
Craig Mautner648f69b2014-09-18 14:16:26 -07002402 }
2403 taskDescription = _taskDescription;
2404 }
2405
Amith Yamasani0af6fa72016-01-17 15:36:19 -08002406 void setVoiceSessionLocked(IVoiceInteractionSession session) {
2407 voiceSession = session;
2408 pendingVoiceInteractionStart = false;
2409 }
2410
2411 void clearVoiceSessionLocked() {
2412 voiceSession = null;
2413 pendingVoiceInteractionStart = false;
2414 }
2415
Jorim Jaggi02886a82016-12-06 09:10:06 -08002416 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch) {
Jorim Jaggi42befc62017-06-13 11:54:04 -07002417 showStartingWindow(prev, newTask, taskSwitch, false /* fromRecents */);
2418 }
2419
2420 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
2421 boolean fromRecents) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002422 if (mAppWindowToken == null) {
Jorim Jaggi70176432017-01-18 12:52:13 +01002423 return;
2424 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002425 if (mTaskOverlay) {
2426 // We don't show starting window for overlay activities.
2427 return;
2428 }
Sunny Goyald85bed52018-09-25 12:01:01 -07002429 if (pendingOptions != null
2430 && pendingOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
2431 // Don't show starting window when using shared element transition.
2432 return;
2433 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002434
Wale Ogunwale3b232392016-05-13 15:37:13 -07002435 final CompatibilityInfo compatInfo =
Wale Ogunwale53783742018-09-16 10:21:51 -07002436 service.compatibilityInfoForPackageLocked(info.applicationInfo);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002437 final boolean shown = addStartingWindow(packageName, theme,
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002438 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
Jorim Jaggibae01b12017-04-11 16:29:10 -07002439 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
Jorim Jaggi70aa4d12017-05-15 00:05:54 +02002440 allowTaskSnapshot(),
Bryce Lee7ace3952018-02-16 14:34:32 -08002441 mState.ordinal() >= RESUMED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
Jorim Jaggi42befc62017-06-13 11:54:04 -07002442 fromRecents);
Wale Ogunwale3b232392016-05-13 15:37:13 -07002443 if (shown) {
2444 mStartingWindowState = STARTING_WINDOW_SHOWN;
2445 }
2446 }
2447
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002448 void removeOrphanedStartingWindow(boolean behindFullscreenActivity) {
Jorim Jaggicb956052017-05-09 16:27:24 +02002449 if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002450 if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
2451 mStartingWindowState = STARTING_WINDOW_REMOVED;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002452 mAppWindowToken.removeStartingWindow();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002453 }
2454 }
2455
2456 int getRequestedOrientation() {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002457 return getOrientation();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002458 }
2459
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002460 void setRequestedOrientation(int requestedOrientation) {
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002461 final int displayId = getDisplayId();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002462 final Configuration displayConfig =
Wale Ogunwaled32da472018-11-16 07:19:28 -08002463 mRootActivityContainer.getDisplayOverrideConfiguration(displayId);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002464
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002465 final Configuration config = setOrientation(requestedOrientation,
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002466 displayId, displayConfig, mayFreezeScreenLocked(app));
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002467 if (config != null) {
2468 frozenBeforeDestroy = true;
Wale Ogunwalea6191b42018-05-09 07:41:32 -07002469 if (!service.updateDisplayOverrideConfigurationLocked(config, this,
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002470 false /* deferResume */, displayId)) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002471 mRootActivityContainer.resumeFocusedStacksTopActivities();
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002472 }
2473 }
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002474 service.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
Yorke Leebd54c2a2016-10-25 13:49:23 -07002475 task.taskId, requestedOrientation);
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002476 }
2477
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002478 Configuration setOrientation(int requestedOrientation, int displayId,
2479 Configuration displayConfig, boolean freezeScreenIfNeeded) {
2480 if (mAppWindowToken == null) {
2481 Slog.w(TAG_WM,
2482 "Attempted to set orientation of non-existing app token: " + appToken);
2483 return null;
2484 }
2485
2486 mAppWindowToken.setOrientation(requestedOrientation);
2487
2488 final IBinder binder = freezeScreenIfNeeded ? appToken.asBinder() : null;
2489 return service.mWindowManager.updateOrientationFromAppTokens(displayConfig, binder,
2490 displayId);
2491 }
2492
2493 int getOrientation() {
2494 if (mAppWindowToken == null) {
2495 return SCREEN_ORIENTATION_UNSPECIFIED;
2496 }
2497
2498 return mAppWindowToken.getOrientationIgnoreVisibility();
2499 }
2500
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002501 void setDisablePreviewScreenshots(boolean disable) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002502 if (mAppWindowToken == null) {
2503 Slog.w(TAG_WM, "Attempted to set disable screenshots of non-existing app"
2504 + " token: " + appToken);
2505 return;
2506 }
2507 mAppWindowToken.setDisablePreviewScreenshots(disable);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002508 }
2509
Bryce Leea163b762017-01-24 11:05:01 -08002510 /**
2511 * Set the last reported global configuration to the client. Should be called whenever a new
2512 * global configuration is sent to the client for this activity.
2513 */
2514 void setLastReportedGlobalConfiguration(@NonNull Configuration config) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002515 mLastReportedConfiguration.setGlobalConfiguration(config);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002516 }
2517
Bryce Leea163b762017-01-24 11:05:01 -08002518 /**
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002519 * Set the last reported configuration to the client. Should be called whenever
Bryce Leea163b762017-01-24 11:05:01 -08002520 * a new merged configuration is sent to the client for this activity.
2521 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002522 void setLastReportedConfiguration(@NonNull MergedConfiguration config) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002523 setLastReportedConfiguration(config.getGlobalConfiguration(),
2524 config.getOverrideConfiguration());
Bryce Leea163b762017-01-24 11:05:01 -08002525 }
2526
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002527 private void setLastReportedConfiguration(Configuration global, Configuration override) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002528 mLastReportedConfiguration.setConfiguration(global, override);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002529 }
2530
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002531 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002532 private void updateOverrideConfiguration() {
2533 mTmpConfig.unset();
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002534 computeBounds(mTmpBounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08002535
2536 if (mTmpBounds.equals(getOverrideBounds())) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002537 return;
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002538 }
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002539
Bryce Leef3c6a472017-11-14 14:53:06 -08002540 setBounds(mTmpBounds);
2541
2542 final Rect updatedBounds = getOverrideBounds();
2543
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002544 // Bounds changed...update configuration to match.
Bryce Leef3c6a472017-11-14 14:53:06 -08002545 if (!matchParentBounds()) {
2546 task.computeOverrideConfiguration(mTmpConfig, updatedBounds, null /* insetBounds */,
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002547 false /* overrideWidth */, false /* overrideHeight */);
2548 }
Bryce Leef3c6a472017-11-14 14:53:06 -08002549
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002550 onOverrideConfigurationChanged(mTmpConfig);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002551 }
2552
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07002553 /** Returns true if the configuration is compatible with this activity. */
Wale Ogunwale42f07d92017-05-01 21:32:58 -07002554 boolean isConfigurationCompatible(Configuration config) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002555 final int orientation = mAppWindowToken != null
2556 ? getOrientation() : info.screenOrientation;
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07002557 if (isFixedOrientationPortrait(orientation)
2558 && config.orientation != ORIENTATION_PORTRAIT) {
2559 return false;
2560 }
2561 if (isFixedOrientationLandscape(orientation)
2562 && config.orientation != ORIENTATION_LANDSCAPE) {
2563 return false;
2564 }
2565 return true;
2566 }
2567
Bryce Lee7566d762017-03-30 09:34:15 -07002568 /**
2569 * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}.
2570 */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002571 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
2572 private void computeBounds(Rect outBounds) {
2573 outBounds.setEmpty();
2574 final float maxAspectRatio = info.maxAspectRatio;
2575 final ActivityStack stack = getStack();
Bryce Leef3c6a472017-11-14 14:53:06 -08002576 if (task == null || stack == null || task.inMultiWindowMode() || maxAspectRatio == 0
Bryce Leee5ab4502017-07-11 08:58:05 -07002577 || isInVrUiMode(getConfiguration())) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002578 // We don't set override configuration if that activity task isn't fullscreen. I.e. the
2579 // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
Bryce Leee5ab4502017-07-11 08:58:05 -07002580 // the activity. This is indicated by an empty {@link outBounds}. We also don't set it
2581 // if we are in VR mode.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002582 return;
2583 }
2584
Bryce Lee7566d762017-03-30 09:34:15 -07002585 // We must base this on the parent configuration, because we set our override
2586 // configuration's appBounds based on the result of this method. If we used our own
2587 // configuration, it would be influenced by past invocations.
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002588 final Rect appBounds = getParent().getWindowConfiguration().getAppBounds();
Wale Ogunwale822e5122017-07-26 06:02:24 -07002589 final int containingAppWidth = appBounds.width();
2590 final int containingAppHeight = appBounds.height();
Bryce Lee7566d762017-03-30 09:34:15 -07002591 int maxActivityWidth = containingAppWidth;
2592 int maxActivityHeight = containingAppHeight;
2593
2594 if (containingAppWidth < containingAppHeight) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002595 // Width is the shorter side, so we use that to figure-out what the max. height
2596 // should be given the aspect ratio.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002597 maxActivityHeight = (int) ((maxActivityWidth * maxAspectRatio) + 0.5f);
2598 } else {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002599 // Height is the shorter side, so we use that to figure-out what the max. width
2600 // should be given the aspect ratio.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002601 maxActivityWidth = (int) ((maxActivityHeight * maxAspectRatio) + 0.5f);
2602 }
2603
Bryce Lee7566d762017-03-30 09:34:15 -07002604 if (containingAppWidth <= maxActivityWidth && containingAppHeight <= maxActivityHeight) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002605 // The display matches or is less than the activity aspect ratio, so nothing else to do.
Bryce Lee7566d762017-03-30 09:34:15 -07002606 // Return the existing bounds. If this method is running for the first time,
Bryce Leef3c6a472017-11-14 14:53:06 -08002607 // {@link #getOverrideBounds()} will be empty (representing no override). If the method has run
2608 // before, then effect of {@link #getOverrideBounds()} will already have been applied to the
Bryce Lee7566d762017-03-30 09:34:15 -07002609 // value returned from {@link getConfiguration}. Refer to
2610 // {@link TaskRecord#computeOverrideConfiguration}.
Bryce Leef3c6a472017-11-14 14:53:06 -08002611 outBounds.set(getOverrideBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002612 return;
2613 }
2614
2615 // Compute configuration based on max supported width and height.
Adrian Roos24be34d2018-05-28 18:55:38 +02002616 // Also account for the left / top insets (e.g. from display cutouts), which will be clipped
2617 // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app
2618 // bounds would end up too small.
2619 outBounds.set(0, 0, maxActivityWidth + appBounds.left, maxActivityHeight + appBounds.top);
2620
Tiger Huang7c610aa2018-10-27 00:01:01 +08002621 if (service.mWindowManager.getNavBarPosition(getDisplayId()) == NAV_BAR_LEFT) {
Adrian Roos24be34d2018-05-28 18:55:38 +02002622 // Position the activity frame on the opposite side of the nav bar.
2623 outBounds.left = appBounds.right - maxActivityWidth;
2624 outBounds.right = appBounds.right;
2625 }
Andrii Kulian3a1619d2017-07-07 14:38:09 -07002626 }
2627
Riddle Hsu16567132018-08-16 21:37:47 +08002628 /**
2629 * @return {@code true} if this activity was reparented to another display but
2630 * {@link #ensureActivityConfiguration} is not called.
2631 */
2632 boolean shouldUpdateConfigForDisplayChanged() {
2633 return mLastReportedDisplayId != getDisplayId();
2634 }
2635
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002636 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
2637 return ensureActivityConfiguration(globalChanges, preserveWindow,
2638 false /* ignoreStopState */);
2639 }
2640
Andrii Kulian21713ac2016-10-12 22:05:05 -07002641 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002642 * Make sure the given activity matches the current configuration. Ensures the HistoryRecord
2643 * is updated with the correct configuration and all other bookkeeping is handled.
2644 *
2645 * @param globalChanges The changes to the global configuration.
2646 * @param preserveWindow If the activity window should be preserved on screen if the activity
2647 * is relaunched.
2648 * @param ignoreStopState If we should try to relaunch the activity even if it is in the stopped
2649 * state. This is useful for the case where we know the activity will be
2650 * visible soon and we want to ensure its configuration before we make it
2651 * visible.
2652 * @return True if the activity was relaunched and false if it wasn't relaunched because we
2653 * can't or the app handles the specific configuration that is changing.
Andrii Kulian21713ac2016-10-12 22:05:05 -07002654 */
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002655 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
2656 boolean ignoreStopState) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002657 final ActivityStack stack = getStack();
2658 if (stack.mConfigWillChange) {
2659 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2660 "Skipping config check (will change): " + this);
2661 return true;
2662 }
2663
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002664 // We don't worry about activities that are finishing.
2665 if (finishing) {
2666 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2667 "Configuration doesn't matter in finishing " + this);
2668 stopFreezingScreenLocked(false);
2669 return true;
2670 }
2671
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002672 if (!ignoreStopState && (mState == STOPPING || mState == STOPPED)) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07002673 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2674 "Skipping config check stopped or stopping: " + this);
2675 return true;
2676 }
2677
Wale Ogunwaleea3d3fd2017-05-01 07:41:08 -07002678 // TODO: We should add ActivityRecord.shouldBeVisible() that checks if the activity should
2679 // be visible based on the stack, task, and lockscreen state and use that here instead. The
2680 // method should be based on the logic in ActivityStack.ensureActivitiesVisibleLocked().
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07002681 // Skip updating configuration for activity is a stack that shouldn't be visible.
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002682 if (!stack.shouldBeVisible(null /* starting */)) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07002683 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2684 "Skipping config check invisible stack: " + this);
2685 return true;
2686 }
2687
Andrii Kulian21713ac2016-10-12 22:05:05 -07002688 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2689 "Ensuring correct configuration: " + this);
2690
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002691 final int newDisplayId = getDisplayId();
2692 final boolean displayChanged = mLastReportedDisplayId != newDisplayId;
2693 if (displayChanged) {
2694 mLastReportedDisplayId = newDisplayId;
2695 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002696 // TODO(b/36505427): Is there a better place to do this?
2697 updateOverrideConfiguration();
2698
Winson Chungbdc646f2017-02-13 12:12:22 -08002699 // Short circuit: if the two full configurations are equal (the common case), then there is
2700 // nothing to do. We test the full configuration instead of the global and merged override
2701 // configurations because there are cases (like moving a task to the pinned stack) where
2702 // the combine configurations are equal, but would otherwise differ in the override config
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002703 mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
2704 if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002705 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002706 "Configuration & display unchanged in " + this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002707 return true;
2708 }
2709
2710 // Okay we now are going to make this activity have the new config.
2711 // But then we need to figure out how it needs to deal with that.
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002712
2713 // Find changes between last reported merged configuration and the current one. This is used
2714 // to decide whether to relaunch an activity or just report a configuration change.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002715 final int changes = getConfigurationChanges(mTmpConfig);
Ruben Brunkf64af332017-03-22 22:03:25 -07002716
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002717 // Update last reported values.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002718 final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
Bryce Lee8104e7a2017-08-17 09:16:03 -07002719
Wale Ogunwalef6733932018-06-27 05:14:34 -07002720 setLastReportedConfiguration(service.getGlobalConfiguration(), newMergedOverrideConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002721
Bryce Lee7ace3952018-02-16 14:34:32 -08002722 if (mState == INITIALIZING) {
Andrii Kulianb372da62018-01-18 10:46:24 -08002723 // No need to relaunch or schedule new config for activity that hasn't been launched
2724 // yet. We do, however, return after applying the config to activity record, so that
2725 // it will use it for launch transaction.
2726 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2727 "Skipping config check for initializing activity: " + this);
2728 return true;
2729 }
2730
Andrii Kulian21713ac2016-10-12 22:05:05 -07002731 if (changes == 0 && !forceNewConfig) {
2732 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2733 "Configuration no differences in " + this);
2734 // There are no significant differences, so we won't relaunch but should still deliver
2735 // the new configuration to the client process.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002736 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002737 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002738 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002739 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002740 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002741 return true;
2742 }
2743
2744 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002745 "Configuration changes for " + this + ", allChanges="
Andrii Kulian21713ac2016-10-12 22:05:05 -07002746 + Configuration.configurationDiffToString(changes));
2747
2748 // If the activity isn't currently running, just leave the new configuration and it will
2749 // pick that up next time it starts.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002750 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002751 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2752 "Configuration doesn't matter not running " + this);
2753 stopFreezingScreenLocked(false);
2754 forceNewConfig = false;
2755 return true;
2756 }
2757
2758 // Figure out how to handle the changes between the configurations.
2759 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2760 "Checking to restart " + info.name + ": changed=0x"
2761 + Integer.toHexString(changes) + ", handles=0x"
2762 + Integer.toHexString(info.getRealConfigChanged())
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002763 + ", mLastReportedConfiguration=" + mLastReportedConfiguration);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002764
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002765 if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002766 // Aha, the activity isn't handling the change, so DIE DIE DIE.
2767 configChangeFlags |= changes;
2768 startFreezingScreenLocked(app, globalChanges);
2769 forceNewConfig = false;
2770 preserveWindow &= isResizeOnlyChange(changes);
Garfield Tan2746ab52018-07-25 12:33:01 -07002771 final boolean hasResizeChange = hasResizeChange(changes & ~info.getRealConfigChanged());
2772 if (hasResizeChange) {
2773 final boolean isDragResizing =
2774 getTask().getWindowContainerController().isDragResizing();
2775 mRelaunchReason = isDragResizing ? RELAUNCH_REASON_FREE_RESIZE
2776 : RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
2777 } else {
2778 mRelaunchReason = RELAUNCH_REASON_NONE;
2779 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002780 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002781 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2782 "Config is destroying non-running " + this);
2783 stack.destroyActivityLocked(this, true, "config");
Bryce Lee7ace3952018-02-16 14:34:32 -08002784 } else if (mState == PAUSING) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002785 // A little annoying: we are waiting for this activity to finish pausing. Let's not
2786 // do anything now, but just flag that it needs to be restarted when done pausing.
2787 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2788 "Config is skipping already pausing " + this);
2789 deferRelaunchUntilPaused = true;
2790 preserveWindowOnDeferredRelaunch = preserveWindow;
2791 return true;
Bryce Lee7ace3952018-02-16 14:34:32 -08002792 } else if (mState == RESUMED) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002793 // Try to optimize this case: the configuration is changing and we need to restart
2794 // the top, resumed activity. Instead of doing the normal handshaking, just say
2795 // "restart!".
2796 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2797 "Config is relaunching resumed " + this);
2798
2799 if (DEBUG_STATES && !visible) {
2800 Slog.v(TAG_STATES, "Config is relaunching resumed invisible activity " + this
2801 + " called by " + Debug.getCallers(4));
2802 }
2803
2804 relaunchActivityLocked(true /* andResume */, preserveWindow);
2805 } else {
2806 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2807 "Config is relaunching non-resumed " + this);
2808 relaunchActivityLocked(false /* andResume */, preserveWindow);
2809 }
2810
2811 // All done... tell the caller we weren't able to keep this activity around.
2812 return false;
2813 }
2814
2815 // Default case: the activity can handle this new configuration, so hand it over.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002816 // NOTE: We only forward the override configuration as the system level configuration
Andrii Kulian21713ac2016-10-12 22:05:05 -07002817 // changes is always sent to all processes when they happen so it can just use whatever
2818 // system level configuration it last got.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002819 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002820 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002821 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002822 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002823 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002824 stopFreezingScreenLocked(false);
2825
2826 return true;
2827 }
2828
Zak Cohen90e7116742017-01-29 12:59:23 -08002829 /**
2830 * When assessing a configuration change, decide if the changes flags and the new configurations
2831 * should cause the Activity to relaunch.
Ruben Brunkf64af332017-03-22 22:03:25 -07002832 *
2833 * @param changes the changes due to the given configuration.
2834 * @param changesConfig the configuration that was used to calculate the given changes via a
2835 * call to getConfigurationChanges.
Zak Cohen90e7116742017-01-29 12:59:23 -08002836 */
Ruben Brunkf64af332017-03-22 22:03:25 -07002837 private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
Zak Cohen90e7116742017-01-29 12:59:23 -08002838 int configChanged = info.getRealConfigChanged();
Ruben Brunkf64af332017-03-22 22:03:25 -07002839 boolean onlyVrUiModeChanged = onlyVrUiModeChanged(changes, changesConfig);
Zak Cohen90e7116742017-01-29 12:59:23 -08002840
2841 // Override for apps targeting pre-O sdks
2842 // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
2843 // to the config change.
2844 // For O and later, apps will be required to add configChanges="uimode" to their manifest.
2845 if (appInfo.targetSdkVersion < O
2846 && requestedVrComponent != null
Ruben Brunkf64af332017-03-22 22:03:25 -07002847 && onlyVrUiModeChanged) {
Zak Cohen90e7116742017-01-29 12:59:23 -08002848 configChanged |= CONFIG_UI_MODE;
2849 }
2850
2851 return (changes&(~configChanged)) != 0;
2852 }
2853
Ruben Brunkf64af332017-03-22 22:03:25 -07002854 /**
2855 * Returns true if the configuration change is solely due to the UI mode switching into or out
2856 * of UI_MODE_TYPE_VR_HEADSET.
2857 */
2858 private boolean onlyVrUiModeChanged(int changes, Configuration lastReportedConfig) {
2859 final Configuration currentConfig = getConfiguration();
Ruben Brunkf53497c2017-03-27 20:26:17 -07002860 return changes == CONFIG_UI_MODE && (isInVrUiMode(currentConfig)
Ruben Brunkf64af332017-03-22 22:03:25 -07002861 != isInVrUiMode(lastReportedConfig));
2862 }
2863
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002864 private int getConfigurationChanges(Configuration lastReportedConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002865 // Determine what has changed. May be nothing, if this is a config that has come back from
2866 // the app after going idle. In that case we just want to leave the official config object
2867 // now in the activity and do nothing else.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002868 final Configuration currentConfig = getConfiguration();
2869 int changes = lastReportedConfig.diff(currentConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002870 // We don't want to use size changes if they don't cross boundaries that are important to
2871 // the app.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002872 if ((changes & CONFIG_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002873 final boolean crosses = crossesHorizontalSizeThreshold(lastReportedConfig.screenWidthDp,
2874 currentConfig.screenWidthDp)
2875 || crossesVerticalSizeThreshold(lastReportedConfig.screenHeightDp,
2876 currentConfig.screenHeightDp);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002877 if (!crosses) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002878 changes &= ~CONFIG_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002879 }
2880 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002881 if ((changes & CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002882 final int oldSmallest = lastReportedConfig.smallestScreenWidthDp;
2883 final int newSmallest = currentConfig.smallestScreenWidthDp;
2884 if (!crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002885 changes &= ~CONFIG_SMALLEST_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002886 }
2887 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07002888 // We don't want window configuration to cause relaunches.
2889 if ((changes & CONFIG_WINDOW_CONFIGURATION) != 0) {
2890 changes &= ~CONFIG_WINDOW_CONFIGURATION;
2891 }
Bryce Lee600dadd2017-07-25 10:48:42 -07002892
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002893 return changes;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002894 }
2895
2896 private static boolean isResizeOnlyChange(int change) {
2897 return (change & ~(CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
2898 | CONFIG_SCREEN_LAYOUT)) == 0;
2899 }
2900
Garfield Tan2746ab52018-07-25 12:33:01 -07002901 private static boolean hasResizeChange(int change) {
2902 return (change & (CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
2903 | CONFIG_SCREEN_LAYOUT)) != 0;
2904 }
2905
Andrii Kulian21713ac2016-10-12 22:05:05 -07002906 void relaunchActivityLocked(boolean andResume, boolean preserveWindow) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07002907 if (service.mSuppressResizeConfigChanges && preserveWindow) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002908 configChangeFlags = 0;
2909 return;
2910 }
2911
2912 List<ResultInfo> pendingResults = null;
2913 List<ReferrerIntent> pendingNewIntents = null;
2914 if (andResume) {
2915 pendingResults = results;
2916 pendingNewIntents = newIntents;
2917 }
2918 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2919 "Relaunching: " + this + " with results=" + pendingResults
2920 + " newIntents=" + pendingNewIntents + " andResume=" + andResume
2921 + " preserveWindow=" + preserveWindow);
Ruben Brunkf53497c2017-03-27 20:26:17 -07002922 EventLog.writeEvent(andResume ? AM_RELAUNCH_RESUME_ACTIVITY
2923 : AM_RELAUNCH_ACTIVITY, userId, System.identityHashCode(this),
Andrii Kulian21713ac2016-10-12 22:05:05 -07002924 task.taskId, shortComponentName);
2925
2926 startFreezingScreenLocked(app, 0);
2927
Andrii Kulian21713ac2016-10-12 22:05:05 -07002928 try {
2929 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
2930 "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this
2931 + " callers=" + Debug.getCallers(6));
2932 forceNewConfig = false;
2933 mStackSupervisor.activityRelaunchingLocked(this);
Andrii Kulianb372da62018-01-18 10:46:24 -08002934 final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
2935 pendingNewIntents, configChangeFlags,
Wale Ogunwalef6733932018-06-27 05:14:34 -07002936 new MergedConfiguration(service.getGlobalConfiguration(),
Andrii Kulianb372da62018-01-18 10:46:24 -08002937 getMergedOverrideConfiguration()),
2938 preserveWindow);
2939 final ActivityLifecycleItem lifecycleItem;
2940 if (andResume) {
lumark588a3e82018-07-20 18:53:54 +08002941 lifecycleItem = ResumeActivityItem.obtain(
2942 getDisplay().getWindowContainerController().isNextTransitionForward());
Andrii Kulianb372da62018-01-18 10:46:24 -08002943 } else {
Bryce Lee1d0d5142018-04-12 10:35:07 -07002944 lifecycleItem = PauseActivityItem.obtain();
Andrii Kulianb372da62018-01-18 10:46:24 -08002945 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002946 final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), appToken);
Andrii Kulianb372da62018-01-18 10:46:24 -08002947 transaction.addCallback(callbackItem);
2948 transaction.setLifecycleStateRequest(lifecycleItem);
Bryce Leeb0f993f2018-03-02 15:38:01 -08002949 service.getLifecycleManager().scheduleTransaction(transaction);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002950 // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
Andrii Kulianb372da62018-01-18 10:46:24 -08002951 // request resume if this activity is currently resumed, which implies we aren't
Andrii Kulian21713ac2016-10-12 22:05:05 -07002952 // sleeping.
2953 } catch (RemoteException e) {
2954 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
2955 }
2956
2957 if (andResume) {
2958 if (DEBUG_STATES) {
2959 Slog.d(TAG_STATES, "Resumed after relaunch " + this);
2960 }
2961 results = null;
2962 newIntents = null;
Wale Ogunwale008163e2018-07-23 23:11:08 -07002963 service.getAppWarningsLocked().onResumeActivity(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002964 } else {
Wale Ogunwale008163e2018-07-23 23:11:08 -07002965 final ActivityStack stack = getStack();
2966 if (stack != null) {
2967 stack.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
2968 }
Bryce Lee7ace3952018-02-16 14:34:32 -08002969 setState(PAUSED, "relaunchActivityLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07002970 }
2971
2972 configChangeFlags = 0;
2973 deferRelaunchUntilPaused = false;
2974 preserveWindowOnDeferredRelaunch = false;
2975 }
2976
Jorim Jaggibae01b12017-04-11 16:29:10 -07002977 private boolean isProcessRunning() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002978 WindowProcessController proc = app;
Jorim Jaggi02886a82016-12-06 09:10:06 -08002979 if (proc == null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002980 proc = service.mProcessNames.get(processName, info.applicationInfo.uid);
Jorim Jaggi02886a82016-12-06 09:10:06 -08002981 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002982 return proc != null && proc.hasThread();
Jorim Jaggi02886a82016-12-06 09:10:06 -08002983 }
2984
Jorim Jaggibae01b12017-04-11 16:29:10 -07002985 /**
2986 * @return Whether a task snapshot starting window may be shown.
2987 */
2988 private boolean allowTaskSnapshot() {
2989 if (newIntents == null) {
2990 return true;
2991 }
2992
2993 // Restrict task snapshot starting window to launcher start, or there is no intent at all
2994 // (eg. task being brought to front). If the intent is something else, likely the app is
2995 // going to show some specific page or view, instead of what's left last time.
2996 for (int i = newIntents.size() - 1; i >= 0; i--) {
2997 final Intent intent = newIntents.get(i);
2998 if (intent != null && !ActivityRecord.isMainIntent(intent)) {
2999 return false;
3000 }
3001 }
3002 return true;
3003 }
3004
Bryce Leeb7c9b802017-05-02 14:20:24 -07003005 /**
3006 * Returns {@code true} if the associated activity has the no history flag set on it.
3007 * {@code false} otherwise.
3008 */
3009 boolean isNoHistory() {
3010 return (intent.getFlags() & FLAG_ACTIVITY_NO_HISTORY) != 0
3011 || (info.flags & FLAG_NO_HISTORY) != 0;
3012 }
3013
Craig Mautner21d24a22014-04-23 11:45:37 -07003014 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
3015 out.attribute(null, ATTR_ID, String.valueOf(createTime));
3016 out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
3017 if (launchedFromPackage != null) {
3018 out.attribute(null, ATTR_LAUNCHEDFROMPACKAGE, launchedFromPackage);
3019 }
3020 if (resolvedType != null) {
3021 out.attribute(null, ATTR_RESOLVEDTYPE, resolvedType);
3022 }
3023 out.attribute(null, ATTR_COMPONENTSPECIFIED, String.valueOf(componentSpecified));
3024 out.attribute(null, ATTR_USERID, String.valueOf(userId));
Winson Chung2cb86c72014-06-25 12:03:30 -07003025
Craig Mautner21d24a22014-04-23 11:45:37 -07003026 if (taskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003027 taskDescription.saveToXml(out);
Craig Mautner21d24a22014-04-23 11:45:37 -07003028 }
3029
3030 out.startTag(null, TAG_INTENT);
3031 intent.saveToXml(out);
3032 out.endTag(null, TAG_INTENT);
3033
3034 if (isPersistable() && persistentState != null) {
3035 out.startTag(null, TAG_PERSISTABLEBUNDLE);
3036 persistentState.saveToXml(out);
3037 out.endTag(null, TAG_PERSISTABLEBUNDLE);
3038 }
3039 }
3040
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07003041 static ActivityRecord restoreFromXml(XmlPullParser in,
3042 ActivityStackSupervisor stackSupervisor) throws IOException, XmlPullParserException {
Craig Mautner21d24a22014-04-23 11:45:37 -07003043 Intent intent = null;
3044 PersistableBundle persistentState = null;
3045 int launchedFromUid = 0;
3046 String launchedFromPackage = null;
3047 String resolvedType = null;
3048 boolean componentSpecified = false;
3049 int userId = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07003050 long createTime = -1;
3051 final int outerDepth = in.getDepth();
Winson Chung2cb86c72014-06-25 12:03:30 -07003052 TaskDescription taskDescription = new TaskDescription();
Craig Mautner21d24a22014-04-23 11:45:37 -07003053
3054 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
3055 final String attrName = in.getAttributeName(attrNdx);
3056 final String attrValue = in.getAttributeValue(attrNdx);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003057 if (DEBUG) Slog.d(TaskPersister.TAG,
Wale Ogunwale18795a22014-12-03 11:38:33 -08003058 "ActivityRecord: attribute name=" + attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003059 if (ATTR_ID.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01003060 createTime = Long.parseLong(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003061 } else if (ATTR_LAUNCHEDFROMUID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003062 launchedFromUid = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003063 } else if (ATTR_LAUNCHEDFROMPACKAGE.equals(attrName)) {
3064 launchedFromPackage = attrValue;
3065 } else if (ATTR_RESOLVEDTYPE.equals(attrName)) {
3066 resolvedType = attrValue;
3067 } else if (ATTR_COMPONENTSPECIFIED.equals(attrName)) {
Tobias Thiererb0800dc2016-04-21 17:51:41 +01003068 componentSpecified = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003069 } else if (ATTR_USERID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003070 userId = Integer.parseInt(attrValue);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003071 } else if (attrName.startsWith(ATTR_TASKDESCRIPTION_PREFIX)) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003072 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003073 } else {
3074 Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
3075 }
3076 }
3077
3078 int event;
Ruben Brunkf53497c2017-03-27 20:26:17 -07003079 while (((event = in.next()) != END_DOCUMENT) &&
3080 (event != END_TAG || in.getDepth() >= outerDepth)) {
3081 if (event == START_TAG) {
Craig Mautner21d24a22014-04-23 11:45:37 -07003082 final String name = in.getName();
Ruben Brunkf53497c2017-03-27 20:26:17 -07003083 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003084 Slog.d(TaskPersister.TAG, "ActivityRecord: START_TAG name=" + name);
Craig Mautner21d24a22014-04-23 11:45:37 -07003085 if (TAG_INTENT.equals(name)) {
3086 intent = Intent.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003087 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003088 Slog.d(TaskPersister.TAG, "ActivityRecord: intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003089 } else if (TAG_PERSISTABLEBUNDLE.equals(name)) {
3090 persistentState = PersistableBundle.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003091 if (DEBUG) Slog.d(TaskPersister.TAG,
Craig Mautner21d24a22014-04-23 11:45:37 -07003092 "ActivityRecord: persistentState=" + persistentState);
3093 } else {
3094 Slog.w(TAG, "restoreActivity: unexpected name=" + name);
3095 XmlUtils.skipCurrentTag(in);
3096 }
3097 }
3098 }
3099
3100 if (intent == null) {
Craig Mautnere0129b32014-05-25 16:41:09 -07003101 throw new XmlPullParserException("restoreActivity error intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003102 }
3103
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003104 final ActivityTaskManagerService service = stackSupervisor.mService;
Craig Mautner21d24a22014-04-23 11:45:37 -07003105 final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null,
Patrick Baumann78380272018-04-04 10:41:01 -07003106 userId, Binder.getCallingUid());
Craig Mautnere0129b32014-05-25 16:41:09 -07003107 if (aInfo == null) {
Craig Mautner77b04262014-06-27 15:22:12 -07003108 throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
3109 " resolvedType=" + resolvedType);
Craig Mautnere0129b32014-05-25 16:41:09 -07003110 }
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003111 final ActivityRecord r = new ActivityRecord(service, null /* caller */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003112 0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType,
Wale Ogunwalef6733932018-06-27 05:14:34 -07003113 aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003114 0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07003115 stackSupervisor, null /* options */, null /* sourceRecord */);
Craig Mautner21d24a22014-04-23 11:45:37 -07003116
3117 r.persistentState = persistentState;
Winson Chung2cb86c72014-06-25 12:03:30 -07003118 r.taskDescription = taskDescription;
Craig Mautner21d24a22014-04-23 11:45:37 -07003119 r.createTime = createTime;
3120
3121 return r;
3122 }
3123
Zak Cohen90e7116742017-01-29 12:59:23 -08003124 private static boolean isInVrUiMode(Configuration config) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07003125 return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
Zak Cohen90e7116742017-01-29 12:59:23 -08003126 }
3127
David Stevens82ea6cb2017-03-03 16:18:50 -08003128 int getUid() {
3129 return info.applicationInfo.uid;
3130 }
3131
chaviw59b98852017-06-13 12:05:44 -07003132 void setShowWhenLocked(boolean showWhenLocked) {
3133 mShowWhenLocked = showWhenLocked;
Wale Ogunwaled32da472018-11-16 07:19:28 -08003134 mRootActivityContainer.ensureActivitiesVisible(null, 0 /* configChanges */,
Kevin Chyn44639482017-10-09 18:34:41 -07003135 false /* preserveWindows */);
chaviw59b98852017-06-13 12:05:44 -07003136 }
3137
3138 /**
chaviw2c500982018-01-04 17:05:05 -08003139 * @return true if the activity windowing mode is not
3140 * {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and activity contains
3141 * windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the activity
3142 * has set {@link #mShowWhenLocked}.
3143 * Multi-windowing mode will be exited if true is returned.
chaviw59b98852017-06-13 12:05:44 -07003144 */
3145 boolean canShowWhenLocked() {
chaviw2c500982018-01-04 17:05:05 -08003146 return !inPinnedWindowingMode() && (mShowWhenLocked
Wale Ogunwale2cca8622017-12-11 08:40:13 -08003147 || service.mWindowManager.containsShowWhenLockedWindow(appToken));
chaviw59b98852017-06-13 12:05:44 -07003148 }
3149
3150 void setTurnScreenOn(boolean turnScreenOn) {
3151 mTurnScreenOn = turnScreenOn;
3152 }
3153
3154 /**
3155 * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
3156 * {@link #mTurnScreenOn} is set and checks whether the ActivityRecord should be visible
3157 * depending on Keyguard state
3158 *
3159 * @return true if the screen can be turned on, false otherwise.
3160 */
3161 boolean canTurnScreenOn() {
3162 final ActivityStack stack = getStack();
3163 return mTurnScreenOn && stack != null &&
3164 stack.checkKeyguardVisibility(this, true /* shouldBeVisible */, true /* isTop */);
3165 }
3166
3167 boolean getTurnScreenOnFlag() {
3168 return mTurnScreenOn;
3169 }
3170
3171 boolean isTopRunningActivity() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003172 return mRootActivityContainer.topRunningActivity() == this;
chaviw59b98852017-06-13 12:05:44 -07003173 }
3174
Andrii Kulian52d255c2018-07-13 11:32:19 -07003175 /**
3176 * @return {@code true} if this is the resumed activity on its current display, {@code false}
3177 * otherwise.
3178 */
3179 boolean isResumedActivityOnDisplay() {
3180 final ActivityDisplay display = getDisplay();
3181 return display != null && this == display.getResumedActivity();
3182 }
3183
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003184 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003185 if (mAppWindowToken == null) {
3186 Slog.w(TAG_WM, "Attempted to register remote animations with non-existing app"
3187 + " token: " + appToken);
3188 return;
3189 }
3190 mAppWindowToken.registerRemoteAnimations(definition);
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003191 }
3192
Craig Mautnerf81b90872013-02-26 13:02:43 -08003193 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003194 public String toString() {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003195 if (stringName != null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08003196 return stringName + " t" + (task == null ? INVALID_TASK_ID : task.taskId) +
Craig Mautnerf3333272013-04-22 10:55:53 -07003197 (finishing ? " f}" : "}");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003198 }
3199 StringBuilder sb = new StringBuilder(128);
Dianne Hackborn30d71892010-12-11 10:37:55 -08003200 sb.append("ActivityRecord{");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003201 sb.append(Integer.toHexString(System.identityHashCode(this)));
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003202 sb.append(" u");
3203 sb.append(userId);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003204 sb.append(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003205 sb.append(intent.getComponent().flattenToShortString());
Craig Mautnerf81b90872013-02-26 13:02:43 -08003206 stringName = sb.toString();
3207 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003208 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07003209
3210 void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
3211 final long token = proto.start(fieldId);
3212 proto.write(HASH_CODE, System.identityHashCode(this));
3213 proto.write(USER_ID, userId);
3214 proto.write(TITLE, intent.getComponent().flattenToShortString());
3215 proto.end(token);
3216 }
3217
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003218 /**
3219 * Write all fields to an {@code ActivityRecordProto}. This assumes the
3220 * {@code ActivityRecordProto} is the outer-most proto data.
3221 */
3222 void writeToProto(ProtoOutputStream proto) {
Adrian Roos4921ccf2017-09-28 16:54:06 +02003223 super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003224 writeIdentifierToProto(proto, IDENTIFIER);
Bryce Lee7ace3952018-02-16 14:34:32 -08003225 proto.write(STATE, mState.toString());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003226 proto.write(VISIBLE, visible);
3227 proto.write(FRONT_OF_TASK, frontOfTask);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003228 if (hasProcess()) {
3229 proto.write(PROC_ID, app.getPid());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003230 }
Wale Ogunwale30eab1f2018-05-24 18:25:25 -07003231 proto.write(TRANSLUCENT, !fullscreen);
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003232 }
3233
3234 public void writeToProto(ProtoOutputStream proto, long fieldId) {
3235 final long token = proto.start(fieldId);
3236 writeToProto(proto);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003237 proto.end(token);
3238 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003239}