blob: 263c34f850ce50aebaaa1b594eefcc3eee17e059 [file] [log] [blame]
Filip Gruszczynski77d94482015-12-11 13:59:52 -08001package com.android.server.am;
2
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;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07006import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;
Wale Ogunwale926aade2017-08-29 11:24:37 -07007import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Bryce Lee6c605092017-10-12 11:14:49 -07008import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
Wale Ogunwale3382ab12017-07-27 08:55:03 -07009import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
10import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Wale Ogunwale926aade2017-08-29 11:24:37 -070011import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
12import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
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;
31import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH;
32import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE;
33import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_LAUNCH_MODE;
34import 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;
60import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_PROC_STATE;
61import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
62import 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_REASON;
69import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_FILTER;
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;
Jorim Jaggi172e99f2017-10-20 14:33:18 +020075import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_METRICS;
Jorim Jaggif9704102016-05-05 19:14:22 -070076import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
77import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Ng Zhi Anbbefdec2018-01-30 17:12:39 -080078import static com.android.server.am.MemoryStatUtil.MemoryStat;
Rajeev Kumarbfcd9202018-03-02 22:42:13 +000079import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
Filip Gruszczynski77d94482015-12-11 13:59:52 -080080
Filip Gruszczynski77d94482015-12-11 13:59:52 -080081import android.content.Context;
Michal Karpinski201bc0c2018-07-20 15:32:00 +010082import android.content.Intent;
Calin Juravle759fbda2018-02-20 19:52:30 +000083import android.content.pm.ApplicationInfo;
84import android.content.pm.dex.ArtManagerInternal;
85import android.content.pm.dex.PackageOptimizationInfo;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080086import android.metrics.LogMaker;
Jorim Jaggi172e99f2017-10-20 14:33:18 +020087import android.os.Handler;
88import android.os.Looper;
89import android.os.Message;
Filip Gruszczynski77d94482015-12-11 13:59:52 -080090import android.os.SystemClock;
Jorim Jaggi172e99f2017-10-20 14:33:18 +020091import android.util.Slog;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080092import android.util.SparseArray;
93import android.util.SparseIntArray;
Olivier Gaillardaed7f122017-12-12 14:26:22 +000094import android.util.StatsLog;
Filip Gruszczynski77d94482015-12-11 13:59:52 -080095
96import com.android.internal.logging.MetricsLogger;
Ng Zhi An83473542018-02-20 09:02:14 -080097import com.android.internal.os.BackgroundThread;
Jorim Jaggi172e99f2017-10-20 14:33:18 +020098import com.android.internal.os.SomeArgs;
Calin Juravle759fbda2018-02-20 19:52:30 +000099import com.android.server.LocalServices;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800100
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700101import java.util.ArrayList;
102
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800103/**
104 * Handles logging into Tron.
105 */
106class ActivityMetricsLogger {
Jorim Jaggif9704102016-05-05 19:14:22 -0700107
108 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityMetricsLogger" : TAG_AM;
109
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800110 // Window modes we are interested in logging. If we ever introduce a new type, we need to add
111 // a value here and increase the {@link #TRON_WINDOW_STATE_VARZ_STRINGS} array.
112 private static final int WINDOW_STATE_STANDARD = 0;
113 private static final int WINDOW_STATE_SIDE_BY_SIDE = 1;
114 private static final int WINDOW_STATE_FREEFORM = 2;
Winson Chung83471632016-12-13 11:02:12 -0800115 private static final int WINDOW_STATE_ASSISTANT = 3;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800116 private static final int WINDOW_STATE_INVALID = -1;
117
Jorim Jaggi275561a2016-02-23 10:11:02 -0500118 private static final long INVALID_START_TIME = -1;
119
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200120 private static final int MSG_CHECK_VISIBILITY = 0;
121
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800122 // Preallocated strings we are sending to tron, so we don't have to allocate a new one every
123 // time we log.
124 private static final String[] TRON_WINDOW_STATE_VARZ_STRINGS = {
Winson Chung83471632016-12-13 11:02:12 -0800125 "window_time_0", "window_time_1", "window_time_2", "window_time_3"};
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800126
127 private int mWindowState = WINDOW_STATE_STANDARD;
128 private long mLastLogTimeSecs;
129 private final ActivityStackSupervisor mSupervisor;
130 private final Context mContext;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800131 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800132
Jorim Jaggi275561a2016-02-23 10:11:02 -0500133 private long mCurrentTransitionStartTime = INVALID_START_TIME;
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200134 private long mLastTransitionStartTime = INVALID_START_TIME;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800135
136 private int mCurrentTransitionDeviceUptime;
137 private int mCurrentTransitionDelayMs;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500138 private boolean mLoggedTransitionStarting;
139
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100140 private final SparseArray<WindowingModeTransitionInfo> mWindowingModeTransitionInfo =
141 new SparseArray<>();
142 private final SparseArray<WindowingModeTransitionInfo> mLastWindowingModeTransitionInfo =
143 new SparseArray<>();
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200144 private final H mHandler;
Calin Juravle759fbda2018-02-20 19:52:30 +0000145
146 private ArtManagerInternal mArtManagerInternal;
147
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200148 private final class H extends Handler {
149
150 public H(Looper looper) {
151 super(looper);
152 }
153
154 @Override
155 public void handleMessage(Message msg) {
156 switch (msg.what) {
157 case MSG_CHECK_VISIBILITY:
158 final SomeArgs args = (SomeArgs) msg.obj;
159 checkVisibility((TaskRecord) args.arg1, (ActivityRecord) args.arg2);
160 break;
161 }
162 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000163 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800164
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100165 private final class WindowingModeTransitionInfo {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800166 private ActivityRecord launchedActivity;
167 private int startResult;
168 private boolean currentTransitionProcessRunning;
169 private int windowsDrawnDelayMs;
Jorim Jaggi515dd682017-05-05 15:05:07 +0200170 private int startingWindowDelayMs = -1;
171 private int bindApplicationDelayMs = -1;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800172 private int reason = APP_TRANSITION_TIMEOUT;
173 private boolean loggedWindowsDrawn;
174 private boolean loggedStartingWindowDrawn;
175 }
176
Calin Juravle759fbda2018-02-20 19:52:30 +0000177 private final class WindowingModeTransitionInfoSnapshot {
178 final private ApplicationInfo applicationInfo;
Wale Ogunwalef6733932018-06-27 05:14:34 -0700179 final private WindowProcessController processRecord;
Calin Juravle759fbda2018-02-20 19:52:30 +0000180 final private String packageName;
181 final private String launchedActivityName;
182 final private String launchedActivityLaunchedFromPackage;
183 final private String launchedActivityLaunchToken;
184 final private String launchedActivityAppRecordRequiredAbi;
Ng Zhi An83473542018-02-20 09:02:14 -0800185 final private String processName;
Calin Juravle759fbda2018-02-20 19:52:30 +0000186 final private int reason;
187 final private int startingWindowDelayMs;
188 final private int bindApplicationDelayMs;
189 final private int windowsDrawnDelayMs;
190 final private int type;
191
192 private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info) {
193 applicationInfo = info.launchedActivity.appInfo;
194 packageName = info.launchedActivity.packageName;
195 launchedActivityName = info.launchedActivity.info.name;
196 launchedActivityLaunchedFromPackage = info.launchedActivity.launchedFromPackage;
197 launchedActivityLaunchToken = info.launchedActivity.info.launchToken;
198 launchedActivityAppRecordRequiredAbi = info.launchedActivity.app == null
199 ? null
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700200 : info.launchedActivity.app.getRequiredAbi();
Calin Juravle759fbda2018-02-20 19:52:30 +0000201 reason = info.reason;
202 startingWindowDelayMs = info.startingWindowDelayMs;
203 bindApplicationDelayMs = info.bindApplicationDelayMs;
204 windowsDrawnDelayMs = info.windowsDrawnDelayMs;
205 type = getTransitionType(info);
Ng Zhi An83473542018-02-20 09:02:14 -0800206 processRecord = findProcessForActivity(info.launchedActivity);
207 processName = info.launchedActivity.processName;
Calin Juravle759fbda2018-02-20 19:52:30 +0000208 }
209 }
210
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200211 ActivityMetricsLogger(ActivityStackSupervisor supervisor, Context context, Looper looper) {
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800212 mLastLogTimeSecs = SystemClock.elapsedRealtime() / 1000;
213 mSupervisor = supervisor;
214 mContext = context;
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200215 mHandler = new H(looper);
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800216 }
217
218 void logWindowState() {
219 final long now = SystemClock.elapsedRealtime() / 1000;
220 if (mWindowState != WINDOW_STATE_INVALID) {
221 // We log even if the window state hasn't changed, because the user might remain in
222 // home/fullscreen move forever and we would like to track this kind of behavior
223 // too.
224 MetricsLogger.count(mContext, TRON_WINDOW_STATE_VARZ_STRINGS[mWindowState],
225 (int) (now - mLastLogTimeSecs));
226 }
227 mLastLogTimeSecs = now;
228
Wale Ogunwale926aade2017-08-29 11:24:37 -0700229 mWindowState = WINDOW_STATE_INVALID;
Andrii Kulian5f750bc2018-07-17 08:57:23 -0700230 ActivityStack stack = mSupervisor.getTopDisplayFocusedStack();
lumarkf6c4a982018-06-15 15:43:12 +0800231 if (stack == null) {
232 return;
233 }
234
Wale Ogunwale926aade2017-08-29 11:24:37 -0700235 if (stack.isActivityTypeAssistant()) {
236 mWindowState = WINDOW_STATE_ASSISTANT;
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800237 return;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800238 }
Wale Ogunwale926aade2017-08-29 11:24:37 -0700239
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700240 int windowingMode = stack.getWindowingMode();
241 if (windowingMode == WINDOWING_MODE_PINNED) {
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800242 stack = mSupervisor.findStackBehind(stack);
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700243 windowingMode = stack.getWindowingMode();
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800244 }
Wale Ogunwale926aade2017-08-29 11:24:37 -0700245 switch (windowingMode) {
246 case WINDOWING_MODE_FULLSCREEN:
247 mWindowState = WINDOW_STATE_STANDARD;
248 break;
249 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
250 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
251 mWindowState = WINDOW_STATE_SIDE_BY_SIDE;
252 break;
Bryce Lee6c605092017-10-12 11:14:49 -0700253 case WINDOWING_MODE_FREEFORM:
Wale Ogunwale926aade2017-08-29 11:24:37 -0700254 mWindowState = WINDOW_STATE_FREEFORM;
255 break;
256 default:
257 if (windowingMode != WINDOWING_MODE_UNDEFINED) {
258 throw new IllegalStateException("Unknown windowing mode for stack=" + stack
259 + " windowingMode=" + windowingMode);
260 }
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800261 }
262 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500263
264 /**
265 * Notifies the tracker at the earliest possible point when we are starting to launch an
266 * activity.
267 */
268 void notifyActivityLaunching() {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800269 if (!isAnyTransitionActive()) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200270 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunching");
Alison Cichowlasb7f67ab2017-04-25 18:04:40 -0400271 mCurrentTransitionStartTime = SystemClock.uptimeMillis();
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200272 mLastTransitionStartTime = mCurrentTransitionStartTime;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800273 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500274 }
275
276 /**
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700277 * Notifies the tracker that the activity is actually launching.
278 *
279 * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the
280 * launch
281 * @param launchedActivity the activity that is being launched
282 */
283 void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity) {
Wale Ogunwalef6733932018-06-27 05:14:34 -0700284 final WindowProcessController processRecord = findProcessForActivity(launchedActivity);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700285 final boolean processRunning = processRecord != null;
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700286
287 // We consider this a "process switch" if the process of the activity that gets launched
288 // didn't have an activity that was in started state. In this case, we assume that lot
289 // of caches might be purged so the time until it produces the first frame is very
290 // interesting.
291 final boolean processSwitch = processRecord == null
Wale Ogunwalef6733932018-06-27 05:14:34 -0700292 || !processRecord.hasStartedActivity(launchedActivity);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700293
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800294 notifyActivityLaunched(resultCode, launchedActivity, processRunning, processSwitch);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700295 }
296
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700297 /**
Jorim Jaggi275561a2016-02-23 10:11:02 -0500298 * Notifies the tracker the the activity is actually launching.
299 *
300 * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the
301 * launch
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800302 * @param launchedActivity the activity being launched
Jorim Jaggi275561a2016-02-23 10:11:02 -0500303 * @param processRunning whether the process that will contains the activity is already running
Jorim Jaggibe67c902016-04-12 00:53:16 -0700304 * @param processSwitch whether the process that will contain the activity didn't have any
305 * activity that was stopped, i.e. the started activity is "switching"
306 * processes
Jorim Jaggi275561a2016-02-23 10:11:02 -0500307 */
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800308 private void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity,
Jorim Jaggibe67c902016-04-12 00:53:16 -0700309 boolean processRunning, boolean processSwitch) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500310
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200311 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched"
312 + " resultCode=" + resultCode
313 + " launchedActivity=" + launchedActivity
314 + " processRunning=" + processRunning
315 + " processSwitch=" + processSwitch);
316
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800317 // If we are already in an existing transition, only update the activity name, but not the
318 // other attributes.
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100319 final int windowingMode = launchedActivity != null
320 ? launchedActivity.getWindowingMode()
321 : WINDOWING_MODE_UNDEFINED;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200322
323 if (mCurrentTransitionStartTime == INVALID_START_TIME) {
324 return;
325 }
326
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100327 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800328 if (launchedActivity != null && info != null) {
329 info.launchedActivity = launchedActivity;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500330 return;
331 }
332
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100333 final boolean otherWindowModesLaunching =
334 mWindowingModeTransitionInfo.size() > 0 && info == null;
Jorim Jaggi54cff642018-03-15 15:51:32 +0100335 if ((!isLoggableResultCode(resultCode) || launchedActivity == null || !processSwitch
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100336 || windowingMode == WINDOWING_MODE_UNDEFINED) && !otherWindowModesLaunching) {
Alison Cichowlas803054d2016-12-13 14:38:01 -0500337
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800338 // Failed to launch or it was not a process switch, so we don't care about the timing.
339 reset(true /* abort */);
340 return;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100341 } else if (otherWindowModesLaunching) {
342 // Don't log this windowing mode but continue with the other windowing modes.
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800343 return;
344 }
345
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200346 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched successful");
347
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100348 final WindowingModeTransitionInfo newInfo = new WindowingModeTransitionInfo();
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800349 newInfo.launchedActivity = launchedActivity;
350 newInfo.currentTransitionProcessRunning = processRunning;
351 newInfo.startResult = resultCode;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100352 mWindowingModeTransitionInfo.put(windowingMode, newInfo);
353 mLastWindowingModeTransitionInfo.put(windowingMode, newInfo);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800354 mCurrentTransitionDeviceUptime = (int) (SystemClock.uptimeMillis() / 1000);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500355 }
356
357 /**
Jorim Jaggi54cff642018-03-15 15:51:32 +0100358 * @return True if we should start logging an event for an activity start that returned
359 * {@code resultCode} and that we'll indeed get a windows drawn event.
360 */
361 private boolean isLoggableResultCode(int resultCode) {
362 return resultCode == START_SUCCESS || resultCode == START_TASK_TO_FRONT;
363 }
364
365 /**
Jorim Jaggi275561a2016-02-23 10:11:02 -0500366 * Notifies the tracker that all windows of the app have been drawn.
367 */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100368 void notifyWindowsDrawn(int windowingMode, long timestamp) {
369 if (DEBUG_METRICS) Slog.i(TAG, "notifyWindowsDrawn windowingMode=" + windowingMode);
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200370
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100371 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800372 if (info == null || info.loggedWindowsDrawn) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500373 return;
374 }
Sudheer Shankac766db02017-06-12 10:37:29 -0700375 info.windowsDrawnDelayMs = calculateDelay(timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800376 info.loggedWindowsDrawn = true;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100377 if (allWindowsDrawn() && mLoggedTransitionStarting) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800378 reset(false /* abort */);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500379 }
380 }
381
382 /**
383 * Notifies the tracker that the starting window was drawn.
384 */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100385 void notifyStartingWindowDrawn(int windowingMode, long timestamp) {
386 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800387 if (info == null || info.loggedStartingWindowDrawn) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500388 return;
389 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800390 info.loggedStartingWindowDrawn = true;
Sudheer Shankac766db02017-06-12 10:37:29 -0700391 info.startingWindowDelayMs = calculateDelay(timestamp);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500392 }
393
394 /**
395 * Notifies the tracker that the app transition is starting.
396 *
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100397 * @param windowingModeToReason A map from windowing mode to a reason integer, which must be on
398 * of ActivityManagerInternal.APP_TRANSITION_* reasons.
Jorim Jaggi275561a2016-02-23 10:11:02 -0500399 */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100400 void notifyTransitionStarting(SparseIntArray windowingModeToReason, long timestamp) {
Jorim Jaggid8a57772017-04-14 16:50:42 -0700401 if (!isAnyTransitionActive() || mLoggedTransitionStarting) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500402 return;
403 }
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200404 if (DEBUG_METRICS) Slog.i(TAG, "notifyTransitionStarting");
Sudheer Shankac766db02017-06-12 10:37:29 -0700405 mCurrentTransitionDelayMs = calculateDelay(timestamp);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500406 mLoggedTransitionStarting = true;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100407 for (int index = windowingModeToReason.size() - 1; index >= 0; index--) {
408 final int windowingMode = windowingModeToReason.keyAt(index);
409 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
410 windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800411 if (info == null) {
412 continue;
413 }
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100414 info.reason = windowingModeToReason.valueAt(index);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800415 }
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100416 if (allWindowsDrawn()) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800417 reset(false /* abort */);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500418 }
419 }
420
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200421 /**
422 * Notifies the tracker that the visibility of an app is changing.
423 *
424 * @param activityRecord the app that is changing its visibility
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200425 */
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200426 void notifyVisibilityChanged(ActivityRecord activityRecord) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100427 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
428 activityRecord.getWindowingMode());
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200429 if (info == null) {
430 return;
431 }
432 if (info.launchedActivity != activityRecord) {
433 return;
434 }
435 final TaskRecord t = activityRecord.getTask();
436 final SomeArgs args = SomeArgs.obtain();
437 args.arg1 = t;
438 args.arg2 = activityRecord;
439 mHandler.obtainMessage(MSG_CHECK_VISIBILITY, args).sendToTarget();
440 }
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200441
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200442 private void checkVisibility(TaskRecord t, ActivityRecord r) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700443 synchronized (mSupervisor.mService.mGlobalLock) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200444
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100445 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
446 r.getWindowingMode());
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200447
448 // If we have an active transition that's waiting on a certain activity that will be
449 // invisible now, we'll never get onWindowsDrawn, so abort the transition if necessary.
450 if (info != null && !t.isVisible()) {
451 if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible"
452 + " activity=" + r);
453 logAppTransitionCancel(info);
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100454 mWindowingModeTransitionInfo.remove(r.getWindowingMode());
455 if (mWindowingModeTransitionInfo.size() == 0) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200456 reset(true /* abort */);
457 }
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200458 }
459 }
460 }
461
Jorim Jaggi515dd682017-05-05 15:05:07 +0200462 /**
463 * Notifies the tracker that we called immediately before we call bindApplication on the client.
464 *
465 * @param app The client into which we'll call bindApplication.
466 */
467 void notifyBindApplication(ProcessRecord app) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100468 for (int i = mWindowingModeTransitionInfo.size() - 1; i >= 0; i--) {
469 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(i);
Jorim Jaggi515dd682017-05-05 15:05:07 +0200470
471 // App isn't attached to record yet, so match with info.
472 if (info.launchedActivity.appInfo == app.info) {
473 info.bindApplicationDelayMs = calculateCurrentDelay();
474 }
475 }
476 }
477
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100478 private boolean allWindowsDrawn() {
479 for (int index = mWindowingModeTransitionInfo.size() - 1; index >= 0; index--) {
480 if (!mWindowingModeTransitionInfo.valueAt(index).loggedWindowsDrawn) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800481 return false;
482 }
483 }
484 return true;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500485 }
486
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800487 private boolean isAnyTransitionActive() {
488 return mCurrentTransitionStartTime != INVALID_START_TIME
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100489 && mWindowingModeTransitionInfo.size() > 0;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800490 }
491
492 private void reset(boolean abort) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200493 if (DEBUG_METRICS) Slog.i(TAG, "reset abort=" + abort);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800494 if (!abort && isAnyTransitionActive()) {
495 logAppTransitionMultiEvents();
496 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500497 mCurrentTransitionStartTime = INVALID_START_TIME;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800498 mCurrentTransitionDelayMs = -1;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500499 mLoggedTransitionStarting = false;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100500 mWindowingModeTransitionInfo.clear();
Jorim Jaggi275561a2016-02-23 10:11:02 -0500501 }
502
503 private int calculateCurrentDelay() {
504
505 // Shouldn't take more than 25 days to launch an app, so int is fine here.
Alison Cichowlasb7f67ab2017-04-25 18:04:40 -0400506 return (int) (SystemClock.uptimeMillis() - mCurrentTransitionStartTime);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500507 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800508
Sudheer Shankac766db02017-06-12 10:37:29 -0700509 private int calculateDelay(long timestamp) {
510 // Shouldn't take more than 25 days to launch an app, so int is fine here.
511 return (int) (timestamp - mCurrentTransitionStartTime);
512 }
513
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100514 private void logAppTransitionCancel(WindowingModeTransitionInfo info) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200515 final int type = getTransitionType(info);
516 if (type == -1) {
517 return;
518 }
519 final LogMaker builder = new LogMaker(APP_TRANSITION_CANCELLED);
520 builder.setPackageName(info.launchedActivity.packageName);
521 builder.setType(type);
522 builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivity.info.name);
523 mMetricsLogger.write(builder);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000524 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800525 StatsLog.APP_START_CANCELED,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000526 info.launchedActivity.appInfo.uid,
527 info.launchedActivity.packageName,
528 convertAppStartTransitionType(type),
529 info.launchedActivity.info.name);
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200530 }
531
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800532 private void logAppTransitionMultiEvents() {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200533 if (DEBUG_METRICS) Slog.i(TAG, "logging transition events");
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100534 for (int index = mWindowingModeTransitionInfo.size() - 1; index >= 0; index--) {
535 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(index);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800536 final int type = getTransitionType(info);
537 if (type == -1) {
538 return;
539 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000540
541 // Take a snapshot of the transition info before sending it to the handler for logging.
542 // This will avoid any races with other operations that modify the ActivityRecord.
543 final WindowingModeTransitionInfoSnapshot infoSnapshot =
544 new WindowingModeTransitionInfoSnapshot(info);
Ng Zhi An83473542018-02-20 09:02:14 -0800545 final int currentTransitionDeviceUptime = mCurrentTransitionDeviceUptime;
546 final int currentTransitionDelayMs = mCurrentTransitionDelayMs;
547 BackgroundThread.getHandler().post(() -> logAppTransition(
548 currentTransitionDeviceUptime, currentTransitionDelayMs, infoSnapshot));
Calin Juravle759fbda2018-02-20 19:52:30 +0000549
550 info.launchedActivity.info.launchToken = null;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800551 }
552 }
553
Ng Zhi An83473542018-02-20 09:02:14 -0800554 // This gets called on a background thread without holding the activity manager lock.
Calin Juravle759fbda2018-02-20 19:52:30 +0000555 private void logAppTransition(int currentTransitionDeviceUptime, int currentTransitionDelayMs,
556 WindowingModeTransitionInfoSnapshot info) {
557 final LogMaker builder = new LogMaker(APP_TRANSITION);
558 builder.setPackageName(info.packageName);
559 builder.setType(info.type);
560 builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivityName);
561 final boolean isInstantApp = info.applicationInfo.isInstantApp();
562 if (info.launchedActivityLaunchedFromPackage != null) {
563 builder.addTaggedData(APP_TRANSITION_CALLING_PACKAGE_NAME,
564 info.launchedActivityLaunchedFromPackage);
565 }
566 String launchToken = info.launchedActivityLaunchToken;
567 if (launchToken != null) {
568 builder.addTaggedData(FIELD_INSTANT_APP_LAUNCH_TOKEN, launchToken);
569 }
570 builder.addTaggedData(APP_TRANSITION_IS_EPHEMERAL, isInstantApp ? 1 : 0);
571 builder.addTaggedData(APP_TRANSITION_DEVICE_UPTIME_SECONDS,
572 currentTransitionDeviceUptime);
573 builder.addTaggedData(APP_TRANSITION_DELAY_MS, currentTransitionDelayMs);
574 builder.setSubtype(info.reason);
575 if (info.startingWindowDelayMs != -1) {
576 builder.addTaggedData(APP_TRANSITION_STARTING_WINDOW_DELAY_MS,
577 info.startingWindowDelayMs);
578 }
579 if (info.bindApplicationDelayMs != -1) {
580 builder.addTaggedData(APP_TRANSITION_BIND_APPLICATION_DELAY_MS,
581 info.bindApplicationDelayMs);
582 }
583 builder.addTaggedData(APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, info.windowsDrawnDelayMs);
584 final ArtManagerInternal artManagerInternal = getArtManagerInternal();
585 final PackageOptimizationInfo packageOptimizationInfo =
586 (artManagerInternal == null) || (info.launchedActivityAppRecordRequiredAbi == null)
587 ? PackageOptimizationInfo.createWithNoInfo()
588 : artManagerInternal.getPackageOptimizationInfo(
589 info.applicationInfo,
590 info.launchedActivityAppRecordRequiredAbi);
591 builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_REASON,
592 packageOptimizationInfo.getCompilationReason());
593 builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_FILTER,
594 packageOptimizationInfo.getCompilationFilter());
595 mMetricsLogger.write(builder);
596 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800597 StatsLog.APP_START_OCCURRED,
Calin Juravle759fbda2018-02-20 19:52:30 +0000598 info.applicationInfo.uid,
599 info.packageName,
600 convertAppStartTransitionType(info.type),
601 info.launchedActivityName,
602 info.launchedActivityLaunchedFromPackage,
603 isInstantApp,
604 currentTransitionDeviceUptime * 1000,
605 info.reason,
606 currentTransitionDelayMs,
607 info.startingWindowDelayMs,
608 info.bindApplicationDelayMs,
609 info.windowsDrawnDelayMs,
610 launchToken,
611 packageOptimizationInfo.getCompilationReason(),
612 packageOptimizationInfo.getCompilationFilter());
Ng Zhi An83473542018-02-20 09:02:14 -0800613 logAppStartMemoryStateCapture(info);
Calin Juravle759fbda2018-02-20 19:52:30 +0000614 }
615
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000616 private int convertAppStartTransitionType(int tronType) {
617 if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800618 return StatsLog.APP_START_OCCURRED__TYPE__COLD;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000619 }
620 if (tronType == TYPE_TRANSITION_WARM_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800621 return StatsLog.APP_START_OCCURRED__TYPE__WARM;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000622 }
623 if (tronType == TYPE_TRANSITION_HOT_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800624 return StatsLog.APP_START_OCCURRED__TYPE__HOT;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000625 }
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800626 return StatsLog.APP_START_OCCURRED__TYPE__UNKNOWN;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000627 }
628
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200629 void logAppTransitionReportedDrawn(ActivityRecord r, boolean restoredFromBundle) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100630 final WindowingModeTransitionInfo info = mLastWindowingModeTransitionInfo.get(
631 r.getWindowingMode());
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200632 if (info == null) {
633 return;
634 }
635 final LogMaker builder = new LogMaker(APP_TRANSITION_REPORTED_DRAWN);
636 builder.setPackageName(r.packageName);
637 builder.addTaggedData(FIELD_CLASS_NAME, r.info.name);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000638 long startupTimeMs = SystemClock.uptimeMillis() - mLastTransitionStartTime;
639 builder.addTaggedData(APP_TRANSITION_REPORTED_DRAWN_MS, startupTimeMs);
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200640 builder.setType(restoredFromBundle
641 ? TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE
642 : TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE);
643 builder.addTaggedData(APP_TRANSITION_PROCESS_RUNNING,
644 info.currentTransitionProcessRunning ? 1 : 0);
645 mMetricsLogger.write(builder);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000646 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800647 StatsLog.APP_START_FULLY_DRAWN,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000648 info.launchedActivity.appInfo.uid,
649 info.launchedActivity.packageName,
650 restoredFromBundle
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800651 ? StatsLog.APP_START_FULLY_DRAWN__TYPE__WITH_BUNDLE
652 : StatsLog.APP_START_FULLY_DRAWN__TYPE__WITHOUT_BUNDLE,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000653 info.launchedActivity.info.name,
654 info.currentTransitionProcessRunning,
655 startupTimeMs);
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200656 }
657
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100658 void logActivityStart(Intent intent, ProcessRecord callerApp, ActivityRecord r,
659 int callingUid, String callingPackage, int callingUidProcState,
660 boolean callingUidHasAnyVisibleWindow,
661 int realCallingUid, int realCallingUidProcState,
662 boolean realCallingUidHasAnyVisibleWindow,
663 int targetUid, String targetPackage, int targetUidProcState,
664 boolean targetUidHasAnyVisibleWindow, String targetWhitelistTag,
665 boolean comingFromPendingIntent) {
666
667 final long nowElapsed = SystemClock.elapsedRealtime();
668 final long nowUptime = SystemClock.uptimeMillis();
669 final LogMaker builder = new LogMaker(ACTION_ACTIVITY_START);
670 builder.setTimestamp(System.currentTimeMillis());
671 builder.addTaggedData(FIELD_CALLING_UID, callingUid);
672 builder.addTaggedData(FIELD_CALLING_PACKAGE_NAME, callingPackage);
673 builder.addTaggedData(FIELD_CALLING_UID_PROC_STATE,
674 processStateAmToProto(callingUidProcState));
675 builder.addTaggedData(FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
676 callingUidHasAnyVisibleWindow ? 1 : 0);
677 builder.addTaggedData(FIELD_REAL_CALLING_UID, realCallingUid);
678 builder.addTaggedData(FIELD_REAL_CALLING_UID_PROC_STATE,
679 processStateAmToProto(realCallingUidProcState));
680 builder.addTaggedData(FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
681 realCallingUidHasAnyVisibleWindow ? 1 : 0);
682 builder.addTaggedData(FIELD_TARGET_UID, targetUid);
683 builder.addTaggedData(FIELD_TARGET_PACKAGE_NAME, targetPackage);
684 builder.addTaggedData(FIELD_TARGET_UID_PROC_STATE,
685 processStateAmToProto(targetUidProcState));
686 builder.addTaggedData(FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW,
687 targetUidHasAnyVisibleWindow ? 1 : 0);
688 builder.addTaggedData(FIELD_TARGET_WHITELIST_TAG, targetWhitelistTag);
689 builder.addTaggedData(FIELD_TARGET_SHORT_COMPONENT_NAME, r.shortComponentName);
690 builder.addTaggedData(FIELD_COMING_FROM_PENDING_INTENT, comingFromPendingIntent ? 1 : 0);
691 builder.addTaggedData(FIELD_INTENT_ACTION, intent.getAction());
692 if (callerApp != null) {
693 builder.addTaggedData(FIELD_PROCESS_RECORD_PROCESS_NAME, callerApp.processName);
694 builder.addTaggedData(FIELD_PROCESS_RECORD_CUR_PROC_STATE,
695 processStateAmToProto(callerApp.curProcState));
696 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES,
697 callerApp.hasClientActivities ? 1 : 0);
698 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES,
699 callerApp.hasForegroundServices() ? 1 : 0);
700 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES,
701 callerApp.foregroundActivities ? 1 : 0);
702 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_TOP_UI, callerApp.hasTopUi ? 1 : 0);
703 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_OVERLAY_UI,
704 callerApp.hasOverlayUi ? 1 : 0);
705 builder.addTaggedData(FIELD_PROCESS_RECORD_PENDING_UI_CLEAN,
706 callerApp.pendingUiClean ? 1 : 0);
707 if (callerApp.interactionEventTime != 0) {
708 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT,
709 (nowElapsed - callerApp.interactionEventTime));
710 }
711 if (callerApp.fgInteractionTime != 0) {
712 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION,
713 (nowElapsed - callerApp.fgInteractionTime));
714 }
715 if (callerApp.whenUnimportant != 0) {
716 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT,
717 (nowUptime - callerApp.whenUnimportant));
718 }
719 }
720 builder.addTaggedData(FIELD_ACTIVITY_RECORD_LAUNCH_MODE, r.info.launchMode);
721 builder.addTaggedData(FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY, r.info.targetActivity);
722 builder.addTaggedData(FIELD_ACTIVITY_RECORD_FLAGS, r.info.flags);
723 builder.addTaggedData(FIELD_ACTIVITY_RECORD_REAL_ACTIVITY, r.realActivity.toShortString());
724 builder.addTaggedData(FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME, r.shortComponentName);
725 builder.addTaggedData(FIELD_ACTIVITY_RECORD_PROCESS_NAME, r.processName);
726 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_FULLSCREEN, r.fullscreen ? 1 : 0);
727 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY, r.noDisplay ? 1 : 0);
728 if (r.lastVisibleTime != 0) {
729 builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE,
730 (nowUptime - r.lastVisibleTime));
731 }
732 if (r.resultTo != null) {
733 builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME, r.resultTo.packageName);
734 builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME,
735 r.resultTo.shortComponentName);
736 }
737 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE, r.visible ? 1 : 0);
738 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD,
739 r.visibleIgnoringKeyguard ? 1 : 0);
740 if (r.lastLaunchTime != 0) {
741 builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH,
742 (nowUptime - r.lastLaunchTime));
743 }
744 mMetricsLogger.write(builder);
745 }
746
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100747 private int getTransitionType(WindowingModeTransitionInfo info) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800748 if (info.currentTransitionProcessRunning) {
749 if (info.startResult == START_SUCCESS) {
750 return TYPE_TRANSITION_WARM_LAUNCH;
751 } else if (info.startResult == START_TASK_TO_FRONT) {
752 return TYPE_TRANSITION_HOT_LAUNCH;
753 }
754 } else if (info.startResult == START_SUCCESS) {
755 return TYPE_TRANSITION_COLD_LAUNCH;
756 }
757 return -1;
758 }
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800759
Ng Zhi An83473542018-02-20 09:02:14 -0800760 private void logAppStartMemoryStateCapture(WindowingModeTransitionInfoSnapshot info) {
761 if (info.processRecord == null) {
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800762 if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture processRecord null");
763 return;
764 }
765
Wale Ogunwalef6733932018-06-27 05:14:34 -0700766 final int pid = info.processRecord.getPid();
Ng Zhi An83473542018-02-20 09:02:14 -0800767 final int uid = info.applicationInfo.uid;
Rajeev Kumarbfcd9202018-03-02 22:42:13 +0000768 final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800769 if (memoryStat == null) {
770 if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture memoryStat null");
771 return;
772 }
773
774 StatsLog.write(
775 StatsLog.APP_START_MEMORY_STATE_CAPTURED,
776 uid,
Ng Zhi An83473542018-02-20 09:02:14 -0800777 info.processName,
778 info.launchedActivityName,
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800779 memoryStat.pgfault,
780 memoryStat.pgmajfault,
781 memoryStat.rssInBytes,
782 memoryStat.cacheInBytes,
783 memoryStat.swapInBytes);
784 }
785
Wale Ogunwalef6733932018-06-27 05:14:34 -0700786 private WindowProcessController findProcessForActivity(ActivityRecord launchedActivity) {
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800787 return launchedActivity != null
Wale Ogunwalef6733932018-06-27 05:14:34 -0700788 ? mSupervisor.mService.mProcessNames.get(
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700789 launchedActivity.processName, launchedActivity.appInfo.uid)
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800790 : null;
791 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000792
793 private ArtManagerInternal getArtManagerInternal() {
794 if (mArtManagerInternal == null) {
795 // Note that this may be null.
796 // ArtManagerInternal is registered during PackageManagerService
797 // initialization which happens after ActivityManagerService.
798 mArtManagerInternal = LocalServices.getService(ArtManagerInternal.class);
799 }
800 return mArtManagerInternal;
801 }
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800802}