blob: 8bde7dd92ed34a9dcb91cf5aef231e161cdef4df [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;
Wale Ogunwale59507092018-10-29 09:00:30 -070075import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_METRICS;
76import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
77import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Vishnu Nair132ee832018-09-28 15:00:05 -070078import static com.android.server.am.EventLogTags.AM_ACTIVITY_LAUNCH_TIME;
Ng Zhi Anbbefdec2018-01-30 17:12:39 -080079import static com.android.server.am.MemoryStatUtil.MemoryStat;
Rajeev Kumarbfcd9202018-03-02 22:42:13 +000080import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
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
Filip Gruszczynski77d94482015-12-11 13:59:52 -080083import android.content.Context;
Michal Karpinski201bc0c2018-07-20 15:32:00 +010084import android.content.Intent;
Calin Juravle759fbda2018-02-20 19:52:30 +000085import android.content.pm.ApplicationInfo;
86import android.content.pm.dex.ArtManagerInternal;
87import android.content.pm.dex.PackageOptimizationInfo;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080088import android.metrics.LogMaker;
Jorim Jaggi172e99f2017-10-20 14:33:18 +020089import android.os.Handler;
90import android.os.Looper;
91import android.os.Message;
Filip Gruszczynski77d94482015-12-11 13:59:52 -080092import android.os.SystemClock;
Vishnu Nair132ee832018-09-28 15:00:05 -070093import android.os.Trace;
94import android.util.EventLog;
95import android.util.Log;
Jorim Jaggi172e99f2017-10-20 14:33:18 +020096import android.util.Slog;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080097import android.util.SparseArray;
98import android.util.SparseIntArray;
Olivier Gaillardaed7f122017-12-12 14:26:22 +000099import android.util.StatsLog;
Vishnu Nair132ee832018-09-28 15:00:05 -0700100import android.util.TimeUtils;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800101
102import com.android.internal.logging.MetricsLogger;
Ng Zhi An83473542018-02-20 09:02:14 -0800103import com.android.internal.os.BackgroundThread;
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200104import com.android.internal.os.SomeArgs;
Calin Juravle759fbda2018-02-20 19:52:30 +0000105import com.android.server.LocalServices;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800106
107/**
Vishnu Nair132ee832018-09-28 15:00:05 -0700108 * Listens to activity launches, transitions, visibility changes and window drawn callbacks to
109 * determine app launch times and draw delays. Source of truth for activity metrics and provides
110 * data for Tron, logcat, event logs and {@link android.app.WaitResult}.
111 *
112 * Tests:
Vishnu Nairf8accc52018-10-11 10:19:54 -0700113 * atest CtsActivityManagerDeviceTestCases:ActivityMetricsLoggerTests
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800114 */
115class ActivityMetricsLogger {
Jorim Jaggif9704102016-05-05 19:14:22 -0700116
Wale Ogunwale98875612018-10-12 07:53:02 -0700117 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityMetricsLogger" : TAG_ATM;
Jorim Jaggif9704102016-05-05 19:14:22 -0700118
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800119 // Window modes we are interested in logging. If we ever introduce a new type, we need to add
120 // a value here and increase the {@link #TRON_WINDOW_STATE_VARZ_STRINGS} array.
121 private static final int WINDOW_STATE_STANDARD = 0;
122 private static final int WINDOW_STATE_SIDE_BY_SIDE = 1;
123 private static final int WINDOW_STATE_FREEFORM = 2;
Winson Chung83471632016-12-13 11:02:12 -0800124 private static final int WINDOW_STATE_ASSISTANT = 3;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800125 private static final int WINDOW_STATE_INVALID = -1;
126
Jorim Jaggi275561a2016-02-23 10:11:02 -0500127 private static final long INVALID_START_TIME = -1;
Vishnu Nair132ee832018-09-28 15:00:05 -0700128 private static final int INVALID_DELAY = -1;
129 private static final int INVALID_TRANSITION_TYPE = -1;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500130
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200131 private static final int MSG_CHECK_VISIBILITY = 0;
132
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800133 // Preallocated strings we are sending to tron, so we don't have to allocate a new one every
134 // time we log.
135 private static final String[] TRON_WINDOW_STATE_VARZ_STRINGS = {
Winson Chung83471632016-12-13 11:02:12 -0800136 "window_time_0", "window_time_1", "window_time_2", "window_time_3"};
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800137
138 private int mWindowState = WINDOW_STATE_STANDARD;
139 private long mLastLogTimeSecs;
140 private final ActivityStackSupervisor mSupervisor;
141 private final Context mContext;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800142 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800143
Jorim Jaggi275561a2016-02-23 10:11:02 -0500144 private long mCurrentTransitionStartTime = INVALID_START_TIME;
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200145 private long mLastTransitionStartTime = INVALID_START_TIME;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800146
147 private int mCurrentTransitionDeviceUptime;
148 private int mCurrentTransitionDelayMs;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500149 private boolean mLoggedTransitionStarting;
150
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100151 private final SparseArray<WindowingModeTransitionInfo> mWindowingModeTransitionInfo =
152 new SparseArray<>();
153 private final SparseArray<WindowingModeTransitionInfo> mLastWindowingModeTransitionInfo =
154 new SparseArray<>();
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200155 private final H mHandler;
Calin Juravle759fbda2018-02-20 19:52:30 +0000156
157 private ArtManagerInternal mArtManagerInternal;
Vishnu Nair132ee832018-09-28 15:00:05 -0700158 private final StringBuilder mStringBuilder = new StringBuilder();
Calin Juravle759fbda2018-02-20 19:52:30 +0000159
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200160 private final class H extends Handler {
161
162 public H(Looper looper) {
163 super(looper);
164 }
165
166 @Override
167 public void handleMessage(Message msg) {
168 switch (msg.what) {
169 case MSG_CHECK_VISIBILITY:
170 final SomeArgs args = (SomeArgs) msg.obj;
171 checkVisibility((TaskRecord) args.arg1, (ActivityRecord) args.arg2);
172 break;
173 }
174 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000175 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800176
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100177 private final class WindowingModeTransitionInfo {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800178 private ActivityRecord launchedActivity;
179 private int startResult;
180 private boolean currentTransitionProcessRunning;
Vishnu Nair132ee832018-09-28 15:00:05 -0700181 /** Elapsed time from when we launch an activity to when its windows are drawn. */
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800182 private int windowsDrawnDelayMs;
Vishnu Nair132ee832018-09-28 15:00:05 -0700183 private int startingWindowDelayMs = INVALID_DELAY;
184 private int bindApplicationDelayMs = INVALID_DELAY;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800185 private int reason = APP_TRANSITION_TIMEOUT;
186 private boolean loggedWindowsDrawn;
187 private boolean loggedStartingWindowDrawn;
Vishnu Nair132ee832018-09-28 15:00:05 -0700188 private boolean launchTraceActive;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800189 }
190
Vishnu Nair132ee832018-09-28 15:00:05 -0700191 final class WindowingModeTransitionInfoSnapshot {
Calin Juravle759fbda2018-02-20 19:52:30 +0000192 final private ApplicationInfo applicationInfo;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700193 final private WindowProcessController processRecord;
Vishnu Nair132ee832018-09-28 15:00:05 -0700194 final String packageName;
195 final String launchedActivityName;
Calin Juravle759fbda2018-02-20 19:52:30 +0000196 final private String launchedActivityLaunchedFromPackage;
197 final private String launchedActivityLaunchToken;
198 final private String launchedActivityAppRecordRequiredAbi;
Vishnu Nair132ee832018-09-28 15:00:05 -0700199 final String launchedActivityShortComponentName;
Ng Zhi An83473542018-02-20 09:02:14 -0800200 final private String processName;
Calin Juravle759fbda2018-02-20 19:52:30 +0000201 final private int reason;
202 final private int startingWindowDelayMs;
203 final private int bindApplicationDelayMs;
Vishnu Nair132ee832018-09-28 15:00:05 -0700204 final int windowsDrawnDelayMs;
205 final int type;
206 final int userId;
207 /**
208 * Elapsed time from when we launch an activity to when the app reported it was
209 * fully drawn. If this is not reported then the value is set to INVALID_DELAY.
210 */
211 final int windowsFullyDrawnDelayMs;
212 final int activityRecordIdHashCode;
Calin Juravle759fbda2018-02-20 19:52:30 +0000213
214 private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info) {
Vishnu Nair132ee832018-09-28 15:00:05 -0700215 this(info, info.launchedActivity);
216 }
217
218 private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info,
219 ActivityRecord launchedActivity) {
220 this(info, launchedActivity, INVALID_DELAY);
221 }
222
223 private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info,
224 ActivityRecord launchedActivity, int windowsFullyDrawnDelayMs) {
225 applicationInfo = launchedActivity.appInfo;
226 packageName = launchedActivity.packageName;
227 launchedActivityName = launchedActivity.info.name;
228 launchedActivityLaunchedFromPackage = launchedActivity.launchedFromPackage;
229 launchedActivityLaunchToken = launchedActivity.info.launchToken;
230 launchedActivityAppRecordRequiredAbi = launchedActivity.app == null
Calin Juravle759fbda2018-02-20 19:52:30 +0000231 ? null
Vishnu Nairaf0ea312018-10-15 16:23:55 -0700232 : launchedActivity.app.getRequiredAbi();
Calin Juravle759fbda2018-02-20 19:52:30 +0000233 reason = info.reason;
234 startingWindowDelayMs = info.startingWindowDelayMs;
235 bindApplicationDelayMs = info.bindApplicationDelayMs;
236 windowsDrawnDelayMs = info.windowsDrawnDelayMs;
237 type = getTransitionType(info);
Vishnu Nairaf0ea312018-10-15 16:23:55 -0700238 processRecord = findProcessForActivity(launchedActivity);
239 processName = launchedActivity.processName;
Vishnu Nair132ee832018-09-28 15:00:05 -0700240 userId = launchedActivity.userId;
241 launchedActivityShortComponentName = launchedActivity.shortComponentName;
242 activityRecordIdHashCode = System.identityHashCode(launchedActivity);
243 this.windowsFullyDrawnDelayMs = windowsFullyDrawnDelayMs;
Calin Juravle759fbda2018-02-20 19:52:30 +0000244 }
245 }
246
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200247 ActivityMetricsLogger(ActivityStackSupervisor supervisor, Context context, Looper looper) {
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800248 mLastLogTimeSecs = SystemClock.elapsedRealtime() / 1000;
249 mSupervisor = supervisor;
250 mContext = context;
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200251 mHandler = new H(looper);
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800252 }
253
254 void logWindowState() {
255 final long now = SystemClock.elapsedRealtime() / 1000;
256 if (mWindowState != WINDOW_STATE_INVALID) {
257 // We log even if the window state hasn't changed, because the user might remain in
258 // home/fullscreen move forever and we would like to track this kind of behavior
259 // too.
260 MetricsLogger.count(mContext, TRON_WINDOW_STATE_VARZ_STRINGS[mWindowState],
261 (int) (now - mLastLogTimeSecs));
262 }
263 mLastLogTimeSecs = now;
264
Wale Ogunwale926aade2017-08-29 11:24:37 -0700265 mWindowState = WINDOW_STATE_INVALID;
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700266 ActivityStack stack = mSupervisor.getTopDisplayFocusedStack();
lumarkf6c4a982018-06-15 15:43:12 +0800267 if (stack == null) {
268 return;
269 }
270
Wale Ogunwale926aade2017-08-29 11:24:37 -0700271 if (stack.isActivityTypeAssistant()) {
272 mWindowState = WINDOW_STATE_ASSISTANT;
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800273 return;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800274 }
Wale Ogunwale926aade2017-08-29 11:24:37 -0700275
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700276 int windowingMode = stack.getWindowingMode();
277 if (windowingMode == WINDOWING_MODE_PINNED) {
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800278 stack = mSupervisor.findStackBehind(stack);
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700279 windowingMode = stack.getWindowingMode();
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800280 }
Wale Ogunwale926aade2017-08-29 11:24:37 -0700281 switch (windowingMode) {
282 case WINDOWING_MODE_FULLSCREEN:
283 mWindowState = WINDOW_STATE_STANDARD;
284 break;
285 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
286 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
287 mWindowState = WINDOW_STATE_SIDE_BY_SIDE;
288 break;
Bryce Lee6c605092017-10-12 11:14:49 -0700289 case WINDOWING_MODE_FREEFORM:
Wale Ogunwale926aade2017-08-29 11:24:37 -0700290 mWindowState = WINDOW_STATE_FREEFORM;
291 break;
292 default:
293 if (windowingMode != WINDOWING_MODE_UNDEFINED) {
294 throw new IllegalStateException("Unknown windowing mode for stack=" + stack
295 + " windowingMode=" + windowingMode);
296 }
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800297 }
298 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500299
300 /**
301 * Notifies the tracker at the earliest possible point when we are starting to launch an
302 * activity.
303 */
304 void notifyActivityLaunching() {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800305 if (!isAnyTransitionActive()) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200306 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunching");
Alison Cichowlasb7f67ab2017-04-25 18:04:40 -0400307 mCurrentTransitionStartTime = SystemClock.uptimeMillis();
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200308 mLastTransitionStartTime = mCurrentTransitionStartTime;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800309 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500310 }
311
312 /**
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700313 * Notifies the tracker that the activity is actually launching.
314 *
315 * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the
316 * launch
317 * @param launchedActivity the activity that is being launched
318 */
319 void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity) {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700320 final WindowProcessController processRecord = findProcessForActivity(launchedActivity);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700321 final boolean processRunning = processRecord != null;
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700322
323 // We consider this a "process switch" if the process of the activity that gets launched
324 // didn't have an activity that was in started state. In this case, we assume that lot
325 // of caches might be purged so the time until it produces the first frame is very
326 // interesting.
327 final boolean processSwitch = processRecord == null
Wale Ogunwalef6733932018-06-27 05:14:34 -0700328 || !processRecord.hasStartedActivity(launchedActivity);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700329
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800330 notifyActivityLaunched(resultCode, launchedActivity, processRunning, processSwitch);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700331 }
332
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700333 /**
Jorim Jaggi275561a2016-02-23 10:11:02 -0500334 * Notifies the tracker the the activity is actually launching.
335 *
336 * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the
337 * launch
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800338 * @param launchedActivity the activity being launched
Jorim Jaggi275561a2016-02-23 10:11:02 -0500339 * @param processRunning whether the process that will contains the activity is already running
Jorim Jaggibe67c902016-04-12 00:53:16 -0700340 * @param processSwitch whether the process that will contain the activity didn't have any
341 * activity that was stopped, i.e. the started activity is "switching"
342 * processes
Jorim Jaggi275561a2016-02-23 10:11:02 -0500343 */
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800344 private void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity,
Jorim Jaggibe67c902016-04-12 00:53:16 -0700345 boolean processRunning, boolean processSwitch) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500346
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200347 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched"
348 + " resultCode=" + resultCode
349 + " launchedActivity=" + launchedActivity
350 + " processRunning=" + processRunning
351 + " processSwitch=" + processSwitch);
352
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100353 final int windowingMode = launchedActivity != null
354 ? launchedActivity.getWindowingMode()
355 : WINDOWING_MODE_UNDEFINED;
Vishnu Nairf8accc52018-10-11 10:19:54 -0700356 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200357 if (mCurrentTransitionStartTime == INVALID_START_TIME) {
Vishnu Nairf8accc52018-10-11 10:19:54 -0700358 // No transition is active ignore this launch.
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200359 return;
360 }
361
Vishnu Nairf8accc52018-10-11 10:19:54 -0700362 if (launchedActivity != null && launchedActivity.nowVisible) {
363 // Launched activity is already visible. We cannot measure windows drawn delay.
364 reset(true /* abort */, info);
365 return;
366 }
367
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800368 if (launchedActivity != null && info != null) {
Vishnu Nairf8accc52018-10-11 10:19:54 -0700369 // If we are already in an existing transition, only update the activity name, but not
370 // the other attributes.
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800371 info.launchedActivity = launchedActivity;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500372 return;
373 }
374
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100375 final boolean otherWindowModesLaunching =
376 mWindowingModeTransitionInfo.size() > 0 && info == null;
Jorim Jaggi54cff642018-03-15 15:51:32 +0100377 if ((!isLoggableResultCode(resultCode) || launchedActivity == null || !processSwitch
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100378 || windowingMode == WINDOWING_MODE_UNDEFINED) && !otherWindowModesLaunching) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800379 // Failed to launch or it was not a process switch, so we don't care about the timing.
Vishnu Nair132ee832018-09-28 15:00:05 -0700380 reset(true /* abort */, info);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800381 return;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100382 } else if (otherWindowModesLaunching) {
383 // Don't log this windowing mode but continue with the other windowing modes.
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800384 return;
385 }
386
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200387 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched successful");
388
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100389 final WindowingModeTransitionInfo newInfo = new WindowingModeTransitionInfo();
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800390 newInfo.launchedActivity = launchedActivity;
391 newInfo.currentTransitionProcessRunning = processRunning;
392 newInfo.startResult = resultCode;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100393 mWindowingModeTransitionInfo.put(windowingMode, newInfo);
394 mLastWindowingModeTransitionInfo.put(windowingMode, newInfo);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800395 mCurrentTransitionDeviceUptime = (int) (SystemClock.uptimeMillis() / 1000);
Vishnu Nair132ee832018-09-28 15:00:05 -0700396 startTraces(newInfo);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500397 }
398
399 /**
Jorim Jaggi54cff642018-03-15 15:51:32 +0100400 * @return True if we should start logging an event for an activity start that returned
401 * {@code resultCode} and that we'll indeed get a windows drawn event.
402 */
403 private boolean isLoggableResultCode(int resultCode) {
404 return resultCode == START_SUCCESS || resultCode == START_TASK_TO_FRONT;
405 }
406
407 /**
Jorim Jaggi275561a2016-02-23 10:11:02 -0500408 * Notifies the tracker that all windows of the app have been drawn.
409 */
Vishnu Nair132ee832018-09-28 15:00:05 -0700410 WindowingModeTransitionInfoSnapshot notifyWindowsDrawn(int windowingMode, long timestamp) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100411 if (DEBUG_METRICS) Slog.i(TAG, "notifyWindowsDrawn windowingMode=" + windowingMode);
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200412
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100413 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800414 if (info == null || info.loggedWindowsDrawn) {
Vishnu Nair132ee832018-09-28 15:00:05 -0700415 return null;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500416 }
Sudheer Shankac766db02017-06-12 10:37:29 -0700417 info.windowsDrawnDelayMs = calculateDelay(timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800418 info.loggedWindowsDrawn = true;
Vishnu Nair132ee832018-09-28 15:00:05 -0700419 final WindowingModeTransitionInfoSnapshot infoSnapshot =
420 new WindowingModeTransitionInfoSnapshot(info);
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100421 if (allWindowsDrawn() && mLoggedTransitionStarting) {
Vishnu Nair132ee832018-09-28 15:00:05 -0700422 reset(false /* abort */, info);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500423 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700424 return infoSnapshot;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500425 }
426
427 /**
428 * Notifies the tracker that the starting window was drawn.
429 */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100430 void notifyStartingWindowDrawn(int windowingMode, long timestamp) {
431 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800432 if (info == null || info.loggedStartingWindowDrawn) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500433 return;
434 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800435 info.loggedStartingWindowDrawn = true;
Sudheer Shankac766db02017-06-12 10:37:29 -0700436 info.startingWindowDelayMs = calculateDelay(timestamp);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500437 }
438
439 /**
440 * Notifies the tracker that the app transition is starting.
441 *
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100442 * @param windowingModeToReason A map from windowing mode to a reason integer, which must be on
Vishnu Nair132ee832018-09-28 15:00:05 -0700443 * of ActivityTaskManagerInternal.APP_TRANSITION_* reasons.
Jorim Jaggi275561a2016-02-23 10:11:02 -0500444 */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100445 void notifyTransitionStarting(SparseIntArray windowingModeToReason, long timestamp) {
Jorim Jaggid8a57772017-04-14 16:50:42 -0700446 if (!isAnyTransitionActive() || mLoggedTransitionStarting) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500447 return;
448 }
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200449 if (DEBUG_METRICS) Slog.i(TAG, "notifyTransitionStarting");
Sudheer Shankac766db02017-06-12 10:37:29 -0700450 mCurrentTransitionDelayMs = calculateDelay(timestamp);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500451 mLoggedTransitionStarting = true;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100452 for (int index = windowingModeToReason.size() - 1; index >= 0; index--) {
453 final int windowingMode = windowingModeToReason.keyAt(index);
454 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
455 windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800456 if (info == null) {
457 continue;
458 }
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100459 info.reason = windowingModeToReason.valueAt(index);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800460 }
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100461 if (allWindowsDrawn()) {
Vishnu Nair132ee832018-09-28 15:00:05 -0700462 reset(false /* abort */, null /* WindowingModeTransitionInfo */);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500463 }
464 }
465
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200466 /**
467 * Notifies the tracker that the visibility of an app is changing.
468 *
469 * @param activityRecord the app that is changing its visibility
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200470 */
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200471 void notifyVisibilityChanged(ActivityRecord activityRecord) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100472 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
473 activityRecord.getWindowingMode());
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200474 if (info == null) {
475 return;
476 }
477 if (info.launchedActivity != activityRecord) {
478 return;
479 }
480 final TaskRecord t = activityRecord.getTask();
481 final SomeArgs args = SomeArgs.obtain();
482 args.arg1 = t;
483 args.arg2 = activityRecord;
484 mHandler.obtainMessage(MSG_CHECK_VISIBILITY, args).sendToTarget();
485 }
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200486
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200487 private void checkVisibility(TaskRecord t, ActivityRecord r) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700488 synchronized (mSupervisor.mService.mGlobalLock) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200489
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100490 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
491 r.getWindowingMode());
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200492
493 // If we have an active transition that's waiting on a certain activity that will be
494 // invisible now, we'll never get onWindowsDrawn, so abort the transition if necessary.
495 if (info != null && !t.isVisible()) {
496 if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible"
497 + " activity=" + r);
498 logAppTransitionCancel(info);
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100499 mWindowingModeTransitionInfo.remove(r.getWindowingMode());
500 if (mWindowingModeTransitionInfo.size() == 0) {
Vishnu Nair132ee832018-09-28 15:00:05 -0700501 reset(true /* abort */, info);
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200502 }
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200503 }
504 }
505 }
506
Jorim Jaggi515dd682017-05-05 15:05:07 +0200507 /**
508 * Notifies the tracker that we called immediately before we call bindApplication on the client.
509 *
Wale Ogunwale31913b52018-10-13 08:29:31 -0700510 * @param appInfo The client into which we'll call bindApplication.
Jorim Jaggi515dd682017-05-05 15:05:07 +0200511 */
Wale Ogunwale31913b52018-10-13 08:29:31 -0700512 void notifyBindApplication(ApplicationInfo appInfo) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100513 for (int i = mWindowingModeTransitionInfo.size() - 1; i >= 0; i--) {
514 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(i);
Jorim Jaggi515dd682017-05-05 15:05:07 +0200515
516 // App isn't attached to record yet, so match with info.
Wale Ogunwale31913b52018-10-13 08:29:31 -0700517 if (info.launchedActivity.appInfo == appInfo) {
Jorim Jaggi515dd682017-05-05 15:05:07 +0200518 info.bindApplicationDelayMs = calculateCurrentDelay();
519 }
520 }
521 }
522
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100523 private boolean allWindowsDrawn() {
524 for (int index = mWindowingModeTransitionInfo.size() - 1; index >= 0; index--) {
525 if (!mWindowingModeTransitionInfo.valueAt(index).loggedWindowsDrawn) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800526 return false;
527 }
528 }
529 return true;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500530 }
531
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800532 private boolean isAnyTransitionActive() {
533 return mCurrentTransitionStartTime != INVALID_START_TIME
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100534 && mWindowingModeTransitionInfo.size() > 0;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800535 }
536
Vishnu Nair132ee832018-09-28 15:00:05 -0700537 private void reset(boolean abort, WindowingModeTransitionInfo info) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200538 if (DEBUG_METRICS) Slog.i(TAG, "reset abort=" + abort);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800539 if (!abort && isAnyTransitionActive()) {
540 logAppTransitionMultiEvents();
541 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700542 stopLaunchTrace(info);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500543 mCurrentTransitionStartTime = INVALID_START_TIME;
Vishnu Nair132ee832018-09-28 15:00:05 -0700544 mCurrentTransitionDelayMs = INVALID_DELAY;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500545 mLoggedTransitionStarting = false;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100546 mWindowingModeTransitionInfo.clear();
Jorim Jaggi275561a2016-02-23 10:11:02 -0500547 }
548
549 private int calculateCurrentDelay() {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500550 // Shouldn't take more than 25 days to launch an app, so int is fine here.
Alison Cichowlasb7f67ab2017-04-25 18:04:40 -0400551 return (int) (SystemClock.uptimeMillis() - mCurrentTransitionStartTime);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500552 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800553
Sudheer Shankac766db02017-06-12 10:37:29 -0700554 private int calculateDelay(long timestamp) {
555 // Shouldn't take more than 25 days to launch an app, so int is fine here.
556 return (int) (timestamp - mCurrentTransitionStartTime);
557 }
558
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100559 private void logAppTransitionCancel(WindowingModeTransitionInfo info) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200560 final int type = getTransitionType(info);
Vishnu Nair132ee832018-09-28 15:00:05 -0700561 if (type == INVALID_TRANSITION_TYPE) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200562 return;
563 }
564 final LogMaker builder = new LogMaker(APP_TRANSITION_CANCELLED);
565 builder.setPackageName(info.launchedActivity.packageName);
566 builder.setType(type);
567 builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivity.info.name);
568 mMetricsLogger.write(builder);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000569 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800570 StatsLog.APP_START_CANCELED,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000571 info.launchedActivity.appInfo.uid,
572 info.launchedActivity.packageName,
573 convertAppStartTransitionType(type),
574 info.launchedActivity.info.name);
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200575 }
576
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800577 private void logAppTransitionMultiEvents() {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200578 if (DEBUG_METRICS) Slog.i(TAG, "logging transition events");
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100579 for (int index = mWindowingModeTransitionInfo.size() - 1; index >= 0; index--) {
580 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(index);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800581 final int type = getTransitionType(info);
Vishnu Nair132ee832018-09-28 15:00:05 -0700582 if (type == INVALID_TRANSITION_TYPE) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800583 return;
584 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000585
586 // Take a snapshot of the transition info before sending it to the handler for logging.
587 // This will avoid any races with other operations that modify the ActivityRecord.
588 final WindowingModeTransitionInfoSnapshot infoSnapshot =
589 new WindowingModeTransitionInfoSnapshot(info);
Ng Zhi An83473542018-02-20 09:02:14 -0800590 final int currentTransitionDeviceUptime = mCurrentTransitionDeviceUptime;
591 final int currentTransitionDelayMs = mCurrentTransitionDelayMs;
592 BackgroundThread.getHandler().post(() -> logAppTransition(
593 currentTransitionDeviceUptime, currentTransitionDelayMs, infoSnapshot));
Vishnu Nair132ee832018-09-28 15:00:05 -0700594 BackgroundThread.getHandler().post(() -> logAppDisplayed(infoSnapshot));
Calin Juravle759fbda2018-02-20 19:52:30 +0000595
596 info.launchedActivity.info.launchToken = null;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800597 }
598 }
599
Ng Zhi An83473542018-02-20 09:02:14 -0800600 // This gets called on a background thread without holding the activity manager lock.
Calin Juravle759fbda2018-02-20 19:52:30 +0000601 private void logAppTransition(int currentTransitionDeviceUptime, int currentTransitionDelayMs,
602 WindowingModeTransitionInfoSnapshot info) {
603 final LogMaker builder = new LogMaker(APP_TRANSITION);
604 builder.setPackageName(info.packageName);
605 builder.setType(info.type);
606 builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivityName);
607 final boolean isInstantApp = info.applicationInfo.isInstantApp();
608 if (info.launchedActivityLaunchedFromPackage != null) {
609 builder.addTaggedData(APP_TRANSITION_CALLING_PACKAGE_NAME,
610 info.launchedActivityLaunchedFromPackage);
611 }
612 String launchToken = info.launchedActivityLaunchToken;
613 if (launchToken != null) {
614 builder.addTaggedData(FIELD_INSTANT_APP_LAUNCH_TOKEN, launchToken);
615 }
616 builder.addTaggedData(APP_TRANSITION_IS_EPHEMERAL, isInstantApp ? 1 : 0);
617 builder.addTaggedData(APP_TRANSITION_DEVICE_UPTIME_SECONDS,
618 currentTransitionDeviceUptime);
619 builder.addTaggedData(APP_TRANSITION_DELAY_MS, currentTransitionDelayMs);
620 builder.setSubtype(info.reason);
Vishnu Nair132ee832018-09-28 15:00:05 -0700621 if (info.startingWindowDelayMs != INVALID_DELAY) {
Calin Juravle759fbda2018-02-20 19:52:30 +0000622 builder.addTaggedData(APP_TRANSITION_STARTING_WINDOW_DELAY_MS,
623 info.startingWindowDelayMs);
624 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700625 if (info.bindApplicationDelayMs != INVALID_DELAY) {
Calin Juravle759fbda2018-02-20 19:52:30 +0000626 builder.addTaggedData(APP_TRANSITION_BIND_APPLICATION_DELAY_MS,
627 info.bindApplicationDelayMs);
628 }
629 builder.addTaggedData(APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, info.windowsDrawnDelayMs);
630 final ArtManagerInternal artManagerInternal = getArtManagerInternal();
631 final PackageOptimizationInfo packageOptimizationInfo =
632 (artManagerInternal == null) || (info.launchedActivityAppRecordRequiredAbi == null)
633 ? PackageOptimizationInfo.createWithNoInfo()
634 : artManagerInternal.getPackageOptimizationInfo(
635 info.applicationInfo,
636 info.launchedActivityAppRecordRequiredAbi);
637 builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_REASON,
638 packageOptimizationInfo.getCompilationReason());
639 builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_FILTER,
640 packageOptimizationInfo.getCompilationFilter());
641 mMetricsLogger.write(builder);
642 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800643 StatsLog.APP_START_OCCURRED,
Calin Juravle759fbda2018-02-20 19:52:30 +0000644 info.applicationInfo.uid,
645 info.packageName,
646 convertAppStartTransitionType(info.type),
647 info.launchedActivityName,
648 info.launchedActivityLaunchedFromPackage,
649 isInstantApp,
650 currentTransitionDeviceUptime * 1000,
651 info.reason,
652 currentTransitionDelayMs,
653 info.startingWindowDelayMs,
654 info.bindApplicationDelayMs,
655 info.windowsDrawnDelayMs,
656 launchToken,
657 packageOptimizationInfo.getCompilationReason(),
658 packageOptimizationInfo.getCompilationFilter());
Ng Zhi An83473542018-02-20 09:02:14 -0800659 logAppStartMemoryStateCapture(info);
Calin Juravle759fbda2018-02-20 19:52:30 +0000660 }
661
Vishnu Nair132ee832018-09-28 15:00:05 -0700662 private void logAppDisplayed(WindowingModeTransitionInfoSnapshot info) {
663 if (info.type != TYPE_TRANSITION_WARM_LAUNCH && info.type != TYPE_TRANSITION_COLD_LAUNCH) {
664 return;
665 }
666
667 EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
668 info.userId, info.activityRecordIdHashCode, info.launchedActivityShortComponentName,
669 info.windowsDrawnDelayMs);
670
671 StringBuilder sb = mStringBuilder;
672 sb.setLength(0);
673 sb.append("Displayed ");
674 sb.append(info.launchedActivityShortComponentName);
675 sb.append(": ");
676 TimeUtils.formatDuration(info.windowsDrawnDelayMs, sb);
677 Log.i(TAG, sb.toString());
678 }
679
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000680 private int convertAppStartTransitionType(int tronType) {
681 if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800682 return StatsLog.APP_START_OCCURRED__TYPE__COLD;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000683 }
684 if (tronType == TYPE_TRANSITION_WARM_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800685 return StatsLog.APP_START_OCCURRED__TYPE__WARM;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000686 }
687 if (tronType == TYPE_TRANSITION_HOT_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800688 return StatsLog.APP_START_OCCURRED__TYPE__HOT;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000689 }
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800690 return StatsLog.APP_START_OCCURRED__TYPE__UNKNOWN;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000691 }
692
Vishnu Nair132ee832018-09-28 15:00:05 -0700693 WindowingModeTransitionInfoSnapshot logAppTransitionReportedDrawn(ActivityRecord r,
694 boolean restoredFromBundle) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100695 final WindowingModeTransitionInfo info = mLastWindowingModeTransitionInfo.get(
696 r.getWindowingMode());
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200697 if (info == null) {
Vishnu Nair132ee832018-09-28 15:00:05 -0700698 return null;
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200699 }
Chris Wailes35c193c2018-10-09 18:12:00 -0700700
701 // Record the handling of the reportFullyDrawn callback in the trace system. This is not
702 // actually used to trace this function, but instead the logical task that this function
703 // fullfils (handling reportFullyDrawn() callbacks).
704 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
705 "ActivityManager:ReportingFullyDrawn " + info.launchedActivity.packageName);
706
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200707 final LogMaker builder = new LogMaker(APP_TRANSITION_REPORTED_DRAWN);
708 builder.setPackageName(r.packageName);
709 builder.addTaggedData(FIELD_CLASS_NAME, r.info.name);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000710 long startupTimeMs = SystemClock.uptimeMillis() - mLastTransitionStartTime;
711 builder.addTaggedData(APP_TRANSITION_REPORTED_DRAWN_MS, startupTimeMs);
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200712 builder.setType(restoredFromBundle
713 ? TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE
714 : TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE);
715 builder.addTaggedData(APP_TRANSITION_PROCESS_RUNNING,
716 info.currentTransitionProcessRunning ? 1 : 0);
717 mMetricsLogger.write(builder);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000718 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800719 StatsLog.APP_START_FULLY_DRAWN,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000720 info.launchedActivity.appInfo.uid,
721 info.launchedActivity.packageName,
722 restoredFromBundle
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800723 ? StatsLog.APP_START_FULLY_DRAWN__TYPE__WITH_BUNDLE
724 : StatsLog.APP_START_FULLY_DRAWN__TYPE__WITHOUT_BUNDLE,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000725 info.launchedActivity.info.name,
726 info.currentTransitionProcessRunning,
727 startupTimeMs);
Chris Wailes35c193c2018-10-09 18:12:00 -0700728
729 // Ends the trace started at the beginning of this function. This is located here to allow
730 // the trace slice to have a noticable duration.
731 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
732
Vishnu Nair132ee832018-09-28 15:00:05 -0700733 final WindowingModeTransitionInfoSnapshot infoSnapshot =
734 new WindowingModeTransitionInfoSnapshot(info, r, (int) startupTimeMs);
735 BackgroundThread.getHandler().post(() -> logAppFullyDrawn(infoSnapshot));
736 return infoSnapshot;
737 }
738
739 private void logAppFullyDrawn(WindowingModeTransitionInfoSnapshot info) {
740 if (info.type != TYPE_TRANSITION_WARM_LAUNCH && info.type != TYPE_TRANSITION_COLD_LAUNCH) {
741 return;
742 }
743
744 StringBuilder sb = mStringBuilder;
745 sb.setLength(0);
746 sb.append("Fully drawn ");
747 sb.append(info.launchedActivityShortComponentName);
748 sb.append(": ");
749 TimeUtils.formatDuration(info.windowsFullyDrawnDelayMs, sb);
750 Log.i(TAG, sb.toString());
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200751 }
752
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700753 void logActivityStart(Intent intent, WindowProcessController callerApp, ActivityRecord r,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100754 int callingUid, String callingPackage, int callingUidProcState,
755 boolean callingUidHasAnyVisibleWindow,
756 int realCallingUid, int realCallingUidProcState,
757 boolean realCallingUidHasAnyVisibleWindow,
758 int targetUid, String targetPackage, int targetUidProcState,
759 boolean targetUidHasAnyVisibleWindow, String targetWhitelistTag,
760 boolean comingFromPendingIntent) {
761
762 final long nowElapsed = SystemClock.elapsedRealtime();
763 final long nowUptime = SystemClock.uptimeMillis();
764 final LogMaker builder = new LogMaker(ACTION_ACTIVITY_START);
765 builder.setTimestamp(System.currentTimeMillis());
766 builder.addTaggedData(FIELD_CALLING_UID, callingUid);
767 builder.addTaggedData(FIELD_CALLING_PACKAGE_NAME, callingPackage);
768 builder.addTaggedData(FIELD_CALLING_UID_PROC_STATE,
769 processStateAmToProto(callingUidProcState));
770 builder.addTaggedData(FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
771 callingUidHasAnyVisibleWindow ? 1 : 0);
772 builder.addTaggedData(FIELD_REAL_CALLING_UID, realCallingUid);
773 builder.addTaggedData(FIELD_REAL_CALLING_UID_PROC_STATE,
774 processStateAmToProto(realCallingUidProcState));
775 builder.addTaggedData(FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
776 realCallingUidHasAnyVisibleWindow ? 1 : 0);
777 builder.addTaggedData(FIELD_TARGET_UID, targetUid);
778 builder.addTaggedData(FIELD_TARGET_PACKAGE_NAME, targetPackage);
779 builder.addTaggedData(FIELD_TARGET_UID_PROC_STATE,
780 processStateAmToProto(targetUidProcState));
781 builder.addTaggedData(FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW,
782 targetUidHasAnyVisibleWindow ? 1 : 0);
783 builder.addTaggedData(FIELD_TARGET_WHITELIST_TAG, targetWhitelistTag);
784 builder.addTaggedData(FIELD_TARGET_SHORT_COMPONENT_NAME, r.shortComponentName);
785 builder.addTaggedData(FIELD_COMING_FROM_PENDING_INTENT, comingFromPendingIntent ? 1 : 0);
786 builder.addTaggedData(FIELD_INTENT_ACTION, intent.getAction());
787 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700788 builder.addTaggedData(FIELD_PROCESS_RECORD_PROCESS_NAME, callerApp.mName);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100789 builder.addTaggedData(FIELD_PROCESS_RECORD_CUR_PROC_STATE,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700790 processStateAmToProto(callerApp.getCurrentProcState()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100791 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700792 callerApp.hasClientActivities() ? 1 : 0);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100793 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES,
794 callerApp.hasForegroundServices() ? 1 : 0);
795 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700796 callerApp.hasForegroundActivities() ? 1 : 0);
797 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_TOP_UI, callerApp.hasTopUi() ? 1 : 0);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100798 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_OVERLAY_UI,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700799 callerApp.hasOverlayUi() ? 1 : 0);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100800 builder.addTaggedData(FIELD_PROCESS_RECORD_PENDING_UI_CLEAN,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700801 callerApp.hasPendingUiClean() ? 1 : 0);
802 if (callerApp.getInteractionEventTime() != 0) {
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100803 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700804 (nowElapsed - callerApp.getInteractionEventTime()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100805 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700806 if (callerApp.getFgInteractionTime() != 0) {
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100807 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700808 (nowElapsed - callerApp.getFgInteractionTime()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100809 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700810 if (callerApp.getWhenUnimportant() != 0) {
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100811 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700812 (nowUptime - callerApp.getWhenUnimportant()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100813 }
814 }
815 builder.addTaggedData(FIELD_ACTIVITY_RECORD_LAUNCH_MODE, r.info.launchMode);
816 builder.addTaggedData(FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY, r.info.targetActivity);
817 builder.addTaggedData(FIELD_ACTIVITY_RECORD_FLAGS, r.info.flags);
818 builder.addTaggedData(FIELD_ACTIVITY_RECORD_REAL_ACTIVITY, r.realActivity.toShortString());
819 builder.addTaggedData(FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME, r.shortComponentName);
820 builder.addTaggedData(FIELD_ACTIVITY_RECORD_PROCESS_NAME, r.processName);
821 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_FULLSCREEN, r.fullscreen ? 1 : 0);
822 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY, r.noDisplay ? 1 : 0);
823 if (r.lastVisibleTime != 0) {
824 builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE,
825 (nowUptime - r.lastVisibleTime));
826 }
827 if (r.resultTo != null) {
828 builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME, r.resultTo.packageName);
829 builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME,
830 r.resultTo.shortComponentName);
831 }
832 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE, r.visible ? 1 : 0);
833 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD,
834 r.visibleIgnoringKeyguard ? 1 : 0);
835 if (r.lastLaunchTime != 0) {
836 builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH,
837 (nowUptime - r.lastLaunchTime));
838 }
839 mMetricsLogger.write(builder);
840 }
841
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100842 private int getTransitionType(WindowingModeTransitionInfo info) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800843 if (info.currentTransitionProcessRunning) {
844 if (info.startResult == START_SUCCESS) {
845 return TYPE_TRANSITION_WARM_LAUNCH;
846 } else if (info.startResult == START_TASK_TO_FRONT) {
847 return TYPE_TRANSITION_HOT_LAUNCH;
848 }
849 } else if (info.startResult == START_SUCCESS) {
850 return TYPE_TRANSITION_COLD_LAUNCH;
851 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700852 return INVALID_TRANSITION_TYPE;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800853 }
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800854
Ng Zhi An83473542018-02-20 09:02:14 -0800855 private void logAppStartMemoryStateCapture(WindowingModeTransitionInfoSnapshot info) {
856 if (info.processRecord == null) {
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800857 if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture processRecord null");
858 return;
859 }
860
Wale Ogunwalef6733932018-06-27 05:14:34 -0700861 final int pid = info.processRecord.getPid();
Ng Zhi An83473542018-02-20 09:02:14 -0800862 final int uid = info.applicationInfo.uid;
Rajeev Kumarbfcd9202018-03-02 22:42:13 +0000863 final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800864 if (memoryStat == null) {
865 if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture memoryStat null");
866 return;
867 }
868
869 StatsLog.write(
870 StatsLog.APP_START_MEMORY_STATE_CAPTURED,
871 uid,
Ng Zhi An83473542018-02-20 09:02:14 -0800872 info.processName,
873 info.launchedActivityName,
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800874 memoryStat.pgfault,
875 memoryStat.pgmajfault,
876 memoryStat.rssInBytes,
877 memoryStat.cacheInBytes,
878 memoryStat.swapInBytes);
879 }
880
Wale Ogunwalef6733932018-06-27 05:14:34 -0700881 private WindowProcessController findProcessForActivity(ActivityRecord launchedActivity) {
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800882 return launchedActivity != null
Wale Ogunwalef6733932018-06-27 05:14:34 -0700883 ? mSupervisor.mService.mProcessNames.get(
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700884 launchedActivity.processName, launchedActivity.appInfo.uid)
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800885 : null;
886 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000887
888 private ArtManagerInternal getArtManagerInternal() {
889 if (mArtManagerInternal == null) {
890 // Note that this may be null.
891 // ArtManagerInternal is registered during PackageManagerService
892 // initialization which happens after ActivityManagerService.
893 mArtManagerInternal = LocalServices.getService(ArtManagerInternal.class);
894 }
895 return mArtManagerInternal;
896 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700897
898 /**
Chris Wailes35c193c2018-10-09 18:12:00 -0700899 * Starts traces for app launch.
Vishnu Nair132ee832018-09-28 15:00:05 -0700900 *
901 * @param info
902 * */
903 private void startTraces(WindowingModeTransitionInfo info) {
904 if (info == null) {
905 return;
906 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700907 int transitionType = getTransitionType(info);
908 if (!info.launchTraceActive && transitionType == TYPE_TRANSITION_WARM_LAUNCH
909 || transitionType == TYPE_TRANSITION_COLD_LAUNCH) {
910 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: "
911 + info.launchedActivity.packageName, 0);
Vishnu Nair132ee832018-09-28 15:00:05 -0700912 info.launchTraceActive = true;
913 }
914 }
915
916 private void stopLaunchTrace(WindowingModeTransitionInfo info) {
917 if (info == null) {
918 return;
919 }
920 if (info.launchTraceActive) {
921 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: "
922 + info.launchedActivity.packageName, 0);
923 info.launchTraceActive = false;
924 }
925 }
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800926}