blob: 61e14143f162529fd9f58c3516b582dbfb05507f [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;
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700280 ActivityStack stack = mSupervisor.getTopDisplayFocusedStack();
lumarkf6c4a982018-06-15 15:43:12 +0800281 if (stack == null) {
282 return;
283 }
284
Wale Ogunwale926aade2017-08-29 11:24:37 -0700285 if (stack.isActivityTypeAssistant()) {
286 mWindowState = WINDOW_STATE_ASSISTANT;
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800287 return;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800288 }
Wale Ogunwale926aade2017-08-29 11:24:37 -0700289
Igor Murashkin212d06c2018-10-22 16:34:39 -0700290 @WindowingMode int windowingMode = stack.getWindowingMode();
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700291 if (windowingMode == WINDOWING_MODE_PINNED) {
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800292 stack = mSupervisor.findStackBehind(stack);
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700293 windowingMode = stack.getWindowingMode();
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800294 }
Wale Ogunwale926aade2017-08-29 11:24:37 -0700295 switch (windowingMode) {
296 case WINDOWING_MODE_FULLSCREEN:
297 mWindowState = WINDOW_STATE_STANDARD;
298 break;
299 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
300 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
301 mWindowState = WINDOW_STATE_SIDE_BY_SIDE;
302 break;
Bryce Lee6c605092017-10-12 11:14:49 -0700303 case WINDOWING_MODE_FREEFORM:
Wale Ogunwale926aade2017-08-29 11:24:37 -0700304 mWindowState = WINDOW_STATE_FREEFORM;
305 break;
306 default:
307 if (windowingMode != WINDOWING_MODE_UNDEFINED) {
308 throw new IllegalStateException("Unknown windowing mode for stack=" + stack
309 + " windowingMode=" + windowingMode);
310 }
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800311 }
312 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500313
314 /**
315 * Notifies the tracker at the earliest possible point when we are starting to launch an
316 * activity.
317 */
Igor Murashkin212d06c2018-10-22 16:34:39 -0700318 void notifyActivityLaunching(Intent intent) {
319 if (DEBUG_METRICS) {
320 Slog.i(TAG, String.format("notifyActivityLaunching: active:%b, intent:%s",
321 isAnyTransitionActive(),
322 intent));
323 }
324
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800325 if (!isAnyTransitionActive()) {
Igor Murashkin212d06c2018-10-22 16:34:39 -0700326
Alison Cichowlasb7f67ab2017-04-25 18:04:40 -0400327 mCurrentTransitionStartTime = SystemClock.uptimeMillis();
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200328 mLastTransitionStartTime = mCurrentTransitionStartTime;
Igor Murashkin212d06c2018-10-22 16:34:39 -0700329
330 launchObserverNotifyIntentStarted(intent);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800331 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500332 }
333
334 /**
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700335 * Notifies the tracker that the activity is actually launching.
336 *
337 * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the
338 * launch
339 * @param launchedActivity the activity that is being launched
340 */
341 void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity) {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700342 final WindowProcessController processRecord = findProcessForActivity(launchedActivity);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700343 final boolean processRunning = processRecord != null;
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700344
345 // We consider this a "process switch" if the process of the activity that gets launched
346 // didn't have an activity that was in started state. In this case, we assume that lot
347 // of caches might be purged so the time until it produces the first frame is very
348 // interesting.
349 final boolean processSwitch = processRecord == null
Wale Ogunwalef6733932018-06-27 05:14:34 -0700350 || !processRecord.hasStartedActivity(launchedActivity);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700351
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800352 notifyActivityLaunched(resultCode, launchedActivity, processRunning, processSwitch);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700353 }
354
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700355 /**
Jorim Jaggi275561a2016-02-23 10:11:02 -0500356 * Notifies the tracker the the activity is actually launching.
357 *
358 * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the
359 * launch
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800360 * @param launchedActivity the activity being launched
Jorim Jaggi275561a2016-02-23 10:11:02 -0500361 * @param processRunning whether the process that will contains the activity is already running
Jorim Jaggibe67c902016-04-12 00:53:16 -0700362 * @param processSwitch whether the process that will contain the activity didn't have any
363 * activity that was stopped, i.e. the started activity is "switching"
364 * processes
Jorim Jaggi275561a2016-02-23 10:11:02 -0500365 */
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800366 private void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity,
Jorim Jaggibe67c902016-04-12 00:53:16 -0700367 boolean processRunning, boolean processSwitch) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500368
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200369 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched"
370 + " resultCode=" + resultCode
371 + " launchedActivity=" + launchedActivity
372 + " processRunning=" + processRunning
373 + " processSwitch=" + processSwitch);
374
Igor Murashkin212d06c2018-10-22 16:34:39 -0700375 // If we are already in an existing transition, only update the activity name, but not the
376 // other attributes.
377 final @WindowingMode int windowingMode = launchedActivity != null
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100378 ? launchedActivity.getWindowingMode()
379 : WINDOWING_MODE_UNDEFINED;
Vishnu Nairf8accc52018-10-11 10:19:54 -0700380 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200381 if (mCurrentTransitionStartTime == INVALID_START_TIME) {
Vishnu Nairf8accc52018-10-11 10:19:54 -0700382 // No transition is active ignore this launch.
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200383 return;
384 }
385
Vishnu Nairf8accc52018-10-11 10:19:54 -0700386 if (launchedActivity != null && launchedActivity.nowVisible) {
387 // Launched activity is already visible. We cannot measure windows drawn delay.
Igor Murashkin212d06c2018-10-22 16:34:39 -0700388 reset(true /* abort */, info, "launched activity already visible");
Vishnu Nairf8accc52018-10-11 10:19:54 -0700389 return;
390 }
391
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800392 if (launchedActivity != null && info != null) {
Vishnu Nairf8accc52018-10-11 10:19:54 -0700393 // If we are already in an existing transition, only update the activity name, but not
394 // the other attributes.
Igor Murashkin212d06c2018-10-22 16:34:39 -0700395
396 // Coalesce multiple (trampoline) activities from a single sequence together.
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800397 info.launchedActivity = launchedActivity;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500398 return;
399 }
400
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100401 final boolean otherWindowModesLaunching =
402 mWindowingModeTransitionInfo.size() > 0 && info == null;
Jorim Jaggi54cff642018-03-15 15:51:32 +0100403 if ((!isLoggableResultCode(resultCode) || launchedActivity == null || !processSwitch
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100404 || windowingMode == WINDOWING_MODE_UNDEFINED) && !otherWindowModesLaunching) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800405 // 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 -0700406 reset(true /* abort */, info, "failed to launch or not a process switch");
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800407 return;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100408 } else if (otherWindowModesLaunching) {
409 // Don't log this windowing mode but continue with the other windowing modes.
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800410 return;
411 }
412
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200413 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched successful");
414
Igor Murashkin212d06c2018-10-22 16:34:39 -0700415 // A new launch sequence [with the windowingMode] has begun.
416 // Start tracking it.
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100417 final WindowingModeTransitionInfo newInfo = new WindowingModeTransitionInfo();
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800418 newInfo.launchedActivity = launchedActivity;
419 newInfo.currentTransitionProcessRunning = processRunning;
420 newInfo.startResult = resultCode;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100421 mWindowingModeTransitionInfo.put(windowingMode, newInfo);
422 mLastWindowingModeTransitionInfo.put(windowingMode, newInfo);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800423 mCurrentTransitionDeviceUptime = (int) (SystemClock.uptimeMillis() / 1000);
Vishnu Nair132ee832018-09-28 15:00:05 -0700424 startTraces(newInfo);
Igor Murashkin212d06c2018-10-22 16:34:39 -0700425 launchObserverNotifyActivityLaunched(newInfo);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500426 }
427
428 /**
Jorim Jaggi54cff642018-03-15 15:51:32 +0100429 * @return True if we should start logging an event for an activity start that returned
430 * {@code resultCode} and that we'll indeed get a windows drawn event.
431 */
432 private boolean isLoggableResultCode(int resultCode) {
433 return resultCode == START_SUCCESS || resultCode == START_TASK_TO_FRONT;
434 }
435
436 /**
Jorim Jaggi275561a2016-02-23 10:11:02 -0500437 * Notifies the tracker that all windows of the app have been drawn.
438 */
Igor Murashkin212d06c2018-10-22 16:34:39 -0700439 WindowingModeTransitionInfoSnapshot notifyWindowsDrawn(@WindowingMode int windowingMode,
440 long timestamp) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100441 if (DEBUG_METRICS) Slog.i(TAG, "notifyWindowsDrawn windowingMode=" + windowingMode);
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200442
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100443 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800444 if (info == null || info.loggedWindowsDrawn) {
Vishnu Nair132ee832018-09-28 15:00:05 -0700445 return null;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500446 }
Sudheer Shankac766db02017-06-12 10:37:29 -0700447 info.windowsDrawnDelayMs = calculateDelay(timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800448 info.loggedWindowsDrawn = true;
Vishnu Nair132ee832018-09-28 15:00:05 -0700449 final WindowingModeTransitionInfoSnapshot infoSnapshot =
450 new WindowingModeTransitionInfoSnapshot(info);
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100451 if (allWindowsDrawn() && mLoggedTransitionStarting) {
Igor Murashkin212d06c2018-10-22 16:34:39 -0700452 reset(false /* abort */, info, "notifyWindowsDrawn - all windows drawn");
Jorim Jaggi275561a2016-02-23 10:11:02 -0500453 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700454 return infoSnapshot;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500455 }
456
457 /**
458 * Notifies the tracker that the starting window was drawn.
459 */
Igor Murashkin212d06c2018-10-22 16:34:39 -0700460 void notifyStartingWindowDrawn(@WindowingMode int windowingMode, long timestamp) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100461 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800462 if (info == null || info.loggedStartingWindowDrawn) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500463 return;
464 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800465 info.loggedStartingWindowDrawn = true;
Sudheer Shankac766db02017-06-12 10:37:29 -0700466 info.startingWindowDelayMs = calculateDelay(timestamp);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500467 }
468
469 /**
470 * Notifies the tracker that the app transition is starting.
471 *
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100472 * @param windowingModeToReason A map from windowing mode to a reason integer, which must be on
Vishnu Nair132ee832018-09-28 15:00:05 -0700473 * of ActivityTaskManagerInternal.APP_TRANSITION_* reasons.
Jorim Jaggi275561a2016-02-23 10:11:02 -0500474 */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100475 void notifyTransitionStarting(SparseIntArray windowingModeToReason, long timestamp) {
Jorim Jaggid8a57772017-04-14 16:50:42 -0700476 if (!isAnyTransitionActive() || mLoggedTransitionStarting) {
Igor Murashkin212d06c2018-10-22 16:34:39 -0700477 // Ignore calls to this made after a reset and prior to notifyActivityLaunching.
478
479 // Ignore any subsequent notifyTransitionStarting until the next reset.
Jorim Jaggi275561a2016-02-23 10:11:02 -0500480 return;
481 }
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200482 if (DEBUG_METRICS) Slog.i(TAG, "notifyTransitionStarting");
Sudheer Shankac766db02017-06-12 10:37:29 -0700483 mCurrentTransitionDelayMs = calculateDelay(timestamp);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500484 mLoggedTransitionStarting = true;
Igor Murashkin212d06c2018-10-22 16:34:39 -0700485
486 WindowingModeTransitionInfo foundInfo = null;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100487 for (int index = windowingModeToReason.size() - 1; index >= 0; index--) {
Igor Murashkin212d06c2018-10-22 16:34:39 -0700488 final @WindowingMode int windowingMode = windowingModeToReason.keyAt(index);
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100489 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
490 windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800491 if (info == null) {
492 continue;
493 }
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100494 info.reason = windowingModeToReason.valueAt(index);
Igor Murashkin212d06c2018-10-22 16:34:39 -0700495 foundInfo = info;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800496 }
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100497 if (allWindowsDrawn()) {
Vishnu Naira62534b2018-11-09 09:13:22 -0800498 // abort metrics collection if we cannot find a matching transition.
499 final boolean abortMetrics = foundInfo == null;
500 reset(abortMetrics, foundInfo, "notifyTransitionStarting - all windows drawn");
Jorim Jaggi275561a2016-02-23 10:11:02 -0500501 }
502 }
503
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200504 /**
505 * Notifies the tracker that the visibility of an app is changing.
506 *
507 * @param activityRecord the app that is changing its visibility
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200508 */
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200509 void notifyVisibilityChanged(ActivityRecord activityRecord) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100510 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
511 activityRecord.getWindowingMode());
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200512 if (info == null) {
513 return;
514 }
515 if (info.launchedActivity != activityRecord) {
516 return;
517 }
518 final TaskRecord t = activityRecord.getTask();
519 final SomeArgs args = SomeArgs.obtain();
520 args.arg1 = t;
521 args.arg2 = activityRecord;
522 mHandler.obtainMessage(MSG_CHECK_VISIBILITY, args).sendToTarget();
523 }
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200524
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200525 private void checkVisibility(TaskRecord t, ActivityRecord r) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700526 synchronized (mSupervisor.mService.mGlobalLock) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200527
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100528 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
529 r.getWindowingMode());
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200530
531 // If we have an active transition that's waiting on a certain activity that will be
532 // invisible now, we'll never get onWindowsDrawn, so abort the transition if necessary.
533 if (info != null && !t.isVisible()) {
534 if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible"
535 + " activity=" + r);
536 logAppTransitionCancel(info);
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100537 mWindowingModeTransitionInfo.remove(r.getWindowingMode());
538 if (mWindowingModeTransitionInfo.size() == 0) {
Igor Murashkin212d06c2018-10-22 16:34:39 -0700539 reset(true /* abort */, info, "notifyVisibilityChanged to invisible");
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200540 }
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200541 }
542 }
543 }
544
Jorim Jaggi515dd682017-05-05 15:05:07 +0200545 /**
546 * Notifies the tracker that we called immediately before we call bindApplication on the client.
547 *
Wale Ogunwale31913b52018-10-13 08:29:31 -0700548 * @param appInfo The client into which we'll call bindApplication.
Jorim Jaggi515dd682017-05-05 15:05:07 +0200549 */
Wale Ogunwale31913b52018-10-13 08:29:31 -0700550 void notifyBindApplication(ApplicationInfo appInfo) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100551 for (int i = mWindowingModeTransitionInfo.size() - 1; i >= 0; i--) {
552 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(i);
Jorim Jaggi515dd682017-05-05 15:05:07 +0200553
554 // App isn't attached to record yet, so match with info.
Wale Ogunwale31913b52018-10-13 08:29:31 -0700555 if (info.launchedActivity.appInfo == appInfo) {
Jorim Jaggi515dd682017-05-05 15:05:07 +0200556 info.bindApplicationDelayMs = calculateCurrentDelay();
557 }
558 }
559 }
560
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100561 private boolean allWindowsDrawn() {
562 for (int index = mWindowingModeTransitionInfo.size() - 1; index >= 0; index--) {
563 if (!mWindowingModeTransitionInfo.valueAt(index).loggedWindowsDrawn) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800564 return false;
565 }
566 }
567 return true;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500568 }
569
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800570 private boolean isAnyTransitionActive() {
571 return mCurrentTransitionStartTime != INVALID_START_TIME
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100572 && mWindowingModeTransitionInfo.size() > 0;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800573 }
574
Igor Murashkin212d06c2018-10-22 16:34:39 -0700575 private void reset(boolean abort, WindowingModeTransitionInfo info, String cause) {
576 if (DEBUG_METRICS) Slog.i(TAG, "reset abort=" + abort + ",cause=" + cause);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800577 if (!abort && isAnyTransitionActive()) {
578 logAppTransitionMultiEvents();
579 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700580 stopLaunchTrace(info);
Igor Murashkin212d06c2018-10-22 16:34:39 -0700581
582 // Ignore reset-after reset.
583 if (isAnyTransitionActive()) {
584 // LaunchObserver callbacks.
585 if (abort) {
586 launchObserverNotifyActivityLaunchCancelled(info);
587 } else {
588 launchObserverNotifyActivityLaunchFinished(info);
589 }
590 } else {
591 launchObserverNotifyIntentFailed();
592 }
593
Jorim Jaggi275561a2016-02-23 10:11:02 -0500594 mCurrentTransitionStartTime = INVALID_START_TIME;
Vishnu Nair132ee832018-09-28 15:00:05 -0700595 mCurrentTransitionDelayMs = INVALID_DELAY;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500596 mLoggedTransitionStarting = false;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100597 mWindowingModeTransitionInfo.clear();
Jorim Jaggi275561a2016-02-23 10:11:02 -0500598 }
599
600 private int calculateCurrentDelay() {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500601 // Shouldn't take more than 25 days to launch an app, so int is fine here.
Alison Cichowlasb7f67ab2017-04-25 18:04:40 -0400602 return (int) (SystemClock.uptimeMillis() - mCurrentTransitionStartTime);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500603 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800604
Sudheer Shankac766db02017-06-12 10:37:29 -0700605 private int calculateDelay(long timestamp) {
606 // Shouldn't take more than 25 days to launch an app, so int is fine here.
607 return (int) (timestamp - mCurrentTransitionStartTime);
608 }
609
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100610 private void logAppTransitionCancel(WindowingModeTransitionInfo info) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200611 final int type = getTransitionType(info);
Vishnu Nair132ee832018-09-28 15:00:05 -0700612 if (type == INVALID_TRANSITION_TYPE) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200613 return;
614 }
615 final LogMaker builder = new LogMaker(APP_TRANSITION_CANCELLED);
616 builder.setPackageName(info.launchedActivity.packageName);
617 builder.setType(type);
618 builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivity.info.name);
619 mMetricsLogger.write(builder);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000620 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800621 StatsLog.APP_START_CANCELED,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000622 info.launchedActivity.appInfo.uid,
623 info.launchedActivity.packageName,
624 convertAppStartTransitionType(type),
625 info.launchedActivity.info.name);
Igor Murashkin212d06c2018-10-22 16:34:39 -0700626 if (DEBUG_METRICS) {
627 Slog.i(TAG, String.format("APP_START_CANCELED(%s, %s, %s, %s)",
628 info.launchedActivity.appInfo.uid,
629 info.launchedActivity.packageName,
630 convertAppStartTransitionType(type),
631 info.launchedActivity.info.name));
632 }
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200633 }
634
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800635 private void logAppTransitionMultiEvents() {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200636 if (DEBUG_METRICS) Slog.i(TAG, "logging transition events");
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100637 for (int index = mWindowingModeTransitionInfo.size() - 1; index >= 0; index--) {
638 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(index);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800639 final int type = getTransitionType(info);
Vishnu Nair132ee832018-09-28 15:00:05 -0700640 if (type == INVALID_TRANSITION_TYPE) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800641 return;
642 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000643
644 // Take a snapshot of the transition info before sending it to the handler for logging.
645 // This will avoid any races with other operations that modify the ActivityRecord.
646 final WindowingModeTransitionInfoSnapshot infoSnapshot =
647 new WindowingModeTransitionInfoSnapshot(info);
Ng Zhi An83473542018-02-20 09:02:14 -0800648 final int currentTransitionDeviceUptime = mCurrentTransitionDeviceUptime;
649 final int currentTransitionDelayMs = mCurrentTransitionDelayMs;
650 BackgroundThread.getHandler().post(() -> logAppTransition(
651 currentTransitionDeviceUptime, currentTransitionDelayMs, infoSnapshot));
Vishnu Nair132ee832018-09-28 15:00:05 -0700652 BackgroundThread.getHandler().post(() -> logAppDisplayed(infoSnapshot));
Calin Juravle759fbda2018-02-20 19:52:30 +0000653
654 info.launchedActivity.info.launchToken = null;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800655 }
656 }
657
Ng Zhi An83473542018-02-20 09:02:14 -0800658 // This gets called on a background thread without holding the activity manager lock.
Calin Juravle759fbda2018-02-20 19:52:30 +0000659 private void logAppTransition(int currentTransitionDeviceUptime, int currentTransitionDelayMs,
660 WindowingModeTransitionInfoSnapshot info) {
661 final LogMaker builder = new LogMaker(APP_TRANSITION);
662 builder.setPackageName(info.packageName);
663 builder.setType(info.type);
664 builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivityName);
665 final boolean isInstantApp = info.applicationInfo.isInstantApp();
666 if (info.launchedActivityLaunchedFromPackage != null) {
667 builder.addTaggedData(APP_TRANSITION_CALLING_PACKAGE_NAME,
668 info.launchedActivityLaunchedFromPackage);
669 }
670 String launchToken = info.launchedActivityLaunchToken;
671 if (launchToken != null) {
672 builder.addTaggedData(FIELD_INSTANT_APP_LAUNCH_TOKEN, launchToken);
673 }
674 builder.addTaggedData(APP_TRANSITION_IS_EPHEMERAL, isInstantApp ? 1 : 0);
675 builder.addTaggedData(APP_TRANSITION_DEVICE_UPTIME_SECONDS,
676 currentTransitionDeviceUptime);
677 builder.addTaggedData(APP_TRANSITION_DELAY_MS, currentTransitionDelayMs);
678 builder.setSubtype(info.reason);
Vishnu Nair132ee832018-09-28 15:00:05 -0700679 if (info.startingWindowDelayMs != INVALID_DELAY) {
Calin Juravle759fbda2018-02-20 19:52:30 +0000680 builder.addTaggedData(APP_TRANSITION_STARTING_WINDOW_DELAY_MS,
681 info.startingWindowDelayMs);
682 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700683 if (info.bindApplicationDelayMs != INVALID_DELAY) {
Calin Juravle759fbda2018-02-20 19:52:30 +0000684 builder.addTaggedData(APP_TRANSITION_BIND_APPLICATION_DELAY_MS,
685 info.bindApplicationDelayMs);
686 }
687 builder.addTaggedData(APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, info.windowsDrawnDelayMs);
688 final ArtManagerInternal artManagerInternal = getArtManagerInternal();
689 final PackageOptimizationInfo packageOptimizationInfo =
690 (artManagerInternal == null) || (info.launchedActivityAppRecordRequiredAbi == null)
691 ? PackageOptimizationInfo.createWithNoInfo()
692 : artManagerInternal.getPackageOptimizationInfo(
693 info.applicationInfo,
694 info.launchedActivityAppRecordRequiredAbi);
695 builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_REASON,
696 packageOptimizationInfo.getCompilationReason());
697 builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_FILTER,
698 packageOptimizationInfo.getCompilationFilter());
699 mMetricsLogger.write(builder);
700 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800701 StatsLog.APP_START_OCCURRED,
Calin Juravle759fbda2018-02-20 19:52:30 +0000702 info.applicationInfo.uid,
703 info.packageName,
704 convertAppStartTransitionType(info.type),
705 info.launchedActivityName,
706 info.launchedActivityLaunchedFromPackage,
707 isInstantApp,
708 currentTransitionDeviceUptime * 1000,
709 info.reason,
710 currentTransitionDelayMs,
711 info.startingWindowDelayMs,
712 info.bindApplicationDelayMs,
713 info.windowsDrawnDelayMs,
714 launchToken,
715 packageOptimizationInfo.getCompilationReason(),
716 packageOptimizationInfo.getCompilationFilter());
Igor Murashkin212d06c2018-10-22 16:34:39 -0700717
718 if (DEBUG_METRICS) {
719 Slog.i(TAG, String.format("APP_START_OCCURRED(%s, %s, %s, %s, %s)",
720 info.applicationInfo.uid,
721 info.packageName,
722 convertAppStartTransitionType(info.type),
723 info.launchedActivityName,
724 info.launchedActivityLaunchedFromPackage));
725 }
726
727
Ng Zhi An83473542018-02-20 09:02:14 -0800728 logAppStartMemoryStateCapture(info);
Calin Juravle759fbda2018-02-20 19:52:30 +0000729 }
730
Vishnu Nair132ee832018-09-28 15:00:05 -0700731 private void logAppDisplayed(WindowingModeTransitionInfoSnapshot info) {
732 if (info.type != TYPE_TRANSITION_WARM_LAUNCH && info.type != TYPE_TRANSITION_COLD_LAUNCH) {
733 return;
734 }
735
736 EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
737 info.userId, info.activityRecordIdHashCode, info.launchedActivityShortComponentName,
738 info.windowsDrawnDelayMs);
739
740 StringBuilder sb = mStringBuilder;
741 sb.setLength(0);
742 sb.append("Displayed ");
743 sb.append(info.launchedActivityShortComponentName);
744 sb.append(": ");
745 TimeUtils.formatDuration(info.windowsDrawnDelayMs, sb);
746 Log.i(TAG, sb.toString());
747 }
748
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000749 private int convertAppStartTransitionType(int tronType) {
750 if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800751 return StatsLog.APP_START_OCCURRED__TYPE__COLD;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000752 }
753 if (tronType == TYPE_TRANSITION_WARM_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800754 return StatsLog.APP_START_OCCURRED__TYPE__WARM;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000755 }
756 if (tronType == TYPE_TRANSITION_HOT_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800757 return StatsLog.APP_START_OCCURRED__TYPE__HOT;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000758 }
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800759 return StatsLog.APP_START_OCCURRED__TYPE__UNKNOWN;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000760 }
761
Vishnu Nair132ee832018-09-28 15:00:05 -0700762 WindowingModeTransitionInfoSnapshot logAppTransitionReportedDrawn(ActivityRecord r,
763 boolean restoredFromBundle) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100764 final WindowingModeTransitionInfo info = mLastWindowingModeTransitionInfo.get(
765 r.getWindowingMode());
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200766 if (info == null) {
Vishnu Nair132ee832018-09-28 15:00:05 -0700767 return null;
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200768 }
Chris Wailes35c193c2018-10-09 18:12:00 -0700769
770 // Record the handling of the reportFullyDrawn callback in the trace system. This is not
771 // actually used to trace this function, but instead the logical task that this function
772 // fullfils (handling reportFullyDrawn() callbacks).
773 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
774 "ActivityManager:ReportingFullyDrawn " + info.launchedActivity.packageName);
775
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200776 final LogMaker builder = new LogMaker(APP_TRANSITION_REPORTED_DRAWN);
777 builder.setPackageName(r.packageName);
778 builder.addTaggedData(FIELD_CLASS_NAME, r.info.name);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000779 long startupTimeMs = SystemClock.uptimeMillis() - mLastTransitionStartTime;
780 builder.addTaggedData(APP_TRANSITION_REPORTED_DRAWN_MS, startupTimeMs);
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200781 builder.setType(restoredFromBundle
782 ? TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE
783 : TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE);
784 builder.addTaggedData(APP_TRANSITION_PROCESS_RUNNING,
785 info.currentTransitionProcessRunning ? 1 : 0);
786 mMetricsLogger.write(builder);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000787 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800788 StatsLog.APP_START_FULLY_DRAWN,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000789 info.launchedActivity.appInfo.uid,
790 info.launchedActivity.packageName,
791 restoredFromBundle
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800792 ? StatsLog.APP_START_FULLY_DRAWN__TYPE__WITH_BUNDLE
793 : StatsLog.APP_START_FULLY_DRAWN__TYPE__WITHOUT_BUNDLE,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000794 info.launchedActivity.info.name,
795 info.currentTransitionProcessRunning,
796 startupTimeMs);
Chris Wailes35c193c2018-10-09 18:12:00 -0700797
798 // Ends the trace started at the beginning of this function. This is located here to allow
799 // the trace slice to have a noticable duration.
800 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
801
Vishnu Nair132ee832018-09-28 15:00:05 -0700802 final WindowingModeTransitionInfoSnapshot infoSnapshot =
803 new WindowingModeTransitionInfoSnapshot(info, r, (int) startupTimeMs);
804 BackgroundThread.getHandler().post(() -> logAppFullyDrawn(infoSnapshot));
805 return infoSnapshot;
806 }
807
808 private void logAppFullyDrawn(WindowingModeTransitionInfoSnapshot info) {
809 if (info.type != TYPE_TRANSITION_WARM_LAUNCH && info.type != TYPE_TRANSITION_COLD_LAUNCH) {
810 return;
811 }
812
813 StringBuilder sb = mStringBuilder;
814 sb.setLength(0);
815 sb.append("Fully drawn ");
816 sb.append(info.launchedActivityShortComponentName);
817 sb.append(": ");
818 TimeUtils.formatDuration(info.windowsFullyDrawnDelayMs, sb);
819 Log.i(TAG, sb.toString());
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200820 }
821
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700822 void logActivityStart(Intent intent, WindowProcessController callerApp, ActivityRecord r,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100823 int callingUid, String callingPackage, int callingUidProcState,
824 boolean callingUidHasAnyVisibleWindow,
825 int realCallingUid, int realCallingUidProcState,
826 boolean realCallingUidHasAnyVisibleWindow,
827 int targetUid, String targetPackage, int targetUidProcState,
828 boolean targetUidHasAnyVisibleWindow, String targetWhitelistTag,
829 boolean comingFromPendingIntent) {
830
831 final long nowElapsed = SystemClock.elapsedRealtime();
832 final long nowUptime = SystemClock.uptimeMillis();
833 final LogMaker builder = new LogMaker(ACTION_ACTIVITY_START);
834 builder.setTimestamp(System.currentTimeMillis());
835 builder.addTaggedData(FIELD_CALLING_UID, callingUid);
836 builder.addTaggedData(FIELD_CALLING_PACKAGE_NAME, callingPackage);
837 builder.addTaggedData(FIELD_CALLING_UID_PROC_STATE,
838 processStateAmToProto(callingUidProcState));
839 builder.addTaggedData(FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
840 callingUidHasAnyVisibleWindow ? 1 : 0);
841 builder.addTaggedData(FIELD_REAL_CALLING_UID, realCallingUid);
842 builder.addTaggedData(FIELD_REAL_CALLING_UID_PROC_STATE,
843 processStateAmToProto(realCallingUidProcState));
844 builder.addTaggedData(FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
845 realCallingUidHasAnyVisibleWindow ? 1 : 0);
846 builder.addTaggedData(FIELD_TARGET_UID, targetUid);
847 builder.addTaggedData(FIELD_TARGET_PACKAGE_NAME, targetPackage);
848 builder.addTaggedData(FIELD_TARGET_UID_PROC_STATE,
849 processStateAmToProto(targetUidProcState));
850 builder.addTaggedData(FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW,
851 targetUidHasAnyVisibleWindow ? 1 : 0);
852 builder.addTaggedData(FIELD_TARGET_WHITELIST_TAG, targetWhitelistTag);
853 builder.addTaggedData(FIELD_TARGET_SHORT_COMPONENT_NAME, r.shortComponentName);
854 builder.addTaggedData(FIELD_COMING_FROM_PENDING_INTENT, comingFromPendingIntent ? 1 : 0);
855 builder.addTaggedData(FIELD_INTENT_ACTION, intent.getAction());
856 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700857 builder.addTaggedData(FIELD_PROCESS_RECORD_PROCESS_NAME, callerApp.mName);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100858 builder.addTaggedData(FIELD_PROCESS_RECORD_CUR_PROC_STATE,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700859 processStateAmToProto(callerApp.getCurrentProcState()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100860 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700861 callerApp.hasClientActivities() ? 1 : 0);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100862 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES,
863 callerApp.hasForegroundServices() ? 1 : 0);
864 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700865 callerApp.hasForegroundActivities() ? 1 : 0);
866 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_TOP_UI, callerApp.hasTopUi() ? 1 : 0);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100867 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_OVERLAY_UI,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700868 callerApp.hasOverlayUi() ? 1 : 0);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100869 builder.addTaggedData(FIELD_PROCESS_RECORD_PENDING_UI_CLEAN,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700870 callerApp.hasPendingUiClean() ? 1 : 0);
871 if (callerApp.getInteractionEventTime() != 0) {
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100872 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700873 (nowElapsed - callerApp.getInteractionEventTime()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100874 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700875 if (callerApp.getFgInteractionTime() != 0) {
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100876 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700877 (nowElapsed - callerApp.getFgInteractionTime()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100878 }
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700879 if (callerApp.getWhenUnimportant() != 0) {
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100880 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700881 (nowUptime - callerApp.getWhenUnimportant()));
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100882 }
883 }
884 builder.addTaggedData(FIELD_ACTIVITY_RECORD_LAUNCH_MODE, r.info.launchMode);
885 builder.addTaggedData(FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY, r.info.targetActivity);
886 builder.addTaggedData(FIELD_ACTIVITY_RECORD_FLAGS, r.info.flags);
887 builder.addTaggedData(FIELD_ACTIVITY_RECORD_REAL_ACTIVITY, r.realActivity.toShortString());
888 builder.addTaggedData(FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME, r.shortComponentName);
889 builder.addTaggedData(FIELD_ACTIVITY_RECORD_PROCESS_NAME, r.processName);
890 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_FULLSCREEN, r.fullscreen ? 1 : 0);
891 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY, r.noDisplay ? 1 : 0);
892 if (r.lastVisibleTime != 0) {
893 builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE,
894 (nowUptime - r.lastVisibleTime));
895 }
896 if (r.resultTo != null) {
897 builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME, r.resultTo.packageName);
898 builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME,
899 r.resultTo.shortComponentName);
900 }
901 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE, r.visible ? 1 : 0);
902 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD,
903 r.visibleIgnoringKeyguard ? 1 : 0);
904 if (r.lastLaunchTime != 0) {
905 builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH,
906 (nowUptime - r.lastLaunchTime));
907 }
908 mMetricsLogger.write(builder);
909 }
910
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100911 private int getTransitionType(WindowingModeTransitionInfo info) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800912 if (info.currentTransitionProcessRunning) {
913 if (info.startResult == START_SUCCESS) {
914 return TYPE_TRANSITION_WARM_LAUNCH;
915 } else if (info.startResult == START_TASK_TO_FRONT) {
916 return TYPE_TRANSITION_HOT_LAUNCH;
917 }
918 } else if (info.startResult == START_SUCCESS) {
919 return TYPE_TRANSITION_COLD_LAUNCH;
920 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700921 return INVALID_TRANSITION_TYPE;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800922 }
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800923
Ng Zhi An83473542018-02-20 09:02:14 -0800924 private void logAppStartMemoryStateCapture(WindowingModeTransitionInfoSnapshot info) {
925 if (info.processRecord == null) {
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800926 if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture processRecord null");
927 return;
928 }
929
Wale Ogunwalef6733932018-06-27 05:14:34 -0700930 final int pid = info.processRecord.getPid();
Ng Zhi An83473542018-02-20 09:02:14 -0800931 final int uid = info.applicationInfo.uid;
Rajeev Kumarbfcd9202018-03-02 22:42:13 +0000932 final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800933 if (memoryStat == null) {
934 if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture memoryStat null");
935 return;
936 }
937
938 StatsLog.write(
939 StatsLog.APP_START_MEMORY_STATE_CAPTURED,
940 uid,
Ng Zhi An83473542018-02-20 09:02:14 -0800941 info.processName,
942 info.launchedActivityName,
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800943 memoryStat.pgfault,
944 memoryStat.pgmajfault,
945 memoryStat.rssInBytes,
946 memoryStat.cacheInBytes,
947 memoryStat.swapInBytes);
948 }
949
Wale Ogunwalef6733932018-06-27 05:14:34 -0700950 private WindowProcessController findProcessForActivity(ActivityRecord launchedActivity) {
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800951 return launchedActivity != null
Wale Ogunwalef6733932018-06-27 05:14:34 -0700952 ? mSupervisor.mService.mProcessNames.get(
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700953 launchedActivity.processName, launchedActivity.appInfo.uid)
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800954 : null;
955 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000956
957 private ArtManagerInternal getArtManagerInternal() {
958 if (mArtManagerInternal == null) {
959 // Note that this may be null.
960 // ArtManagerInternal is registered during PackageManagerService
961 // initialization which happens after ActivityManagerService.
962 mArtManagerInternal = LocalServices.getService(ArtManagerInternal.class);
963 }
964 return mArtManagerInternal;
965 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700966
967 /**
Chris Wailes35c193c2018-10-09 18:12:00 -0700968 * Starts traces for app launch.
Vishnu Nair132ee832018-09-28 15:00:05 -0700969 *
970 * @param info
971 * */
972 private void startTraces(WindowingModeTransitionInfo info) {
973 if (info == null) {
974 return;
975 }
Vishnu Nair132ee832018-09-28 15:00:05 -0700976 int transitionType = getTransitionType(info);
977 if (!info.launchTraceActive && transitionType == TYPE_TRANSITION_WARM_LAUNCH
978 || transitionType == TYPE_TRANSITION_COLD_LAUNCH) {
979 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: "
980 + info.launchedActivity.packageName, 0);
Vishnu Nair132ee832018-09-28 15:00:05 -0700981 info.launchTraceActive = true;
982 }
983 }
984
985 private void stopLaunchTrace(WindowingModeTransitionInfo info) {
986 if (info == null) {
987 return;
988 }
989 if (info.launchTraceActive) {
990 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: "
991 + info.launchedActivity.packageName, 0);
992 info.launchTraceActive = false;
993 }
994 }
Igor Murashkin212d06c2018-10-22 16:34:39 -0700995
996 /** Notify the {@link ActivityMetricsLaunchObserver} that a new launch sequence has begun. */
997 private void launchObserverNotifyIntentStarted(Intent intent) {
998 if (mLaunchObserver != null) {
999 // Beginning a launch is timing sensitive and so should be observed as soon as possible.
1000 mLaunchObserver.onIntentStarted(intent);
1001 }
1002 }
1003
1004 /**
1005 * Notify the {@link ActivityMetricsLaunchObserver} that the previous launch sequence has
1006 * aborted due to intent failure (e.g. intent resolve failed or security error, etc) or
1007 * intent being delivered to the top running activity.
1008 */
1009 private void launchObserverNotifyIntentFailed() {
1010 if (mLaunchObserver != null) {
1011 mLaunchObserver.onIntentFailed();
1012 }
1013 }
1014
1015 /**
1016 * Notify the {@link ActivityMetricsLaunchObserver} that the current launch sequence's activity
1017 * has started.
1018 */
1019 private void launchObserverNotifyActivityLaunched(WindowingModeTransitionInfo info) {
1020 @ActivityMetricsLaunchObserver.Temperature int temperature =
1021 convertTransitionTypeToLaunchObserverTemperature(getTransitionType(info));
1022
1023 if (mLaunchObserver != null) {
1024 // Beginning a launch is timing sensitive and so should be observed as soon as possible.
1025 mLaunchObserver.onActivityLaunched(info.launchedActivity,
1026 temperature);
1027 }
1028 }
1029
1030 /**
1031 * Notify the {@link ActivityMetricsLaunchObserver} that the current launch sequence is
1032 * cancelled.
1033 */
1034 private void launchObserverNotifyActivityLaunchCancelled(WindowingModeTransitionInfo info) {
1035 final ActivityRecord launchedActivity = info != null ? info.launchedActivity : null;
1036
1037 if (mLaunchObserver != null) {
1038 mLaunchObserver.onActivityLaunchCancelled(launchedActivity);
1039 }
1040 }
1041
1042 /**
1043 * Notify the {@link ActivityMetricsLaunchObserver} that the current launch sequence's activity
1044 * has fully finished (successfully).
1045 */
1046 private void launchObserverNotifyActivityLaunchFinished(WindowingModeTransitionInfo info) {
1047 final ActivityRecord launchedActivity = info.launchedActivity;
1048
1049 if (mLaunchObserver != null) {
1050 mLaunchObserver.onActivityLaunchFinished(launchedActivity);
1051 }
1052 }
1053
1054 private static @ActivityMetricsLaunchObserver.Temperature int
1055 convertTransitionTypeToLaunchObserverTemperature(int transitionType) {
1056 switch (transitionType) {
1057 case TYPE_TRANSITION_WARM_LAUNCH:
1058 return ActivityMetricsLaunchObserver.TEMPERATURE_WARM;
1059 case TYPE_TRANSITION_HOT_LAUNCH:
1060 return ActivityMetricsLaunchObserver.TEMPERATURE_HOT;
1061 case TYPE_TRANSITION_COLD_LAUNCH:
1062 return ActivityMetricsLaunchObserver.TEMPERATURE_COLD;
1063 default:
1064 return -1;
1065 }
1066 }
Filip Gruszczynski77d94482015-12-11 13:59:52 -08001067}