blob: 9ffa6627836f0568a8ca1d2a7f68d6794e67c811 [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 Karpinski3eab9512018-07-20 15:32:00 +01005import static android.app.ActivityManager.processStateAmToProto;
Jorim Jaggi3878ca32017-02-02 17:13:05 -08006import static android.app.ActivityManagerInternal.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 Karpinski3eab9512018-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 Karpinski3eab9512018-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 Karpinski3eab9512018-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 Karpinski3eab9512018-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 Karpinski3eab9512018-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;
Ng Zhi An83473542018-02-20 09:02:14 -0800179 final private ProcessRecord 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
200 : info.launchedActivity.app.requiredAbi;
201 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;
230 ActivityStack stack = mSupervisor.getFocusedStack();
231 if (stack.isActivityTypeAssistant()) {
232 mWindowState = WINDOW_STATE_ASSISTANT;
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800233 return;
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800234 }
Wale Ogunwale926aade2017-08-29 11:24:37 -0700235
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700236 int windowingMode = stack.getWindowingMode();
237 if (windowingMode == WINDOWING_MODE_PINNED) {
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800238 stack = mSupervisor.findStackBehind(stack);
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700239 windowingMode = stack.getWindowingMode();
Filip Gruszczynskicaae14e2015-12-16 14:40:04 -0800240 }
Wale Ogunwale926aade2017-08-29 11:24:37 -0700241 switch (windowingMode) {
242 case WINDOWING_MODE_FULLSCREEN:
243 mWindowState = WINDOW_STATE_STANDARD;
244 break;
245 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
246 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
247 mWindowState = WINDOW_STATE_SIDE_BY_SIDE;
248 break;
Bryce Lee6c605092017-10-12 11:14:49 -0700249 case WINDOWING_MODE_FREEFORM:
Wale Ogunwale926aade2017-08-29 11:24:37 -0700250 mWindowState = WINDOW_STATE_FREEFORM;
251 break;
252 default:
253 if (windowingMode != WINDOWING_MODE_UNDEFINED) {
254 throw new IllegalStateException("Unknown windowing mode for stack=" + stack
255 + " windowingMode=" + windowingMode);
256 }
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800257 }
258 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500259
260 /**
261 * Notifies the tracker at the earliest possible point when we are starting to launch an
262 * activity.
263 */
264 void notifyActivityLaunching() {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800265 if (!isAnyTransitionActive()) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200266 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunching");
Alison Cichowlasb7f67ab2017-04-25 18:04:40 -0400267 mCurrentTransitionStartTime = SystemClock.uptimeMillis();
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200268 mLastTransitionStartTime = mCurrentTransitionStartTime;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800269 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500270 }
271
272 /**
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700273 * Notifies the tracker that the activity is actually launching.
274 *
275 * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the
276 * launch
277 * @param launchedActivity the activity that is being launched
278 */
279 void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity) {
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800280 final ProcessRecord processRecord = findProcessForActivity(launchedActivity);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700281 final boolean processRunning = processRecord != null;
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700282
283 // We consider this a "process switch" if the process of the activity that gets launched
284 // didn't have an activity that was in started state. In this case, we assume that lot
285 // of caches might be purged so the time until it produces the first frame is very
286 // interesting.
287 final boolean processSwitch = processRecord == null
288 || !hasStartedActivity(processRecord, launchedActivity);
289
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800290 notifyActivityLaunched(resultCode, launchedActivity, processRunning, processSwitch);
Jorim Jaggi1e630c02016-05-16 12:13:13 -0700291 }
292
293 private boolean hasStartedActivity(ProcessRecord record, ActivityRecord launchedActivity) {
294 final ArrayList<ActivityRecord> activities = record.activities;
295 for (int i = activities.size() - 1; i >= 0; i--) {
296 final ActivityRecord activity = activities.get(i);
297 if (launchedActivity == activity) {
298 continue;
299 }
300 if (!activity.stopped) {
301 return true;
302 }
303 }
304 return false;
305 }
306
307 /**
Jorim Jaggi275561a2016-02-23 10:11:02 -0500308 * Notifies the tracker the the activity is actually launching.
309 *
310 * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the
311 * launch
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800312 * @param launchedActivity the activity being launched
Jorim Jaggi275561a2016-02-23 10:11:02 -0500313 * @param processRunning whether the process that will contains the activity is already running
Jorim Jaggibe67c902016-04-12 00:53:16 -0700314 * @param processSwitch whether the process that will contain the activity didn't have any
315 * activity that was stopped, i.e. the started activity is "switching"
316 * processes
Jorim Jaggi275561a2016-02-23 10:11:02 -0500317 */
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800318 private void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity,
Jorim Jaggibe67c902016-04-12 00:53:16 -0700319 boolean processRunning, boolean processSwitch) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500320
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200321 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched"
322 + " resultCode=" + resultCode
323 + " launchedActivity=" + launchedActivity
324 + " processRunning=" + processRunning
325 + " processSwitch=" + processSwitch);
326
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800327 // If we are already in an existing transition, only update the activity name, but not the
328 // other attributes.
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100329 final int windowingMode = launchedActivity != null
330 ? launchedActivity.getWindowingMode()
331 : WINDOWING_MODE_UNDEFINED;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200332
333 if (mCurrentTransitionStartTime == INVALID_START_TIME) {
334 return;
335 }
336
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100337 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800338 if (launchedActivity != null && info != null) {
339 info.launchedActivity = launchedActivity;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500340 return;
341 }
342
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100343 final boolean otherWindowModesLaunching =
344 mWindowingModeTransitionInfo.size() > 0 && info == null;
Jorim Jaggi54cff642018-03-15 15:51:32 +0100345 if ((!isLoggableResultCode(resultCode) || launchedActivity == null || !processSwitch
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100346 || windowingMode == WINDOWING_MODE_UNDEFINED) && !otherWindowModesLaunching) {
Alison Cichowlas803054d2016-12-13 14:38:01 -0500347
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800348 // Failed to launch or it was not a process switch, so we don't care about the timing.
349 reset(true /* abort */);
350 return;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100351 } else if (otherWindowModesLaunching) {
352 // Don't log this windowing mode but continue with the other windowing modes.
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800353 return;
354 }
355
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200356 if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched successful");
357
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100358 final WindowingModeTransitionInfo newInfo = new WindowingModeTransitionInfo();
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800359 newInfo.launchedActivity = launchedActivity;
360 newInfo.currentTransitionProcessRunning = processRunning;
361 newInfo.startResult = resultCode;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100362 mWindowingModeTransitionInfo.put(windowingMode, newInfo);
363 mLastWindowingModeTransitionInfo.put(windowingMode, newInfo);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800364 mCurrentTransitionDeviceUptime = (int) (SystemClock.uptimeMillis() / 1000);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500365 }
366
367 /**
Jorim Jaggi54cff642018-03-15 15:51:32 +0100368 * @return True if we should start logging an event for an activity start that returned
369 * {@code resultCode} and that we'll indeed get a windows drawn event.
370 */
371 private boolean isLoggableResultCode(int resultCode) {
372 return resultCode == START_SUCCESS || resultCode == START_TASK_TO_FRONT;
373 }
374
375 /**
Jorim Jaggi275561a2016-02-23 10:11:02 -0500376 * Notifies the tracker that all windows of the app have been drawn.
377 */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100378 void notifyWindowsDrawn(int windowingMode, long timestamp) {
379 if (DEBUG_METRICS) Slog.i(TAG, "notifyWindowsDrawn windowingMode=" + windowingMode);
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200380
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100381 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800382 if (info == null || info.loggedWindowsDrawn) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500383 return;
384 }
Sudheer Shankac766db02017-06-12 10:37:29 -0700385 info.windowsDrawnDelayMs = calculateDelay(timestamp);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800386 info.loggedWindowsDrawn = true;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100387 if (allWindowsDrawn() && mLoggedTransitionStarting) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800388 reset(false /* abort */);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500389 }
390 }
391
392 /**
393 * Notifies the tracker that the starting window was drawn.
394 */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100395 void notifyStartingWindowDrawn(int windowingMode, long timestamp) {
396 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800397 if (info == null || info.loggedStartingWindowDrawn) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500398 return;
399 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800400 info.loggedStartingWindowDrawn = true;
Sudheer Shankac766db02017-06-12 10:37:29 -0700401 info.startingWindowDelayMs = calculateDelay(timestamp);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500402 }
403
404 /**
405 * Notifies the tracker that the app transition is starting.
406 *
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100407 * @param windowingModeToReason A map from windowing mode to a reason integer, which must be on
408 * of ActivityManagerInternal.APP_TRANSITION_* reasons.
Jorim Jaggi275561a2016-02-23 10:11:02 -0500409 */
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100410 void notifyTransitionStarting(SparseIntArray windowingModeToReason, long timestamp) {
Jorim Jaggid8a57772017-04-14 16:50:42 -0700411 if (!isAnyTransitionActive() || mLoggedTransitionStarting) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500412 return;
413 }
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200414 if (DEBUG_METRICS) Slog.i(TAG, "notifyTransitionStarting");
Sudheer Shankac766db02017-06-12 10:37:29 -0700415 mCurrentTransitionDelayMs = calculateDelay(timestamp);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500416 mLoggedTransitionStarting = true;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100417 for (int index = windowingModeToReason.size() - 1; index >= 0; index--) {
418 final int windowingMode = windowingModeToReason.keyAt(index);
419 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
420 windowingMode);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800421 if (info == null) {
422 continue;
423 }
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100424 info.reason = windowingModeToReason.valueAt(index);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800425 }
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100426 if (allWindowsDrawn()) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800427 reset(false /* abort */);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500428 }
429 }
430
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200431 /**
432 * Notifies the tracker that the visibility of an app is changing.
433 *
434 * @param activityRecord the app that is changing its visibility
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200435 */
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200436 void notifyVisibilityChanged(ActivityRecord activityRecord) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100437 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
438 activityRecord.getWindowingMode());
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200439 if (info == null) {
440 return;
441 }
442 if (info.launchedActivity != activityRecord) {
443 return;
444 }
445 final TaskRecord t = activityRecord.getTask();
446 final SomeArgs args = SomeArgs.obtain();
447 args.arg1 = t;
448 args.arg2 = activityRecord;
449 mHandler.obtainMessage(MSG_CHECK_VISIBILITY, args).sendToTarget();
450 }
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200451
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200452 private void checkVisibility(TaskRecord t, ActivityRecord r) {
453 synchronized (mSupervisor.mService) {
454
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100455 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
456 r.getWindowingMode());
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200457
458 // If we have an active transition that's waiting on a certain activity that will be
459 // invisible now, we'll never get onWindowsDrawn, so abort the transition if necessary.
460 if (info != null && !t.isVisible()) {
461 if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible"
462 + " activity=" + r);
463 logAppTransitionCancel(info);
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100464 mWindowingModeTransitionInfo.remove(r.getWindowingMode());
465 if (mWindowingModeTransitionInfo.size() == 0) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200466 reset(true /* abort */);
467 }
Jorim Jaggicdfc04e2017-04-28 19:06:24 +0200468 }
469 }
470 }
471
Jorim Jaggi515dd682017-05-05 15:05:07 +0200472 /**
473 * Notifies the tracker that we called immediately before we call bindApplication on the client.
474 *
475 * @param app The client into which we'll call bindApplication.
476 */
477 void notifyBindApplication(ProcessRecord app) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100478 for (int i = mWindowingModeTransitionInfo.size() - 1; i >= 0; i--) {
479 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(i);
Jorim Jaggi515dd682017-05-05 15:05:07 +0200480
481 // App isn't attached to record yet, so match with info.
482 if (info.launchedActivity.appInfo == app.info) {
483 info.bindApplicationDelayMs = calculateCurrentDelay();
484 }
485 }
486 }
487
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100488 private boolean allWindowsDrawn() {
489 for (int index = mWindowingModeTransitionInfo.size() - 1; index >= 0; index--) {
490 if (!mWindowingModeTransitionInfo.valueAt(index).loggedWindowsDrawn) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800491 return false;
492 }
493 }
494 return true;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500495 }
496
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800497 private boolean isAnyTransitionActive() {
498 return mCurrentTransitionStartTime != INVALID_START_TIME
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100499 && mWindowingModeTransitionInfo.size() > 0;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800500 }
501
502 private void reset(boolean abort) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200503 if (DEBUG_METRICS) Slog.i(TAG, "reset abort=" + abort);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800504 if (!abort && isAnyTransitionActive()) {
505 logAppTransitionMultiEvents();
506 }
Jorim Jaggi275561a2016-02-23 10:11:02 -0500507 mCurrentTransitionStartTime = INVALID_START_TIME;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800508 mCurrentTransitionDelayMs = -1;
Jorim Jaggi275561a2016-02-23 10:11:02 -0500509 mLoggedTransitionStarting = false;
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100510 mWindowingModeTransitionInfo.clear();
Jorim Jaggi275561a2016-02-23 10:11:02 -0500511 }
512
513 private int calculateCurrentDelay() {
514
515 // Shouldn't take more than 25 days to launch an app, so int is fine here.
Alison Cichowlasb7f67ab2017-04-25 18:04:40 -0400516 return (int) (SystemClock.uptimeMillis() - mCurrentTransitionStartTime);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500517 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800518
Sudheer Shankac766db02017-06-12 10:37:29 -0700519 private int calculateDelay(long timestamp) {
520 // Shouldn't take more than 25 days to launch an app, so int is fine here.
521 return (int) (timestamp - mCurrentTransitionStartTime);
522 }
523
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100524 private void logAppTransitionCancel(WindowingModeTransitionInfo info) {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200525 final int type = getTransitionType(info);
526 if (type == -1) {
527 return;
528 }
529 final LogMaker builder = new LogMaker(APP_TRANSITION_CANCELLED);
530 builder.setPackageName(info.launchedActivity.packageName);
531 builder.setType(type);
532 builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivity.info.name);
533 mMetricsLogger.write(builder);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000534 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800535 StatsLog.APP_START_CANCELED,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000536 info.launchedActivity.appInfo.uid,
537 info.launchedActivity.packageName,
538 convertAppStartTransitionType(type),
539 info.launchedActivity.info.name);
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200540 }
541
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800542 private void logAppTransitionMultiEvents() {
Jorim Jaggi172e99f2017-10-20 14:33:18 +0200543 if (DEBUG_METRICS) Slog.i(TAG, "logging transition events");
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100544 for (int index = mWindowingModeTransitionInfo.size() - 1; index >= 0; index--) {
545 final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(index);
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800546 final int type = getTransitionType(info);
547 if (type == -1) {
548 return;
549 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000550
551 // Take a snapshot of the transition info before sending it to the handler for logging.
552 // This will avoid any races with other operations that modify the ActivityRecord.
553 final WindowingModeTransitionInfoSnapshot infoSnapshot =
554 new WindowingModeTransitionInfoSnapshot(info);
Ng Zhi An83473542018-02-20 09:02:14 -0800555 final int currentTransitionDeviceUptime = mCurrentTransitionDeviceUptime;
556 final int currentTransitionDelayMs = mCurrentTransitionDelayMs;
557 BackgroundThread.getHandler().post(() -> logAppTransition(
558 currentTransitionDeviceUptime, currentTransitionDelayMs, infoSnapshot));
Calin Juravle759fbda2018-02-20 19:52:30 +0000559
560 info.launchedActivity.info.launchToken = null;
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800561 }
562 }
563
Ng Zhi An83473542018-02-20 09:02:14 -0800564 // This gets called on a background thread without holding the activity manager lock.
Calin Juravle759fbda2018-02-20 19:52:30 +0000565 private void logAppTransition(int currentTransitionDeviceUptime, int currentTransitionDelayMs,
566 WindowingModeTransitionInfoSnapshot info) {
567 final LogMaker builder = new LogMaker(APP_TRANSITION);
568 builder.setPackageName(info.packageName);
569 builder.setType(info.type);
570 builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivityName);
571 final boolean isInstantApp = info.applicationInfo.isInstantApp();
572 if (info.launchedActivityLaunchedFromPackage != null) {
573 builder.addTaggedData(APP_TRANSITION_CALLING_PACKAGE_NAME,
574 info.launchedActivityLaunchedFromPackage);
575 }
576 String launchToken = info.launchedActivityLaunchToken;
577 if (launchToken != null) {
578 builder.addTaggedData(FIELD_INSTANT_APP_LAUNCH_TOKEN, launchToken);
579 }
580 builder.addTaggedData(APP_TRANSITION_IS_EPHEMERAL, isInstantApp ? 1 : 0);
581 builder.addTaggedData(APP_TRANSITION_DEVICE_UPTIME_SECONDS,
582 currentTransitionDeviceUptime);
583 builder.addTaggedData(APP_TRANSITION_DELAY_MS, currentTransitionDelayMs);
584 builder.setSubtype(info.reason);
585 if (info.startingWindowDelayMs != -1) {
586 builder.addTaggedData(APP_TRANSITION_STARTING_WINDOW_DELAY_MS,
587 info.startingWindowDelayMs);
588 }
589 if (info.bindApplicationDelayMs != -1) {
590 builder.addTaggedData(APP_TRANSITION_BIND_APPLICATION_DELAY_MS,
591 info.bindApplicationDelayMs);
592 }
593 builder.addTaggedData(APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, info.windowsDrawnDelayMs);
594 final ArtManagerInternal artManagerInternal = getArtManagerInternal();
595 final PackageOptimizationInfo packageOptimizationInfo =
596 (artManagerInternal == null) || (info.launchedActivityAppRecordRequiredAbi == null)
597 ? PackageOptimizationInfo.createWithNoInfo()
598 : artManagerInternal.getPackageOptimizationInfo(
599 info.applicationInfo,
600 info.launchedActivityAppRecordRequiredAbi);
601 builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_REASON,
602 packageOptimizationInfo.getCompilationReason());
603 builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_FILTER,
604 packageOptimizationInfo.getCompilationFilter());
605 mMetricsLogger.write(builder);
606 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800607 StatsLog.APP_START_OCCURRED,
Calin Juravle759fbda2018-02-20 19:52:30 +0000608 info.applicationInfo.uid,
609 info.packageName,
610 convertAppStartTransitionType(info.type),
611 info.launchedActivityName,
612 info.launchedActivityLaunchedFromPackage,
613 isInstantApp,
614 currentTransitionDeviceUptime * 1000,
615 info.reason,
616 currentTransitionDelayMs,
617 info.startingWindowDelayMs,
618 info.bindApplicationDelayMs,
619 info.windowsDrawnDelayMs,
620 launchToken,
621 packageOptimizationInfo.getCompilationReason(),
622 packageOptimizationInfo.getCompilationFilter());
Ng Zhi An83473542018-02-20 09:02:14 -0800623 logAppStartMemoryStateCapture(info);
Calin Juravle759fbda2018-02-20 19:52:30 +0000624 }
625
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000626 private int convertAppStartTransitionType(int tronType) {
627 if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800628 return StatsLog.APP_START_OCCURRED__TYPE__COLD;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000629 }
630 if (tronType == TYPE_TRANSITION_WARM_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800631 return StatsLog.APP_START_OCCURRED__TYPE__WARM;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000632 }
633 if (tronType == TYPE_TRANSITION_HOT_LAUNCH) {
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800634 return StatsLog.APP_START_OCCURRED__TYPE__HOT;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000635 }
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800636 return StatsLog.APP_START_OCCURRED__TYPE__UNKNOWN;
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000637 }
638
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200639 void logAppTransitionReportedDrawn(ActivityRecord r, boolean restoredFromBundle) {
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100640 final WindowingModeTransitionInfo info = mLastWindowingModeTransitionInfo.get(
641 r.getWindowingMode());
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200642 if (info == null) {
643 return;
644 }
645 final LogMaker builder = new LogMaker(APP_TRANSITION_REPORTED_DRAWN);
646 builder.setPackageName(r.packageName);
647 builder.addTaggedData(FIELD_CLASS_NAME, r.info.name);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000648 long startupTimeMs = SystemClock.uptimeMillis() - mLastTransitionStartTime;
649 builder.addTaggedData(APP_TRANSITION_REPORTED_DRAWN_MS, startupTimeMs);
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200650 builder.setType(restoredFromBundle
651 ? TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE
652 : TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE);
653 builder.addTaggedData(APP_TRANSITION_PROCESS_RUNNING,
654 info.currentTransitionProcessRunning ? 1 : 0);
655 mMetricsLogger.write(builder);
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000656 StatsLog.write(
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800657 StatsLog.APP_START_FULLY_DRAWN,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000658 info.launchedActivity.appInfo.uid,
659 info.launchedActivity.packageName,
660 restoredFromBundle
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800661 ? StatsLog.APP_START_FULLY_DRAWN__TYPE__WITH_BUNDLE
662 : StatsLog.APP_START_FULLY_DRAWN__TYPE__WITHOUT_BUNDLE,
Olivier Gaillardaed7f122017-12-12 14:26:22 +0000663 info.launchedActivity.info.name,
664 info.currentTransitionProcessRunning,
665 startupTimeMs);
Jorim Jaggi4d27b842017-08-17 17:22:26 +0200666 }
667
Michal Karpinski3eab9512018-07-20 15:32:00 +0100668 void logActivityStart(Intent intent, ProcessRecord callerApp, ActivityRecord r,
669 int callingUid, String callingPackage, int callingUidProcState,
670 boolean callingUidHasAnyVisibleWindow,
671 int realCallingUid, int realCallingUidProcState,
672 boolean realCallingUidHasAnyVisibleWindow,
673 int targetUid, String targetPackage, int targetUidProcState,
674 boolean targetUidHasAnyVisibleWindow, String targetWhitelistTag,
675 boolean comingFromPendingIntent) {
676
677 final long nowElapsed = SystemClock.elapsedRealtime();
678 final long nowUptime = SystemClock.uptimeMillis();
679 final LogMaker builder = new LogMaker(ACTION_ACTIVITY_START);
680 builder.setTimestamp(System.currentTimeMillis());
681 builder.addTaggedData(FIELD_CALLING_UID, callingUid);
682 builder.addTaggedData(FIELD_CALLING_PACKAGE_NAME, callingPackage);
683 builder.addTaggedData(FIELD_CALLING_UID_PROC_STATE,
684 processStateAmToProto(callingUidProcState));
685 builder.addTaggedData(FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
686 callingUidHasAnyVisibleWindow ? 1 : 0);
687 builder.addTaggedData(FIELD_REAL_CALLING_UID, realCallingUid);
688 builder.addTaggedData(FIELD_REAL_CALLING_UID_PROC_STATE,
689 processStateAmToProto(realCallingUidProcState));
690 builder.addTaggedData(FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
691 realCallingUidHasAnyVisibleWindow ? 1 : 0);
692 builder.addTaggedData(FIELD_TARGET_UID, targetUid);
693 builder.addTaggedData(FIELD_TARGET_PACKAGE_NAME, targetPackage);
694 builder.addTaggedData(FIELD_TARGET_UID_PROC_STATE,
695 processStateAmToProto(targetUidProcState));
696 builder.addTaggedData(FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW,
697 targetUidHasAnyVisibleWindow ? 1 : 0);
698 builder.addTaggedData(FIELD_TARGET_WHITELIST_TAG, targetWhitelistTag);
699 builder.addTaggedData(FIELD_TARGET_SHORT_COMPONENT_NAME, r.shortComponentName);
700 builder.addTaggedData(FIELD_COMING_FROM_PENDING_INTENT, comingFromPendingIntent ? 1 : 0);
701 builder.addTaggedData(FIELD_INTENT_ACTION, intent.getAction());
702 if (callerApp != null) {
703 builder.addTaggedData(FIELD_PROCESS_RECORD_PROCESS_NAME, callerApp.processName);
704 builder.addTaggedData(FIELD_PROCESS_RECORD_CUR_PROC_STATE,
705 processStateAmToProto(callerApp.curProcState));
706 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES,
707 callerApp.hasClientActivities ? 1 : 0);
708 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES,
709 callerApp.hasForegroundServices() ? 1 : 0);
710 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES,
711 callerApp.foregroundActivities ? 1 : 0);
712 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_TOP_UI, callerApp.hasTopUi ? 1 : 0);
713 builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_OVERLAY_UI,
714 callerApp.hasOverlayUi ? 1 : 0);
715 builder.addTaggedData(FIELD_PROCESS_RECORD_PENDING_UI_CLEAN,
716 callerApp.pendingUiClean ? 1 : 0);
717 if (callerApp.interactionEventTime != 0) {
718 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT,
719 (nowElapsed - callerApp.interactionEventTime));
720 }
721 if (callerApp.fgInteractionTime != 0) {
722 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION,
723 (nowElapsed - callerApp.fgInteractionTime));
724 }
725 if (callerApp.whenUnimportant != 0) {
726 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT,
727 (nowUptime - callerApp.whenUnimportant));
728 }
729 }
730 builder.addTaggedData(FIELD_ACTIVITY_RECORD_LAUNCH_MODE, r.info.launchMode);
731 builder.addTaggedData(FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY, r.info.targetActivity);
732 builder.addTaggedData(FIELD_ACTIVITY_RECORD_FLAGS, r.info.flags);
733 builder.addTaggedData(FIELD_ACTIVITY_RECORD_REAL_ACTIVITY, r.realActivity.toShortString());
734 builder.addTaggedData(FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME, r.shortComponentName);
735 builder.addTaggedData(FIELD_ACTIVITY_RECORD_PROCESS_NAME, r.processName);
736 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_FULLSCREEN, r.fullscreen ? 1 : 0);
737 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY, r.noDisplay ? 1 : 0);
738 if (r.lastVisibleTime != 0) {
739 builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE,
740 (nowUptime - r.lastVisibleTime));
741 }
742 if (r.resultTo != null) {
743 builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME, r.resultTo.packageName);
744 builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME,
745 r.resultTo.shortComponentName);
746 }
747 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE, r.visible ? 1 : 0);
748 builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD,
749 r.visibleIgnoringKeyguard ? 1 : 0);
750 if (r.lastLaunchTime != 0) {
751 builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH,
752 (nowUptime - r.lastLaunchTime));
753 }
754 mMetricsLogger.write(builder);
755 }
756
Jorim Jaggi9b58f2d2018-02-19 17:48:44 +0100757 private int getTransitionType(WindowingModeTransitionInfo info) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800758 if (info.currentTransitionProcessRunning) {
759 if (info.startResult == START_SUCCESS) {
760 return TYPE_TRANSITION_WARM_LAUNCH;
761 } else if (info.startResult == START_TASK_TO_FRONT) {
762 return TYPE_TRANSITION_HOT_LAUNCH;
763 }
764 } else if (info.startResult == START_SUCCESS) {
765 return TYPE_TRANSITION_COLD_LAUNCH;
766 }
767 return -1;
768 }
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800769
Ng Zhi An83473542018-02-20 09:02:14 -0800770 private void logAppStartMemoryStateCapture(WindowingModeTransitionInfoSnapshot info) {
771 if (info.processRecord == null) {
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800772 if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture processRecord null");
773 return;
774 }
775
Ng Zhi An83473542018-02-20 09:02:14 -0800776 final int pid = info.processRecord.pid;
777 final int uid = info.applicationInfo.uid;
Rajeev Kumarbfcd9202018-03-02 22:42:13 +0000778 final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800779 if (memoryStat == null) {
780 if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture memoryStat null");
781 return;
782 }
783
784 StatsLog.write(
785 StatsLog.APP_START_MEMORY_STATE_CAPTURED,
786 uid,
Ng Zhi An83473542018-02-20 09:02:14 -0800787 info.processName,
788 info.launchedActivityName,
Ng Zhi Anbbefdec2018-01-30 17:12:39 -0800789 memoryStat.pgfault,
790 memoryStat.pgmajfault,
791 memoryStat.rssInBytes,
792 memoryStat.cacheInBytes,
793 memoryStat.swapInBytes);
794 }
795
796 private ProcessRecord findProcessForActivity(ActivityRecord launchedActivity) {
797 return launchedActivity != null
798 ? mSupervisor.mService.mProcessNames.get(launchedActivity.processName,
799 launchedActivity.appInfo.uid)
800 : null;
801 }
Calin Juravle759fbda2018-02-20 19:52:30 +0000802
803 private ArtManagerInternal getArtManagerInternal() {
804 if (mArtManagerInternal == null) {
805 // Note that this may be null.
806 // ArtManagerInternal is registered during PackageManagerService
807 // initialization which happens after ActivityManagerService.
808 mArtManagerInternal = LocalServices.getService(ArtManagerInternal.class);
809 }
810 return mArtManagerInternal;
811 }
Filip Gruszczynski77d94482015-12-11 13:59:52 -0800812}