blob: b7c35c083174007bb1be45c37be6cc8eebe973a1 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Winson Chungbb348802017-01-30 12:01:45 -080019import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
Ruben Brunkf53497c2017-03-27 20:26:17 -070020import static android.app.ActivityManager.TaskDescription.ATTR_TASKDESCRIPTION_PREFIX;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080021import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
22import static android.app.ActivityOptions.ANIM_CUSTOM;
23import static android.app.ActivityOptions.ANIM_NONE;
24import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
25import static android.app.ActivityOptions.ANIM_REMOTE_ANIMATION;
26import static android.app.ActivityOptions.ANIM_SCALE_UP;
Ruben Brunkf53497c2017-03-27 20:26:17 -070027import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080028import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
29import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP;
30import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
31import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
Riddle Hsu16567132018-08-16 21:37:47 +080032import static android.app.ActivityTaskManager.INVALID_STACK_ID;
Vishnu Nair9ba31652018-11-13 14:34:05 -080033import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Winson Chung59fda9e2017-01-20 16:14:51 -080034import static android.app.AppOpsManager.MODE_ALLOWED;
Winson Chungf4ac0632017-03-17 12:34:12 -070035import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
Vishnu Nair132ee832018-09-28 15:00:05 -070036import static android.app.WaitResult.INVALID_DELAY;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070037import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
38import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
39import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -070040import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
41import static android.app.WindowConfiguration.activityTypeToString;
Ruben Brunkf53497c2017-03-27 20:26:17 -070042import static android.content.Intent.ACTION_MAIN;
43import static android.content.Intent.CATEGORY_HOME;
44import static android.content.Intent.CATEGORY_LAUNCHER;
Chilun2ef71f72018-11-16 17:57:15 +080045import static android.content.Intent.CATEGORY_SECONDARY_HOME;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080046import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
Bryce Leeb7c9b802017-05-02 14:20:24 -070047import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY;
Andrii Kulian21713ac2016-10-12 22:05:05 -070048import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
49import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
50import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
51import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
Zak Cohen90e7116742017-01-29 12:59:23 -080052import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
Wale Ogunwale822e5122017-07-26 06:02:24 -070053import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
Jorim Jaggi02886a82016-12-06 09:10:06 -080054import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080055import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
56import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
Issei Suzuki74e1eb22018-12-20 17:42:52 +010057import static android.content.pm.ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080058import static android.content.pm.ActivityInfo.FLAG_MULTIPROCESS;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020059import static android.content.pm.ActivityInfo.FLAG_NO_HISTORY;
Chong Zhang87761972016-08-22 13:53:24 -070060import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
Jorim Jaggie7d2b852017-08-28 17:55:15 +020061import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080062import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
chaviw59b98852017-06-13 12:05:44 -070063import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080064import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -080065import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
66import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080067import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
Charles He2bf28322017-10-12 22:24:49 +010068import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
69import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
70import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
71import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
Ruben Brunkf53497c2017-03-27 20:26:17 -070072import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS;
73import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY;
Wale Ogunwaledf241e92016-10-13 15:14:21 -070074import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
Jorim Jaggicd13d332016-04-27 15:40:20 -070075import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
Wale Ogunwale72a73e32016-10-13 12:16:39 -070076import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Wale Ogunwaledf241e92016-10-13 15:14:21 -070077import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080078import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -070079import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
80import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -070081import static android.content.res.Configuration.EMPTY;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -070082import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
83import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
Ruben Brunkf53497c2017-03-27 20:26:17 -070084import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
Zak Cohen90e7116742017-01-29 12:59:23 -080085import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080086import static android.os.Build.VERSION_CODES.HONEYCOMB;
Zak Cohen90e7116742017-01-29 12:59:23 -080087import static android.os.Build.VERSION_CODES.O;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -080088import static android.os.Process.SYSTEM_UID;
Riddle Hsufd4a0502018-10-16 01:05:16 +080089import static android.view.Display.INVALID_DISPLAY;
Riddle Hsu16567132018-08-16 21:37:47 +080090import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
Adrian Roos917791e2018-11-28 16:30:44 +010091import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
Riddle Hsu16567132018-08-16 21:37:47 +080092
Vishnu Nair9ba31652018-11-13 14:34:05 -080093import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
94import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
95import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
96import static com.android.server.am.ActivityRecordProto.PROC_ID;
97import static com.android.server.am.ActivityRecordProto.STATE;
98import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
99import static com.android.server.am.ActivityRecordProto.VISIBLE;
100import static com.android.server.am.EventLogTags.AM_RELAUNCH_ACTIVITY;
101import static com.android.server.am.EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY;
Hui Yu03d12402018-12-06 18:00:37 -0800102import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800103import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
104import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
105import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
106import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
107import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
108import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
109import static com.android.server.wm.ActivityStack.LAUNCH_TICK;
110import static com.android.server.wm.ActivityStack.LAUNCH_TICK_MSG;
111import static com.android.server.wm.ActivityStack.PAUSE_TIMEOUT_MSG;
112import static com.android.server.wm.ActivityStack.STOP_TIMEOUT_MSG;
Wale Ogunwale59507092018-10-29 09:00:30 -0700113import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
114import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
115import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
116import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
117import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
118import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
119import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
120import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
121import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SAVED_STATE;
122import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
123import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
124import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
125import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
126import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Wale Ogunwale59507092018-10-29 09:00:30 -0700127import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
128import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
Hui Yu03d12402018-12-06 18:00:37 -0800129import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -0700130import static com.android.server.wm.IdentifierProto.HASH_CODE;
131import static com.android.server.wm.IdentifierProto.TITLE;
132import static com.android.server.wm.IdentifierProto.USER_ID;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800133import static com.android.server.wm.TaskPersister.DEBUG;
134import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800135import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
136import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
137import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
138import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
139import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700140
Ruben Brunkf53497c2017-03-27 20:26:17 -0700141import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
142import static org.xmlpull.v1.XmlPullParser.END_TAG;
143import static org.xmlpull.v1.XmlPullParser.START_TAG;
Wale Ogunwale18795a22014-12-03 11:38:33 -0800144
Andrii Kulian21713ac2016-10-12 22:05:05 -0700145import android.annotation.NonNull;
Issei Suzuki74e1eb22018-12-20 17:42:52 +0100146import android.annotation.Nullable;
Craig Mautner21d24a22014-04-23 11:45:37 -0700147import android.app.ActivityManager.TaskDescription;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700148import android.app.ActivityOptions;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800149import android.app.PendingIntent;
Winson Chung709904f2017-04-25 11:00:48 -0700150import android.app.PictureInPictureParams;
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800151import android.app.ResultInfo;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -0800152import android.app.WaitResult.LaunchState;
Riddle Hsu16567132018-08-16 21:37:47 +0800153import android.app.servertransaction.ActivityConfigurationChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800154import android.app.servertransaction.ActivityLifecycleItem;
155import android.app.servertransaction.ActivityRelaunchItem;
156import android.app.servertransaction.ClientTransaction;
157import android.app.servertransaction.ClientTransactionItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700158import android.app.servertransaction.MoveToDisplayItem;
159import android.app.servertransaction.MultiWindowModeChangeItem;
160import android.app.servertransaction.NewIntentItem;
Bryce Lee0bd8d422018-01-09 09:45:57 -0800161import android.app.servertransaction.PauseActivityItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700162import android.app.servertransaction.PipModeChangeItem;
Andrii Kulianb372da62018-01-18 10:46:24 -0800163import android.app.servertransaction.ResumeActivityItem;
Andrii Kulian446e8242017-10-26 15:17:29 -0700164import android.app.servertransaction.WindowVisibilityItem;
Hui Yu03d12402018-12-06 18:00:37 -0800165import android.app.usage.UsageEvents.Event;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166import android.content.ComponentName;
167import android.content.Intent;
168import android.content.pm.ActivityInfo;
169import android.content.pm.ApplicationInfo;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700170import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171import android.content.res.Configuration;
172import android.graphics.Bitmap;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800173import android.graphics.GraphicBuffer;
Dianne Hackbornd367ca82012-05-07 15:49:39 -0700174import android.graphics.Rect;
Patrick Baumann78380272018-04-04 10:41:01 -0700175import android.os.Binder;
Bryce Lee39791592017-04-26 09:29:12 -0700176import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177import android.os.Bundle;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700178import android.os.Debug;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800179import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180import android.os.Message;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800181import android.os.PersistableBundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182import android.os.Process;
Dianne Hackborn39792d22010-08-19 18:01:52 -0700183import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700185import android.os.UserHandle;
Bryce Lee8558ec72017-08-17 15:37:26 -0700186import android.os.storage.StorageManager;
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800187import android.service.voice.IVoiceInteractionSession;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188import android.util.EventLog;
189import android.util.Log;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700190import android.util.MergedConfiguration;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700191import android.util.Slog;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700192import android.util.TimeUtils;
Steven Timotius4346f0a2017-09-12 11:07:21 -0700193import android.util.proto.ProtoOutputStream;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800194import android.view.AppTransitionAnimationSpec;
195import android.view.IAppTransitionAnimationSpecsFuture;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196import android.view.IApplicationToken;
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100197import android.view.RemoteAnimationDefinition;
Jorim Jaggife762342016-10-13 14:33:27 +0200198import android.view.WindowManager.LayoutParams;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700199
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700200import com.android.internal.R;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800201import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski3d026712015-12-16 13:46:38 -0800202import com.android.internal.app.ResolverActivity;
203import com.android.internal.content.ReferrerIntent;
204import com.android.internal.util.XmlUtils;
205import com.android.server.AttributeCache;
Ruben Brunkf53497c2017-03-27 20:26:17 -0700206import com.android.server.AttributeCache.Entry;
Wale Ogunwale59507092018-10-29 09:00:30 -0700207import com.android.server.am.AppTimeTracker;
208import com.android.server.am.PendingIntentRecord;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800209import com.android.server.uri.UriPermissionOwner;
Wale Ogunwale59507092018-10-29 09:00:30 -0700210import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
211import com.android.server.wm.ActivityStack.ActivityState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212
Jorim Jaggi02886a82016-12-06 09:10:06 -0800213import org.xmlpull.v1.XmlPullParser;
214import org.xmlpull.v1.XmlPullParserException;
215import org.xmlpull.v1.XmlSerializer;
216
Suprabh Shukla23593142015-11-03 17:31:15 -0800217import java.io.File;
Craig Mautner21d24a22014-04-23 11:45:37 -0700218import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219import java.io.PrintWriter;
220import java.lang.ref.WeakReference;
221import java.util.ArrayList;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800222import java.util.Arrays;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223import java.util.HashSet;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700224import java.util.List;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700225import java.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226
227/**
228 * An entry in the history stack, representing an activity.
229 */
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800230final class ActivityRecord extends ConfigurationContainer {
Wale Ogunwale98875612018-10-12 07:53:02 -0700231 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_ATM;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700232 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
233 private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
Wale Ogunwale0fc365c2015-05-25 19:35:42 -0700234 private static final String TAG_STATES = TAG + POSTFIX_STATES;
Wale Ogunwaleee006da2015-03-30 14:49:25 -0700235 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
Andrii Kulian21713ac2016-10-12 22:05:05 -0700236 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
Louis Chang19443452018-10-09 12:10:21 +0800237 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
Winson Chung16e185e2017-11-07 08:30:54 -0800238 // TODO(b/67864419): Remove once recents component is overridden
239 private static final String LEGACY_RECENTS_PACKAGE_NAME = "com.android.systemui.recents";
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800240
Wale Ogunwale3ab9a272015-03-16 09:55:45 -0700241 private static final boolean SHOW_ACTIVITY_START_TIME = true;
Craig Mautnerb59dcfd2013-05-06 13:12:58 -0700242
Craig Mautner21d24a22014-04-23 11:45:37 -0700243 private static final String ATTR_ID = "id";
244 private static final String TAG_INTENT = "intent";
245 private static final String ATTR_USERID = "user_id";
246 private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle";
247 private static final String ATTR_LAUNCHEDFROMUID = "launched_from_uid";
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700248 private static final String ATTR_LAUNCHEDFROMPACKAGE = "launched_from_package";
Craig Mautner21d24a22014-04-23 11:45:37 -0700249 private static final String ATTR_RESOLVEDTYPE = "resolved_type";
250 private static final String ATTR_COMPONENTSPECIFIED = "component_specified";
Dianne Hackborn337abb32014-09-24 12:44:29 -0700251 static final String ACTIVITY_ICON_SUFFIX = "_activity_icon_";
Craig Mautner21d24a22014-04-23 11:45:37 -0700252
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800253 final ActivityTaskManagerService mAtmService; // owner
Dianne Hackbornbe707852011-11-11 14:32:10 -0800254 final IApplicationToken.Stub appToken; // window manager token
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800255 // TODO: Remove after unification
256 AppWindowToken mAppWindowToken;
257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 final ActivityInfo info; // all about me
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700259 // TODO: This is duplicated state already contained in info.applicationInfo - remove
260 ApplicationInfo appInfo; // information about activity's app
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800261 final int launchedFromPid; // always the pid who started the activity.
Stefan Kuhnee88d1e52015-05-18 10:33:45 -0700262 final int launchedFromUid; // always the uid who started the activity.
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800263 final String launchedFromPackage; // always the package who started the activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800264 final int mUserId; // Which user is this running for?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 final Intent intent; // the original intent that generated us
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800266 final ComponentName mActivityComponent; // the intent component, or target of an alias.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 final String shortComponentName; // the short component name of the intent
268 final String resolvedType; // as per original caller;
269 final String packageName; // the package implementing intent's component
270 final String processName; // process where this component wants to run
271 final String taskAffinity; // as per ActivityInfo.taskAffinity
272 final boolean stateNotNeeded; // As per ActivityInfo.flags
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700273 boolean fullscreen; // The activity is opaque and fills the entire space of this task.
274 // TODO: See if it possible to combine this with the fullscreen field.
275 final boolean hasWallpaper; // Has a wallpaper window as a background.
Louis Changd58cb672018-12-24 17:45:16 +0800276 @VisibleForTesting
277 boolean noDisplay; // activity is not displayed?
278 @VisibleForTesting
279 int mHandoverLaunchDisplayId = INVALID_DISPLAY; // Handover launch display id to next activity.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800280 private final boolean componentSpecified; // did caller specify an explicit component?
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700281 final boolean rootVoiceInteraction; // was this the root activity of a voice interaction?
Craig Mautner86d67a42013-05-14 10:34:38 -0700282
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800283 private CharSequence nonLocalizedLabel; // the label information from the package mgr.
284 private int labelRes; // the label information from the package mgr.
285 private int icon; // resource identifier of activity's icon.
286 private int logo; // resource identifier of activity's logo.
287 private int theme; // resource identifier of activity's theme.
288 private int realTheme; // actual theme resource we will use, never 0.
289 private int windowFlags; // custom window flags for preview window.
Bryce Leeaf691c02017-03-20 14:20:22 -0700290 private TaskRecord task; // the task this is in.
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800291 private long createTime = System.currentTimeMillis();
Dianne Hackborn50685602011-12-01 12:23:37 -0800292 long lastVisibleTime; // last time this activity became visible
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700293 long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700294 long pauseTime; // last time we started pausing the activity
295 long launchTickTime; // base time for launch tick messages
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700296 // Last configuration reported to the activity in the client process.
297 private MergedConfiguration mLastReportedConfiguration;
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800298 private int mLastReportedDisplayId;
Winson Chung609e1e92017-05-08 10:52:12 -0700299 private boolean mLastReportedMultiWindowMode;
300 private boolean mLastReportedPictureInPictureMode;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -0700301 CompatibilityInfo compat;// last used compatibility mode
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700302 ActivityRecord resultTo; // who started this entry, so will get our reply
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 final String resultWho; // additional identifier for use by resultTo.
304 final int requestCode; // code given by requester (resultTo)
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800305 ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
Dianne Hackborn85d558c2014-11-04 10:31:54 -0800307 ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700308 ActivityOptions pendingOptions; // most recently given options
George Mount6ba042b2014-07-28 11:12:28 -0700309 ActivityOptions returningOptions; // options that are coming back via convertToTranslucent
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700310 AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity
Wale Ogunwalec4e63a42018-10-02 13:19:54 -0700311 ActivityServiceConnectionsHolder mServiceConnectionsHolder; // Service connections.
Dianne Hackborn7e269642010-08-25 19:50:20 -0700312 UriPermissionOwner uriPermissions; // current special URI access perms.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700313 WindowProcessController app; // if non-null, hosting application
Bryce Lee7ace3952018-02-16 14:34:32 -0800314 private ActivityState mState; // current state we are in
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 Bundle icicle; // last saved activity state
Craig Mautnera0026042014-04-23 11:45:37 -0700316 PersistableBundle persistentState; // last persistently saved activity state
Wale Ogunwale66e16852017-10-19 13:35:52 -0700317 // TODO: See if this is still needed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 boolean frontOfTask; // is this the root activity of its task?
319 boolean launchFailed; // set if a launched failed, to abort on 2nd try
320 boolean haveState; // have we gotten the last activity state?
321 boolean stopped; // is activity pause finished?
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700322 boolean delayedResume; // not yet resumed because of stopped app switches?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 boolean finishing; // activity in pending finish list?
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800324 boolean deferRelaunchUntilPaused; // relaunch of activity is being deferred until pause is
325 // completed
326 boolean preserveWindowOnDeferredRelaunch; // activity windows are preserved on deferred relaunch
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 int configChangeFlags; // which config values have changed
Wale Ogunwaleec950642017-04-25 07:44:21 -0700328 private boolean keysPaused; // has key dispatching been paused for it?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 int launchMode; // the launch mode activity attribute.
Charles He2bf28322017-10-12 22:24:49 +0100330 int lockTaskLaunchMode; // the lockTaskMode manifest attribute, subject to override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 boolean visible; // does this activity's window need to be shown?
Jorim Jaggi241ae102016-11-02 21:57:33 -0700332 boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
333 // might hide this activity?
Wale Ogunwaleec950642017-04-25 07:44:21 -0700334 private boolean mDeferHidingClient; // If true we told WM to defer reporting to the client
335 // process that it is hidden.
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800336 boolean sleeping; // have we told the activity to sleep?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 boolean nowVisible; // is this activity's window visible?
Vishnu Nair9ba31652018-11-13 14:34:05 -0800338 boolean mDrawn; // is this activity's window drawn?
Andrii Kuliana39ae3e2018-05-31 12:43:54 -0700339 boolean mClientVisibilityDeferred;// was the visibility change message to client deferred?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 boolean idle; // has the activity gone idle?
341 boolean hasBeenLaunched;// has this activity ever been launched?
342 boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
Daniel Sandler69a48172010-06-23 16:29:36 -0400343 boolean immersive; // immersive mode (don't interrupt if possible)
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400344 boolean forceNewConfig; // force re-create with new config next time
Winson Chungf7e03e12017-08-22 11:32:16 -0700345 boolean supportsEnterPipOnTaskSwitch; // This flag is set by the system to indicate that the
346 // activity can enter picture in picture while pausing (only when switching to another task)
Winson Chung709904f2017-04-25 11:00:48 -0700347 PictureInPictureParams pictureInPictureArgs = new PictureInPictureParams.Builder().build();
348 // The PiP params used when deferring the entering of picture-in-picture.
Dianne Hackborn07981492013-01-28 11:36:23 -0800349 int launchCount; // count of launches since last state
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800350 long lastLaunchTime; // time of last launch of this activity
Ruben Brunke24b9a62016-02-16 21:38:24 -0800351 ComponentName requestedVrComponent; // the requested component for handling VR mode.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700353 String stringName; // for caching of toString().
Craig Mautnerde4ef022013-04-07 19:01:33 -0700354
Dianne Hackbornf26fd992011-04-08 18:14:09 -0700355 private boolean inHistory; // are we in the history stack?
Craig Mautnerde4ef022013-04-07 19:01:33 -0700356 final ActivityStackSupervisor mStackSupervisor;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800357 final RootActivityContainer mRootActivityContainer;
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800358
359 static final int STARTING_WINDOW_NOT_SHOWN = 0;
360 static final int STARTING_WINDOW_SHOWN = 1;
361 static final int STARTING_WINDOW_REMOVED = 2;
362 int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;
Wale Ogunwale3b232392016-05-13 15:37:13 -0700363 boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800364
Garfield Tan2746ab52018-07-25 12:33:01 -0700365 // Marking the reason why this activity is being relaunched. Mainly used to track that this
366 // activity is being relaunched to fulfill a resize request due to compatibility issues, e.g. in
367 // pre-NYC apps that don't have a sense of being resized.
368 int mRelaunchReason = RELAUNCH_REASON_NONE;
369
Craig Mautner21d24a22014-04-23 11:45:37 -0700370 TaskDescription taskDescription; // the recents information for this activity
Craig Mautnerbb742462014-07-07 15:28:55 -0700371 boolean mLaunchTaskBehind; // this activity is actively being launched with
372 // ActivityOptions.setLaunchTaskBehind, will be cleared once launch is completed.
Craig Mautner2fbd7542014-03-21 09:34:07 -0700373
Filip Gruszczynski23493322015-07-29 17:02:59 -0700374 // These configurations are collected from application's resources based on size-sensitive
375 // qualifiers. For example, layout-w800dp will be added to mHorizontalSizeConfigurations as 800
376 // and drawable-sw400dp will be added to both as 400.
377 private int[] mVerticalSizeConfigurations;
378 private int[] mHorizontalSizeConfigurations;
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700379 private int[] mSmallestSizeConfigurations;
Filip Gruszczynski23493322015-07-29 17:02:59 -0700380
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800381 boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session
382 IVoiceInteractionSession voiceSession; // Voice interaction session for this activity
383
Robert Carrd2265122016-08-05 10:25:21 -0700384 // A hint to override the window specified rotation animation, or -1
385 // to use the window specified value. We use this so that
386 // we can select the right animation in the cases of starting
387 // windows, where the app hasn't had time to set a value
388 // on the window.
389 int mRotationAnimationHint = -1;
Robert Carrfd10cd12016-06-29 16:41:50 -0700390
chaviw59b98852017-06-13 12:05:44 -0700391 private boolean mShowWhenLocked;
Issei Suzuki74e1eb22018-12-20 17:42:52 +0100392 private boolean mInheritShownWhenLocked;
chaviw59b98852017-06-13 12:05:44 -0700393 private boolean mTurnScreenOn;
394
Andrii Kulian21713ac2016-10-12 22:05:05 -0700395 /**
Garfield Tan0443b372019-01-04 15:00:13 -0800396 * Current sequencing integer of the configuration, for skipping old activity configurations.
397 */
398 private int mConfigurationSeq;
399
400 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -0800401 * Temp configs used in {@link #ensureActivityConfiguration(int, boolean)}
Andrii Kulian21713ac2016-10-12 22:05:05 -0700402 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700403 private final Configuration mTmpConfig = new Configuration();
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700404 private final Rect mTmpBounds = new Rect();
Andrii Kulian21713ac2016-10-12 22:05:05 -0700405
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800406 private static String startingWindowStateToString(int state) {
407 switch (state) {
408 case STARTING_WINDOW_NOT_SHOWN:
409 return "STARTING_WINDOW_NOT_SHOWN";
410 case STARTING_WINDOW_SHOWN:
411 return "STARTING_WINDOW_SHOWN";
412 case STARTING_WINDOW_REMOVED:
413 return "STARTING_WINDOW_REMOVED";
414 default:
415 return "unknown state=" + state;
416 }
417 }
418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700420 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700421 pw.print(prefix); pw.print("packageName="); pw.print(packageName);
422 pw.print(" processName="); pw.println(processName);
423 pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
Craig Mautnere11f2b72013-04-01 12:37:17 -0700424 pw.print(" launchedFromPackage="); pw.print(launchedFromPackage);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800425 pw.print(" userId="); pw.println(mUserId);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800426 pw.print(prefix); pw.print("app="); pw.println(app);
427 pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700428 pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask);
429 pw.print(" task="); pw.println(task);
430 pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800431 pw.print(prefix); pw.print("mActivityComponent=");
432 pw.println(mActivityComponent.flattenToShortString());
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700433 if (appInfo != null) {
434 pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir);
435 if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) {
436 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir);
437 }
438 pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800439 if (appInfo.splitSourceDirs != null) {
440 pw.print(prefix); pw.print("splitDir=");
441 pw.println(Arrays.toString(appInfo.splitSourceDirs));
442 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800443 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700444 pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
445 pw.print(" componentSpecified="); pw.print(componentSpecified);
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700446 pw.print(" mActivityType="); pw.println(
447 activityTypeToString(getActivityType()));
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700448 if (rootVoiceInteraction) {
449 pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
450 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800451 pw.print(prefix); pw.print("compat="); pw.print(compat);
452 pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
453 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
454 pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700455 pw.println(prefix + "mLastReportedConfigurations:");
456 mLastReportedConfiguration.dump(pw, prefix + " ");
457
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700458 pw.print(prefix); pw.print("CurrentConfiguration="); pw.println(getConfiguration());
Evan Roskydfe3da72018-10-26 17:21:06 -0700459 if (!getRequestedOverrideConfiguration().equals(EMPTY)) {
460 pw.println(prefix + "RequestedOverrideConfiguration="
461 + getRequestedOverrideConfiguration());
462 }
463 if (!getResolvedOverrideConfiguration().equals(getRequestedOverrideConfiguration())) {
464 pw.println(prefix + "ResolvedOverrideConfiguration="
465 + getResolvedOverrideConfiguration());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700466 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800467 if (!matchParentBounds()) {
468 pw.println(prefix + "bounds=" + getBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700469 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700470 if (resultTo != null || resultWho != null) {
471 pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
472 pw.print(" resultWho="); pw.print(resultWho);
473 pw.print(" resultCode="); pw.println(requestCode);
474 }
Craig Mautner29c58ca2014-10-14 16:17:06 -0700475 if (taskDescription != null) {
476 final String iconFilename = taskDescription.getIconFilename();
477 if (iconFilename != null || taskDescription.getLabel() != null ||
478 taskDescription.getPrimaryColor() != 0) {
479 pw.print(prefix); pw.print("taskDescription:");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700480 pw.print(" label=\""); pw.print(taskDescription.getLabel());
481 pw.print("\"");
Matthew Ng54bc9422017-10-02 17:16:28 -0700482 pw.print(" icon="); pw.print(taskDescription.getInMemoryIcon() != null
483 ? taskDescription.getInMemoryIcon().getByteCount() + " bytes"
484 : "null");
485 pw.print(" iconResource="); pw.print(taskDescription.getIconResource());
486 pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200487 pw.print(" primaryColor=");
Craig Mautner29c58ca2014-10-14 16:17:06 -0700488 pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700489 pw.print(prefix + " backgroundColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200490 pw.println(Integer.toHexString(taskDescription.getBackgroundColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700491 pw.print(prefix + " statusBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200492 pw.println(Integer.toHexString(taskDescription.getStatusBarColor()));
Wale Ogunwale822e5122017-07-26 06:02:24 -0700493 pw.print(prefix + " navigationBarColor=");
Jorim Jaggi30d64f32017-04-07 16:33:17 +0200494 pw.println(Integer.toHexString(taskDescription.getNavigationBarColor()));
Craig Mautner29c58ca2014-10-14 16:17:06 -0700495 }
Craig Mautner648f69b2014-09-18 14:16:26 -0700496 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700497 if (results != null) {
498 pw.print(prefix); pw.print("results="); pw.println(results);
499 }
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700500 if (pendingResults != null && pendingResults.size() > 0) {
501 pw.print(prefix); pw.println("Pending Results:");
502 for (WeakReference<PendingIntentRecord> wpir : pendingResults) {
503 PendingIntentRecord pir = wpir != null ? wpir.get() : null;
504 pw.print(prefix); pw.print(" - ");
505 if (pir == null) {
506 pw.println("null");
507 } else {
508 pw.println(pir);
509 pir.dump(pw, prefix + " ");
510 }
511 }
512 }
513 if (newIntents != null && newIntents.size() > 0) {
514 pw.print(prefix); pw.println("Pending New Intents:");
515 for (int i=0; i<newIntents.size(); i++) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800516 Intent intent = newIntents.get(i);
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700517 pw.print(prefix); pw.print(" - ");
518 if (intent == null) {
519 pw.println("null");
520 } else {
521 pw.println(intent.toShortString(false, true, false, true));
522 }
523 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700524 }
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700525 if (pendingOptions != null) {
526 pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions);
527 }
Dianne Hackbornb5a380d2015-05-20 18:18:46 -0700528 if (appTimeTracker != null) {
529 appTimeTracker.dumpWithHeader(pw, prefix, false);
530 }
Dianne Hackborn7e269642010-08-25 19:50:20 -0700531 if (uriPermissions != null) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700532 uriPermissions.dump(pw, prefix);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700533 }
534 pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed);
Dianne Hackborn07981492013-01-28 11:36:23 -0800535 pw.print(" launchCount="); pw.print(launchCount);
536 pw.print(" lastLaunchTime=");
537 if (lastLaunchTime == 0) pw.print("0");
538 else TimeUtils.formatDuration(lastLaunchTime, now, pw);
539 pw.println();
Dianne Hackborncfc837f2013-06-27 18:32:07 -0700540 pw.print(prefix); pw.print("haveState="); pw.print(haveState);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700541 pw.print(" icicle="); pw.println(icicle);
Bryce Lee7ace3952018-02-16 14:34:32 -0800542 pw.print(prefix); pw.print("state="); pw.print(mState);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700543 pw.print(" stopped="); pw.print(stopped);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700544 pw.print(" delayedResume="); pw.print(delayedResume);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700545 pw.print(" finishing="); pw.println(finishing);
546 pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
547 pw.print(" inHistory="); pw.print(inHistory);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700548 pw.print(" visible="); pw.print(visible);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800549 pw.print(" sleeping="); pw.print(sleeping);
Wale Ogunwalef40c11b2016-02-26 08:16:02 -0800550 pw.print(" idle="); pw.print(idle);
551 pw.print(" mStartingWindowState=");
552 pw.println(startingWindowStateToString(mStartingWindowState));
Dianne Hackbornff801ec2011-01-22 18:05:38 -0800553 pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
554 pw.print(" noDisplay="); pw.print(noDisplay);
555 pw.print(" immersive="); pw.print(immersive);
556 pw.print(" launchMode="); pw.println(launchMode);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800557 pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400558 pw.print(" forceNewConfig="); pw.println(forceNewConfig);
Craig Mautnerae7ecab2013-09-18 11:48:14 -0700559 pw.print(prefix); pw.print("mActivityType=");
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700560 pw.println(activityTypeToString(getActivityType()));
Ruben Brunke24b9a62016-02-16 21:38:24 -0800561 if (requestedVrComponent != null) {
562 pw.print(prefix);
563 pw.print("requestedVrComponent=");
564 pw.println(requestedVrComponent);
565 }
Bryce Lee4a194382017-04-04 14:32:48 -0700566 final boolean waitingVisible =
567 mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800568 if (lastVisibleTime != 0 || waitingVisible || nowVisible) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700569 pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
Dianne Hackborn21c241e2012-03-08 13:57:23 -0800570 pw.print(" nowVisible="); pw.print(nowVisible);
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -0700571 pw.print(" lastVisibleTime=");
Dianne Hackbornf530ac32012-06-21 14:17:48 -0700572 if (lastVisibleTime == 0) pw.print("0");
573 else TimeUtils.formatDuration(lastVisibleTime, now, pw);
574 pw.println();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700575 }
Wale Ogunwaleec950642017-04-25 07:44:21 -0700576 if (mDeferHidingClient) {
577 pw.println(prefix + "mDeferHidingClient=" + mDeferHidingClient);
578 }
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800579 if (deferRelaunchUntilPaused || configChangeFlags != 0) {
580 pw.print(prefix); pw.print("deferRelaunchUntilPaused="); pw.print(deferRelaunchUntilPaused);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700581 pw.print(" configChangeFlags=");
582 pw.println(Integer.toHexString(configChangeFlags));
583 }
Wale Ogunwalec4e63a42018-10-02 13:19:54 -0700584 if (mServiceConnectionsHolder != null) {
585 pw.print(prefix); pw.print("connections="); pw.println(mServiceConnectionsHolder);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700586 }
Wale Ogunwaled26176f2016-01-25 20:04:04 -0800587 if (info != null) {
588 pw.println(prefix + "resizeMode=" + ActivityInfo.resizeModeToString(info.resizeMode));
Winson Chung609e1e92017-05-08 10:52:12 -0700589 pw.println(prefix + "mLastReportedMultiWindowMode=" + mLastReportedMultiWindowMode
590 + " mLastReportedPictureInPictureMode=" + mLastReportedPictureInPictureMode);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700591 if (info.supportsPictureInPicture()) {
592 pw.println(prefix + "supportsPictureInPicture=" + info.supportsPictureInPicture());
Winson Chungf7e03e12017-08-22 11:32:16 -0700593 pw.println(prefix + "supportsEnterPipOnTaskSwitch: "
594 + supportsEnterPipOnTaskSwitch);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700595 }
596 if (info.maxAspectRatio != 0) {
597 pw.println(prefix + "maxAspectRatio=" + info.maxAspectRatio);
598 }
Adrian Roos917791e2018-11-28 16:30:44 +0100599 if (info.minAspectRatio != 0) {
600 pw.println(prefix + "minAspectRatio=" + info.minAspectRatio);
601 }
Wale Ogunwaled26176f2016-01-25 20:04:04 -0800602 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 }
604
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700605 void updateApplicationInfo(ApplicationInfo aInfo) {
606 appInfo = aInfo;
607 info.applicationInfo = aInfo;
608 }
609
Andrii Kulian21713ac2016-10-12 22:05:05 -0700610 private boolean crossesHorizontalSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700611 return crossesSizeThreshold(mHorizontalSizeConfigurations, firstDp, secondDp);
612 }
613
Andrii Kulian21713ac2016-10-12 22:05:05 -0700614 private boolean crossesVerticalSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700615 return crossesSizeThreshold(mVerticalSizeConfigurations, firstDp, secondDp);
616 }
617
Andrii Kulian21713ac2016-10-12 22:05:05 -0700618 private boolean crossesSmallestSizeThreshold(int firstDp, int secondDp) {
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700619 return crossesSizeThreshold(mSmallestSizeConfigurations, firstDp, secondDp);
620 }
621
Filip Gruszczynski23493322015-07-29 17:02:59 -0700622 /**
623 * The purpose of this method is to decide whether the activity needs to be relaunched upon
624 * changing its size. In most cases the activities don't need to be relaunched, if the resize
625 * is small, all the activity content has to do is relayout itself within new bounds. There are
626 * cases however, where the activity's content would be completely changed in the new size and
627 * the full relaunch is required.
628 *
629 * The activity will report to us vertical and horizontal thresholds after which a relaunch is
630 * required. These thresholds are collected from the application resource qualifiers. For
631 * example, if application has layout-w600dp resource directory, then it needs a relaunch when
632 * we resize from width of 650dp to 550dp, as it crosses the 600dp threshold. However, if
633 * it resizes width from 620dp to 700dp, it won't be relaunched as it stays on the same side
634 * of the threshold.
635 */
636 private static boolean crossesSizeThreshold(int[] thresholds, int firstDp,
637 int secondDp) {
638 if (thresholds == null) {
639 return false;
640 }
641 for (int i = thresholds.length - 1; i >= 0; i--) {
642 final int threshold = thresholds[i];
643 if ((firstDp < threshold && secondDp >= threshold)
644 || (firstDp >= threshold && secondDp < threshold)) {
645 return true;
646 }
647 }
648 return false;
649 }
650
Andrii Kulian21713ac2016-10-12 22:05:05 -0700651 void setSizeConfigurations(int[] horizontalSizeConfiguration,
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700652 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
Filip Gruszczynski23493322015-07-29 17:02:59 -0700653 mHorizontalSizeConfigurations = horizontalSizeConfiguration;
654 mVerticalSizeConfigurations = verticalSizeConfigurations;
Filip Gruszczynski20aa0ae2015-10-30 10:08:27 -0700655 mSmallestSizeConfigurations = smallestSizeConfigurations;
Filip Gruszczynski23493322015-07-29 17:02:59 -0700656 }
657
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800658 private void scheduleActivityMovedToDisplay(int displayId, Configuration config) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700659 if (!attachedToProcess()) {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800660 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.w(TAG,
661 "Can't report activity moved to display - client not running, activityRecord="
662 + this + ", displayId=" + displayId);
Wale Ogunwale22e25262016-02-01 10:32:02 -0800663 return;
664 }
665 try {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800666 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
667 "Reporting activity moved to display" + ", activityRecord=" + this
668 + ", displayId=" + displayId + ", config=" + config);
Chong Zhang6be533e2016-06-17 16:24:21 -0700669
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800670 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800671 MoveToDisplayItem.obtain(displayId, config));
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800672 } catch (RemoteException e) {
673 // If process died, whatever.
674 }
675 }
676
677 private void scheduleConfigurationChanged(Configuration config) {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700678 if (!attachedToProcess()) {
Andrii Kulianb047b8b2017-02-08 18:38:26 -0800679 if (DEBUG_CONFIGURATION) Slog.w(TAG,
680 "Can't report activity configuration update - client not running"
681 + ", activityRecord=" + this);
682 return;
683 }
684 try {
685 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + this + ", config: "
686 + config);
687
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800688 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800689 ActivityConfigurationChangeItem.obtain(config));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800690 } catch (RemoteException e) {
691 // If process died, whatever.
692 }
693 }
694
Winson Chung5af42fc2017-03-24 17:11:33 -0700695 void updateMultiWindowMode() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700696 if (task == null || task.getStack() == null || !attachedToProcess()) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800697 return;
698 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700699
Wale Ogunwaleeb76b762017-11-17 10:08:04 -0800700 if (task.getStack().deferScheduleMultiWindowModeChanged()) {
701 // Don't do anything if we are currently deferring multi-window mode change.
702 return;
703 }
704
Winson Chung5af42fc2017-03-24 17:11:33 -0700705 // An activity is considered to be in multi-window mode if its task isn't fullscreen.
Wale Ogunwaleeb76b762017-11-17 10:08:04 -0800706 final boolean inMultiWindowMode = inMultiWindowMode();
Winson Chung609e1e92017-05-08 10:52:12 -0700707 if (inMultiWindowMode != mLastReportedMultiWindowMode) {
708 mLastReportedMultiWindowMode = inMultiWindowMode;
Winson Chung5af42fc2017-03-24 17:11:33 -0700709 scheduleMultiWindowModeChanged(getConfiguration());
710 }
711 }
712
713 private void scheduleMultiWindowModeChanged(Configuration overrideConfig) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800714 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800715 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Wale Ogunwaled0412b32018-05-08 09:25:50 -0700716 MultiWindowModeChangeItem.obtain(mLastReportedMultiWindowMode, overrideConfig));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800717 } catch (Exception e) {
718 // If process died, I don't care.
719 }
720 }
721
Winson Chungab76bbc2017-08-14 13:33:51 -0700722 void updatePictureInPictureMode(Rect targetStackBounds, boolean forceUpdate) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700723 if (task == null || task.getStack() == null || !attachedToProcess()) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800724 return;
725 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700726
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700727 final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null;
Winson Chungab76bbc2017-08-14 13:33:51 -0700728 if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) {
Winson Chung5af42fc2017-03-24 17:11:33 -0700729 // Picture-in-picture mode changes also trigger a multi-window mode change as well, so
Winson Chung059955f2018-08-08 16:10:20 -0700730 // update that here in order. Set the last reported MW state to the same as the PiP
731 // state since we haven't yet actually resized the task (these callbacks need to
732 // preceed the configuration change from the resiez.
733 // TODO(110009072): Once we move these callbacks to the client, remove all logic related
734 // to forcing the update of the picture-in-picture mode as a part of the PiP animation.
Winson Chung609e1e92017-05-08 10:52:12 -0700735 mLastReportedPictureInPictureMode = inPictureInPictureMode;
Winson Chung059955f2018-08-08 16:10:20 -0700736 mLastReportedMultiWindowMode = inPictureInPictureMode;
Evan Rosky1ac84462018-11-13 11:25:30 -0800737 final Configuration newConfig = new Configuration();
738 if (targetStackBounds != null && !targetStackBounds.isEmpty()) {
Evan Rosky730f6e82018-12-03 17:40:11 -0800739 newConfig.setTo(task.getRequestedOverrideConfiguration());
740 Rect outBounds = newConfig.windowConfiguration.getBounds();
741 task.adjustForMinimalTaskDimensions(outBounds, outBounds);
742 task.computeConfigResourceOverrides(newConfig, task.getParent().getConfiguration());
Evan Rosky1ac84462018-11-13 11:25:30 -0800743 }
Winson Chung5af42fc2017-03-24 17:11:33 -0700744 schedulePictureInPictureModeChanged(newConfig);
745 scheduleMultiWindowModeChanged(newConfig);
746 }
747 }
748
749 private void schedulePictureInPictureModeChanged(Configuration overrideConfig) {
Wale Ogunwale22e25262016-02-01 10:32:02 -0800750 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800751 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800752 PipModeChangeItem.obtain(mLastReportedPictureInPictureMode,
Andrii Kulian446e8242017-10-26 15:17:29 -0700753 overrideConfig));
Wale Ogunwale22e25262016-02-01 10:32:02 -0800754 } catch (Exception e) {
755 // If process died, no one cares.
Filip Gruszczynskica664812015-12-04 12:43:36 -0800756 }
757 }
758
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700759 @Override
760 protected int getChildCount() {
761 // {@link ActivityRecord} is a leaf node and has no children.
762 return 0;
763 }
764
765 @Override
766 protected ConfigurationContainer getChildAt(int index) {
767 return null;
768 }
769
770 @Override
771 protected ConfigurationContainer getParent() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800772 return getTaskRecord();
Bryce Leeaf691c02017-03-20 14:20:22 -0700773 }
774
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800775 TaskRecord getTaskRecord() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700776 return task;
777 }
778
Bryce Leeaf691c02017-03-20 14:20:22 -0700779 /**
780 * Sets reference to the {@link TaskRecord} the {@link ActivityRecord} will treat as its parent.
781 * Note that this does not actually add the {@link ActivityRecord} as a {@link TaskRecord}
782 * children. However, this method will clean up references to this {@link ActivityRecord} in
783 * {@link ActivityStack}.
784 * @param task The new parent {@link TaskRecord}.
785 */
786 void setTask(TaskRecord task) {
Bryce Lee84730a02018-04-03 14:10:04 -0700787 setTask(task /* task */, false /* reparenting */);
Bryce Leeaf691c02017-03-20 14:20:22 -0700788 }
789
790 /**
791 * This method should only be called by {@link TaskRecord#removeActivity(ActivityRecord)}.
Bryce Lee84730a02018-04-03 14:10:04 -0700792 * @param task The new parent task.
793 * @param reparenting Whether we're in the middle of reparenting.
Bryce Leeaf691c02017-03-20 14:20:22 -0700794 */
795 void setTask(TaskRecord task, boolean reparenting) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800796 // Do nothing if the {@link TaskRecord} is the same as the current {@link getTaskRecord}.
797 if (task != null && task == getTaskRecord()) {
Bryce Leeaf691c02017-03-20 14:20:22 -0700798 return;
799 }
800
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800801 final ActivityStack oldStack = getActivityStack();
Bryce Lee84730a02018-04-03 14:10:04 -0700802 final ActivityStack newStack = task != null ? task.getStack() : null;
Bryce Leeaf691c02017-03-20 14:20:22 -0700803
Bryce Lee84730a02018-04-03 14:10:04 -0700804 // Inform old stack (if present) of activity removal and new stack (if set) of activity
805 // addition.
806 if (oldStack != newStack) {
807 if (!reparenting && oldStack != null) {
808 oldStack.onActivityRemovedFromStack(this);
809 }
810
811 if (newStack != null) {
812 newStack.onActivityAddedToStack(this);
813 }
Bryce Leeaf691c02017-03-20 14:20:22 -0700814 }
815
816 this.task = task;
817
818 if (!reparenting) {
819 onParentChanged();
820 }
821 }
822
chaviw4ad54912018-05-30 11:05:44 -0700823 /**
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800824 * Notifies AWT that this app is waiting to pause in order to determine if it will enter PIP.
825 * This information helps AWT know that the app is in the process of pausing before it gets the
826 * signal on the WM side.
chaviw4ad54912018-05-30 11:05:44 -0700827 */
828 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800829 if (mAppWindowToken == null) {
830 return;
831 }
832
833 mAppWindowToken.setWillCloseOrEnterPip(willCloseOrEnterPip);
chaviw4ad54912018-05-30 11:05:44 -0700834 }
835
Dianne Hackbornbe707852011-11-11 14:32:10 -0800836 static class Token extends IApplicationToken.Stub {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700837 private final WeakReference<ActivityRecord> weakActivity;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700838 private final String name;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800839
Steven Timotiusaf03df62017-07-18 16:56:43 -0700840 Token(ActivityRecord activity, Intent intent) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800841 weakActivity = new WeakReference<>(activity);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700842 name = intent.getComponent().flattenToShortString();
Wale Ogunwale7d701172015-03-11 15:36:30 -0700843 }
844
Andrii Kulian21713ac2016-10-12 22:05:05 -0700845 private static ActivityRecord tokenToActivityRecordLocked(Token token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700846 if (token == null) {
847 return null;
848 }
849 ActivityRecord r = token.weakActivity.get();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800850 if (r == null || r.getActivityStack() == null) {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700851 return null;
852 }
853 return r;
Dianne Hackbornbe707852011-11-11 14:32:10 -0800854 }
855
Craig Mautnerde4ef022013-04-07 19:01:33 -0700856 @Override
Dianne Hackbornbe707852011-11-11 14:32:10 -0800857 public String toString() {
858 StringBuilder sb = new StringBuilder(128);
859 sb.append("Token{");
860 sb.append(Integer.toHexString(System.identityHashCode(this)));
861 sb.append(' ');
862 sb.append(weakActivity.get());
863 sb.append('}');
864 return sb.toString();
865 }
Steven Timotiusaf03df62017-07-18 16:56:43 -0700866
867 @Override
868 public String getName() {
869 return name;
870 }
Dianne Hackbornbe707852011-11-11 14:32:10 -0800871 }
872
Wale Ogunwale7d701172015-03-11 15:36:30 -0700873 static ActivityRecord forTokenLocked(IBinder token) {
Dianne Hackbornbe707852011-11-11 14:32:10 -0800874 try {
Wale Ogunwale7d701172015-03-11 15:36:30 -0700875 return Token.tokenToActivityRecordLocked((Token)token);
Dianne Hackbornbe707852011-11-11 14:32:10 -0800876 } catch (ClassCastException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800877 Slog.w(TAG, "Bad activity token: " + token, e);
Dianne Hackbornbe707852011-11-11 14:32:10 -0800878 return null;
879 }
880 }
881
Chong Zhang85ee6542015-10-02 13:36:38 -0700882 boolean isResolverActivity() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800883 return ResolverActivity.class.getName().equals(mActivityComponent.getClassName());
Craig Mautnerac6f8432013-07-17 13:24:59 -0700884 }
885
Patrick Baumann31426b22018-05-21 13:46:40 -0700886 boolean isResolverOrChildActivity() {
887 if (!"android".equals(packageName)) {
888 return false;
889 }
890 try {
891 return ResolverActivity.class.isAssignableFrom(
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800892 Object.class.getClassLoader().loadClass(mActivityComponent.getClassName()));
Patrick Baumann31426b22018-05-21 13:46:40 -0700893 } catch (ClassNotFoundException e) {
894 return false;
895 }
896 }
897
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700898 ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
899 int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage, Intent _intent,
900 String _resolvedType, ActivityInfo aInfo, Configuration _configuration,
901 ActivityRecord _resultTo, String _resultWho, int _reqCode, boolean _componentSpecified,
902 boolean _rootVoiceInteraction, ActivityStackSupervisor supervisor,
903 ActivityOptions options, ActivityRecord sourceRecord) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800904 mAtmService = _service;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800905 mRootActivityContainer = _service.mRootActivityContainer;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700906 appToken = new Token(this, _intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907 info = aInfo;
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800908 launchedFromPid = _launchedFromPid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 launchedFromUid = _launchedFromUid;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800910 launchedFromPackage = _launchedFromPackage;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800911 mUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 intent = _intent;
913 shortComponentName = _intent.getComponent().flattenToShortString();
914 resolvedType = _resolvedType;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800915 componentSpecified = _componentSpecified;
Dianne Hackbornfb81d092015-08-03 17:14:46 -0700916 rootVoiceInteraction = _rootVoiceInteraction;
Wale Ogunwalee610d3d2017-04-25 10:23:48 -0700917 mLastReportedConfiguration = new MergedConfiguration(_configuration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 resultTo = _resultTo;
919 resultWho = _resultWho;
920 requestCode = _reqCode;
Bryce Lee7ace3952018-02-16 14:34:32 -0800921 setState(INITIALIZING, "ActivityRecord ctor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 frontOfTask = false;
923 launchFailed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 stopped = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700925 delayedResume = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 finishing = false;
Wale Ogunwalef81c1d12016-01-12 12:20:18 -0800927 deferRelaunchUntilPaused = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 keysPaused = false;
929 inHistory = false;
Chong Zhanga48ef662015-08-18 19:21:47 -0700930 visible = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 nowVisible = false;
Vishnu Nair9ba31652018-11-13 14:34:05 -0800932 mDrawn = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 idle = false;
934 hasBeenLaunched = false;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700935 mStackSupervisor = supervisor;
Robert Carr0f5d7532016-10-17 16:39:17 -0700936
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800937 // This starts out true, since the initial state of an activity is that we have everything,
938 // and we shouldn't never consider it lacking in state to be removed if it dies.
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700939 haveState = true;
940
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800941 // If the class name in the intent doesn't match that of the target, this is
942 // probably an alias. We have to create a new ComponentName object to keep track
943 // of the real activity name, so that FLAG_ACTIVITY_CLEAR_TOP is handled properly.
944 if (aInfo.targetActivity == null
945 || (aInfo.targetActivity.equals(_intent.getComponent().getClassName())
946 && (aInfo.launchMode == LAUNCH_MULTIPLE
947 || aInfo.launchMode == LAUNCH_SINGLE_TOP))) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800948 mActivityComponent = _intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800950 mActivityComponent = new ComponentName(aInfo.packageName, aInfo.targetActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800952 taskAffinity = aInfo.taskAffinity;
953 stateNotNeeded = (aInfo.flags & FLAG_STATE_NOT_NEEDED) != 0;
954 appInfo = aInfo.applicationInfo;
955 nonLocalizedLabel = aInfo.nonLocalizedLabel;
956 labelRes = aInfo.labelRes;
957 if (nonLocalizedLabel == null && labelRes == 0) {
958 ApplicationInfo app = aInfo.applicationInfo;
959 nonLocalizedLabel = app.nonLocalizedLabel;
960 labelRes = app.labelRes;
961 }
962 icon = aInfo.getIconResource();
963 logo = aInfo.getLogoResource();
964 theme = aInfo.getThemeResource();
965 realTheme = theme;
966 if (realTheme == 0) {
967 realTheme = aInfo.applicationInfo.targetSdkVersion < HONEYCOMB
968 ? android.R.style.Theme : android.R.style.Theme_Holo;
969 }
970 if ((aInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
971 windowFlags |= LayoutParams.FLAG_HARDWARE_ACCELERATED;
972 }
973 if ((aInfo.flags & FLAG_MULTIPROCESS) != 0 && _caller != null
974 && (aInfo.applicationInfo.uid == SYSTEM_UID
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700975 || aInfo.applicationInfo.uid == _caller.mInfo.uid)) {
976 processName = _caller.mName;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800977 } else {
978 processName = aInfo.processName;
979 }
980
981 if ((aInfo.flags & FLAG_EXCLUDE_FROM_RECENTS) != 0) {
982 intent.addFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
983 }
984
985 packageName = aInfo.applicationInfo.packageName;
986 launchMode = aInfo.launchMode;
987
Ruben Brunkf53497c2017-03-27 20:26:17 -0700988 Entry ent = AttributeCache.instance().get(packageName,
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800989 realTheme, com.android.internal.R.styleable.Window, mUserId);
Bryce Leee83f34cd2017-10-31 19:50:54 -0700990
Wale Ogunwale7e1f5f52017-10-18 15:19:59 -0700991 if (ent != null) {
992 fullscreen = !ActivityInfo.isTranslucentOrFloating(ent.array);
993 hasWallpaper = ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
994 noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
995 } else {
996 hasWallpaper = false;
997 noDisplay = false;
998 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800999
Winson Chung83471632016-12-13 11:02:12 -08001000 setActivityType(_componentSpecified, _launchedFromUid, _intent, options, sourceRecord);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001001
1002 immersive = (aInfo.flags & FLAG_IMMERSIVE) != 0;
1003
1004 requestedVrComponent = (aInfo.requestedVrComponent == null) ?
1005 null : ComponentName.unflattenFromString(aInfo.requestedVrComponent);
chaviw59b98852017-06-13 12:05:44 -07001006
1007 mShowWhenLocked = (aInfo.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
Issei Suzuki74e1eb22018-12-20 17:42:52 +01001008 mInheritShownWhenLocked = (aInfo.privateFlags & FLAG_INHERIT_SHOW_WHEN_LOCKED) != 0;
chaviw59b98852017-06-13 12:05:44 -07001009 mTurnScreenOn = (aInfo.flags & FLAG_TURN_SCREEN_ON) != 0;
Charles He2bf28322017-10-12 22:24:49 +01001010
1011 mRotationAnimationHint = aInfo.rotationAnimation;
1012 lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
1013 if (appInfo.isPrivilegedApp() && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
1014 || lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
1015 lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
1016 }
1017
1018 if (options != null) {
1019 pendingOptions = options;
1020 mLaunchTaskBehind = options.getLaunchTaskBehind();
1021
1022 final int rotationAnimation = pendingOptions.getRotationAnimationHint();
1023 // Only override manifest supplied option if set.
1024 if (rotationAnimation >= 0) {
1025 mRotationAnimationHint = rotationAnimation;
1026 }
1027 final PendingIntent usageReport = pendingOptions.getUsageTimeReport();
1028 if (usageReport != null) {
1029 appTimeTracker = new AppTimeTracker(usageReport);
1030 }
1031 final boolean useLockTask = pendingOptions.getLockTaskMode();
1032 if (useLockTask && lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_DEFAULT) {
1033 lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
1034 }
Louis Changd58cb672018-12-24 17:45:16 +08001035 // Gets launch display id from options. It returns INVALID_DISPLAY if not set.
1036 mHandoverLaunchDisplayId = options.getLaunchDisplayId();
Charles He2bf28322017-10-12 22:24:49 +01001037 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001038 }
1039
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001040 void setProcess(WindowProcessController proc) {
Dianne Hackborn68a06332017-11-15 17:54:18 -08001041 app = proc;
1042 final ActivityRecord root = task != null ? task.getRootActivity() : null;
1043 if (root == this) {
1044 task.setRootProcess(proc);
1045 }
1046 }
1047
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001048 boolean hasProcess() {
1049 return app != null;
1050 }
1051
1052 boolean attachedToProcess() {
1053 return hasProcess() && app.hasThread();
1054 }
1055
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001056 void createAppWindowToken() {
1057 if (mAppWindowToken != null) {
1058 throw new IllegalArgumentException("App Window Token=" + mAppWindowToken
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001059 + " already created for r=" + this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001060 }
1061
1062 inHistory = true;
1063
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07001064 // TODO(b/36505427): Maybe this call should be moved inside updateOverrideConfiguration()
1065 task.updateOverrideConfigurationFromLaunchBounds();
1066 // Make sure override configuration is up-to-date before using to create window controller.
1067 updateOverrideConfiguration();
1068
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001069 // TODO: remove after unification
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001070 mAppWindowToken = mAtmService.mWindowManager.mRoot.getAppWindowToken(appToken.asBinder());
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001071 if (mAppWindowToken != null) {
1072 // TODO: Should this throw an exception instead?
1073 Slog.w(TAG, "Attempted to add existing app token: " + appToken);
1074 } else {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001075 final Task container = task.getTask();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001076 if (container == null) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001077 throw new IllegalArgumentException("createAppWindowToken: invalid task =" + task);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001078 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001079 mAppWindowToken = createAppWindow(mAtmService.mWindowManager, appToken,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001080 task.voiceSession != null, container.getDisplayContent(),
1081 ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this)
1082 * 1000000L, fullscreen,
1083 (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, appInfo.targetSdkVersion,
1084 info.screenOrientation, mRotationAnimationHint, info.configChanges,
1085 mLaunchTaskBehind, isAlwaysFocusable());
1086 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) {
1087 Slog.v(TAG, "addAppToken: "
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001088 + mAppWindowToken + " task=" + container + " at "
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001089 + Integer.MAX_VALUE);
1090 }
1091 container.addChild(mAppWindowToken, Integer.MAX_VALUE /* add on top */);
1092 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001093
1094 task.addActivityToTop(this);
1095
Winson Chung609e1e92017-05-08 10:52:12 -07001096 // When an activity is started directly into a split-screen fullscreen stack, we need to
1097 // update the initial multi-window modes so that the callbacks are scheduled correctly when
1098 // the user leaves that mode.
Bryce Leef3c6a472017-11-14 14:53:06 -08001099 mLastReportedMultiWindowMode = inMultiWindowMode();
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001100 mLastReportedPictureInPictureMode = inPinnedWindowingMode();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001101 }
1102
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001103 boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
1104 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
1105 IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
1106 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
1107 if (DEBUG_STARTING_WINDOW) {
1108 Slog.v(TAG, "setAppStartingWindow: token=" + appToken
1109 + " pkg=" + pkg + " transferFrom=" + transferFrom + " newTask=" + newTask
1110 + " taskSwitch=" + taskSwitch + " processRunning=" + processRunning
1111 + " allowTaskSnapshot=" + allowTaskSnapshot);
1112 }
1113 if (mAppWindowToken == null) {
1114 Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + appToken);
1115 return false;
1116 }
Yunfan Chen48c0ed082018-12-05 18:15:35 -08001117 if (mAppWindowToken.getTask() == null) {
1118 // Can be removed after unification of Task and TaskRecord.
1119 Slog.w(TAG_WM, "Attempted to start a window to an app token not having attached to any"
1120 + " task: " + appToken);
1121 return false;
1122 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001123 return mAppWindowToken.addStartingWindow(pkg, theme, compatInfo, nonLocalizedLabel,
1124 labelRes, icon, logo, windowFlags, transferFrom, newTask, taskSwitch,
1125 processRunning, allowTaskSnapshot, activityCreated, fromRecents);
1126 }
1127
1128 // TODO: Remove after unification
1129 @VisibleForTesting
1130 AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
1131 boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
1132 boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
1133 int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
1134 boolean alwaysFocusable) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001135 return new AppWindowToken(service, token, mActivityComponent, voiceInteraction, dc,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001136 inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation,
1137 rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable,
1138 this);
1139 }
1140
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001141 void removeWindowContainer() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001142 if (mAtmService.mWindowManager.mRoot == null) return;
Yunfan Chend4ef3012018-11-28 21:14:32 -08001143
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001144 final DisplayContent dc = mAtmService.mWindowManager.mRoot.getDisplayContent(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001145 getDisplayId());
1146 if (dc == null) {
1147 Slog.w(TAG, "removeWindowContainer: Attempted to remove token: "
1148 + appToken + " from non-existing displayId=" + getDisplayId());
Bryce Lee7ace3952018-02-16 14:34:32 -08001149 return;
1150 }
Wale Ogunwalecc367f42017-02-01 08:12:14 -08001151 // Resume key dispatching if it is currently paused before we remove the container.
1152 resumeKeyDispatchingLocked();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001153 dc.removeAppToken(appToken.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001154 }
1155
Winson Chung30480042017-01-26 10:55:34 -08001156 /**
1157 * Reparents this activity into {@param newTask} at the provided {@param position}. The caller
1158 * should ensure that the {@param newTask} is not already the parent of this activity.
1159 */
1160 void reparent(TaskRecord newTask, int position, String reason) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001161 if (mAppWindowToken == null) {
1162 Slog.w(TAG, "reparent: Attempted to reparent non-existing app token: " + appToken);
1163 return;
1164 }
Winson Chung30480042017-01-26 10:55:34 -08001165 final TaskRecord prevTask = task;
1166 if (prevTask == newTask) {
1167 throw new IllegalArgumentException(reason + ": task=" + newTask
1168 + " is already the parent of r=" + this);
1169 }
1170
Winson Chung74666102017-02-22 17:49:24 -08001171 // TODO: Ensure that we do not directly reparent activities across stacks, as that may leave
1172 // the stacks in strange states. For now, we should use Task.reparent() to ensure that
1173 // the stack is left in an OK state.
1174 if (prevTask != null && newTask != null && prevTask.getStack() != newTask.getStack()) {
1175 throw new IllegalArgumentException(reason + ": task=" + newTask
1176 + " is in a different stack (" + newTask.getStackId() + ") than the parent of"
1177 + " r=" + this + " (" + prevTask.getStackId() + ")");
1178 }
1179
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001180 mAppWindowToken.reparent(newTask.getTask(), position);
Winson Chung30480042017-01-26 10:55:34 -08001181
Bryce Lee84730a02018-04-03 14:10:04 -07001182 // Reparenting prevents informing the parent stack of activity removal in the case that
1183 // the new stack has the same parent. we must manually signal here if this is not the case.
1184 final ActivityStack prevStack = prevTask.getStack();
1185
1186 if (prevStack != newTask.getStack()) {
1187 prevStack.onActivityRemovedFromStack(this);
1188 }
Bryce Leeaf691c02017-03-20 14:20:22 -07001189 // Remove the activity from the old task and add it to the new task.
Bryce Lee84730a02018-04-03 14:10:04 -07001190 prevTask.removeActivity(this, true /* reparenting */);
Bryce Lee0f9bde82017-02-22 16:39:06 -08001191
Winson Chung30480042017-01-26 10:55:34 -08001192 newTask.addActivityAtIndex(position, this);
1193 }
1194
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001195 private boolean isHomeIntent(Intent intent) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001196 return ACTION_MAIN.equals(intent.getAction())
Chilun2ef71f72018-11-16 17:57:15 +08001197 && (intent.hasCategory(CATEGORY_HOME)
1198 || intent.hasCategory(CATEGORY_SECONDARY_HOME))
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001199 && intent.getCategories().size() == 1
1200 && intent.getData() == null
1201 && intent.getType() == null;
1202 }
1203
Chong Zhangad24f962016-08-25 12:12:33 -07001204 static boolean isMainIntent(Intent intent) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001205 return ACTION_MAIN.equals(intent.getAction())
1206 && intent.hasCategory(CATEGORY_LAUNCHER)
Chong Zhangad24f962016-08-25 12:12:33 -07001207 && intent.getCategories().size() == 1
1208 && intent.getData() == null
1209 && intent.getType() == null;
1210 }
1211
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001212 private boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
1213 if (uid == Process.myUid() || uid == 0) {
1214 // System process can launch home activity.
1215 return true;
1216 }
Winson Chung547afd22018-05-17 16:03:25 -07001217 // Allow the recents component to launch the home activity.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001218 final RecentTasks recentTasks = mStackSupervisor.mService.getRecentTasks();
Winson Chung547afd22018-05-17 16:03:25 -07001219 if (recentTasks != null && recentTasks.isCallerRecents(uid)) {
1220 return true;
1221 }
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001222 // Resolver activity can launch home activity.
1223 return sourceRecord != null && sourceRecord.isResolverActivity();
1224 }
1225
Winson Chung83471632016-12-13 11:02:12 -08001226 /**
1227 * @return whether the given package name can launch an assist activity.
1228 */
1229 private boolean canLaunchAssistActivity(String packageName) {
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001230 final ComponentName assistComponent =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001231 mAtmService.mActiveVoiceInteractionServiceComponent;
Winson Chung83471632016-12-13 11:02:12 -08001232 if (assistComponent != null) {
1233 return assistComponent.getPackageName().equals(packageName);
1234 }
1235 return false;
1236 }
1237
1238 private void setActivityType(boolean componentSpecified, int launchedFromUid, Intent intent,
1239 ActivityOptions options, ActivityRecord sourceRecord) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001240 int activityType = ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001241 if ((!componentSpecified || canLaunchHomeActivity(launchedFromUid, sourceRecord))
1242 && isHomeIntent(intent) && !isResolverActivity()) {
1243 // This sure looks like a home activity!
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001244 activityType = ACTIVITY_TYPE_HOME;
Wale Ogunwaledf241e92016-10-13 15:14:21 -07001245
1246 if (info.resizeMode == RESIZE_MODE_FORCE_RESIZEABLE
1247 || info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
1248 // We only allow home activities to be resizeable if they explicitly requested it.
1249 info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
1250 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001251 } else if (mActivityComponent.getClassName().contains(LEGACY_RECENTS_PACKAGE_NAME)
1252 || mAtmService.getRecentTasks().isRecentsComponent(mActivityComponent, appInfo.uid)) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001253 activityType = ACTIVITY_TYPE_RECENTS;
Wale Ogunwale0568aed2017-09-08 13:29:37 -07001254 } else if (options != null && options.getLaunchActivityType() == ACTIVITY_TYPE_ASSISTANT
Winson Chung83471632016-12-13 11:02:12 -08001255 && canLaunchAssistActivity(launchedFromPackage)) {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001256 activityType = ACTIVITY_TYPE_ASSISTANT;
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001257 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001258 setActivityType(activityType);
Wale Ogunwale1affbbc2016-05-01 09:03:52 -07001259 }
1260
Craig Mautnera228ae92014-07-09 05:44:55 -07001261 void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08001262 if (launchMode != LAUNCH_SINGLE_INSTANCE && launchMode != LAUNCH_SINGLE_TASK) {
Craig Mautnera228ae92014-07-09 05:44:55 -07001263 task.setTaskToAffiliateWith(taskToAffiliateWith);
1264 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001265 }
1266
Andrii Kulian02b7a832016-10-06 23:11:56 -07001267 /**
1268 * @return Stack value from current task, null if there is no task.
1269 */
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001270 <T extends ActivityStack> T getActivityStack() {
Winson Chung55893332017-02-17 17:13:10 -08001271 return task != null ? (T) task.getStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001272 }
1273
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001274 int getStackId() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001275 return getActivityStack() != null ? getActivityStack().mStackId : INVALID_STACK_ID;
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001276 }
1277
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001278 ActivityDisplay getDisplay() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001279 final ActivityStack stack = getActivityStack();
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001280 return stack != null ? stack.getDisplay() : null;
1281 }
1282
Craig Mautner5eda9b32013-07-02 11:58:16 -07001283 boolean changeWindowTranslucency(boolean toOpaque) {
1284 if (fullscreen == toOpaque) {
1285 return false;
1286 }
Craig Mautner4addfc52013-06-25 08:05:45 -07001287
Craig Mautner5eda9b32013-07-02 11:58:16 -07001288 // Keep track of the number of fullscreen activities in this task.
1289 task.numFullscreen += toOpaque ? +1 : -1;
1290
1291 fullscreen = toOpaque;
1292 return true;
Craig Mautner4addfc52013-06-25 08:05:45 -07001293 }
1294
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001295 void takeFromHistory() {
1296 if (inHistory) {
1297 inHistory = false;
1298 if (task != null && !finishing) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001299 task = null;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001300 }
Dianne Hackborn6e3d6da2012-06-15 12:05:27 -07001301 clearOptionsLocked();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001302 }
1303 }
1304
1305 boolean isInHistory() {
1306 return inHistory;
1307 }
1308
Wale Ogunwale7d701172015-03-11 15:36:30 -07001309 boolean isInStackLocked() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001310 final ActivityStack stack = getActivityStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07001311 return stack != null && stack.isInStackLocked(this) != null;
Wale Ogunwale7d701172015-03-11 15:36:30 -07001312 }
1313
Craig Mautner21d24a22014-04-23 11:45:37 -07001314 boolean isPersistable() {
Ruben Brunkf53497c2017-03-27 20:26:17 -07001315 return (info.persistableMode == PERSIST_ROOT_ONLY ||
1316 info.persistableMode == PERSIST_ACROSS_REBOOTS) &&
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001317 (intent == null || (intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
Craig Mautner21d24a22014-04-23 11:45:37 -07001318 }
1319
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08001320 boolean isFocusable() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001321 return mRootActivityContainer.isFocusable(this, isAlwaysFocusable());
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001322 }
1323
1324 boolean isResizeable() {
Winson Chungd3395382016-12-13 11:49:09 -08001325 return ActivityInfo.isResizeableMode(info.resizeMode) || info.supportsPictureInPicture();
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001326 }
1327
Winson Chungd3395382016-12-13 11:49:09 -08001328 /**
1329 * @return whether this activity is non-resizeable or forced to be resizeable
1330 */
1331 boolean isNonResizableOrForcedResizable() {
Wale Ogunwaledf241e92016-10-13 15:14:21 -07001332 return info.resizeMode != RESIZE_MODE_RESIZEABLE
Wale Ogunwale72a73e32016-10-13 12:16:39 -07001333 && info.resizeMode != RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
Jorim Jaggicd13d332016-04-27 15:40:20 -07001334 }
1335
Winson Chunge6308042016-10-31 09:24:01 -07001336 /**
Winson Chungd3395382016-12-13 11:49:09 -08001337 * @return whether this activity supports PiP multi-window and can be put in the pinned stack.
Winson Chunge6308042016-10-31 09:24:01 -07001338 */
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001339 boolean supportsPictureInPicture() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001340 return mAtmService.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
Winson Chungd3395382016-12-13 11:49:09 -08001341 && info.supportsPictureInPicture();
1342 }
1343
1344 /**
1345 * @return whether this activity supports split-screen multi-window and can be put in the docked
1346 * stack.
1347 */
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001348 @Override
1349 public boolean supportsSplitScreenWindowingMode() {
Winson Chungd3395382016-12-13 11:49:09 -08001350 // An activity can not be docked even if it is considered resizeable because it only
1351 // supports picture-in-picture mode but has a non-resizeable resizeMode
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001352 return super.supportsSplitScreenWindowingMode()
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001353 && mAtmService.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow();
Winson Chungd3395382016-12-13 11:49:09 -08001354 }
1355
1356 /**
1357 * @return whether this activity supports freeform multi-window and can be put in the freeform
1358 * stack.
1359 */
1360 boolean supportsFreeform() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001361 return mAtmService.mSupportsFreeformWindowManagement && supportsResizeableMultiWindow();
Winson Chungd3395382016-12-13 11:49:09 -08001362 }
1363
1364 /**
1365 * @return whether this activity supports non-PiP multi-window.
1366 */
1367 private boolean supportsResizeableMultiWindow() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001368 return mAtmService.mSupportsMultiWindow && !isActivityTypeHome()
Winson Chungd3395382016-12-13 11:49:09 -08001369 && (ActivityInfo.isResizeableMode(info.resizeMode)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001370 || mAtmService.mForceResizableActivities);
Wale Ogunwaled26176f2016-01-25 20:04:04 -08001371 }
1372
Winson Chunge6308042016-10-31 09:24:01 -07001373 /**
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001374 * Check whether this activity can be launched on the specified display.
Riddle Hsu16567132018-08-16 21:37:47 +08001375 *
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001376 * @param displayId Target display id.
Riddle Hsu16567132018-08-16 21:37:47 +08001377 * @return {@code true} if either it is the default display or this activity can be put on a
1378 * secondary screen.
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001379 */
1380 boolean canBeLaunchedOnDisplay(int displayId) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001381 return mAtmService.mStackSupervisor.canPlaceEntityOnDisplay(displayId, launchedFromPid,
Riddle Hsu16567132018-08-16 21:37:47 +08001382 launchedFromUid, info);
Andrii Kulian036e3ad2017-04-19 10:55:10 -07001383 }
1384
1385 /**
Robert Carrc33658e2017-04-11 18:24:20 -07001386 * @param beforeStopping Whether this check is for an auto-enter-pip operation, that is to say
1387 * the activity has requested to enter PiP when it would otherwise be stopped.
1388 *
Winson Chung298f95b2017-08-10 15:57:18 -07001389 * @return whether this activity is currently allowed to enter PIP.
Winson Chunge6308042016-10-31 09:24:01 -07001390 */
Winson Chung298f95b2017-08-10 15:57:18 -07001391 boolean checkEnterPictureInPictureState(String caller, boolean beforeStopping) {
Wale Ogunwaleb9a0c992017-04-18 07:25:20 -07001392 if (!supportsPictureInPicture()) {
1393 return false;
1394 }
1395
Winson Chungf4ac0632017-03-17 12:34:12 -07001396 // Check app-ops and see if PiP is supported for this package
1397 if (!checkEnterPictureInPictureAppOpsState()) {
1398 return false;
1399 }
1400
Winson Chungf1bfee12017-03-24 17:11:33 -07001401 // Check to see if we are in VR mode, and disallow PiP if so
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001402 if (mAtmService.shouldDisableNonVrUiLocked()) {
Winson Chungf1bfee12017-03-24 17:11:33 -07001403 return false;
1404 }
1405
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001406 boolean isKeyguardLocked = mAtmService.isKeyguardLocked();
Wale Ogunwaled0412b32018-05-08 09:25:50 -07001407 boolean isCurrentAppLocked =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001408 mAtmService.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001409 final ActivityDisplay display = getDisplay();
1410 boolean hasPinnedStack = display != null && display.hasPinnedStack();
Winson Chungbb348802017-01-30 12:01:45 -08001411 // Don't return early if !isNotLocked, since we want to throw an exception if the activity
1412 // is in an incorrect state
Winson Chunge581ebf2017-02-21 08:25:03 -08001413 boolean isNotLockedOrOnKeyguard = !isKeyguardLocked && !isCurrentAppLocked;
Robert Carrc33658e2017-04-11 18:24:20 -07001414
1415 // We don't allow auto-PiP when something else is already pipped.
1416 if (beforeStopping && hasPinnedStack) {
1417 return false;
1418 }
1419
Bryce Lee7ace3952018-02-16 14:34:32 -08001420 switch (mState) {
Winson Chungc2baac02017-01-11 13:34:47 -08001421 case RESUMED:
Winson Chunge581ebf2017-02-21 08:25:03 -08001422 // When visible, allow entering PiP if the app is not locked. If it is over the
1423 // keyguard, then we will prompt to unlock in the caller before entering PiP.
Robert Carrc33658e2017-04-11 18:24:20 -07001424 return !isCurrentAppLocked &&
Winson Chungf7e03e12017-08-22 11:32:16 -07001425 (supportsEnterPipOnTaskSwitch || !beforeStopping);
Winson Chungc2baac02017-01-11 13:34:47 -08001426 case PAUSING:
1427 case PAUSED:
Winson Chungbb348802017-01-30 12:01:45 -08001428 // When pausing, then only allow enter PiP as in the resume state, and in addition,
1429 // require that there is not an existing PiP activity and that the current system
1430 // state supports entering PiP
Winson Chunge581ebf2017-02-21 08:25:03 -08001431 return isNotLockedOrOnKeyguard && !hasPinnedStack
Winson Chungf7e03e12017-08-22 11:32:16 -07001432 && supportsEnterPipOnTaskSwitch;
Winson Chungc2baac02017-01-11 13:34:47 -08001433 case STOPPING:
1434 // When stopping in a valid state, then only allow enter PiP as in the pause state.
1435 // Otherwise, fall through to throw an exception if the caller is trying to enter
1436 // PiP in an invalid stopping state.
Winson Chungf7e03e12017-08-22 11:32:16 -07001437 if (supportsEnterPipOnTaskSwitch) {
Winson Chungf4ac0632017-03-17 12:34:12 -07001438 return isNotLockedOrOnKeyguard && !hasPinnedStack;
Winson Chungc2baac02017-01-11 13:34:47 -08001439 }
1440 default:
Winson Chung298f95b2017-08-10 15:57:18 -07001441 return false;
Winson Chungb5c41b72016-12-07 15:00:47 -08001442 }
Winson Chunge6308042016-10-31 09:24:01 -07001443 }
1444
Winson Chung59fda9e2017-01-20 16:14:51 -08001445 /**
Winson Chungf4ac0632017-03-17 12:34:12 -07001446 * @return Whether AppOps allows this package to enter picture-in-picture.
Winson Chung59fda9e2017-01-20 16:14:51 -08001447 */
Winson Chungf4ac0632017-03-17 12:34:12 -07001448 private boolean checkEnterPictureInPictureAppOpsState() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001449 return mAtmService.getAppOpsService().checkOperation(
Wale Ogunwalef6733932018-06-27 05:14:34 -07001450 OP_PICTURE_IN_PICTURE, appInfo.uid, packageName) == MODE_ALLOWED;
Winson Chung59fda9e2017-01-20 16:14:51 -08001451 }
1452
Wale Ogunwale6cae7652015-12-26 07:36:26 -08001453 boolean isAlwaysFocusable() {
1454 return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
Wale Ogunwale4cea0f52015-12-25 06:30:31 -08001455 }
1456
Louis Chang19443452018-10-09 12:10:21 +08001457 /** Move activity with its stack to front and make the stack focused. */
1458 boolean moveFocusableActivityToTop(String reason) {
1459 if (!isFocusable()) {
1460 if (DEBUG_FOCUS) {
1461 Slog.d(TAG_FOCUS, "moveActivityStackToFront: unfocusable activity=" + this);
1462 }
1463 return false;
1464 }
1465
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001466 final TaskRecord task = getTaskRecord();
1467 final ActivityStack stack = getActivityStack();
Louis Chang19443452018-10-09 12:10:21 +08001468 if (stack == null) {
1469 Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: activity="
1470 + this + " task=" + task);
1471 return false;
1472 }
1473
Wale Ogunwaled32da472018-11-16 07:19:28 -08001474 if (mRootActivityContainer.getTopResumedActivity() == this) {
Louis Chang19443452018-10-09 12:10:21 +08001475 if (DEBUG_FOCUS) {
1476 Slog.d(TAG_FOCUS, "moveActivityStackToFront: already on top, activity=" + this);
1477 }
1478 return false;
1479 }
1480
1481 if (DEBUG_FOCUS) {
1482 Slog.d(TAG_FOCUS, "moveActivityStackToFront: activity=" + this);
1483 }
1484
1485 stack.moveToFront(reason, task);
1486 // Report top activity change to tracking services and WM
Wale Ogunwaled32da472018-11-16 07:19:28 -08001487 if (mRootActivityContainer.getTopResumedActivity() == this) {
Louis Chang19443452018-10-09 12:10:21 +08001488 // TODO(b/111361570): Support multiple focused apps in WM
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001489 mAtmService.setResumedActivityUncheckLocked(this, reason);
Louis Chang19443452018-10-09 12:10:21 +08001490 }
1491 return true;
1492 }
Jorim Jaggife762342016-10-13 14:33:27 +02001493
Wale Ogunwale7d701172015-03-11 15:36:30 -07001494 void makeFinishingLocked() {
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001495 if (finishing) {
1496 return;
1497 }
1498 finishing = true;
1499 if (stopped) {
1500 clearOptionsLocked();
1501 }
Yorke Leebd54c2a2016-10-25 13:49:23 -07001502
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001503 if (mAtmService != null) {
1504 mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08001505 }
1506 }
1507
Dianne Hackborn7e269642010-08-25 19:50:20 -07001508 UriPermissionOwner getUriPermissionsLocked() {
1509 if (uriPermissions == null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001510 uriPermissions = new UriPermissionOwner(mAtmService.mUgmInternal, this);
Dianne Hackborn7e269642010-08-25 19:50:20 -07001511 }
1512 return uriPermissions;
1513 }
1514
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001515 void addResultLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 int requestCode, int resultCode,
1517 Intent resultData) {
1518 ActivityResult r = new ActivityResult(from, resultWho,
John Spurlock8a985d22014-02-25 09:40:05 -05001519 requestCode, resultCode, resultData);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 if (results == null) {
Craig Mautner5d9c7be2013-02-15 14:02:56 -08001521 results = new ArrayList<ResultInfo>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 }
1523 results.add(r);
1524 }
1525
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001526 void removeResultsLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 int requestCode) {
1528 if (results != null) {
1529 for (int i=results.size()-1; i>=0; i--) {
1530 ActivityResult r = (ActivityResult)results.get(i);
1531 if (r.mFrom != from) continue;
1532 if (r.mResultWho == null) {
1533 if (resultWho != null) continue;
1534 } else {
1535 if (!r.mResultWho.equals(resultWho)) continue;
1536 }
1537 if (r.mRequestCode != requestCode) continue;
1538
1539 results.remove(i);
1540 }
1541 }
1542 }
1543
Andrii Kulian21713ac2016-10-12 22:05:05 -07001544 private void addNewIntentLocked(ReferrerIntent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 if (newIntents == null) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001546 newIntents = new ArrayList<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001547 }
1548 newIntents.add(intent);
1549 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07001550
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001551 final boolean isSleeping() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001552 final ActivityStack stack = getActivityStack();
1553 return stack != null ? stack.shouldSleepActivities() : mAtmService.isSleepingLocked();
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001554 }
1555
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001556 /**
1557 * Deliver a new Intent to an existing activity, so that its onNewIntent()
1558 * method will be called at the proper time.
1559 */
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001560 final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
Dianne Hackborn514074f2013-02-11 10:52:46 -08001561 // The activity now gets access to the data associated with this Intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001562 mAtmService.mUgmInternal.grantUriPermissionFromIntent(callingUid, packageName,
1563 intent, getUriPermissionsLocked(), mUserId);
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001564 final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
Craig Mautner86d67a42013-05-14 10:34:38 -07001565 boolean unsent = true;
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001566 final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping();
Wale Ogunwale826c7062016-09-13 08:25:54 -07001567
1568 // We want to immediately deliver the intent to the activity if:
Wale Ogunwale03f7e9e2016-09-22 09:04:09 -07001569 // - It is currently resumed or paused. i.e. it is currently visible to the user and we want
1570 // the user to see the visual effects caused by the intent delivery now.
Wale Ogunwale826c7062016-09-13 08:25:54 -07001571 // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001572 if ((mState == RESUMED || mState == PAUSED || isTopActivityWhileSleeping)
1573 && attachedToProcess()) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001574 try {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001575 ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
1576 ar.add(rintent);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001577 mAtmService.getLifecycleManager().scheduleTransaction(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001578 app.getThread(), appToken, NewIntentItem.obtain(ar, mState == PAUSED));
Craig Mautner86d67a42013-05-14 10:34:38 -07001579 unsent = false;
Dianne Hackborn39792d22010-08-19 18:01:52 -07001580 } catch (RemoteException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001581 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
Dianne Hackborn39792d22010-08-19 18:01:52 -07001582 } catch (NullPointerException e) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001583 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001584 }
1585 }
Craig Mautner86d67a42013-05-14 10:34:38 -07001586 if (unsent) {
Dianne Hackborn85d558c2014-11-04 10:31:54 -08001587 addNewIntentLocked(rintent);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001588 }
1589 }
1590
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001591 void updateOptionsLocked(ActivityOptions options) {
1592 if (options != null) {
1593 if (pendingOptions != null) {
1594 pendingOptions.abort();
1595 }
1596 pendingOptions = options;
1597 }
1598 }
1599
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001600 void applyOptionsLocked() {
George Mount2c92c972014-03-20 09:38:23 -07001601 if (pendingOptions != null
Ruben Brunkf53497c2017-03-27 20:26:17 -07001602 && pendingOptions.getAnimationType() != ANIM_SCENE_TRANSITION) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001603 applyOptionsLocked(pendingOptions, intent);
chaviw82a0ba82018-03-15 14:26:29 -07001604 if (task == null) {
1605 clearOptionsLocked(false /* withAbort */);
1606 } else {
1607 // This will clear the options for all the ActivityRecords for this Task.
1608 task.clearAllPendingOptions();
1609 }
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001610 }
1611 }
1612
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001613 /**
1614 * Apply override app transition base on options & animation type.
1615 */
1616 void applyOptionsLocked(ActivityOptions pendingOptions, Intent intent) {
1617 final int animationType = pendingOptions.getAnimationType();
1618 final DisplayContent displayContent = mAppWindowToken.getDisplayContent();
1619 switch (animationType) {
1620 case ANIM_CUSTOM:
1621 displayContent.mAppTransition.overridePendingAppTransition(
1622 pendingOptions.getPackageName(),
1623 pendingOptions.getCustomEnterResId(),
1624 pendingOptions.getCustomExitResId(),
1625 pendingOptions.getOnAnimationStartListener());
1626 break;
1627 case ANIM_CLIP_REVEAL:
1628 displayContent.mAppTransition.overridePendingAppTransitionClipReveal(
1629 pendingOptions.getStartX(), pendingOptions.getStartY(),
1630 pendingOptions.getWidth(), pendingOptions.getHeight());
1631 if (intent.getSourceBounds() == null) {
1632 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1633 pendingOptions.getStartY(),
1634 pendingOptions.getStartX() + pendingOptions.getWidth(),
1635 pendingOptions.getStartY() + pendingOptions.getHeight()));
1636 }
1637 break;
1638 case ANIM_SCALE_UP:
1639 displayContent.mAppTransition.overridePendingAppTransitionScaleUp(
1640 pendingOptions.getStartX(), pendingOptions.getStartY(),
1641 pendingOptions.getWidth(), pendingOptions.getHeight());
1642 if (intent.getSourceBounds() == null) {
1643 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1644 pendingOptions.getStartY(),
1645 pendingOptions.getStartX() + pendingOptions.getWidth(),
1646 pendingOptions.getStartY() + pendingOptions.getHeight()));
1647 }
1648 break;
1649 case ANIM_THUMBNAIL_SCALE_UP:
1650 case ANIM_THUMBNAIL_SCALE_DOWN:
1651 final boolean scaleUp = (animationType == ANIM_THUMBNAIL_SCALE_UP);
1652 final GraphicBuffer buffer = pendingOptions.getThumbnail();
1653 displayContent.mAppTransition.overridePendingAppTransitionThumb(buffer,
1654 pendingOptions.getStartX(), pendingOptions.getStartY(),
1655 pendingOptions.getOnAnimationStartListener(),
1656 scaleUp);
1657 if (intent.getSourceBounds() == null && buffer != null) {
1658 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1659 pendingOptions.getStartY(),
1660 pendingOptions.getStartX() + buffer.getWidth(),
1661 pendingOptions.getStartY() + buffer.getHeight()));
1662 }
1663 break;
1664 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
1665 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
1666 final AppTransitionAnimationSpec[] specs = pendingOptions.getAnimSpecs();
1667 final IAppTransitionAnimationSpecsFuture specsFuture =
1668 pendingOptions.getSpecsFuture();
1669 if (specsFuture != null) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001670 displayContent.mAppTransition.overridePendingAppTransitionMultiThumbFuture(
1671 specsFuture, pendingOptions.getOnAnimationStartListener(),
1672 animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP);
1673 } else if (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
1674 && specs != null) {
1675 displayContent.mAppTransition.overridePendingAppTransitionMultiThumb(
1676 specs, pendingOptions.getOnAnimationStartListener(),
1677 pendingOptions.getAnimationFinishedListener(), false);
1678 } else {
1679 displayContent.mAppTransition.overridePendingAppTransitionAspectScaledThumb(
1680 pendingOptions.getThumbnail(),
1681 pendingOptions.getStartX(), pendingOptions.getStartY(),
1682 pendingOptions.getWidth(), pendingOptions.getHeight(),
1683 pendingOptions.getOnAnimationStartListener(),
1684 (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP));
1685 if (intent.getSourceBounds() == null) {
1686 intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
1687 pendingOptions.getStartY(),
1688 pendingOptions.getStartX() + pendingOptions.getWidth(),
1689 pendingOptions.getStartY() + pendingOptions.getHeight()));
1690 }
1691 }
1692 break;
1693 case ANIM_OPEN_CROSS_PROFILE_APPS:
1694 displayContent.mAppTransition
1695 .overridePendingAppTransitionStartCrossProfileApps();
1696 break;
1697 case ANIM_REMOTE_ANIMATION:
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001698 displayContent.mAppTransition.overridePendingAppTransitionRemote(
1699 pendingOptions.getRemoteAnimationAdapter());
1700 break;
1701 case ANIM_NONE:
1702 break;
1703 default:
1704 Slog.e(TAG_WM, "applyOptionsLocked: Unknown animationType=" + animationType);
1705 break;
1706 }
1707 }
1708
Adam Powellcfbe9be2013-11-06 14:58:58 -08001709 ActivityOptions getOptionsForTargetActivityLocked() {
1710 return pendingOptions != null ? pendingOptions.forTargetActivity() : null;
1711 }
1712
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001713 void clearOptionsLocked() {
chaviw82a0ba82018-03-15 14:26:29 -07001714 clearOptionsLocked(true /* withAbort */);
1715 }
1716
1717 void clearOptionsLocked(boolean withAbort) {
1718 if (withAbort && pendingOptions != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001719 pendingOptions.abort();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07001720 }
chaviw82a0ba82018-03-15 14:26:29 -07001721 pendingOptions = null;
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07001722 }
1723
Dianne Hackborn9622ca42012-10-23 18:56:33 -07001724 ActivityOptions takeOptionsLocked() {
1725 ActivityOptions opts = pendingOptions;
1726 pendingOptions = null;
1727 return opts;
1728 }
1729
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001730 void removeUriPermissionsLocked() {
Dianne Hackborn7e269642010-08-25 19:50:20 -07001731 if (uriPermissions != null) {
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07001732 uriPermissions.removeUriPermissions();
Dianne Hackborn7e269642010-08-25 19:50:20 -07001733 uriPermissions = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001734 }
1735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001736
1737 void pauseKeyDispatchingLocked() {
1738 if (!keysPaused) {
1739 keysPaused = true;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001740
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001741 // TODO: remove the check after unification with AppWindowToken. The DC check is not
1742 // needed after no mock mAppWindowToken in tests.
1743 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
1744 mAppWindowToken.getDisplayContent().getInputMonitor().pauseDispatchingLw(
1745 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07001746 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001747 }
1748 }
1749
1750 void resumeKeyDispatchingLocked() {
1751 if (keysPaused) {
1752 keysPaused = false;
Bryce Lee2b8e0372018-04-05 17:01:37 -07001753
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001754 // TODO: remove the check after unification with AppWindowToken. The DC check is not
1755 // needed after no mock mAppWindowToken in tests.
1756 if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
1757 mAppWindowToken.getDisplayContent().getInputMonitor().resumeDispatchingLw(
1758 mAppWindowToken);
Bryce Lee2b8e0372018-04-05 17:01:37 -07001759 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001760 }
1761 }
1762
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001763 private void updateTaskDescription(CharSequence description) {
Craig Mautnerc0ffce52014-07-01 12:38:52 -07001764 task.lastDescription = description;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07001765 }
1766
Wale Ogunwaleec950642017-04-25 07:44:21 -07001767 void setDeferHidingClient(boolean deferHidingClient) {
1768 if (mDeferHidingClient == deferHidingClient) {
1769 return;
1770 }
1771 mDeferHidingClient = deferHidingClient;
1772 if (!mDeferHidingClient && !visible) {
1773 // Hiding the client is no longer deferred and the app isn't visible still, go ahead and
1774 // update the visibility.
1775 setVisibility(false);
1776 }
Wale Ogunwale89973222017-04-23 18:39:45 -07001777 }
1778
Wale Ogunwaleec950642017-04-25 07:44:21 -07001779 void setVisibility(boolean visible) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001780 if (mAppWindowToken == null) {
1781 Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: "
1782 + appToken);
1783 return;
1784 }
1785 mAppWindowToken.setVisibility(visible, mDeferHidingClient);
Bryce Lee2a3cc462017-10-27 10:57:35 -07001786 mStackSupervisor.getActivityMetricsLogger().notifyVisibilityChanged(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001787 }
1788
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001789 // TODO: Look into merging with #commitVisibility()
Wale Ogunwaleec950642017-04-25 07:44:21 -07001790 void setVisible(boolean newVisible) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001791 visible = newVisible;
Wale Ogunwaleec950642017-04-25 07:44:21 -07001792 mDeferHidingClient = !visible && mDeferHidingClient;
Wale Ogunwaleec950642017-04-25 07:44:21 -07001793 setVisibility(visible);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001794 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
1795 }
1796
Bryce Lee7ace3952018-02-16 14:34:32 -08001797 void setState(ActivityState state, String reason) {
1798 if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState()
1799 + " to:" + state + " reason:" + reason);
Bryce Lee6ff17072018-02-28 07:26:17 -08001800
Bryce Leeb0f993f2018-03-02 15:38:01 -08001801 if (state == mState) {
1802 // No need to do anything if state doesn't change.
1803 if (DEBUG_STATES) Slog.v(TAG_STATES, "State unchanged from:" + state);
1804 return;
1805 }
1806
Bryce Leeb0f993f2018-03-02 15:38:01 -08001807 mState = state;
1808
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001809 final TaskRecord parent = getTaskRecord();
Bryce Leec4ab62a2018-03-05 14:19:26 -08001810
1811 if (parent != null) {
1812 parent.onActivityStateChanged(this, state, reason);
1813 }
Robert Carr29daa922018-04-27 11:56:48 -07001814
Robert Carr9e1bf7c2018-05-31 15:39:07 -07001815 // The WindowManager interprets the app stopping signal as
1816 // an indication that the Surface will eventually be destroyed.
1817 // This however isn't necessarily true if we are going to sleep.
1818 if (state == STOPPING && !isSleeping()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001819 if (mAppWindowToken == null) {
1820 Slog.w(TAG_WM, "Attempted to notify stopping on non-existing app token: "
1821 + appToken);
1822 return;
1823 }
1824 mAppWindowToken.detachChildren();
Robert Carr29daa922018-04-27 11:56:48 -07001825 }
Hui Yu03d12402018-12-06 18:00:37 -08001826
1827 if (state == RESUMED) {
1828 mAtmService.updateBatteryStats(this, true);
1829 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_RESUMED);
1830 } else if (state == PAUSED) {
1831 mAtmService.updateBatteryStats(this, false);
1832 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_PAUSED);
1833 } else if (state == STOPPED) {
1834 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_STOPPED);
1835 } else if (state == DESTROYED) {
1836 mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_DESTROYED);
1837 }
Bryce Lee7ace3952018-02-16 14:34:32 -08001838 }
1839
1840 ActivityState getState() {
1841 return mState;
1842 }
1843
1844 /**
1845 * Returns {@code true} if the Activity is in the specified state.
1846 */
1847 boolean isState(ActivityState state) {
1848 return state == mState;
1849 }
1850
1851 /**
1852 * Returns {@code true} if the Activity is in one of the specified states.
1853 */
1854 boolean isState(ActivityState state1, ActivityState state2) {
1855 return state1 == mState || state2 == mState;
1856 }
1857
1858 /**
1859 * Returns {@code true} if the Activity is in one of the specified states.
1860 */
1861 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3) {
1862 return state1 == mState || state2 == mState || state3 == mState;
1863 }
1864
1865 /**
1866 * Returns {@code true} if the Activity is in one of the specified states.
1867 */
1868 boolean isState(ActivityState state1, ActivityState state2, ActivityState state3,
1869 ActivityState state4) {
1870 return state1 == mState || state2 == mState || state3 == mState || state4 == mState;
1871 }
1872
Jorim Jaggibae01b12017-04-11 16:29:10 -07001873 void notifyAppResumed(boolean wasStopped) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001874 if (mAppWindowToken == null) {
1875 Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: "
1876 + appToken);
1877 return;
1878 }
1879 mAppWindowToken.notifyAppResumed(wasStopped);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001880 }
1881
1882 void notifyUnknownVisibilityLaunched() {
Jorim Jaggi838c2452017-08-28 15:44:43 +02001883
1884 // No display activities never add a window, so there is no point in waiting them for
1885 // relayout.
1886 if (!noDisplay) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001887 if (mAppWindowToken != null) {
1888 mAppWindowToken.getDisplayContent().mUnknownAppVisibilityController
1889 .notifyLaunched(mAppWindowToken);
1890 }
Jorim Jaggi838c2452017-08-28 15:44:43 +02001891 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08001892 }
1893
Jorim Jaggi241ae102016-11-02 21:57:33 -07001894 /**
1895 * @return true if the input activity should be made visible, ignoring any effect Keyguard
1896 * might have on the visibility
1897 *
1898 * @see {@link ActivityStack#checkKeyguardVisibility}
1899 */
Wale Ogunwalec981ad52017-06-13 11:40:06 -07001900 boolean shouldBeVisibleIgnoringKeyguard(boolean behindFullscreenActivity) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001901 if (!okToShowLocked()) {
1902 return false;
1903 }
1904
Winson Chung3f0e59a2017-10-25 10:19:05 -07001905 return !behindFullscreenActivity || mLaunchTaskBehind;
Andrii Kulian21713ac2016-10-12 22:05:05 -07001906 }
1907
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001908 void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001909 // This activity is not currently visible, but is running. Tell it to become visible.
Bryce Lee7ace3952018-02-16 14:34:32 -08001910 if (mState == RESUMED || this == starting) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07001911 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
Bryce Lee7ace3952018-02-16 14:34:32 -08001912 "Not making visible, r=" + this + " state=" + mState + " starting=" + starting);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001913 return;
1914 }
1915
1916 // If this activity is paused, tell it to now show its window.
1917 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1918 "Making visible and scheduling visibility: " + this);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001919 final ActivityStack stack = getActivityStack();
Andrii Kulian21713ac2016-10-12 22:05:05 -07001920 try {
1921 if (stack.mTranslucentActivityWaiting != null) {
1922 updateOptionsLocked(returningOptions);
1923 stack.mUndrawnActivitiesBelowTopTranslucent.add(this);
1924 }
1925 setVisible(true);
1926 sleeping = false;
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001927 app.postPendingUiCleanMsg(true);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001928 if (reportToClient) {
1929 makeClientVisible();
1930 } else {
1931 mClientVisibilityDeferred = true;
1932 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07001933 // The activity may be waiting for stop, but that is no longer appropriate for it.
1934 mStackSupervisor.mStoppingActivities.remove(this);
1935 mStackSupervisor.mGoingToSleepActivities.remove(this);
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001936 } catch (Exception e) {
1937 // Just skip on any failure; we'll make it visible when it next restarts.
1938 Slog.w(TAG, "Exception thrown making visible: " + intent.getComponent(), e);
1939 }
1940 handleAlreadyVisible();
1941 }
Andrii Kulian0d595f32018-02-21 15:47:33 -08001942
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001943 /** Send visibility change message to the client and pause if needed. */
1944 void makeClientVisible() {
1945 mClientVisibilityDeferred = false;
1946 try {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001947 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001948 WindowVisibilityItem.obtain(true /* showWindow */));
Andrii Kulian6b321512019-01-23 06:37:00 +00001949 makeActiveIfNeeded(null /* activeActivity*/);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001950 } catch (Exception e) {
Andrii Kuliana39ae3e2018-05-31 12:43:54 -07001951 Slog.w(TAG, "Exception thrown sending visibility update: " + intent.getComponent(), e);
Andrii Kulian21713ac2016-10-12 22:05:05 -07001952 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07001953 }
1954
Andrii Kulian6b321512019-01-23 06:37:00 +00001955 /**
1956 * Make activity resumed or paused if needed.
1957 * @param activeActivity an activity that is resumed or just completed pause action.
1958 * We won't change the state of this activity.
1959 */
1960 boolean makeActiveIfNeeded(ActivityRecord activeActivity) {
1961 if (shouldResumeActivity(activeActivity)) {
1962 if (DEBUG_VISIBILITY) {
1963 Slog.v("TAG_VISIBILITY", "Resume visible activity, " + this);
1964 }
1965 return getActivityStack().resumeTopActivityUncheckedLocked(activeActivity /* prev */,
1966 null /* options */);
1967 } else if (shouldPauseActivity(activeActivity)) {
1968 if (DEBUG_VISIBILITY) {
1969 Slog.v("TAG_VISIBILITY", "Pause visible activity, " + this);
1970 }
1971 // An activity must be in the {@link PAUSING} state for the system to validate
1972 // the move to {@link PAUSED}.
1973 setState(PAUSING, "makeVisibleIfNeeded");
1974 try {
1975 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
1976 PauseActivityItem.obtain(finishing, false /* userLeaving */,
1977 configChangeFlags, false /* dontReport */));
1978 } catch (Exception e) {
1979 Slog.w(TAG, "Exception thrown sending pause: " + intent.getComponent(), e);
1980 }
1981 }
1982 return false;
1983 }
1984
1985 /**
1986 * Check if activity should be moved to PAUSED state. The activity:
1987 * - should be eligible to be made active (see {@link #shouldMakeActive(ActivityRecord)})
1988 * - should be non-focusable
1989 * - should not be currently pausing or paused
1990 * @param activeActivity the activity that is active or just completed pause action. We won't
1991 * resume if this activity is active.
1992 */
1993 private boolean shouldPauseActivity(ActivityRecord activeActivity) {
1994 return shouldMakeActive(activeActivity) && !isFocusable() && !isState(PAUSING, PAUSED);
1995 }
1996
1997 /**
1998 * Check if activity should be moved to RESUMED state. The activity:
1999 * - should be eligible to be made active (see {@link #shouldMakeActive(ActivityRecord)})
2000 * - should be focusable
2001 * @param activeActivity the activity that is active or just completed pause action. We won't
2002 * resume if this activity is active.
2003 */
2004 private boolean shouldResumeActivity(ActivityRecord activeActivity) {
2005 return shouldMakeActive(activeActivity) && isFocusable() && !isState(RESUMED);
2006 }
2007
2008 /**
2009 * Check if activity is eligible to be made active (resumed of paused). The activity:
2010 * - should be paused, stopped or stopping
Andrii Kulian996df0d2019-01-24 17:04:36 -08002011 * - should not be the currently active one or launching behind other tasks
Andrii Kulian6b321512019-01-23 06:37:00 +00002012 * - should be either the topmost in task, or right below the top activity that is finishing
2013 * If all of these conditions are not met at the same time, the activity cannot be made active.
2014 */
2015 private boolean shouldMakeActive(ActivityRecord activeActivity) {
2016 // If the activity is stopped, stopping, cycle to an active state. We avoid doing
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002017 // this when there is an activity waiting to become translucent as the extra binder
2018 // calls will lead to noticeable jank. A later call to
Andrii Kulian6b321512019-01-23 06:37:00 +00002019 // ActivityStack#ensureActivitiesVisibleLocked will bring the activity to a proper
2020 // active state.
2021 if (!isState(RESUMED, PAUSED, STOPPED, STOPPING)
2022 || getActivityStack().mTranslucentActivityWaiting != null) {
2023 return false;
2024 }
2025
2026 if (this == activeActivity) {
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002027 return false;
2028 }
2029
Andrii Kulian996df0d2019-01-24 17:04:36 -08002030 if (this.mLaunchTaskBehind) {
2031 // This activity is being launched from behind, which means that it's not intended to be
2032 // presented to user right now, even if it's set to be visible.
2033 return false;
2034 }
2035
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002036 // Check if position in task allows to become paused
2037 final int positionInTask = task.mActivities.indexOf(this);
2038 if (positionInTask == -1) {
2039 throw new IllegalStateException("Activity not found in its task");
2040 }
2041 if (positionInTask == task.mActivities.size() - 1) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002042 // It's the topmost activity in the task - should become resumed now
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002043 return true;
2044 }
2045 // Check if activity above is finishing now and this one becomes the topmost in task.
2046 final ActivityRecord activityAbove = task.mActivities.get(positionInTask + 1);
2047 if (activityAbove.finishing && results == null) {
Andrii Kulian6b321512019-01-23 06:37:00 +00002048 // We will only allow making active if activity above wasn't launched for result.
2049 // Otherwise it will cause this activity to resume before getting result.
Andrii Kulian09e1afa2018-05-16 21:29:34 -07002050 return true;
2051 }
2052 return false;
2053 }
2054
Andrii Kulian21713ac2016-10-12 22:05:05 -07002055 boolean handleAlreadyVisible() {
2056 stopFreezingScreenLocked(false);
2057 try {
2058 if (returningOptions != null) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002059 app.getThread().scheduleOnNewActivityOptions(appToken, returningOptions.toBundle());
Andrii Kulian21713ac2016-10-12 22:05:05 -07002060 }
2061 } catch(RemoteException e) {
2062 }
Bryce Lee7ace3952018-02-16 14:34:32 -08002063 return mState == RESUMED;
Andrii Kulian21713ac2016-10-12 22:05:05 -07002064 }
2065
2066 static void activityResumedLocked(IBinder token) {
2067 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2068 if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
2069 if (r != null) {
2070 r.icicle = null;
2071 r.haveState = false;
2072 }
2073 }
2074
2075 /**
2076 * Once we know that we have asked an application to put an activity in the resumed state
2077 * (either by launching it or explicitly telling it), this function updates the rest of our
2078 * state to match that fact.
2079 */
2080 void completeResumeLocked() {
2081 final boolean wasVisible = visible;
Jorim Jaggi8d062052017-08-22 14:55:17 +02002082 setVisible(true);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002083 if (!wasVisible) {
2084 // Visibility has changed, so take a note of it so we call the TaskStackChangedListener
2085 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
2086 }
2087 idle = false;
2088 results = null;
2089 newIntents = null;
2090 stopped = false;
2091
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002092 if (isActivityTypeHome()) {
Louis Changdcdde952018-12-04 15:38:44 +08002093 mStackSupervisor.updateHomeProcess(task.mActivities.get(0).app);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002094 }
2095
2096 if (nowVisible) {
2097 // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
2098 mStackSupervisor.reportActivityVisibleLocked(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002099 }
2100
2101 // Schedule an idle timeout in case the app doesn't do it for us.
2102 mStackSupervisor.scheduleIdleTimeoutLocked(this);
2103
2104 mStackSupervisor.reportResumedActivityLocked(this);
2105
2106 resumeKeyDispatchingLocked();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002107 final ActivityStack stack = getActivityStack();
Jorim Jaggifa9ed962018-01-25 00:16:49 +01002108 mStackSupervisor.mNoAnimActivities.clear();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002109
2110 // Mark the point when the activity is resuming
2111 // TODO: To be more accurate, the mark should be before the onCreate,
2112 // not after the onResume. But for subsequent starts, onResume is fine.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002113 if (hasProcess()) {
Wale Ogunwale86b74462018-07-02 08:42:43 -07002114 cpuTimeAtResume = app.getCpuTime();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002115 } else {
2116 cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2117 }
2118
2119 returningOptions = null;
chaviw59b98852017-06-13 12:05:44 -07002120
2121 if (canTurnScreenOn()) {
2122 mStackSupervisor.wakeUp("turnScreenOnFlag");
2123 } else {
2124 // If the screen is going to turn on because the caller explicitly requested it and
2125 // the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
2126 // pause and then resume again later, which will result in a double life-cycle event.
David Stevens9440dc82017-03-16 19:00:20 -07002127 stack.checkReadyForSleep();
chaviw59b98852017-06-13 12:05:44 -07002128 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002129 }
2130
2131 final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
2132 CharSequence description) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002133 final ActivityStack stack = getActivityStack();
Bryce Lee7ace3952018-02-16 14:34:32 -08002134 if (mState != STOPPING) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002135 Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
Ruben Brunkf53497c2017-03-27 20:26:17 -07002136 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002137 return;
2138 }
2139 if (newPersistentState != null) {
2140 persistentState = newPersistentState;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002141 mAtmService.notifyTaskPersisterLocked(task, false);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002142 }
2143 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + icicle);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002144
Andrii Kulian21713ac2016-10-12 22:05:05 -07002145 if (newIcicle != null) {
2146 // If icicle is null, this is happening due to a timeout, so we haven't really saved
2147 // the state.
2148 icicle = newIcicle;
2149 haveState = true;
2150 launchCount = 0;
Jorim Jaggie7d2b852017-08-28 17:55:15 +02002151 updateTaskDescription(description);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002152 }
2153 if (!stopped) {
2154 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
Ruben Brunkf53497c2017-03-27 20:26:17 -07002155 stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002156 stopped = true;
Bryce Lee7ace3952018-02-16 14:34:32 -08002157 setState(STOPPED, "activityStoppedLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07002158
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002159 if (mAppWindowToken != null) {
2160 mAppWindowToken.notifyAppStopped();
2161 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002162
Andrii Kulian21713ac2016-10-12 22:05:05 -07002163 if (finishing) {
2164 clearOptionsLocked();
2165 } else {
2166 if (deferRelaunchUntilPaused) {
2167 stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002168 mRootActivityContainer.resumeFocusedStacksTopActivities();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002169 } else {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002170 mRootActivityContainer.updatePreviousProcess(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002171 }
2172 }
2173 }
2174 }
2175
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002176 void startLaunchTickingLocked() {
Jeff Sharkey5ab02432017-06-27 11:01:36 -06002177 if (Build.IS_USER) {
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002178 return;
2179 }
2180 if (launchTickTime == 0) {
2181 launchTickTime = SystemClock.uptimeMillis();
2182 continueLaunchTickingLocked();
2183 }
2184 }
2185
2186 boolean continueLaunchTickingLocked() {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002187 if (launchTickTime == 0) {
2188 return false;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002189 }
Wale Ogunwale7d701172015-03-11 15:36:30 -07002190
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002191 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002192 if (stack == null) {
2193 return false;
2194 }
2195
Ruben Brunkf53497c2017-03-27 20:26:17 -07002196 Message msg = stack.mHandler.obtainMessage(LAUNCH_TICK_MSG, this);
2197 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
2198 stack.mHandler.sendMessageDelayed(msg, LAUNCH_TICK);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002199 return true;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002200 }
2201
2202 void finishLaunchTickingLocked() {
2203 launchTickTime = 0;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002204 final ActivityStack stack = getActivityStack();
Wale Ogunwale7d701172015-03-11 15:36:30 -07002205 if (stack != null) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07002206 stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
Wale Ogunwale7d701172015-03-11 15:36:30 -07002207 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07002208 }
2209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002210 // IApplicationToken
2211
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002212 public boolean mayFreezeScreenLocked(WindowProcessController app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213 // Only freeze the screen if this activity is currently attached to
2214 // an application, and that application is not blocked or unresponding.
2215 // In any other case, we can't count on getting the screen unfrozen,
2216 // so it is best to leave as-is.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002217 return hasProcess() && !app.isCrashing() && !app.isNotResponding();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002218 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002219
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002220 public void startFreezingScreenLocked(WindowProcessController app, int configChanges) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 if (mayFreezeScreenLocked(app)) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002222 if (mAppWindowToken == null) {
2223 Slog.w(TAG_WM,
2224 "Attempted to freeze screen with non-existing app token: " + appToken);
2225 return;
2226 }
2227
2228 if (configChanges == 0 && mAppWindowToken.okToDisplay()) {
2229 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + appToken);
2230 return;
2231 }
2232
2233 mAppWindowToken.startFreezingScreen();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002234 }
2235 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002237 public void stopFreezingScreenLocked(boolean force) {
2238 if (force || frozenBeforeDestroy) {
2239 frozenBeforeDestroy = false;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002240 if (mAppWindowToken == null) {
2241 return;
2242 }
2243 if (DEBUG_ORIENTATION) {
2244 Slog.v(TAG_WM, "Clear freezing of " + appToken + ": hidden="
2245 + mAppWindowToken.isHidden() + " freezing="
2246 + mAppWindowToken.isFreezingScreen());
2247 }
2248 mAppWindowToken.stopFreezingScreen(true, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002249 }
2250 }
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002251
Jorim Jaggi4d27b842017-08-17 17:22:26 +02002252 public void reportFullyDrawnLocked(boolean restoredFromBundle) {
Vishnu Nair132ee832018-09-28 15:00:05 -07002253 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2254 .getActivityMetricsLogger().logAppTransitionReportedDrawn(this, restoredFromBundle);
2255 if (info != null) {
2256 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002257 info.windowsFullyDrawnDelayMs, info.getLaunchState());
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002258 }
Dianne Hackborn2286cdc2013-07-01 19:10:06 -07002259 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002260
2261 /**
2262 * Called when the starting window for this container is drawn.
2263 */
Sudheer Shankac766db02017-06-12 10:37:29 -07002264 public void onStartingWindowDrawn(long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002265 synchronized (mAtmService.mGlobalLock) {
Bryce Lee2a3cc462017-10-27 10:57:35 -07002266 mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +01002267 getWindowingMode(), timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -08002268 }
2269 }
2270
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002271 /** Called when the windows associated app window container are drawn. */
Vishnu Nair9ba31652018-11-13 14:34:05 -08002272 public void onWindowsDrawn(boolean drawn, long timestamp) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002273 synchronized (mAtmService.mGlobalLock) {
Vishnu Nair9ba31652018-11-13 14:34:05 -08002274 mDrawn = drawn;
2275 if (!drawn) {
2276 return;
2277 }
Vishnu Nair132ee832018-09-28 15:00:05 -07002278 final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
2279 .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
2280 final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002281 final @LaunchState int launchState = info != null ? info.getLaunchState() : -1;
Vishnu Nair132ee832018-09-28 15:00:05 -07002282 mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -08002283 windowsDrawnDelayMs, launchState);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002284 mStackSupervisor.sendWaitingVisibleReportLocked(this);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002285 finishLaunchTickingLocked();
2286 if (task != null) {
2287 task.hasBeenVisible = true;
2288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 }
2290 }
2291
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002292 /** Called when the windows associated app window container are visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002293 public void onWindowsVisible() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002294 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002295 mStackSupervisor.reportActivityVisibleLocked(this);
2296 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
2297 if (!nowVisible) {
2298 nowVisible = true;
2299 lastVisibleTime = SystemClock.uptimeMillis();
Bryce Leeb7c9b802017-05-02 14:20:24 -07002300 if (idle || mStackSupervisor.isStoppingNoHistoryActivity()) {
2301 // If this activity was already idle or there is an activity that must be
2302 // stopped immediately after visible, then we now need to make sure we perform
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002303 // the full stop of any activities that are waiting to do so. This is because
2304 // we won't do that while they are still waiting for this one to become visible.
Bryce Lee4a194382017-04-04 14:32:48 -07002305 final int size = mStackSupervisor.mActivitiesWaitingForVisibleActivity.size();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002306 if (size > 0) {
2307 for (int i = 0; i < size; i++) {
Bryce Lee4a194382017-04-04 14:32:48 -07002308 final ActivityRecord r =
2309 mStackSupervisor.mActivitiesWaitingForVisibleActivity.get(i);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002310 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "Was waiting for visible: " + r);
2311 }
Bryce Lee4a194382017-04-04 14:32:48 -07002312 mStackSupervisor.mActivitiesWaitingForVisibleActivity.clear();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002313 mStackSupervisor.scheduleIdleLocked();
2314 }
Bryce Leeb7c9b802017-05-02 14:20:24 -07002315 } else {
2316 // Instead of doing the full stop routine here, let's just hide any activities
2317 // we now can, and let them stop when the normal idle happens.
2318 mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
2319 false /* remove */, true /* processPausingActivities */);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002320 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002321 mAtmService.scheduleAppGcsLocked();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002322 }
2323 }
2324 }
2325
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002326 /** Called when the windows associated app window container are no longer visible. */
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002327 public void onWindowsGone() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002328 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002329 if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + this);
2330 nowVisible = false;
2331 }
2332 }
2333
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002334 /**
2335 * Called when the key dispatching to a window associated with the app window container
2336 * timed-out.
2337 *
2338 * @param reason The reason for the key dispatching time out.
2339 * @param windowPid The pid of the window key dispatching timed out on.
2340 * @return True if input dispatching should be aborted.
2341 */
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002342 public boolean keyDispatchingTimedOut(String reason, int windowPid) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002343 ActivityRecord anrActivity;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002344 WindowProcessController anrApp;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002345 boolean windowFromSameProcessAsActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002346 synchronized (mAtmService.mGlobalLock) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002347 anrActivity = getWaitingHistoryRecordLocked();
2348 anrApp = app;
Brian Carlstrom7b0f2e82017-03-31 00:24:18 -07002349 windowFromSameProcessAsActivity =
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002350 !hasProcess() || app.getPid() == windowPid || windowPid == -1;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002351 }
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002352
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002353 if (windowFromSameProcessAsActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002354 return mAtmService.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner,
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002355 anrActivity.shortComponentName, anrActivity.appInfo, shortComponentName,
2356 app, false, reason);
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002357 } else {
2358 // In this case another process added windows using this activity token. So, we call the
2359 // generic service input dispatch timed out method so that the right process is blamed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002360 return mAtmService.mAmInternal.inputDispatchingTimedOut(
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07002361 windowPid, false /* aboveSystem */, reason) < 0;
Wale Ogunwale7402ddf2017-03-29 12:58:24 -07002362 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002363 }
2364
2365 private ActivityRecord getWaitingHistoryRecordLocked() {
riddle_hsudb46d6b2015-04-01 18:58:07 +08002366 // First find the real culprit... if this activity is waiting for
2367 // another activity to start or has stopped, then the key dispatching
2368 // timeout should not be caused by this.
Bryce Lee4a194382017-04-04 14:32:48 -07002369 if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this) || stopped) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002370 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
riddle_hsudb46d6b2015-04-01 18:58:07 +08002371 // Try to use the one which is closest to top.
Bryce Leec4ab62a2018-03-05 14:19:26 -08002372 ActivityRecord r = stack.getResumedActivity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 if (r == null) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002374 r = stack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002376 if (r != null) {
2377 return r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002378 }
2379 }
riddle_hsudb46d6b2015-04-01 18:58:07 +08002380 return this;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 }
2382
Chong Zhang87761972016-08-22 13:53:24 -07002383 /** Checks whether the activity should be shown for current user. */
2384 public boolean okToShowLocked() {
Bryce Lee8558ec72017-08-17 15:37:26 -07002385 // We cannot show activities when the device is locked and the application is not
2386 // encryption aware.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002387 if (!StorageManager.isUserKeyUnlocked(mUserId)
Bryce Lee8558ec72017-08-17 15:37:26 -07002388 && !info.applicationInfo.isEncryptionAware()) {
2389 return false;
2390 }
2391
Chong Zhang87761972016-08-22 13:53:24 -07002392 return (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002393 || (mStackSupervisor.isCurrentProfileLocked(mUserId)
2394 && mAtmService.mAmInternal.isUserRunning(mUserId, 0 /* flags */));
Chong Zhang87761972016-08-22 13:53:24 -07002395 }
2396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002397 /**
2398 * This method will return true if the activity is either visible, is becoming visible, is
2399 * currently pausing, or is resumed.
2400 */
2401 public boolean isInterestingToUserLocked() {
Bryce Lee7ace3952018-02-16 14:34:32 -08002402 return visible || nowVisible || mState == PAUSING || mState == RESUMED;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002403 }
2404
Wale Ogunwale3e997362016-09-06 10:37:56 -07002405 void setSleeping(boolean _sleeping) {
2406 setSleeping(_sleeping, false);
2407 }
2408
2409 void setSleeping(boolean _sleeping, boolean force) {
2410 if (!force && sleeping == _sleeping) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002411 return;
2412 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002413 if (attachedToProcess()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002414 try {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002415 app.getThread().scheduleSleeping(appToken, _sleeping);
Craig Mautner0eea92c2013-05-16 13:35:39 -07002416 if (_sleeping && !mStackSupervisor.mGoingToSleepActivities.contains(this)) {
2417 mStackSupervisor.mGoingToSleepActivities.add(this);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002418 }
2419 sleeping = _sleeping;
2420 } catch (RemoteException e) {
Craig Mautner0eea92c2013-05-16 13:35:39 -07002421 Slog.w(TAG, "Exception thrown when sleeping: " + intent.getComponent(), e);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002422 }
2423 }
2424 }
Craig Mautnerf81b90872013-02-26 13:02:43 -08002425
Craig Mautnerd2328952013-03-05 12:46:26 -08002426 static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002427 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Craig Mautnerd2328952013-03-05 12:46:26 -08002428 if (r == null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002429 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002430 }
2431 final TaskRecord task = r.task;
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002432 final int activityNdx = task.mActivities.indexOf(r);
2433 if (activityNdx < 0 || (onlyRoot && activityNdx > task.findEffectiveRootIndex())) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08002434 return INVALID_TASK_ID;
Craig Mautnerd2328952013-03-05 12:46:26 -08002435 }
Craig Mautner9d4e9bc2014-06-18 18:34:56 -07002436 return task.taskId;
Craig Mautnerd2328952013-03-05 12:46:26 -08002437 }
2438
2439 static ActivityRecord isInStackLocked(IBinder token) {
Wale Ogunwale7d701172015-03-11 15:36:30 -07002440 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002441 return (r != null) ? r.getActivityStack().isInStackLocked(r) : null;
Craig Mautnerd2328952013-03-05 12:46:26 -08002442 }
2443
Craig Mautnerb59dcfd2013-05-06 13:12:58 -07002444 static ActivityStack getStackLocked(IBinder token) {
Craig Mautnerd2328952013-03-05 12:46:26 -08002445 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
2446 if (r != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002447 return r.getActivityStack();
Craig Mautnerd2328952013-03-05 12:46:26 -08002448 }
2449 return null;
2450 }
2451
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002452 /**
Riddle Hsufd4a0502018-10-16 01:05:16 +08002453 * @return display id to which this record is attached,
2454 * {@link android.view.Display#INVALID_DISPLAY} if not attached.
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002455 */
2456 int getDisplayId() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002457 final ActivityStack stack = getActivityStack();
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002458 if (stack == null) {
Riddle Hsufd4a0502018-10-16 01:05:16 +08002459 return INVALID_DISPLAY;
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002460 }
2461 return stack.mDisplayId;
2462 }
2463
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002464 final boolean isDestroyable() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002465 if (finishing || !hasProcess()) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002466 // This would be redundant.
2467 return false;
2468 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002469 final ActivityStack stack = getActivityStack();
Bryce Leec4ab62a2018-03-05 14:19:26 -08002470 if (stack == null || this == stack.getResumedActivity() || this == stack.mPausingActivity
Andrii Kulian02b7a832016-10-06 23:11:56 -07002471 || !haveState || !stopped) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -07002472 // We're not ready for this kind of thing.
2473 return false;
2474 }
2475 if (visible) {
2476 // The user would notice this!
2477 return false;
2478 }
2479 return true;
2480 }
2481
Winson Chung3bad5cc02014-08-19 17:44:32 -07002482 private static String createImageFilename(long createTime, int taskId) {
2483 return String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX + createTime +
Ruben Brunkf53497c2017-03-27 20:26:17 -07002484 IMAGE_EXTENSION;
Craig Mautnerc0ffce52014-07-01 12:38:52 -07002485 }
2486
Craig Mautner648f69b2014-09-18 14:16:26 -07002487 void setTaskDescription(TaskDescription _taskDescription) {
2488 Bitmap icon;
2489 if (_taskDescription.getIconFilename() == null &&
2490 (icon = _taskDescription.getIcon()) != null) {
2491 final String iconFilename = createImageFilename(createTime, task.taskId);
Winson Chungc8408b82017-01-25 17:58:56 -08002492 final File iconFile = new File(TaskPersister.getUserImagesDir(task.userId),
2493 iconFilename);
Suprabh Shukla23593142015-11-03 17:31:15 -08002494 final String iconFilePath = iconFile.getAbsolutePath();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002495 mAtmService.getRecentTasks().saveImage(icon, iconFilePath);
Suprabh Shukla23593142015-11-03 17:31:15 -08002496 _taskDescription.setIconFilename(iconFilePath);
Craig Mautner648f69b2014-09-18 14:16:26 -07002497 }
2498 taskDescription = _taskDescription;
2499 }
2500
Amith Yamasani0af6fa72016-01-17 15:36:19 -08002501 void setVoiceSessionLocked(IVoiceInteractionSession session) {
2502 voiceSession = session;
2503 pendingVoiceInteractionStart = false;
2504 }
2505
2506 void clearVoiceSessionLocked() {
2507 voiceSession = null;
2508 pendingVoiceInteractionStart = false;
2509 }
2510
Jorim Jaggi02886a82016-12-06 09:10:06 -08002511 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch) {
Jorim Jaggi42befc62017-06-13 11:54:04 -07002512 showStartingWindow(prev, newTask, taskSwitch, false /* fromRecents */);
2513 }
2514
2515 void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
2516 boolean fromRecents) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002517 if (mAppWindowToken == null) {
Jorim Jaggi70176432017-01-18 12:52:13 +01002518 return;
2519 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002520 if (mTaskOverlay) {
2521 // We don't show starting window for overlay activities.
2522 return;
2523 }
Sunny Goyald85bed52018-09-25 12:01:01 -07002524 if (pendingOptions != null
2525 && pendingOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
2526 // Don't show starting window when using shared element transition.
2527 return;
2528 }
Wale Ogunwale19866e22017-04-19 06:05:13 -07002529
Wale Ogunwale3b232392016-05-13 15:37:13 -07002530 final CompatibilityInfo compatInfo =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002531 mAtmService.compatibilityInfoForPackageLocked(info.applicationInfo);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002532 final boolean shown = addStartingWindow(packageName, theme,
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002533 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
Jorim Jaggibae01b12017-04-11 16:29:10 -07002534 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
Jorim Jaggi70aa4d12017-05-15 00:05:54 +02002535 allowTaskSnapshot(),
Bryce Lee7ace3952018-02-16 14:34:32 -08002536 mState.ordinal() >= RESUMED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
Jorim Jaggi42befc62017-06-13 11:54:04 -07002537 fromRecents);
Wale Ogunwale3b232392016-05-13 15:37:13 -07002538 if (shown) {
2539 mStartingWindowState = STARTING_WINDOW_SHOWN;
2540 }
2541 }
2542
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002543 void removeOrphanedStartingWindow(boolean behindFullscreenActivity) {
Jorim Jaggicb956052017-05-09 16:27:24 +02002544 if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002545 if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
2546 mStartingWindowState = STARTING_WINDOW_REMOVED;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002547 mAppWindowToken.removeStartingWindow();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002548 }
2549 }
2550
2551 int getRequestedOrientation() {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002552 return getOrientation();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -08002553 }
2554
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002555 void setRequestedOrientation(int requestedOrientation) {
Garfield Tan90b04282018-12-11 14:04:42 -08002556 setOrientation(requestedOrientation, mayFreezeScreenLocked(app));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002557 mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
Yorke Leebd54c2a2016-10-25 13:49:23 -07002558 task.taskId, requestedOrientation);
Andrii Kulian5406e7a2016-10-21 11:55:23 -07002559 }
2560
Garfield Tan90b04282018-12-11 14:04:42 -08002561 private void setOrientation(int requestedOrientation, boolean freezeScreenIfNeeded) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002562 if (mAppWindowToken == null) {
2563 Slog.w(TAG_WM,
2564 "Attempted to set orientation of non-existing app token: " + appToken);
Garfield Tan90b04282018-12-11 14:04:42 -08002565 return;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002566 }
2567
Evan Rosky730f6e82018-12-03 17:40:11 -08002568 final IBinder binder =
2569 (freezeScreenIfNeeded && appToken != null) ? appToken.asBinder() : null;
Garfield Tan90b04282018-12-11 14:04:42 -08002570 mAppWindowToken.setOrientation(requestedOrientation, binder, this);
Garfield Tan36a69ad2019-01-16 17:08:23 -08002571
2572 // Push the new configuration to the requested app in case where it's not pushed, e.g. when
2573 // the request is handled at task level with letterbox.
2574 if (!getMergedOverrideConfiguration().equals(
2575 mLastReportedConfiguration.getMergedConfiguration())) {
2576 ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
2577 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002578 }
2579
2580 int getOrientation() {
2581 if (mAppWindowToken == null) {
2582 return SCREEN_ORIENTATION_UNSPECIFIED;
2583 }
2584
2585 return mAppWindowToken.getOrientationIgnoreVisibility();
2586 }
2587
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002588 void setDisablePreviewScreenshots(boolean disable) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002589 if (mAppWindowToken == null) {
2590 Slog.w(TAG_WM, "Attempted to set disable screenshots of non-existing app"
2591 + " token: " + appToken);
2592 return;
2593 }
2594 mAppWindowToken.setDisablePreviewScreenshots(disable);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002595 }
2596
Bryce Leea163b762017-01-24 11:05:01 -08002597 /**
2598 * Set the last reported global configuration to the client. Should be called whenever a new
2599 * global configuration is sent to the client for this activity.
2600 */
2601 void setLastReportedGlobalConfiguration(@NonNull Configuration config) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002602 mLastReportedConfiguration.setGlobalConfiguration(config);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002603 }
2604
Bryce Leea163b762017-01-24 11:05:01 -08002605 /**
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002606 * Set the last reported configuration to the client. Should be called whenever
Bryce Leea163b762017-01-24 11:05:01 -08002607 * a new merged configuration is sent to the client for this activity.
2608 */
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002609 void setLastReportedConfiguration(@NonNull MergedConfiguration config) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002610 setLastReportedConfiguration(config.getGlobalConfiguration(),
2611 config.getOverrideConfiguration());
Bryce Leea163b762017-01-24 11:05:01 -08002612 }
2613
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002614 private void setLastReportedConfiguration(Configuration global, Configuration override) {
Bryce Lee8104e7a2017-08-17 09:16:03 -07002615 mLastReportedConfiguration.setConfiguration(global, override);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002616 }
2617
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002618 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002619 private void updateOverrideConfiguration() {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002620 computeBounds(mTmpBounds);
Bryce Leef3c6a472017-11-14 14:53:06 -08002621
Evan Roskydfe3da72018-10-26 17:21:06 -07002622 if (mTmpBounds.equals(getRequestedOverrideBounds())) {
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002623 return;
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002624 }
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002625
Bryce Leef3c6a472017-11-14 14:53:06 -08002626 setBounds(mTmpBounds);
2627
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002628 // Bounds changed...update configuration to match.
Bryce Leef3c6a472017-11-14 14:53:06 -08002629 if (!matchParentBounds()) {
Evan Rosky730f6e82018-12-03 17:40:11 -08002630 mTmpConfig.setTo(getRequestedOverrideConfiguration());
2631 task.computeConfigResourceOverrides(mTmpConfig, task.getParent().getConfiguration());
2632 } else {
2633 mTmpConfig.unset();
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002634 }
Bryce Leef3c6a472017-11-14 14:53:06 -08002635
Evan Roskydfe3da72018-10-26 17:21:06 -07002636 onRequestedOverrideConfigurationChanged(mTmpConfig);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002637 }
2638
Garfield Tan0443b372019-01-04 15:00:13 -08002639 @Override
2640 void resolveOverrideConfiguration(Configuration newParentConfiguration) {
2641 super.resolveOverrideConfiguration(newParentConfiguration);
2642
2643 // Assign configuration sequence number into hierarchy because there is a different way than
2644 // ensureActivityConfiguration() in this class that uses configuration in WindowState during
2645 // layout traversals.
2646 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
2647 getResolvedOverrideConfiguration().seq = mConfigurationSeq;
2648 }
2649
2650 @Override
2651 public void onConfigurationChanged(Configuration newParentConfig) {
2652 super.onConfigurationChanged(newParentConfig);
2653
2654 // Configuration's equality doesn't consider seq so if only seq number changes in resolved
2655 // override configuration. Therefore ConfigurationContainer doesn't change merged override
2656 // configuration, but it's used to push configuration changes so explicitly update that.
2657 if (getMergedOverrideConfiguration().seq != getResolvedOverrideConfiguration().seq) {
2658 onMergedOverrideConfigurationChanged();
2659 }
2660
2661 // TODO(b/80414790): Remove code below after unification.
2662 // Same as above it doesn't notify configuration listeners, and consequently AppWindowToken
2663 // can't get updated seq number. However WindowState's merged override configuration needs
2664 // to have this seq number because that's also used for activity config pushes during layout
2665 // traversal. Therefore explicitly update them here.
2666 if (mAppWindowToken == null) {
2667 return;
2668 }
2669 final Configuration appWindowTokenRequestedOverrideConfig =
2670 mAppWindowToken.getRequestedOverrideConfiguration();
2671 if (appWindowTokenRequestedOverrideConfig.seq != getResolvedOverrideConfiguration().seq) {
2672 appWindowTokenRequestedOverrideConfig.seq =
2673 getResolvedOverrideConfiguration().seq;
2674 mAppWindowToken.onMergedOverrideConfigurationChanged();
2675 }
2676 }
2677
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07002678 /** Returns true if the configuration is compatible with this activity. */
Wale Ogunwale42f07d92017-05-01 21:32:58 -07002679 boolean isConfigurationCompatible(Configuration config) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002680 final int orientation = mAppWindowToken != null
2681 ? getOrientation() : info.screenOrientation;
Wale Ogunwaled4b1d1e2017-04-10 06:35:59 -07002682 if (isFixedOrientationPortrait(orientation)
2683 && config.orientation != ORIENTATION_PORTRAIT) {
2684 return false;
2685 }
2686 if (isFixedOrientationLandscape(orientation)
2687 && config.orientation != ORIENTATION_LANDSCAPE) {
2688 return false;
2689 }
2690 return true;
2691 }
2692
Bryce Lee7566d762017-03-30 09:34:15 -07002693 /**
2694 * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}.
2695 */
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002696 // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
2697 private void computeBounds(Rect outBounds) {
2698 outBounds.setEmpty();
2699 final float maxAspectRatio = info.maxAspectRatio;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002700 final ActivityStack stack = getActivityStack();
Adrian Roos917791e2018-11-28 16:30:44 +01002701 final float minAspectRatio = info.minAspectRatio;
2702
2703 if (task == null || stack == null || task.inMultiWindowMode()
2704 || (maxAspectRatio == 0 && minAspectRatio == 0)
Bryce Leee5ab4502017-07-11 08:58:05 -07002705 || isInVrUiMode(getConfiguration())) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002706 // We don't set override configuration if that activity task isn't fullscreen. I.e. the
2707 // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
Bryce Leee5ab4502017-07-11 08:58:05 -07002708 // the activity. This is indicated by an empty {@link outBounds}. We also don't set it
2709 // if we are in VR mode.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002710 return;
2711 }
2712
Bryce Lee7566d762017-03-30 09:34:15 -07002713 // We must base this on the parent configuration, because we set our override
2714 // configuration's appBounds based on the result of this method. If we used our own
2715 // configuration, it would be influenced by past invocations.
Wale Ogunwale3382ab12017-07-27 08:55:03 -07002716 final Rect appBounds = getParent().getWindowConfiguration().getAppBounds();
Wale Ogunwale822e5122017-07-26 06:02:24 -07002717 final int containingAppWidth = appBounds.width();
2718 final int containingAppHeight = appBounds.height();
Adrian Roos917791e2018-11-28 16:30:44 +01002719 final float containingRatio = Math.max(containingAppWidth, containingAppHeight)
2720 / (float) Math.min(containingAppWidth, containingAppHeight);
Bryce Lee7566d762017-03-30 09:34:15 -07002721
Adrian Roos917791e2018-11-28 16:30:44 +01002722 int activityWidth = containingAppWidth;
2723 int activityHeight = containingAppHeight;
2724
2725 if (containingRatio > maxAspectRatio && maxAspectRatio != 0) {
2726 if (containingAppWidth < containingAppHeight) {
2727 // Width is the shorter side, so we use that to figure-out what the max. height
2728 // should be given the aspect ratio.
2729 activityHeight = (int) ((activityWidth * maxAspectRatio) + 0.5f);
2730 } else {
2731 // Height is the shorter side, so we use that to figure-out what the max. width
2732 // should be given the aspect ratio.
2733 activityWidth = (int) ((activityHeight * maxAspectRatio) + 0.5f);
2734 }
2735 } else if (containingRatio < minAspectRatio && minAspectRatio != 0) {
2736 if (containingAppWidth < containingAppHeight) {
2737 // Width is the shorter side, so we use the height to figure-out what the max. width
2738 // should be given the aspect ratio.
2739 activityWidth = (int) ((activityHeight / minAspectRatio) + 0.5f);
2740 } else {
2741 // Height is the shorter side, so we use the width to figure-out what the max.
2742 // height should be given the aspect ratio.
2743 activityHeight = (int) ((activityWidth / minAspectRatio) + 0.5f);
2744 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002745 }
2746
Adrian Roos917791e2018-11-28 16:30:44 +01002747 if (containingAppWidth <= activityWidth && containingAppHeight <= activityHeight) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002748 // The display matches or is less than the activity aspect ratio, so nothing else to do.
Bryce Lee7566d762017-03-30 09:34:15 -07002749 // Return the existing bounds. If this method is running for the first time,
Evan Roskydfe3da72018-10-26 17:21:06 -07002750 // {@link #getRequestedOverrideBounds()} will be empty (representing no override). If
2751 // the method has run before, then effect of {@link #getRequestedOverrideBounds()} will
2752 // already have been applied to the value returned from {@link getConfiguration}. Refer
2753 // to {@link TaskRecord#computeOverrideConfiguration}.
2754 outBounds.set(getRequestedOverrideBounds());
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002755 return;
2756 }
2757
2758 // Compute configuration based on max supported width and height.
Adrian Roos24be34d2018-05-28 18:55:38 +02002759 // Also account for the left / top insets (e.g. from display cutouts), which will be clipped
2760 // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app
2761 // bounds would end up too small.
Adrian Roos917791e2018-11-28 16:30:44 +01002762 outBounds.set(0, 0, activityWidth + appBounds.left, activityHeight + appBounds.top);
Adrian Roos24be34d2018-05-28 18:55:38 +02002763
Adrian Roos917791e2018-11-28 16:30:44 +01002764 final int navBarPosition = mAtmService.mWindowManager.getNavBarPosition(getDisplayId());
2765 if (navBarPosition == NAV_BAR_LEFT) {
Adrian Roos24be34d2018-05-28 18:55:38 +02002766 // Position the activity frame on the opposite side of the nav bar.
Adrian Roos917791e2018-11-28 16:30:44 +01002767 outBounds.left = appBounds.right - activityWidth;
Adrian Roos24be34d2018-05-28 18:55:38 +02002768 outBounds.right = appBounds.right;
Adrian Roos917791e2018-11-28 16:30:44 +01002769 } else if (navBarPosition == NAV_BAR_RIGHT) {
2770 // Position the activity frame on the opposite side of the nav bar.
2771 outBounds.left = 0;
2772 outBounds.right = activityWidth + appBounds.left;
2773 } else {
2774 // Horizontally center the frame.
2775 outBounds.left = appBounds.left + (containingAppWidth - activityWidth) / 2;
2776 outBounds.right = outBounds.left + activityWidth;
Adrian Roos24be34d2018-05-28 18:55:38 +02002777 }
Andrii Kulian3a1619d2017-07-07 14:38:09 -07002778 }
2779
Riddle Hsu16567132018-08-16 21:37:47 +08002780 /**
2781 * @return {@code true} if this activity was reparented to another display but
2782 * {@link #ensureActivityConfiguration} is not called.
2783 */
2784 boolean shouldUpdateConfigForDisplayChanged() {
2785 return mLastReportedDisplayId != getDisplayId();
2786 }
2787
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002788 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
2789 return ensureActivityConfiguration(globalChanges, preserveWindow,
2790 false /* ignoreStopState */);
2791 }
2792
Andrii Kulian21713ac2016-10-12 22:05:05 -07002793 /**
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002794 * Make sure the given activity matches the current configuration. Ensures the HistoryRecord
2795 * is updated with the correct configuration and all other bookkeeping is handled.
2796 *
2797 * @param globalChanges The changes to the global configuration.
2798 * @param preserveWindow If the activity window should be preserved on screen if the activity
2799 * is relaunched.
2800 * @param ignoreStopState If we should try to relaunch the activity even if it is in the stopped
2801 * state. This is useful for the case where we know the activity will be
2802 * visible soon and we want to ensure its configuration before we make it
2803 * visible.
2804 * @return True if the activity was relaunched and false if it wasn't relaunched because we
2805 * can't or the app handles the specific configuration that is changing.
Andrii Kulian21713ac2016-10-12 22:05:05 -07002806 */
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002807 boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
2808 boolean ignoreStopState) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002809 final ActivityStack stack = getActivityStack();
Andrii Kulian21713ac2016-10-12 22:05:05 -07002810 if (stack.mConfigWillChange) {
2811 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2812 "Skipping config check (will change): " + this);
2813 return true;
2814 }
2815
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002816 // We don't worry about activities that are finishing.
2817 if (finishing) {
2818 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2819 "Configuration doesn't matter in finishing " + this);
2820 stopFreezingScreenLocked(false);
2821 return true;
2822 }
2823
Wale Ogunwaleb6d75f32018-02-22 20:44:56 -08002824 if (!ignoreStopState && (mState == STOPPING || mState == STOPPED)) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07002825 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2826 "Skipping config check stopped or stopping: " + this);
2827 return true;
2828 }
2829
Wale Ogunwaleea3d3fd2017-05-01 07:41:08 -07002830 // TODO: We should add ActivityRecord.shouldBeVisible() that checks if the activity should
2831 // be visible based on the stack, task, and lockscreen state and use that here instead. The
2832 // method should be based on the logic in ActivityStack.ensureActivitiesVisibleLocked().
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07002833 // Skip updating configuration for activity is a stack that shouldn't be visible.
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002834 if (!stack.shouldBeVisible(null /* starting */)) {
Wale Ogunwale9b7a8272017-04-10 08:05:41 -07002835 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2836 "Skipping config check invisible stack: " + this);
2837 return true;
2838 }
2839
Andrii Kulian21713ac2016-10-12 22:05:05 -07002840 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2841 "Ensuring correct configuration: " + this);
2842
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002843 final int newDisplayId = getDisplayId();
2844 final boolean displayChanged = mLastReportedDisplayId != newDisplayId;
2845 if (displayChanged) {
2846 mLastReportedDisplayId = newDisplayId;
2847 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002848 // TODO(b/36505427): Is there a better place to do this?
2849 updateOverrideConfiguration();
2850
Winson Chungbdc646f2017-02-13 12:12:22 -08002851 // Short circuit: if the two full configurations are equal (the common case), then there is
2852 // nothing to do. We test the full configuration instead of the global and merged override
2853 // configurations because there are cases (like moving a task to the pinned stack) where
2854 // the combine configurations are equal, but would otherwise differ in the override config
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002855 mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
2856 if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002857 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002858 "Configuration & display unchanged in " + this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002859 return true;
2860 }
2861
2862 // Okay we now are going to make this activity have the new config.
2863 // But then we need to figure out how it needs to deal with that.
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002864
2865 // Find changes between last reported merged configuration and the current one. This is used
2866 // to decide whether to relaunch an activity or just report a configuration change.
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002867 final int changes = getConfigurationChanges(mTmpConfig);
Ruben Brunkf64af332017-03-22 22:03:25 -07002868
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002869 // Update last reported values.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002870 final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
Bryce Lee8104e7a2017-08-17 09:16:03 -07002871
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002872 setLastReportedConfiguration(mAtmService.getGlobalConfiguration(), newMergedOverrideConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002873
Bryce Lee7ace3952018-02-16 14:34:32 -08002874 if (mState == INITIALIZING) {
Andrii Kulianb372da62018-01-18 10:46:24 -08002875 // No need to relaunch or schedule new config for activity that hasn't been launched
2876 // yet. We do, however, return after applying the config to activity record, so that
2877 // it will use it for launch transaction.
2878 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2879 "Skipping config check for initializing activity: " + this);
2880 return true;
2881 }
2882
Andrii Kulian21713ac2016-10-12 22:05:05 -07002883 if (changes == 0 && !forceNewConfig) {
2884 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2885 "Configuration no differences in " + this);
2886 // There are no significant differences, so we won't relaunch but should still deliver
2887 // the new configuration to the client process.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002888 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002889 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002890 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002891 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002892 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002893 return true;
2894 }
2895
2896 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
Andrii Kulianb43be0a2017-03-02 17:29:40 -08002897 "Configuration changes for " + this + ", allChanges="
Andrii Kulian21713ac2016-10-12 22:05:05 -07002898 + Configuration.configurationDiffToString(changes));
2899
2900 // If the activity isn't currently running, just leave the new configuration and it will
2901 // pick that up next time it starts.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002902 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002903 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2904 "Configuration doesn't matter not running " + this);
2905 stopFreezingScreenLocked(false);
2906 forceNewConfig = false;
2907 return true;
2908 }
2909
2910 // Figure out how to handle the changes between the configurations.
2911 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2912 "Checking to restart " + info.name + ": changed=0x"
2913 + Integer.toHexString(changes) + ", handles=0x"
2914 + Integer.toHexString(info.getRealConfigChanged())
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002915 + ", mLastReportedConfiguration=" + mLastReportedConfiguration);
Andrii Kulian21713ac2016-10-12 22:05:05 -07002916
Wale Ogunwalee610d3d2017-04-25 10:23:48 -07002917 if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002918 // Aha, the activity isn't handling the change, so DIE DIE DIE.
2919 configChangeFlags |= changes;
2920 startFreezingScreenLocked(app, globalChanges);
2921 forceNewConfig = false;
2922 preserveWindow &= isResizeOnlyChange(changes);
Garfield Tan2746ab52018-07-25 12:33:01 -07002923 final boolean hasResizeChange = hasResizeChange(changes & ~info.getRealConfigChanged());
2924 if (hasResizeChange) {
2925 final boolean isDragResizing =
Yunfan Chen0e7aff92018-12-05 16:35:32 -08002926 getTaskRecord().getTask().isDragResizing();
Garfield Tan2746ab52018-07-25 12:33:01 -07002927 mRelaunchReason = isDragResizing ? RELAUNCH_REASON_FREE_RESIZE
2928 : RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
2929 } else {
2930 mRelaunchReason = RELAUNCH_REASON_NONE;
2931 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07002932 if (!attachedToProcess()) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002933 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2934 "Config is destroying non-running " + this);
2935 stack.destroyActivityLocked(this, true, "config");
Bryce Lee7ace3952018-02-16 14:34:32 -08002936 } else if (mState == PAUSING) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002937 // A little annoying: we are waiting for this activity to finish pausing. Let's not
2938 // do anything now, but just flag that it needs to be restarted when done pausing.
2939 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2940 "Config is skipping already pausing " + this);
2941 deferRelaunchUntilPaused = true;
2942 preserveWindowOnDeferredRelaunch = preserveWindow;
2943 return true;
Bryce Lee7ace3952018-02-16 14:34:32 -08002944 } else if (mState == RESUMED) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07002945 // Try to optimize this case: the configuration is changing and we need to restart
2946 // the top, resumed activity. Instead of doing the normal handshaking, just say
2947 // "restart!".
2948 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2949 "Config is relaunching resumed " + this);
2950
2951 if (DEBUG_STATES && !visible) {
2952 Slog.v(TAG_STATES, "Config is relaunching resumed invisible activity " + this
2953 + " called by " + Debug.getCallers(4));
2954 }
2955
2956 relaunchActivityLocked(true /* andResume */, preserveWindow);
2957 } else {
2958 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
2959 "Config is relaunching non-resumed " + this);
2960 relaunchActivityLocked(false /* andResume */, preserveWindow);
2961 }
2962
2963 // All done... tell the caller we weren't able to keep this activity around.
2964 return false;
2965 }
2966
2967 // Default case: the activity can handle this new configuration, so hand it over.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002968 // NOTE: We only forward the override configuration as the system level configuration
Andrii Kulian21713ac2016-10-12 22:05:05 -07002969 // changes is always sent to all processes when they happen so it can just use whatever
2970 // system level configuration it last got.
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002971 if (displayChanged) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002972 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002973 } else {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07002974 scheduleConfigurationChanged(newMergedOverrideConfig);
Andrii Kulianb047b8b2017-02-08 18:38:26 -08002975 }
Andrii Kulian21713ac2016-10-12 22:05:05 -07002976 stopFreezingScreenLocked(false);
2977
2978 return true;
2979 }
2980
Zak Cohen90e7116742017-01-29 12:59:23 -08002981 /**
2982 * When assessing a configuration change, decide if the changes flags and the new configurations
2983 * should cause the Activity to relaunch.
Ruben Brunkf64af332017-03-22 22:03:25 -07002984 *
2985 * @param changes the changes due to the given configuration.
2986 * @param changesConfig the configuration that was used to calculate the given changes via a
2987 * call to getConfigurationChanges.
Zak Cohen90e7116742017-01-29 12:59:23 -08002988 */
Ruben Brunkf64af332017-03-22 22:03:25 -07002989 private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
Zak Cohen90e7116742017-01-29 12:59:23 -08002990 int configChanged = info.getRealConfigChanged();
Ruben Brunkf64af332017-03-22 22:03:25 -07002991 boolean onlyVrUiModeChanged = onlyVrUiModeChanged(changes, changesConfig);
Zak Cohen90e7116742017-01-29 12:59:23 -08002992
2993 // Override for apps targeting pre-O sdks
2994 // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
2995 // to the config change.
2996 // For O and later, apps will be required to add configChanges="uimode" to their manifest.
2997 if (appInfo.targetSdkVersion < O
2998 && requestedVrComponent != null
Ruben Brunkf64af332017-03-22 22:03:25 -07002999 && onlyVrUiModeChanged) {
Zak Cohen90e7116742017-01-29 12:59:23 -08003000 configChanged |= CONFIG_UI_MODE;
3001 }
3002
3003 return (changes&(~configChanged)) != 0;
3004 }
3005
Ruben Brunkf64af332017-03-22 22:03:25 -07003006 /**
3007 * Returns true if the configuration change is solely due to the UI mode switching into or out
3008 * of UI_MODE_TYPE_VR_HEADSET.
3009 */
3010 private boolean onlyVrUiModeChanged(int changes, Configuration lastReportedConfig) {
3011 final Configuration currentConfig = getConfiguration();
Ruben Brunkf53497c2017-03-27 20:26:17 -07003012 return changes == CONFIG_UI_MODE && (isInVrUiMode(currentConfig)
Ruben Brunkf64af332017-03-22 22:03:25 -07003013 != isInVrUiMode(lastReportedConfig));
3014 }
3015
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003016 private int getConfigurationChanges(Configuration lastReportedConfig) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003017 // Determine what has changed. May be nothing, if this is a config that has come back from
3018 // the app after going idle. In that case we just want to leave the official config object
3019 // now in the activity and do nothing else.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003020 final Configuration currentConfig = getConfiguration();
3021 int changes = lastReportedConfig.diff(currentConfig);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003022 // We don't want to use size changes if they don't cross boundaries that are important to
3023 // the app.
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003024 if ((changes & CONFIG_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003025 final boolean crosses = crossesHorizontalSizeThreshold(lastReportedConfig.screenWidthDp,
3026 currentConfig.screenWidthDp)
3027 || crossesVerticalSizeThreshold(lastReportedConfig.screenHeightDp,
3028 currentConfig.screenHeightDp);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003029 if (!crosses) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003030 changes &= ~CONFIG_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003031 }
3032 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003033 if ((changes & CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
Andrii Kulianb43be0a2017-03-02 17:29:40 -08003034 final int oldSmallest = lastReportedConfig.smallestScreenWidthDp;
3035 final int newSmallest = currentConfig.smallestScreenWidthDp;
3036 if (!crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003037 changes &= ~CONFIG_SMALLEST_SCREEN_SIZE;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003038 }
3039 }
Wale Ogunwale822e5122017-07-26 06:02:24 -07003040 // We don't want window configuration to cause relaunches.
3041 if ((changes & CONFIG_WINDOW_CONFIGURATION) != 0) {
3042 changes &= ~CONFIG_WINDOW_CONFIGURATION;
3043 }
Bryce Lee600dadd2017-07-25 10:48:42 -07003044
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -07003045 return changes;
Andrii Kulian21713ac2016-10-12 22:05:05 -07003046 }
3047
3048 private static boolean isResizeOnlyChange(int change) {
3049 return (change & ~(CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
3050 | CONFIG_SCREEN_LAYOUT)) == 0;
3051 }
3052
Garfield Tan2746ab52018-07-25 12:33:01 -07003053 private static boolean hasResizeChange(int change) {
3054 return (change & (CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
3055 | CONFIG_SCREEN_LAYOUT)) != 0;
3056 }
3057
Andrii Kulian21713ac2016-10-12 22:05:05 -07003058 void relaunchActivityLocked(boolean andResume, boolean preserveWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003059 if (mAtmService.mSuppressResizeConfigChanges && preserveWindow) {
Andrii Kulian21713ac2016-10-12 22:05:05 -07003060 configChangeFlags = 0;
3061 return;
3062 }
3063
3064 List<ResultInfo> pendingResults = null;
3065 List<ReferrerIntent> pendingNewIntents = null;
3066 if (andResume) {
3067 pendingResults = results;
3068 pendingNewIntents = newIntents;
3069 }
3070 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
3071 "Relaunching: " + this + " with results=" + pendingResults
3072 + " newIntents=" + pendingNewIntents + " andResume=" + andResume
3073 + " preserveWindow=" + preserveWindow);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003074 EventLog.writeEvent(andResume ? AM_RELAUNCH_RESUME_ACTIVITY
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003075 : AM_RELAUNCH_ACTIVITY, mUserId, System.identityHashCode(this),
Andrii Kulian21713ac2016-10-12 22:05:05 -07003076 task.taskId, shortComponentName);
3077
3078 startFreezingScreenLocked(app, 0);
3079
Andrii Kulian21713ac2016-10-12 22:05:05 -07003080 try {
3081 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
3082 "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this
3083 + " callers=" + Debug.getCallers(6));
3084 forceNewConfig = false;
3085 mStackSupervisor.activityRelaunchingLocked(this);
Andrii Kulianb372da62018-01-18 10:46:24 -08003086 final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
3087 pendingNewIntents, configChangeFlags,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003088 new MergedConfiguration(mAtmService.getGlobalConfiguration(),
Andrii Kulianb372da62018-01-18 10:46:24 -08003089 getMergedOverrideConfiguration()),
3090 preserveWindow);
3091 final ActivityLifecycleItem lifecycleItem;
3092 if (andResume) {
lumark588a3e82018-07-20 18:53:54 +08003093 lifecycleItem = ResumeActivityItem.obtain(
Wale Ogunwale3a256e62018-12-06 14:41:18 -08003094 getDisplay().mDisplayContent.isNextTransitionForward());
Andrii Kulianb372da62018-01-18 10:46:24 -08003095 } else {
Bryce Lee1d0d5142018-04-12 10:35:07 -07003096 lifecycleItem = PauseActivityItem.obtain();
Andrii Kulianb372da62018-01-18 10:46:24 -08003097 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003098 final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), appToken);
Andrii Kulianb372da62018-01-18 10:46:24 -08003099 transaction.addCallback(callbackItem);
3100 transaction.setLifecycleStateRequest(lifecycleItem);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003101 mAtmService.getLifecycleManager().scheduleTransaction(transaction);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003102 // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
Andrii Kulianb372da62018-01-18 10:46:24 -08003103 // request resume if this activity is currently resumed, which implies we aren't
Andrii Kulian21713ac2016-10-12 22:05:05 -07003104 // sleeping.
3105 } catch (RemoteException e) {
3106 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
3107 }
3108
3109 if (andResume) {
3110 if (DEBUG_STATES) {
3111 Slog.d(TAG_STATES, "Resumed after relaunch " + this);
3112 }
3113 results = null;
3114 newIntents = null;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003115 mAtmService.getAppWarningsLocked().onResumeActivity(this);
Andrii Kulian21713ac2016-10-12 22:05:05 -07003116 } else {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003117 final ActivityStack stack = getActivityStack();
Wale Ogunwale008163e2018-07-23 23:11:08 -07003118 if (stack != null) {
3119 stack.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
3120 }
Bryce Lee7ace3952018-02-16 14:34:32 -08003121 setState(PAUSED, "relaunchActivityLocked");
Andrii Kulian21713ac2016-10-12 22:05:05 -07003122 }
3123
3124 configChangeFlags = 0;
3125 deferRelaunchUntilPaused = false;
3126 preserveWindowOnDeferredRelaunch = false;
3127 }
3128
Jorim Jaggibae01b12017-04-11 16:29:10 -07003129 private boolean isProcessRunning() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003130 WindowProcessController proc = app;
Jorim Jaggi02886a82016-12-06 09:10:06 -08003131 if (proc == null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003132 proc = mAtmService.mProcessNames.get(processName, info.applicationInfo.uid);
Jorim Jaggi02886a82016-12-06 09:10:06 -08003133 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003134 return proc != null && proc.hasThread();
Jorim Jaggi02886a82016-12-06 09:10:06 -08003135 }
3136
Jorim Jaggibae01b12017-04-11 16:29:10 -07003137 /**
3138 * @return Whether a task snapshot starting window may be shown.
3139 */
3140 private boolean allowTaskSnapshot() {
3141 if (newIntents == null) {
3142 return true;
3143 }
3144
3145 // Restrict task snapshot starting window to launcher start, or there is no intent at all
3146 // (eg. task being brought to front). If the intent is something else, likely the app is
3147 // going to show some specific page or view, instead of what's left last time.
3148 for (int i = newIntents.size() - 1; i >= 0; i--) {
3149 final Intent intent = newIntents.get(i);
3150 if (intent != null && !ActivityRecord.isMainIntent(intent)) {
3151 return false;
3152 }
3153 }
3154 return true;
3155 }
3156
Bryce Leeb7c9b802017-05-02 14:20:24 -07003157 /**
3158 * Returns {@code true} if the associated activity has the no history flag set on it.
3159 * {@code false} otherwise.
3160 */
3161 boolean isNoHistory() {
3162 return (intent.getFlags() & FLAG_ACTIVITY_NO_HISTORY) != 0
3163 || (info.flags & FLAG_NO_HISTORY) != 0;
3164 }
3165
Craig Mautner21d24a22014-04-23 11:45:37 -07003166 void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
3167 out.attribute(null, ATTR_ID, String.valueOf(createTime));
3168 out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
3169 if (launchedFromPackage != null) {
3170 out.attribute(null, ATTR_LAUNCHEDFROMPACKAGE, launchedFromPackage);
3171 }
3172 if (resolvedType != null) {
3173 out.attribute(null, ATTR_RESOLVEDTYPE, resolvedType);
3174 }
3175 out.attribute(null, ATTR_COMPONENTSPECIFIED, String.valueOf(componentSpecified));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003176 out.attribute(null, ATTR_USERID, String.valueOf(mUserId));
Winson Chung2cb86c72014-06-25 12:03:30 -07003177
Craig Mautner21d24a22014-04-23 11:45:37 -07003178 if (taskDescription != null) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003179 taskDescription.saveToXml(out);
Craig Mautner21d24a22014-04-23 11:45:37 -07003180 }
3181
3182 out.startTag(null, TAG_INTENT);
3183 intent.saveToXml(out);
3184 out.endTag(null, TAG_INTENT);
3185
3186 if (isPersistable() && persistentState != null) {
3187 out.startTag(null, TAG_PERSISTABLEBUNDLE);
3188 persistentState.saveToXml(out);
3189 out.endTag(null, TAG_PERSISTABLEBUNDLE);
3190 }
3191 }
3192
Stefan Kuhnee88d1e52015-05-18 10:33:45 -07003193 static ActivityRecord restoreFromXml(XmlPullParser in,
3194 ActivityStackSupervisor stackSupervisor) throws IOException, XmlPullParserException {
Craig Mautner21d24a22014-04-23 11:45:37 -07003195 Intent intent = null;
3196 PersistableBundle persistentState = null;
3197 int launchedFromUid = 0;
3198 String launchedFromPackage = null;
3199 String resolvedType = null;
3200 boolean componentSpecified = false;
3201 int userId = 0;
Craig Mautner21d24a22014-04-23 11:45:37 -07003202 long createTime = -1;
3203 final int outerDepth = in.getDepth();
Winson Chung2cb86c72014-06-25 12:03:30 -07003204 TaskDescription taskDescription = new TaskDescription();
Craig Mautner21d24a22014-04-23 11:45:37 -07003205
3206 for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
3207 final String attrName = in.getAttributeName(attrNdx);
3208 final String attrValue = in.getAttributeValue(attrNdx);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003209 if (DEBUG) Slog.d(TaskPersister.TAG,
Wale Ogunwale18795a22014-12-03 11:38:33 -08003210 "ActivityRecord: attribute name=" + attrName + " value=" + attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003211 if (ATTR_ID.equals(attrName)) {
Tobias Thierer28532d02016-04-21 14:52:10 +01003212 createTime = Long.parseLong(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003213 } else if (ATTR_LAUNCHEDFROMUID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003214 launchedFromUid = Integer.parseInt(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003215 } else if (ATTR_LAUNCHEDFROMPACKAGE.equals(attrName)) {
3216 launchedFromPackage = attrValue;
3217 } else if (ATTR_RESOLVEDTYPE.equals(attrName)) {
3218 resolvedType = attrValue;
3219 } else if (ATTR_COMPONENTSPECIFIED.equals(attrName)) {
Tobias Thiererb0800dc2016-04-21 17:51:41 +01003220 componentSpecified = Boolean.parseBoolean(attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003221 } else if (ATTR_USERID.equals(attrName)) {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01003222 userId = Integer.parseInt(attrValue);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003223 } else if (attrName.startsWith(ATTR_TASKDESCRIPTION_PREFIX)) {
Craig Mautner648f69b2014-09-18 14:16:26 -07003224 taskDescription.restoreFromXml(attrName, attrValue);
Craig Mautner21d24a22014-04-23 11:45:37 -07003225 } else {
3226 Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
3227 }
3228 }
3229
3230 int event;
Ruben Brunkf53497c2017-03-27 20:26:17 -07003231 while (((event = in.next()) != END_DOCUMENT) &&
3232 (event != END_TAG || in.getDepth() >= outerDepth)) {
3233 if (event == START_TAG) {
Craig Mautner21d24a22014-04-23 11:45:37 -07003234 final String name = in.getName();
Ruben Brunkf53497c2017-03-27 20:26:17 -07003235 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003236 Slog.d(TaskPersister.TAG, "ActivityRecord: START_TAG name=" + name);
Craig Mautner21d24a22014-04-23 11:45:37 -07003237 if (TAG_INTENT.equals(name)) {
3238 intent = Intent.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003239 if (DEBUG)
Wale Ogunwale18795a22014-12-03 11:38:33 -08003240 Slog.d(TaskPersister.TAG, "ActivityRecord: intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003241 } else if (TAG_PERSISTABLEBUNDLE.equals(name)) {
3242 persistentState = PersistableBundle.restoreFromXml(in);
Ruben Brunkf53497c2017-03-27 20:26:17 -07003243 if (DEBUG) Slog.d(TaskPersister.TAG,
Craig Mautner21d24a22014-04-23 11:45:37 -07003244 "ActivityRecord: persistentState=" + persistentState);
3245 } else {
3246 Slog.w(TAG, "restoreActivity: unexpected name=" + name);
3247 XmlUtils.skipCurrentTag(in);
3248 }
3249 }
3250 }
3251
3252 if (intent == null) {
Craig Mautnere0129b32014-05-25 16:41:09 -07003253 throw new XmlPullParserException("restoreActivity error intent=" + intent);
Craig Mautner21d24a22014-04-23 11:45:37 -07003254 }
3255
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003256 final ActivityTaskManagerService service = stackSupervisor.mService;
Craig Mautner21d24a22014-04-23 11:45:37 -07003257 final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null,
Patrick Baumann78380272018-04-04 10:41:01 -07003258 userId, Binder.getCallingUid());
Craig Mautnere0129b32014-05-25 16:41:09 -07003259 if (aInfo == null) {
Craig Mautner77b04262014-06-27 15:22:12 -07003260 throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
3261 " resolvedType=" + resolvedType);
Craig Mautnere0129b32014-05-25 16:41:09 -07003262 }
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07003263 final ActivityRecord r = new ActivityRecord(service, null /* caller */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003264 0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType,
Wale Ogunwalef6733932018-06-27 05:14:34 -07003265 aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */,
Andrii Kulianfb1bf692017-01-17 11:17:34 -08003266 0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07003267 stackSupervisor, null /* options */, null /* sourceRecord */);
Craig Mautner21d24a22014-04-23 11:45:37 -07003268
3269 r.persistentState = persistentState;
Winson Chung2cb86c72014-06-25 12:03:30 -07003270 r.taskDescription = taskDescription;
Craig Mautner21d24a22014-04-23 11:45:37 -07003271 r.createTime = createTime;
3272
3273 return r;
3274 }
3275
Zak Cohen90e7116742017-01-29 12:59:23 -08003276 private static boolean isInVrUiMode(Configuration config) {
Ruben Brunkf53497c2017-03-27 20:26:17 -07003277 return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
Zak Cohen90e7116742017-01-29 12:59:23 -08003278 }
3279
David Stevens82ea6cb2017-03-03 16:18:50 -08003280 int getUid() {
3281 return info.applicationInfo.uid;
3282 }
3283
chaviw59b98852017-06-13 12:05:44 -07003284 void setShowWhenLocked(boolean showWhenLocked) {
3285 mShowWhenLocked = showWhenLocked;
Wale Ogunwaled32da472018-11-16 07:19:28 -08003286 mRootActivityContainer.ensureActivitiesVisible(null, 0 /* configChanges */,
Kevin Chyn44639482017-10-09 18:34:41 -07003287 false /* preserveWindows */);
chaviw59b98852017-06-13 12:05:44 -07003288 }
3289
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003290 void setInheritShowWhenLocked(boolean inheritShowWhenLocked) {
3291 mInheritShownWhenLocked = inheritShowWhenLocked;
3292 mRootActivityContainer.ensureActivitiesVisible(null, 0, false);
3293 }
3294
chaviw59b98852017-06-13 12:05:44 -07003295 /**
chaviw2c500982018-01-04 17:05:05 -08003296 * @return true if the activity windowing mode is not
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003297 * {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and a) activity
3298 * contains windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the
3299 * activity has set {@link #mShowWhenLocked}, or b) if the activity has set
3300 * {@link #mInheritShownWhenLocked} and the activity behind this satisfies the
3301 * conditions a) above.
chaviw2c500982018-01-04 17:05:05 -08003302 * Multi-windowing mode will be exited if true is returned.
chaviw59b98852017-06-13 12:05:44 -07003303 */
3304 boolean canShowWhenLocked() {
Issei Suzuki74e1eb22018-12-20 17:42:52 +01003305 if (!inPinnedWindowingMode() && (mShowWhenLocked
3306 || (mAppWindowToken != null && mAppWindowToken.containsShowWhenLockedWindow()))) {
3307 return true;
3308 } else if (mInheritShownWhenLocked) {
3309 ActivityRecord r = getActivityBelow();
3310 return r != null && !r.inPinnedWindowingMode() && (r.mShowWhenLocked
3311 || (r.mAppWindowToken != null
3312 && r.mAppWindowToken.containsShowWhenLockedWindow()));
3313 } else {
3314 return false;
3315 }
3316 }
3317
3318 /**
3319 * @return an {@link ActivityRecord} of the activity below this activity, or {@code null} if no
3320 * such activity exists.
3321 */
3322 @Nullable
3323 private ActivityRecord getActivityBelow() {
3324 final int pos = task.mActivities.indexOf(this);
3325 if (pos == -1) {
3326 throw new IllegalStateException("Activity not found in its task");
3327 }
3328 return pos == 0 ? null : task.getChildAt(pos - 1);
chaviw59b98852017-06-13 12:05:44 -07003329 }
3330
3331 void setTurnScreenOn(boolean turnScreenOn) {
3332 mTurnScreenOn = turnScreenOn;
3333 }
3334
3335 /**
3336 * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
3337 * {@link #mTurnScreenOn} is set and checks whether the ActivityRecord should be visible
3338 * depending on Keyguard state
3339 *
3340 * @return true if the screen can be turned on, false otherwise.
3341 */
3342 boolean canTurnScreenOn() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003343 final ActivityStack stack = getActivityStack();
chaviw59b98852017-06-13 12:05:44 -07003344 return mTurnScreenOn && stack != null &&
3345 stack.checkKeyguardVisibility(this, true /* shouldBeVisible */, true /* isTop */);
3346 }
3347
3348 boolean getTurnScreenOnFlag() {
3349 return mTurnScreenOn;
3350 }
3351
3352 boolean isTopRunningActivity() {
Wale Ogunwaled32da472018-11-16 07:19:28 -08003353 return mRootActivityContainer.topRunningActivity() == this;
chaviw59b98852017-06-13 12:05:44 -07003354 }
3355
Andrii Kulian52d255c2018-07-13 11:32:19 -07003356 /**
3357 * @return {@code true} if this is the resumed activity on its current display, {@code false}
3358 * otherwise.
3359 */
3360 boolean isResumedActivityOnDisplay() {
3361 final ActivityDisplay display = getDisplay();
3362 return display != null && this == display.getResumedActivity();
3363 }
3364
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003365 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08003366 if (mAppWindowToken == null) {
3367 Slog.w(TAG_WM, "Attempted to register remote animations with non-existing app"
3368 + " token: " + appToken);
3369 return;
3370 }
3371 mAppWindowToken.registerRemoteAnimations(definition);
Jorim Jaggif84e2f62018-01-16 14:17:59 +01003372 }
3373
Craig Mautnerf81b90872013-02-26 13:02:43 -08003374 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003375 public String toString() {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003376 if (stringName != null) {
Wale Ogunwale18795a22014-12-03 11:38:33 -08003377 return stringName + " t" + (task == null ? INVALID_TASK_ID : task.taskId) +
Craig Mautnerf3333272013-04-22 10:55:53 -07003378 (finishing ? " f}" : "}");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003379 }
3380 StringBuilder sb = new StringBuilder(128);
Dianne Hackborn30d71892010-12-11 10:37:55 -08003381 sb.append("ActivityRecord{");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003382 sb.append(Integer.toHexString(System.identityHashCode(this)));
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003383 sb.append(" u");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003384 sb.append(mUserId);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003385 sb.append(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003386 sb.append(intent.getComponent().flattenToShortString());
Craig Mautnerf81b90872013-02-26 13:02:43 -08003387 stringName = sb.toString();
3388 return toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003389 }
Steven Timotius4346f0a2017-09-12 11:07:21 -07003390
3391 void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
3392 final long token = proto.start(fieldId);
3393 proto.write(HASH_CODE, System.identityHashCode(this));
Wale Ogunwale8b19de92018-11-29 19:58:26 -08003394 proto.write(USER_ID, mUserId);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003395 proto.write(TITLE, intent.getComponent().flattenToShortString());
3396 proto.end(token);
3397 }
3398
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003399 /**
3400 * Write all fields to an {@code ActivityRecordProto}. This assumes the
3401 * {@code ActivityRecordProto} is the outer-most proto data.
3402 */
3403 void writeToProto(ProtoOutputStream proto) {
Adrian Roos4921ccf2017-09-28 16:54:06 +02003404 super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003405 writeIdentifierToProto(proto, IDENTIFIER);
Bryce Lee7ace3952018-02-16 14:34:32 -08003406 proto.write(STATE, mState.toString());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003407 proto.write(VISIBLE, visible);
3408 proto.write(FRONT_OF_TASK, frontOfTask);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07003409 if (hasProcess()) {
3410 proto.write(PROC_ID, app.getPid());
Steven Timotius4346f0a2017-09-12 11:07:21 -07003411 }
Wale Ogunwale30eab1f2018-05-24 18:25:25 -07003412 proto.write(TRANSLUCENT, !fullscreen);
Igor Murashkinc0b47e42018-11-07 15:54:18 -08003413 }
3414
3415 public void writeToProto(ProtoOutputStream proto, long fieldId) {
3416 final long token = proto.start(fieldId);
3417 writeToProto(proto);
Steven Timotius4346f0a2017-09-12 11:07:21 -07003418 proto.end(token);
3419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003420}