blob: 0c0c818e0baab1eb569d42ad896abeb1bfdb005b [file] [log] [blame]
Wale Ogunwale59507092018-10-29 09:00:30 -07001package com.android.server.wm;
Filip Gruszczynski77d94482015-12-11 13:59:52 -08002
Jorim Jaggi3878ca32017-02-02 17:13:05 -08003import static android.app.ActivityManager.START_SUCCESS;
4import static android.app.ActivityManager.START_TASK_TO_FRONT;
Michal Karpinski201bc0c2018-07-20 15:32:00 +01005import static android.app.ActivityManager.processStateAmToProto;
Bryce Lee6c605092017-10-12 11:14:49 -07006import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07007import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
8import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Vishnu Nair132ee832018-09-28 15:00:05 -07009import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Wale Ogunwale926aade2017-08-29 11:24:37 -070010import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
11import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Vishnu Nair132ee832018-09-28 15:00:05 -070012
Michal Karpinski201bc0c2018-07-20 15:32:00 +010013import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_ACTIVITY_START;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080014import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION;
Jorim Jaggi515dd682017-05-05 15:05:07 +020015import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_BIND_APPLICATION_DELAY_MS;
Todd Kennedy50d946c12017-03-17 13:55:38 -070016import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CALLING_PACKAGE_NAME;
Jorim Jaggi172e99f2017-10-20 14:33:18 +020017import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CANCELLED;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080018import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DELAY_MS;
19import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS;
Todd Kennedy50d946c12017-03-17 13:55:38 -070020import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_IS_EPHEMERAL;
Jorim Jaggi4d27b842017-08-17 17:22:26 +020021import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_PROCESS_RUNNING;
22import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_REPORTED_DRAWN;
23import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_REPORTED_DRAWN_MS;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080024import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_STARTING_WINDOW_DELAY_MS;
25import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS;
Michal Karpinski201bc0c2018-07-20 15:32:00 +010026import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_FLAGS;
27import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_FULLSCREEN;
28import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY;
29import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE;
30import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD;
Vishnu Nair132ee832018-09-28 15:00:05 -070031import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_LAUNCH_MODE;
Michal Karpinski201bc0c2018-07-20 15:32:00 +010032import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH;
33import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE;
Michal Karpinski201bc0c2018-07-20 15:32:00 +010034import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_PROCESS_NAME;
35import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_REAL_ACTIVITY;
36import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME;
37import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME;
38import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME;
39import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY;
40import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_PACKAGE_NAME;
41import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID;
42import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
43import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID_PROC_STATE;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +020044import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CLASS_NAME;
Michal Karpinski201bc0c2018-07-20 15:32:00 +010045import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_COMING_FROM_PENDING_INTENT;
Todd Kennedy50d946c12017-03-17 13:55:38 -070046import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_LAUNCH_TOKEN;
Michal Karpinski201bc0c2018-07-20 15:32:00 +010047import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INTENT_ACTION;
48import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_CUR_PROC_STATE;
49import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES;
50import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES;
51import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES;
52import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_OVERLAY_UI;
53import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_TOP_UI;
54import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION;
55import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT;
56import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT;
57import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_PENDING_UI_CLEAN;
58import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_PROCESS_NAME;
59import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID;
Michal Karpinski201bc0c2018-07-20 15:32:00 +010060import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
Vishnu Nair132ee832018-09-28 15:00:05 -070061import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_PROC_STATE;
Michal Karpinski201bc0c2018-07-20 15:32:00 +010062import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_PACKAGE_NAME;
63import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_SHORT_COMPONENT_NAME;
64import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID;
65import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW;
66import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_PROC_STATE;
67import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_WHITELIST_TAG;
Calin Juravle759fbda2018-02-20 19:52:30 +000068import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_FILTER;
Vishnu Nair132ee832018-09-28 15:00:05 -070069import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_REASON;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080070import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_COLD_LAUNCH;
71import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_HOT_LAUNCH;
Jorim Jaggi4d27b842017-08-17 17:22:26 +020072import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE;
73import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080074import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_WARM_LAUNCH;
Vishnu Nair132ee832018-09-28 15:00:05 -070075import static com.android.server.am.EventLogTags.AM_ACTIVITY_LAUNCH_TIME;
Ng Zhi Anbbefdec2018-01-30 17:12:39 -080076import static com.android.server.am.MemoryStatUtil.MemoryStat;
Rajeev Kumarbfcd9202018-03-02 22:42:13 +000077import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
Vishnu Naira62534b2018-11-09 09:13:22 -080078import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_METRICS;
79import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
80import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Vishnu Nair132ee832018-09-28 15:00:05 -070081import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;
Filip Gruszczynski77d94482015-12-11 13:59:52 -080082
Igor Murashkin212d06c2018-10-22 16:34:39 -070083import android.app.WindowConfiguration.WindowingMode;
Filip Gruszczynski77d94482015-12-11 13:59:52 -080084import android.content.Context;
Michal Karpinski201bc0c2018-07-20 15:32:00 +010085import android.content.Intent;
Calin Juravle759fbda2018-02-20 19:52:30 +000086import android.content.pm.ApplicationInfo;
87import android.content.pm.dex.ArtManagerInternal;
88import android.content.pm.dex.PackageOptimizationInfo;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080089import android.metrics.LogMaker;
Jorim Jaggi172e99f2017-10-20 14:33:18 +020090import android.os.Handler;
91import android.os.Looper;
92import android.os.Message;
Filip Gruszczynski77d94482015-12-11 13:59:52 -080093import android.os.SystemClock;
Vishnu Nair132ee832018-09-28 15:00:05 -070094import android.os.Trace;
95import android.util.EventLog;
96import android.util.Log;
Jorim Jaggi172e99f2017-10-20 14:33:18 +020097import android.util.Slog;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080098import android.util.SparseArray;
99import android.util.SparseIntArray;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000100import android.util.StatsLog;
Vishnu Nair132ee832018-09-28 15:00:05 -0700101import android.util.TimeUtils;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800102
103import com.android.internal.logging.MetricsLogger;
Ng Zhi An83473542018-02-20 09:02:14 -0800104import com.android.internal.os.BackgroundThread;
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200105import com.android.internal.os.SomeArgs;
Calin Juravle759fbda2018-02-20 19:52:30 +0000106import com.android.server.LocalServices;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800107
108/**
Vishnu Nair132ee832018-09-28 15:00:05 -0700109 * Listens to activity launches, transitions, visibility changes and window drawn callbacks to
110 * determine app launch times and draw delays. Source of truth for activity metrics and provides
111 * data for Tron, logcat, event logs and {@link android.app.WaitResult}.
112 *
113 * Tests:
Vishnu Nairf8accc52018-10-11 10:19:54 -0700114 * atest CtsActivityManagerDeviceTestCases:ActivityMetricsLoggerTests
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800115 */
116class ActivityMetricsLogger {
Jorim Jaggif9704102016-05-05 19:14:22 -0700117
Wale Ogunwale98875612018-10-12 07:53:02 -0700118 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityMetricsLogger" : TAG_ATM;
Jorim Jaggif9704102016-05-05 19:14:22 -0700119
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800120 // Window modes we are interested in logging. If we ever introduce a new type, we need to add
121 // a value here and increase the {@link #TRON_WINDOW_STATE_VARZ_STRINGS} array.
122 private static final int WINDOW_STATE_STANDARD = 0;
123 private static final int WINDOW_STATE_SIDE_BY_SIDE = 1;
124 private static final int WINDOW_STATE_FREEFORM = 2;
Winson Chung83471632016-12-13 11:02:12 -0800125 private static final int WINDOW_STATE_ASSISTANT = 3;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800126 private static final int WINDOW_STATE_INVALID = -1;
127
Jorim Jaggi275561a2016-02-23 10:11:02 -0500128 private static final long INVALID_START_TIME = -1;
Vishnu Nair132ee832018-09-28 15:00:05 -0700129 private static final int INVALID_DELAY = -1;
130 private static final int INVALID_TRANSITION_TYPE = -1;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500131
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200132 private static final int MSG_CHECK_VISIBILITY = 0;
133
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800134 // Preallocated strings we are sending to tron, so we don't have to allocate a new one every
135 // time we log.
136 private static final String[] TRON_WINDOW_STATE_VARZ_STRINGS = {
Winson Chung83471632016-12-13 11:02:12 -0800137 "window_time_0", "window_time_1", "window_time_2", "window_time_3"};
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800138
139 private int mWindowState = WINDOW_STATE_STANDARD;
140 private long mLastLogTimeSecs;
141 private final ActivityStackSupervisor mSupervisor;
142 private final Context mContext;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800143 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800144
Igor Murashkin212d06c2018-10-22 16:34:39 -0700145 // set to INVALID_START_TIME in reset.
146 // set to valid value in notifyActivityLaunching
Jorim Jaggi275561a2016-02-23 10:11:02 -0500147 private long mCurrentTransitionStartTime = INVALID_START_TIME;
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200148 private long mLastTransitionStartTime = INVALID_START_TIME;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800149
150 private int mCurrentTransitionDeviceUptime;
151 private int mCurrentTransitionDelayMs;
Igor Murashkin212d06c2018-10-22 16:34:39 -0700152
153 /** If the any app transitions have been logged as starting, after the latest reset. */
Jorim Jaggi275561a2016-02-23 10:11:02 -0500154 private boolean mLoggedTransitionStarting;
155
Igor Murashkin212d06c2018-10-22 16:34:39 -0700156 /** Map : @WindowingMode int => WindowingModeTransitionInfo */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100157 private final SparseArray<WindowingModeTransitionInfo> mWindowingModeTransitionInfo =
158 new SparseArray<>();
Igor Murashkin212d06c2018-10-22 16:34:39 -0700159 /** Map : @WindowingMode int => WindowingModeTransitionInfo */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100160 private final SparseArray<WindowingModeTransitionInfo> mLastWindowingModeTransitionInfo =
161 new SparseArray<>();
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200162 private final H mHandler;
Calin Juravle759fbda2018-02-20 19:52:30 +0000163
164 private ArtManagerInternal mArtManagerInternal;
Vishnu Nair132ee832018-09-28 15:00:05 -0700165 private final StringBuilder mStringBuilder = new StringBuilder();
Calin Juravle759fbda2018-02-20 19:52:30 +0000166
Igor Murashkin212d06c2018-10-22 16:34:39 -0700167 /**
168 * Due to the global single concurrent launch sequence, all calls to this observer must be made
169 * in-order on the same thread to fulfill the "happens-before" guarantee in LaunchObserver.
170 */
171 private final ActivityMetricsLaunchObserver mLaunchObserver = null;
172
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200173 private final class H extends Handler {
174
175 public H(Looper looper) {
176 super(looper);
177 }
178
179 @Override
180 public void handleMessage(Message msg) {
181 switch (msg.what) {
182 case MSG_CHECK_VISIBILITY:
183 final SomeArgs args = (SomeArgs) msg.obj;
184 checkVisibility((TaskRecord) args.arg1, (ActivityRecord) args.arg2);
185 break;
186 }
187 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000188 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800189
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100190 private final class WindowingModeTransitionInfo {
Igor Murashkin212d06c2018-10-22 16:34:39 -0700191 /** The latest activity to have been launched. */
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800192 private ActivityRecord launchedActivity;
193 private int startResult;
194 private boolean currentTransitionProcessRunning;
Vishnu Nair132ee832018-09-28 15:00:05 -0700195 /** Elapsed time from when we launch an activity to when its windows are drawn. */
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800196 private int windowsDrawnDelayMs;
Vishnu Nair132ee832018-09-28 15:00:05 -0700197 private int startingWindowDelayMs = INVALID_DELAY;
198 private int bindApplicationDelayMs = INVALID_DELAY;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800199 private int reason = APP_TRANSITION_TIMEOUT;
200 private boolean loggedWindowsDrawn;
201 private boolean loggedStartingWindowDrawn;
Vishnu Nair132ee832018-09-28 15:00:05 -0700202 private boolean launchTraceActive;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800203 }
204
Vishnu Nair132ee832018-09-28 15:00:05 -0700205 final class WindowingModeTransitionInfoSnapshot {
Calin Juravle759fbda2018-02-20 19:52:30 +0000206 final private ApplicationInfo applicationInfo;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700207 final private WindowProcessController processRecord;
Vishnu Nair132ee832018-09-28 15:00:05 -0700208 final String packageName;
209 final String launchedActivityName;
Calin Juravle759fbda2018-02-20 19:52:30 +0000210 final private String launchedActivityLaunchedFromPackage;
211 final private String launchedActivityLaunchToken;
212 final private String launchedActivityAppRecordRequiredAbi;
Vishnu Nair132ee832018-09-28 15:00:05 -0700213 final String launchedActivityShortComponentName;
Ng Zhi An83473542018-02-20 09:02:14 -0800214 final private String processName;
Calin Juravle759fbda2018-02-20 19:52:30 +0000215 final private int reason;
216 final private int startingWindowDelayMs;
217 final private int bindApplicationDelayMs;
Vishnu Nair132ee832018-09-28 15:00:05 -0700218 final int windowsDrawnDelayMs;
219 final int type;
220 final int userId;
221 /**
222 * Elapsed time from when we launch an activity to when the app reported it was
223 * fully drawn. If this is not reported then the value is set to INVALID_DELAY.
224 */
225 final int windowsFullyDrawnDelayMs;
226 final int activityRecordIdHashCode;
Calin Juravle759fbda2018-02-20 19:52:30 +0000227
228 private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info) {
Vishnu Nair132ee832018-09-28 15:00:05 -0700229 this(info, info.launchedActivity);
230 }
231
232 private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info,
233 ActivityRecord launchedActivity) {
234 this(info, launchedActivity, INVALID_DELAY);
235 }
236
237 private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info,
238 ActivityRecord launchedActivity, int windowsFullyDrawnDelayMs) {
239 applicationInfo = launchedActivity.appInfo;
240 packageName = launchedActivity.packageName;
241 launchedActivityName = launchedActivity.info.name;
242 launchedActivityLaunchedFromPackage = launchedActivity.launchedFromPackage;
243 launchedActivityLaunchToken = launchedActivity.info.launchToken;
244 launchedActivityAppRecordRequiredAbi = launchedActivity.app == null
Calin Juravle759fbda2018-02-20 19:52:30 +0000245 ? null
Vishnu Nairaf0ea312018-10-15 16:23:55 -0700246 : launchedActivity.app.getRequiredAbi();
Calin Juravle759fbda2018-02-20 19:52:30 +0000247 reason = info.reason;
248 startingWindowDelayMs = info.startingWindowDelayMs;
249 bindApplicationDelayMs = info.bindApplicationDelayMs;
250 windowsDrawnDelayMs = info.windowsDrawnDelayMs;
251 type = getTransitionType(info);
Vishnu Nairaf0ea312018-10-15 16:23:55 -0700252 processRecord = findProcessForActivity(launchedActivity);
253 processName = launchedActivity.processName;
Vishnu Nair132ee832018-09-28 15:00:05 -0700254 userId = launchedActivity.userId;
255 launchedActivityShortComponentName = launchedActivity.shortComponentName;
256 activityRecordIdHashCode = System.identityHashCode(launchedActivity);
257 this.windowsFullyDrawnDelayMs = windowsFullyDrawnDelayMs;
Calin Juravle759fbda2018-02-20 19:52:30 +0000258 }
259 }
260
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200261 ActivityMetricsLogger(ActivityStackSupervisor supervisor, Context context, Looper looper) {
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800262 mLastLogTimeSecs = SystemClock.elapsedRealtime() / 1000;
263 mSupervisor = supervisor;
264 mContext = context;
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200265 mHandler = new H(looper);
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800266 }
267
268 void logWindowState() {
269 final long now = SystemClock.elapsedRealtime() / 1000;
270 if (mWindowState != WINDOW_STATE_INVALID) {
271 // We log even if the window state hasn't changed, because the user might remain in
272 // home/fullscreen move forever and we would like to track this kind of behavior
273 // too.
274 MetricsLogger.count(mContext, TRON_WINDOW_STATE_VARZ_STRINGS[mWindowState],
275 (int) (now - mLastLogTimeSecs));
276 }
277 mLastLogTimeSecs = now;
278
Wale Ogunwale926aade2017-08-29 11:24:37 -0700279 mWindowState = WINDOW_STATE_INVALID;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800280 ActivityStack stack =
281 mSupervisor.mRootActivityContainer.getTopDisplayFocusedStack();
lumarkf6c4a982018-06-15 15:43:12 +0800282 if (stack == null) {
283 return;
284 }
285
Wale Ogunwale926aade2017-08-29 11:24:37 -0700286 if (stack.isActivityTypeAssistant()) {
287 mWindowState = WINDOW_STATE_ASSISTANT;
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800288 return;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800289 }
Wale Ogunwale926aade2017-08-29 11:24:37 -0700290
Igor Murashkin212d06c2018-10-22 16:34:39 -0700291 @WindowingMode int windowingMode = stack.getWindowingMode();
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700292 if (windowingMode == WINDOWING_MODE_PINNED) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800293 stack = mSupervisor.mRootActivityContainer.findStackBehind(stack);
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700294 windowingMode = stack.getWindowingMode();
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800295 }
Wale Ogunwale926aade2017-08-29 11:24:37 -0700296 switch (windowingMode) {
297 case WINDOWING_MODE_FULLSCREEN:
298 mWindowState = WINDOW_STATE_STANDARD;
299 break;
300 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
301 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
302 mWindowState = WINDOW_STATE_SIDE_BY_SIDE;
303 break;
Bryce Lee6c605092017-10-12 11:14:49 -0700304 case WINDOWING_MODE_FREEFORM:
Wale Ogunwale926aade2017-08-29 11:24:37 -0700305 mWindowState = WINDOW_STATE_FREEFORM;
306 break;
307 default:
308 if (windowingMode != WINDOWING_MODE_UNDEFINED) {
309 throw new IllegalStateException("Unknown windowing mode for stack=" + stack
310 + " windowingMode=" + windowingMode);
311 }
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800312 }
313 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500314
315 /**
316 * Notifies the tracker at the earliest possible point when we are starting to launch an
317 * activity.
318 */
Igor Murashkin212d06c2018-10-22 16:34:39 -0700319 void notifyActivityLaunching(Intent intent) {
320 if (DEBUG_METRICS) {
321 Slog.i(TAG, String.format("notifyActivityLaunching: active:%b, intent:%s",
322 isAnyTransitionActive(),
323 intent));
324 }
325
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800326 if (!isAnyTransitionActive()) {
Igor Murashkin212d06c2018-10-22 16:34:39 -0700327
Alison Cichowlasb7f67ab2017-04-25 18:04:40 -0400328 mCurrentTransitionStartTime = SystemClock.uptimeMillis();
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200329 mLastTransitionStartTime = mCurrentTransitionStartTime;
Igor Murashkin212d06c2018-10-22 16:34:39 -0700330
331 launchObserverNotifyIntentStarted(intent);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800332 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500333 }
334
335 /**
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700336 * Notifies the tracker that the activity is actually launching.
337 *
338 * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the
339 * launch
340 * @param launchedActivity the activity that is being launched
341 */
342 void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity) {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700343 final WindowProcessController processRecord = findProcessForActivity(launchedActivity);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700344 final boolean processRunning = processRecord != null;
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700345
346 // We consider this a "process switch" if the process of the activity that gets launched
347 // didn't have an activity that was in started state. In this case, we assume that lot
348 // of caches might be purged so the time until it produces the first frame is very
349 // interesting.
350 final boolean processSwitch = processRecord == null
Wale Ogunwalef6733932018-06-27 05:14:34 -0700351 || !processRecord.hasStartedActivity(launchedActivity);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700352
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800353 notifyActivityLaunched(resultCode, launchedActivity, processRunning, processSwitch);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700354 }
355
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700356 /**
Jorim Jaggi275561a2016-02-23 10:11:02 -0500357 * Notifies the tracker the the activity is actually launching.
358 *
359 * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the
360 * launch
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800361 * @param launchedActivity the activity being launched
Jorim Jaggi275561a2016-02-23 10:11:02 -0500362 * @param processRunning whether the process that will contains the activity is already running
Jorim Jaggibe67c902016-04-12 00:53:16 -0700363 * @param processSwitch whether the process that will contain the activity didn't have any
364 * activity that was stopped, i.e. the started activity is "switching"
365 * processes
Jorim Jaggi275561a2016-02-23 10:11:02 -0500366 */
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800367 private void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity,
Jorim Jaggibe67c902016-04-12 00:53:16 -0700368 boolean processRunning, boolean processSwitch) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500369
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200370 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched"
371 + " resultCode=" + resultCode
372 + " launchedActivity=" + launchedActivity
373 + " processRunning=" + processRunning
374 + " processSwitch=" + processSwitch);
375
Igor Murashkin212d06c2018-10-22 16:34:39 -0700376 // If we are already in an existing transition, only update the activity name, but not the
377 // other attributes.
378 final @WindowingMode int windowingMode = launchedActivity != null
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100379 ? launchedActivity.getWindowingMode()
380 : WINDOWING_MODE_UNDEFINED;
Vishnu Nairf8accc52018-10-11 10:19:54 -0700381 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200382 if (mCurrentTransitionStartTime == INVALID_START_TIME) {
Vishnu Nairf8accc52018-10-11 10:19:54 -0700383 // No transition is active ignore this launch.
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200384 return;
385 }
386
Vishnu Nair9ba31652018-11-13 14:34:05 -0800387 if (launchedActivity != null && launchedActivity.mDrawn) {
Vishnu Nairf8accc52018-10-11 10:19:54 -0700388 // Launched activity is already visible. We cannot measure windows drawn delay.
Igor Murashkin212d06c2018-10-22 16:34:39 -0700389 reset(true /* abort */, info, "launched activity already visible");
Vishnu Nairf8accc52018-10-11 10:19:54 -0700390 return;
391 }
392
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800393 if (launchedActivity != null && info != null) {
Vishnu Nairf8accc52018-10-11 10:19:54 -0700394 // If we are already in an existing transition, only update the activity name, but not
395 // the other attributes.
Igor Murashkin212d06c2018-10-22 16:34:39 -0700396
397 // Coalesce multiple (trampoline) activities from a single sequence together.
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800398 info.launchedActivity = launchedActivity;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500399 return;
400 }
401
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100402 final boolean otherWindowModesLaunching =
403 mWindowingModeTransitionInfo.size() > 0 && info == null;
Jorim Jaggi54cff642018-03-15 15:51:32 +0100404 if ((!isLoggableResultCode(resultCode) || launchedActivity == null || !processSwitch
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100405 || windowingMode == WINDOWING_MODE_UNDEFINED) && !otherWindowModesLaunching) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800406 // Failed to launch or it was not a process switch, so we don't care about the timing.
Igor Murashkin212d06c2018-10-22 16:34:39 -0700407 reset(true /* abort */, info, "failed to launch or not a process switch");
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800408 return;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100409 } else if (otherWindowModesLaunching) {
410 // Don't log this windowing mode but continue with the other windowing modes.
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800411 return;
412 }
413
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200414 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched successful");
415
Igor Murashkin212d06c2018-10-22 16:34:39 -0700416 // A new launch sequence [with the windowingMode] has begun.
417 // Start tracking it.
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100418 final WindowingModeTransitionInfo newInfo = new WindowingModeTransitionInfo();
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800419 newInfo.launchedActivity = launchedActivity;
420 newInfo.currentTransitionProcessRunning = processRunning;
421 newInfo.startResult = resultCode;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100422 mWindowingModeTransitionInfo.put(windowingMode, newInfo);
423 mLastWindowingModeTransitionInfo.put(windowingMode, newInfo);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800424 mCurrentTransitionDeviceUptime = (int) (SystemClock.uptimeMillis() / 1000);
Vishnu Nair132ee832018-09-28 15:00:05 -0700425 startTraces(newInfo);
Igor Murashkin212d06c2018-10-22 16:34:39 -0700426 launchObserverNotifyActivityLaunched(newInfo);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500427 }
428
429 /**
Jorim Jaggi54cff642018-03-15 15:51:32 +0100430 * @return True if we should start logging an event for an activity start that returned
431 * {@code resultCode} and that we'll indeed get a windows drawn event.
432 */
433 private boolean isLoggableResultCode(int resultCode) {
434 return resultCode == START_SUCCESS || resultCode == START_TASK_TO_FRONT;
435 }
436
437 /**
Jorim Jaggi275561a2016-02-23 10:11:02 -0500438 * Notifies the tracker that all windows of the app have been drawn.
439 */
Igor Murashkin212d06c2018-10-22 16:34:39 -0700440 WindowingModeTransitionInfoSnapshot notifyWindowsDrawn(@WindowingMode int windowingMode,
441 long timestamp) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100442 if (DEBUG_METRICS) Slog.i(TAG, "notifyWindowsDrawn windowingMode=" + windowingMode);
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200443
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100444 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800445 if (info == null || info.loggedWindowsDrawn) {
Vishnu Nair132ee832018-09-28 15:00:05 -0700446 return null;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500447 }
Sudheer Shankac766db02017-06-12 10:37:29 -0700448 info.windowsDrawnDelayMs = calculateDelay(timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800449 info.loggedWindowsDrawn = true;
Vishnu Nair132ee832018-09-28 15:00:05 -0700450 final WindowingModeTransitionInfoSnapshot infoSnapshot =
451 new WindowingModeTransitionInfoSnapshot(info);
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100452 if (allWindowsDrawn() && mLoggedTransitionStarting) {
Igor Murashkin212d06c2018-10-22 16:34:39 -0700453 reset(false /* abort */, info, "notifyWindowsDrawn - all windows drawn");
Jorim Jaggi275561a2016-02-23 10:11:02 -0500454 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700455 return infoSnapshot;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500456 }
457
458 /**
459 * Notifies the tracker that the starting window was drawn.
460 */
Igor Murashkin212d06c2018-10-22 16:34:39 -0700461 void notifyStartingWindowDrawn(@WindowingMode int windowingMode, long timestamp) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100462 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800463 if (info == null || info.loggedStartingWindowDrawn) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500464 return;
465 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800466 info.loggedStartingWindowDrawn = true;
Sudheer Shankac766db02017-06-12 10:37:29 -0700467 info.startingWindowDelayMs = calculateDelay(timestamp);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500468 }
469
470 /**
471 * Notifies the tracker that the app transition is starting.
472 *
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100473 * @param windowingModeToReason A map from windowing mode to a reason integer, which must be on
Vishnu Nair132ee832018-09-28 15:00:05 -0700474 * of ActivityTaskManagerInternal.APP_TRANSITION_* reasons.
Jorim Jaggi275561a2016-02-23 10:11:02 -0500475 */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100476 void notifyTransitionStarting(SparseIntArray windowingModeToReason, long timestamp) {
Jorim Jaggid8a57772017-04-14 16:50:42 -0700477 if (!isAnyTransitionActive() || mLoggedTransitionStarting) {
Igor Murashkin212d06c2018-10-22 16:34:39 -0700478 // Ignore calls to this made after a reset and prior to notifyActivityLaunching.
479
480 // Ignore any subsequent notifyTransitionStarting until the next reset.
Jorim Jaggi275561a2016-02-23 10:11:02 -0500481 return;
482 }
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200483 if (DEBUG_METRICS) Slog.i(TAG, "notifyTransitionStarting");
Sudheer Shankac766db02017-06-12 10:37:29 -0700484 mCurrentTransitionDelayMs = calculateDelay(timestamp);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500485 mLoggedTransitionStarting = true;
Igor Murashkin212d06c2018-10-22 16:34:39 -0700486
487 WindowingModeTransitionInfo foundInfo = null;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100488 for (int index = windowingModeToReason.size() - 1; index >= 0; index--) {
Igor Murashkin212d06c2018-10-22 16:34:39 -0700489 final @WindowingMode int windowingMode = windowingModeToReason.keyAt(index);
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100490 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
491 windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800492 if (info == null) {
493 continue;
494 }
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100495 info.reason = windowingModeToReason.valueAt(index);
Igor Murashkin212d06c2018-10-22 16:34:39 -0700496 foundInfo = info;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800497 }
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100498 if (allWindowsDrawn()) {
Vishnu Naira62534b2018-11-09 09:13:22 -0800499 // abort metrics collection if we cannot find a matching transition.
500 final boolean abortMetrics = foundInfo == null;
501 reset(abortMetrics, foundInfo, "notifyTransitionStarting - all windows drawn");
Jorim Jaggi275561a2016-02-23 10:11:02 -0500502 }
503 }
504
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200505 /**
506 * Notifies the tracker that the visibility of an app is changing.
507 *
508 * @param activityRecord the app that is changing its visibility
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200509 */
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200510 void notifyVisibilityChanged(ActivityRecord activityRecord) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100511 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
512 activityRecord.getWindowingMode());
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200513 if (info == null) {
514 return;
515 }
516 if (info.launchedActivity != activityRecord) {
517 return;
518 }
519 final TaskRecord t = activityRecord.getTask();
520 final SomeArgs args = SomeArgs.obtain();
521 args.arg1 = t;
522 args.arg2 = activityRecord;
523 mHandler.obtainMessage(MSG_CHECK_VISIBILITY, args).sendToTarget();
524 }
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200525
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200526 private void checkVisibility(TaskRecord t, ActivityRecord r) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700527 synchronized (mSupervisor.mService.mGlobalLock) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200528
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100529 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
530 r.getWindowingMode());
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200531
532 // If we have an active transition that's waiting on a certain activity that will be
533 // invisible now, we'll never get onWindowsDrawn, so abort the transition if necessary.
534 if (info != null && !t.isVisible()) {
535 if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible"
536 + " activity=" + r);
537 logAppTransitionCancel(info);
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100538 mWindowingModeTransitionInfo.remove(r.getWindowingMode());
539 if (mWindowingModeTransitionInfo.size() == 0) {
Igor Murashkin212d06c2018-10-22 16:34:39 -0700540 reset(true /* abort */, info, "notifyVisibilityChanged to invisible");
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200541 }
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200542 }
543 }
544 }
545
Jorim Jaggi515dd682017-05-05 15:05:07 +0200546 /**
547 * Notifies the tracker that we called immediately before we call bindApplication on the client.
548 *
Wale Ogunwale31913b52018-10-13 08:29:31 -0700549 * @param appInfo The client into which we'll call bindApplication.
Jorim Jaggi515dd682017-05-05 15:05:07 +0200550 */
Wale Ogunwale31913b52018-10-13 08:29:31 -0700551 void notifyBindApplication(ApplicationInfo appInfo) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100552 for (int i = mWindowingModeTransitionInfo.size() - 1; i >= 0; i--) {
553 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(i);
Jorim Jaggi515dd682017-05-05 15:05:07 +0200554
555 // App isn't attached to record yet, so match with info.
Wale Ogunwale31913b52018-10-13 08:29:31 -0700556 if (info.launchedActivity.appInfo == appInfo) {
Jorim Jaggi515dd682017-05-05 15:05:07 +0200557 info.bindApplicationDelayMs = calculateCurrentDelay();
558 }
559 }
560 }
561
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100562 private boolean allWindowsDrawn() {
563 for (int index = mWindowingModeTransitionInfo.size() - 1; index >= 0; index--) {
564 if (!mWindowingModeTransitionInfo.valueAt(index).loggedWindowsDrawn) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800565 return false;
566 }
567 }
568 return true;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500569 }
570
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800571 private boolean isAnyTransitionActive() {
572 return mCurrentTransitionStartTime != INVALID_START_TIME
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100573 && mWindowingModeTransitionInfo.size() > 0;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800574 }
575
Igor Murashkin212d06c2018-10-22 16:34:39 -0700576 private void reset(boolean abort, WindowingModeTransitionInfo info, String cause) {
577 if (DEBUG_METRICS) Slog.i(TAG, "reset abort=" + abort + ",cause=" + cause);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800578 if (!abort && isAnyTransitionActive()) {
579 logAppTransitionMultiEvents();
580 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700581 stopLaunchTrace(info);
Igor Murashkin212d06c2018-10-22 16:34:39 -0700582
583 // Ignore reset-after reset.
584 if (isAnyTransitionActive()) {
585 // LaunchObserver callbacks.
586 if (abort) {
587 launchObserverNotifyActivityLaunchCancelled(info);
588 } else {
589 launchObserverNotifyActivityLaunchFinished(info);
590 }
591 } else {
592 launchObserverNotifyIntentFailed();
593 }
594
Jorim Jaggi275561a2016-02-23 10:11:02 -0500595 mCurrentTransitionStartTime = INVALID_START_TIME;
Vishnu Nair132ee832018-09-28 15:00:05 -0700596 mCurrentTransitionDelayMs = INVALID_DELAY;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500597 mLoggedTransitionStarting = false;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100598 mWindowingModeTransitionInfo.clear();
Jorim Jaggi275561a2016-02-23 10:11:02 -0500599 }
600
601 private int calculateCurrentDelay() {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500602 // Shouldn't take more than 25 days to launch an app, so int is fine here.
Alison Cichowlasb7f67ab2017-04-25 18:04:40 -0400603 return (int) (SystemClock.uptimeMillis() - mCurrentTransitionStartTime);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500604 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800605
Sudheer Shankac766db02017-06-12 10:37:29 -0700606 private int calculateDelay(long timestamp) {
607 // Shouldn't take more than 25 days to launch an app, so int is fine here.
608 return (int) (timestamp - mCurrentTransitionStartTime);
609 }
610
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100611 private void logAppTransitionCancel(WindowingModeTransitionInfo info) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200612 final int type = getTransitionType(info);
Vishnu Nair132ee832018-09-28 15:00:05 -0700613 if (type == INVALID_TRANSITION_TYPE) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200614 return;
615 }
616 final LogMaker builder = new LogMaker(APP_TRANSITION_CANCELLED);
617 builder.setPackageName(info.launchedActivity.packageName);
618 builder.setType(type);
619 builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivity.info.name);
620 mMetricsLogger.write(builder);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000621 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800622 StatsLog.APP_START_CANCELED,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000623 info.launchedActivity.appInfo.uid,
624 info.launchedActivity.packageName,
625 convertAppStartTransitionType(type),
626 info.launchedActivity.info.name);
Igor Murashkin212d06c2018-10-22 16:34:39 -0700627 if (DEBUG_METRICS) {
628 Slog.i(TAG, String.format("APP_START_CANCELED(%s, %s, %s, %s)",
629 info.launchedActivity.appInfo.uid,
630 info.launchedActivity.packageName,
631 convertAppStartTransitionType(type),
632 info.launchedActivity.info.name));
633 }
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200634 }
635
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800636 private void logAppTransitionMultiEvents() {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200637 if (DEBUG_METRICS) Slog.i(TAG, "logging transition events");
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100638 for (int index = mWindowingModeTransitionInfo.size() - 1; index >= 0; index--) {
639 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(index);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800640 final int type = getTransitionType(info);
Vishnu Nair132ee832018-09-28 15:00:05 -0700641 if (type == INVALID_TRANSITION_TYPE) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800642 return;
643 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000644
645 // Take a snapshot of the transition info before sending it to the handler for logging.
646 // This will avoid any races with other operations that modify the ActivityRecord.
647 final WindowingModeTransitionInfoSnapshot infoSnapshot =
648 new WindowingModeTransitionInfoSnapshot(info);
Ng Zhi An83473542018-02-20 09:02:14 -0800649 final int currentTransitionDeviceUptime = mCurrentTransitionDeviceUptime;
650 final int currentTransitionDelayMs = mCurrentTransitionDelayMs;
651 BackgroundThread.getHandler().post(() -> logAppTransition(
652 currentTransitionDeviceUptime, currentTransitionDelayMs, infoSnapshot));
Vishnu Nair132ee832018-09-28 15:00:05 -0700653 BackgroundThread.getHandler().post(() -> logAppDisplayed(infoSnapshot));
Calin Juravle759fbda2018-02-20 19:52:30 +0000654
655 info.launchedActivity.info.launchToken = null;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800656 }
657 }
658
Ng Zhi An83473542018-02-20 09:02:14 -0800659 // This gets called on a background thread without holding the activity manager lock.
Calin Juravle759fbda2018-02-20 19:52:30 +0000660 private void logAppTransition(int currentTransitionDeviceUptime, int currentTransitionDelayMs,
661 WindowingModeTransitionInfoSnapshot info) {
662 final LogMaker builder = new LogMaker(APP_TRANSITION);
663 builder.setPackageName(info.packageName);
664 builder.setType(info.type);
665 builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivityName);
666 final boolean isInstantApp = info.applicationInfo.isInstantApp();
667 if (info.launchedActivityLaunchedFromPackage != null) {
668 builder.addTaggedData(APP_TRANSITION_CALLING_PACKAGE_NAME,
669 info.launchedActivityLaunchedFromPackage);
670 }
671 String launchToken = info.launchedActivityLaunchToken;
672 if (launchToken != null) {
673 builder.addTaggedData(FIELD_INSTANT_APP_LAUNCH_TOKEN, launchToken);
674 }
675 builder.addTaggedData(APP_TRANSITION_IS_EPHEMERAL, isInstantApp ? 1 : 0);
676 builder.addTaggedData(APP_TRANSITION_DEVICE_UPTIME_SECONDS,
677 currentTransitionDeviceUptime);
678 builder.addTaggedData(APP_TRANSITION_DELAY_MS, currentTransitionDelayMs);
679 builder.setSubtype(info.reason);
Vishnu Nair132ee832018-09-28 15:00:05 -0700680 if (info.startingWindowDelayMs != INVALID_DELAY) {
Calin Juravle759fbda2018-02-20 19:52:30 +0000681 builder.addTaggedData(APP_TRANSITION_STARTING_WINDOW_DELAY_MS,
682 info.startingWindowDelayMs);
683 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700684 if (info.bindApplicationDelayMs != INVALID_DELAY) {
Calin Juravle759fbda2018-02-20 19:52:30 +0000685 builder.addTaggedData(APP_TRANSITION_BIND_APPLICATION_DELAY_MS,
686 info.bindApplicationDelayMs);
687 }
688 builder.addTaggedData(APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, info.windowsDrawnDelayMs);
689 final ArtManagerInternal artManagerInternal = getArtManagerInternal();
690 final PackageOptimizationInfo packageOptimizationInfo =
691 (artManagerInternal == null) || (info.launchedActivityAppRecordRequiredAbi == null)
692 ? PackageOptimizationInfo.createWithNoInfo()
693 : artManagerInternal.getPackageOptimizationInfo(
694 info.applicationInfo,
695 info.launchedActivityAppRecordRequiredAbi);
696 builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_REASON,
697 packageOptimizationInfo.getCompilationReason());
698 builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_FILTER,
699 packageOptimizationInfo.getCompilationFilter());
700 mMetricsLogger.write(builder);
701 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800702 StatsLog.APP_START_OCCURRED,
Calin Juravle759fbda2018-02-20 19:52:30 +0000703 info.applicationInfo.uid,
704 info.packageName,
705 convertAppStartTransitionType(info.type),
706 info.launchedActivityName,
707 info.launchedActivityLaunchedFromPackage,
708 isInstantApp,
709 currentTransitionDeviceUptime * 1000,
710 info.reason,
711 currentTransitionDelayMs,
712 info.startingWindowDelayMs,
713 info.bindApplicationDelayMs,
714 info.windowsDrawnDelayMs,
715 launchToken,
716 packageOptimizationInfo.getCompilationReason(),
717 packageOptimizationInfo.getCompilationFilter());
Igor Murashkin212d06c2018-10-22 16:34:39 -0700718
719 if (DEBUG_METRICS) {
720 Slog.i(TAG, String.format("APP_START_OCCURRED(%s, %s, %s, %s, %s)",
721 info.applicationInfo.uid,
722 info.packageName,
723 convertAppStartTransitionType(info.type),
724 info.launchedActivityName,
725 info.launchedActivityLaunchedFromPackage));
726 }
727
728
Ng Zhi An83473542018-02-20 09:02:14 -0800729 logAppStartMemoryStateCapture(info);
Calin Juravle759fbda2018-02-20 19:52:30 +0000730 }
731
Vishnu Nair132ee832018-09-28 15:00:05 -0700732 private void logAppDisplayed(WindowingModeTransitionInfoSnapshot info) {
733 if (info.type != TYPE_TRANSITION_WARM_LAUNCH && info.type != TYPE_TRANSITION_COLD_LAUNCH) {
734 return;
735 }
736
737 EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
738 info.userId, info.activityRecordIdHashCode, info.launchedActivityShortComponentName,
739 info.windowsDrawnDelayMs);
740
741 StringBuilder sb = mStringBuilder;
742 sb.setLength(0);
743 sb.append("Displayed ");
744 sb.append(info.launchedActivityShortComponentName);
745 sb.append(": ");
746 TimeUtils.formatDuration(info.windowsDrawnDelayMs, sb);
747 Log.i(TAG, sb.toString());
748 }
749
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000750 private int convertAppStartTransitionType(int tronType) {
751 if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800752 return StatsLog.APP_START_OCCURRED__TYPE__COLD;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000753 }
754 if (tronType == TYPE_TRANSITION_WARM_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800755 return StatsLog.APP_START_OCCURRED__TYPE__WARM;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000756 }
757 if (tronType == TYPE_TRANSITION_HOT_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800758 return StatsLog.APP_START_OCCURRED__TYPE__HOT;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000759 }
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800760 return StatsLog.APP_START_OCCURRED__TYPE__UNKNOWN;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000761 }
762
Vishnu Nair132ee832018-09-28 15:00:05 -0700763 WindowingModeTransitionInfoSnapshot logAppTransitionReportedDrawn(ActivityRecord r,
764 boolean restoredFromBundle) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100765 final WindowingModeTransitionInfo info = mLastWindowingModeTransitionInfo.get(
766 r.getWindowingMode());
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200767 if (info == null) {
Vishnu Nair132ee832018-09-28 15:00:05 -0700768 return null;
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200769 }
Chris Wailes35c193c2018-10-09 18:12:00 -0700770
771 // Record the handling of the reportFullyDrawn callback in the trace system. This is not
772 // actually used to trace this function, but instead the logical task that this function
773 // fullfils (handling reportFullyDrawn() callbacks).
774 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
775 "ActivityManager:ReportingFullyDrawn " + info.launchedActivity.packageName);
776
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200777 final LogMaker builder = new LogMaker(APP_TRANSITION_REPORTED_DRAWN);
778 builder.setPackageName(r.packageName);
779 builder.addTaggedData(FIELD_CLASS_NAME, r.info.name);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000780 long startupTimeMs = SystemClock.uptimeMillis() - mLastTransitionStartTime;
781 builder.addTaggedData(APP_TRANSITION_REPORTED_DRAWN_MS, startupTimeMs);
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200782 builder.setType(restoredFromBundle
783 ? TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE
784 : TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE);
785 builder.addTaggedData(APP_TRANSITION_PROCESS_RUNNING,
786 info.currentTransitionProcessRunning ? 1 : 0);
787 mMetricsLogger.write(builder);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000788 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800789 StatsLog.APP_START_FULLY_DRAWN,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000790 info.launchedActivity.appInfo.uid,
791 info.launchedActivity.packageName,
792 restoredFromBundle
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800793 ? StatsLog.APP_START_FULLY_DRAWN__TYPE__WITH_BUNDLE
794 : StatsLog.APP_START_FULLY_DRAWN__TYPE__WITHOUT_BUNDLE,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000795 info.launchedActivity.info.name,
796 info.currentTransitionProcessRunning,
797 startupTimeMs);
Chris Wailes35c193c2018-10-09 18:12:00 -0700798
799 // Ends the trace started at the beginning of this function. This is located here to allow
800 // the trace slice to have a noticable duration.
801 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
802
Vishnu Nair132ee832018-09-28 15:00:05 -0700803 final WindowingModeTransitionInfoSnapshot infoSnapshot =
804 new WindowingModeTransitionInfoSnapshot(info, r, (int) startupTimeMs);
805 BackgroundThread.getHandler().post(() -> logAppFullyDrawn(infoSnapshot));
806 return infoSnapshot;
807 }
808
809 private void logAppFullyDrawn(WindowingModeTransitionInfoSnapshot info) {
810 if (info.type != TYPE_TRANSITION_WARM_LAUNCH && info.type != TYPE_TRANSITION_COLD_LAUNCH) {
811 return;
812 }
813
814 StringBuilder sb = mStringBuilder;
815 sb.setLength(0);
816 sb.append("Fully drawn ");
817 sb.append(info.launchedActivityShortComponentName);
818 sb.append(": ");
819 TimeUtils.formatDuration(info.windowsFullyDrawnDelayMs, sb);
820 Log.i(TAG, sb.toString());
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200821 }
822
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700823 void logActivityStart(Intent intent, WindowProcessController callerApp, ActivityRecord r,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100824 int callingUid, String callingPackage, int callingUidProcState,
825 boolean callingUidHasAnyVisibleWindow,
826 int realCallingUid, int realCallingUidProcState,
827 boolean realCallingUidHasAnyVisibleWindow,
828 int targetUid, String targetPackage, int targetUidProcState,
829 boolean targetUidHasAnyVisibleWindow, String targetWhitelistTag,
830 boolean comingFromPendingIntent) {
831
832 final long nowElapsed = SystemClock.elapsedRealtime();
833 final long nowUptime = SystemClock.uptimeMillis();
834 final LogMaker builder = new LogMaker(ACTION_ACTIVITY_START);
835 builder.setTimestamp(System.currentTimeMillis());
836 builder.addTaggedData(FIELD_CALLING_UID, callingUid);
837 builder.addTaggedData(FIELD_CALLING_PACKAGE_NAME, callingPackage);
838 builder.addTaggedData(FIELD_CALLING_UID_PROC_STATE,
839 processStateAmToProto(callingUidProcState));
840 builder.addTaggedData(FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
841 callingUidHasAnyVisibleWindow ? 1 : 0);
842 builder.addTaggedData(FIELD_REAL_CALLING_UID, realCallingUid);
843 builder.addTaggedData(FIELD_REAL_CALLING_UID_PROC_STATE,
844 processStateAmToProto(realCallingUidProcState));
845 builder.addTaggedData(FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
846 realCallingUidHasAnyVisibleWindow ? 1 : 0);
847 builder.addTaggedData(FIELD_TARGET_UID, targetUid);
848 builder.addTaggedData(FIELD_TARGET_PACKAGE_NAME, targetPackage);
849 builder.addTaggedData(FIELD_TARGET_UID_PROC_STATE,
850 processStateAmToProto(targetUidProcState));
851 builder.addTaggedData(FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW,
852 targetUidHasAnyVisibleWindow ? 1 : 0);
853 builder.addTaggedData(FIELD_TARGET_WHITELIST_TAG, targetWhitelistTag);
854 builder.addTaggedData(FIELD_TARGET_SHORT_COMPONENT_NAME, r.shortComponentName);
855 builder.addTaggedData(FIELD_COMING_FROM_PENDING_INTENT, comingFromPendingIntent ? 1 : 0);
856 builder.addTaggedData(FIELD_INTENT_ACTION, intent.getAction());
857 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700858 builder.addTaggedData(FIELD_PROCESS_RECORD_PROCESS_NAME, callerApp.mName);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100859 builder.addTaggedData(FIELD_PROCESS_RECORD_CUR_PROC_STATE,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700860 processStateAmToProto(callerApp.getCurrentProcState()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100861 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700862 callerApp.hasClientActivities() ? 1 : 0);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100863 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES,
864 callerApp.hasForegroundServices() ? 1 : 0);
865 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700866 callerApp.hasForegroundActivities() ? 1 : 0);
867 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_TOP_UI, callerApp.hasTopUi() ? 1 : 0);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100868 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_OVERLAY_UI,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700869 callerApp.hasOverlayUi() ? 1 : 0);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100870 builder.addTaggedData(FIELD_PROCESS_RECORD_PENDING_UI_CLEAN,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700871 callerApp.hasPendingUiClean() ? 1 : 0);
872 if (callerApp.getInteractionEventTime() != 0) {
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100873 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700874 (nowElapsed - callerApp.getInteractionEventTime()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100875 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700876 if (callerApp.getFgInteractionTime() != 0) {
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100877 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700878 (nowElapsed - callerApp.getFgInteractionTime()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100879 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700880 if (callerApp.getWhenUnimportant() != 0) {
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100881 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700882 (nowUptime - callerApp.getWhenUnimportant()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100883 }
884 }
885 builder.addTaggedData(FIELD_ACTIVITY_RECORD_LAUNCH_MODE, r.info.launchMode);
886 builder.addTaggedData(FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY, r.info.targetActivity);
887 builder.addTaggedData(FIELD_ACTIVITY_RECORD_FLAGS, r.info.flags);
888 builder.addTaggedData(FIELD_ACTIVITY_RECORD_REAL_ACTIVITY, r.realActivity.toShortString());
889 builder.addTaggedData(FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME, r.shortComponentName);
890 builder.addTaggedData(FIELD_ACTIVITY_RECORD_PROCESS_NAME, r.processName);
891 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_FULLSCREEN, r.fullscreen ? 1 : 0);
892 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY, r.noDisplay ? 1 : 0);
893 if (r.lastVisibleTime != 0) {
894 builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE,
895 (nowUptime - r.lastVisibleTime));
896 }
897 if (r.resultTo != null) {
898 builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME, r.resultTo.packageName);
899 builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME,
900 r.resultTo.shortComponentName);
901 }
902 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE, r.visible ? 1 : 0);
903 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD,
904 r.visibleIgnoringKeyguard ? 1 : 0);
905 if (r.lastLaunchTime != 0) {
906 builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH,
907 (nowUptime - r.lastLaunchTime));
908 }
909 mMetricsLogger.write(builder);
910 }
911
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100912 private int getTransitionType(WindowingModeTransitionInfo info) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800913 if (info.currentTransitionProcessRunning) {
914 if (info.startResult == START_SUCCESS) {
915 return TYPE_TRANSITION_WARM_LAUNCH;
916 } else if (info.startResult == START_TASK_TO_FRONT) {
917 return TYPE_TRANSITION_HOT_LAUNCH;
918 }
919 } else if (info.startResult == START_SUCCESS) {
920 return TYPE_TRANSITION_COLD_LAUNCH;
921 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700922 return INVALID_TRANSITION_TYPE;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800923 }
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800924
Ng Zhi An83473542018-02-20 09:02:14 -0800925 private void logAppStartMemoryStateCapture(WindowingModeTransitionInfoSnapshot info) {
926 if (info.processRecord == null) {
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800927 if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture processRecord null");
928 return;
929 }
930
Wale Ogunwalef6733932018-06-27 05:14:34 -0700931 final int pid = info.processRecord.getPid();
Ng Zhi An83473542018-02-20 09:02:14 -0800932 final int uid = info.applicationInfo.uid;
Rajeev Kumarbfcd9202018-03-02 22:42:13 +0000933 final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800934 if (memoryStat == null) {
935 if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture memoryStat null");
936 return;
937 }
938
939 StatsLog.write(
940 StatsLog.APP_START_MEMORY_STATE_CAPTURED,
941 uid,
Ng Zhi An83473542018-02-20 09:02:14 -0800942 info.processName,
943 info.launchedActivityName,
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800944 memoryStat.pgfault,
945 memoryStat.pgmajfault,
946 memoryStat.rssInBytes,
947 memoryStat.cacheInBytes,
948 memoryStat.swapInBytes);
949 }
950
Wale Ogunwalef6733932018-06-27 05:14:34 -0700951 private WindowProcessController findProcessForActivity(ActivityRecord launchedActivity) {
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800952 return launchedActivity != null
Wale Ogunwalef6733932018-06-27 05:14:34 -0700953 ? mSupervisor.mService.mProcessNames.get(
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700954 launchedActivity.processName, launchedActivity.appInfo.uid)
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800955 : null;
956 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000957
958 private ArtManagerInternal getArtManagerInternal() {
959 if (mArtManagerInternal == null) {
960 // Note that this may be null.
961 // ArtManagerInternal is registered during PackageManagerService
962 // initialization which happens after ActivityManagerService.
963 mArtManagerInternal = LocalServices.getService(ArtManagerInternal.class);
964 }
965 return mArtManagerInternal;
966 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700967
968 /**
Chris Wailes35c193c2018-10-09 18:12:00 -0700969 * Starts traces for app launch.
Vishnu Nair132ee832018-09-28 15:00:05 -0700970 *
971 * @param info
972 * */
973 private void startTraces(WindowingModeTransitionInfo info) {
974 if (info == null) {
975 return;
976 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700977 int transitionType = getTransitionType(info);
978 if (!info.launchTraceActive && transitionType == TYPE_TRANSITION_WARM_LAUNCH
979 || transitionType == TYPE_TRANSITION_COLD_LAUNCH) {
980 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: "
981 + info.launchedActivity.packageName, 0);
Vishnu Nair132ee832018-09-28 15:00:05 -0700982 info.launchTraceActive = true;
983 }
984 }
985
986 private void stopLaunchTrace(WindowingModeTransitionInfo info) {
987 if (info == null) {
988 return;
989 }
990 if (info.launchTraceActive) {
991 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: "
992 + info.launchedActivity.packageName, 0);
993 info.launchTraceActive = false;
994 }
995 }
Igor Murashkin212d06c2018-10-22 16:34:39 -0700996
997 /** Notify the {@link ActivityMetricsLaunchObserver} that a new launch sequence has begun. */
998 private void launchObserverNotifyIntentStarted(Intent intent) {
999 if (mLaunchObserver != null) {
1000 // Beginning a launch is timing sensitive and so should be observed as soon as possible.
1001 mLaunchObserver.onIntentStarted(intent);
1002 }
1003 }
1004
1005 /**
1006 * Notify the {@link ActivityMetricsLaunchObserver} that the previous launch sequence has
1007 * aborted due to intent failure (e.g. intent resolve failed or security error, etc) or
1008 * intent being delivered to the top running activity.
1009 */
1010 private void launchObserverNotifyIntentFailed() {
1011 if (mLaunchObserver != null) {
1012 mLaunchObserver.onIntentFailed();
1013 }
1014 }
1015
1016 /**
1017 * Notify the {@link ActivityMetricsLaunchObserver} that the current launch sequence's activity
1018 * has started.
1019 */
1020 private void launchObserverNotifyActivityLaunched(WindowingModeTransitionInfo info) {
1021 @ActivityMetricsLaunchObserver.Temperature int temperature =
1022 convertTransitionTypeToLaunchObserverTemperature(getTransitionType(info));
1023
1024 if (mLaunchObserver != null) {
1025 // Beginning a launch is timing sensitive and so should be observed as soon as possible.
1026 mLaunchObserver.onActivityLaunched(info.launchedActivity,
1027 temperature);
1028 }
1029 }
1030
1031 /**
1032 * Notify the {@link ActivityMetricsLaunchObserver} that the current launch sequence is
1033 * cancelled.
1034 */
1035 private void launchObserverNotifyActivityLaunchCancelled(WindowingModeTransitionInfo info) {
1036 final ActivityRecord launchedActivity = info != null ? info.launchedActivity : null;
1037
1038 if (mLaunchObserver != null) {
1039 mLaunchObserver.onActivityLaunchCancelled(launchedActivity);
1040 }
1041 }
1042
1043 /**
1044 * Notify the {@link ActivityMetricsLaunchObserver} that the current launch sequence's activity
1045 * has fully finished (successfully).
1046 */
1047 private void launchObserverNotifyActivityLaunchFinished(WindowingModeTransitionInfo info) {
1048 final ActivityRecord launchedActivity = info.launchedActivity;
1049
1050 if (mLaunchObserver != null) {
1051 mLaunchObserver.onActivityLaunchFinished(launchedActivity);
1052 }
1053 }
1054
1055 private static @ActivityMetricsLaunchObserver.Temperature int
1056 convertTransitionTypeToLaunchObserverTemperature(int transitionType) {
1057 switch (transitionType) {
1058 case TYPE_TRANSITION_WARM_LAUNCH:
1059 return ActivityMetricsLaunchObserver.TEMPERATURE_WARM;
1060 case TYPE_TRANSITION_HOT_LAUNCH:
1061 return ActivityMetricsLaunchObserver.TEMPERATURE_HOT;
1062 case TYPE_TRANSITION_COLD_LAUNCH:
1063 return ActivityMetricsLaunchObserver.TEMPERATURE_COLD;
1064 default:
1065 return -1;
1066 }
1067 }
Filip Gruszczynski77d94482015-12-11 13:59:52 -08001068}