177d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynskipackage com.android.server.am; 277d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski 377d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynskiimport static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 477d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynskiimport static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; 577d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynskiimport static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; 677d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynskiimport static android.app.ActivityManager.StackId.HOME_STACK_ID; 7caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynskiimport static android.app.ActivityManager.StackId.PINNED_STACK_ID; 8f970410afef518003c84eef022194848b2a4f606Jorim Jaggiimport static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 9f970410afef518003c84eef022194848b2a4f606Jorim Jaggiimport static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 100e381e278a2c2a3a7c86c9951ac5cbcdc3a186f4Filip Gruszczynskiimport static com.android.server.am.ActivityStack.STACK_INVISIBLE; 1177d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski 12275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggiimport android.annotation.Nullable; 1377d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynskiimport android.app.ActivityManager.StackId; 1477d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynskiimport android.content.Context; 1577d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynskiimport android.os.SystemClock; 16f970410afef518003c84eef022194848b2a4f606Jorim Jaggiimport android.util.Slog; 1777d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski 1877d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynskiimport com.android.internal.logging.MetricsLogger; 19275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggiimport com.android.internal.logging.MetricsProto.MetricsEvent; 2077d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski 211e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggiimport java.util.ArrayList; 221e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi 2377d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski/** 2477d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski * Handles logging into Tron. 2577d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski */ 2677d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynskiclass ActivityMetricsLogger { 27f970410afef518003c84eef022194848b2a4f606Jorim Jaggi 28f970410afef518003c84eef022194848b2a4f606Jorim Jaggi private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityMetricsLogger" : TAG_AM; 29f970410afef518003c84eef022194848b2a4f606Jorim Jaggi 3077d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski // Window modes we are interested in logging. If we ever introduce a new type, we need to add 3177d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski // a value here and increase the {@link #TRON_WINDOW_STATE_VARZ_STRINGS} array. 3277d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski private static final int WINDOW_STATE_STANDARD = 0; 3377d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski private static final int WINDOW_STATE_SIDE_BY_SIDE = 1; 3477d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski private static final int WINDOW_STATE_FREEFORM = 2; 3577d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski private static final int WINDOW_STATE_INVALID = -1; 3677d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski 37275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi private static final long INVALID_START_TIME = -1; 38275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 3977d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski // Preallocated strings we are sending to tron, so we don't have to allocate a new one every 4077d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski // time we log. 4177d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski private static final String[] TRON_WINDOW_STATE_VARZ_STRINGS = { 42ae255ee61b5e174c2164e58389b8a7ff8a95e14dChris Wren "window_time_0", "window_time_1", "window_time_2"}; 4377d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski 4477d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski private int mWindowState = WINDOW_STATE_STANDARD; 4577d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski private long mLastLogTimeSecs; 4677d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski private final ActivityStackSupervisor mSupervisor; 4777d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski private final Context mContext; 4877d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski 49275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi private long mCurrentTransitionStartTime = INVALID_START_TIME; 50275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi private boolean mLoggedWindowsDrawn; 51275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi private boolean mLoggedStartingWindowDrawn; 52275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi private boolean mLoggedTransitionStarting; 53275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 5477d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski ActivityMetricsLogger(ActivityStackSupervisor supervisor, Context context) { 5577d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski mLastLogTimeSecs = SystemClock.elapsedRealtime() / 1000; 5677d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski mSupervisor = supervisor; 5777d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski mContext = context; 5877d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski } 5977d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski 6077d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski void logWindowState() { 6177d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski final long now = SystemClock.elapsedRealtime() / 1000; 6277d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski if (mWindowState != WINDOW_STATE_INVALID) { 6377d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski // We log even if the window state hasn't changed, because the user might remain in 6477d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski // home/fullscreen move forever and we would like to track this kind of behavior 6577d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski // too. 6677d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski MetricsLogger.count(mContext, TRON_WINDOW_STATE_VARZ_STRINGS[mWindowState], 6777d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski (int) (now - mLastLogTimeSecs)); 6877d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski } 6977d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski mLastLogTimeSecs = now; 7077d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski 7177d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski ActivityStack stack = mSupervisor.getStack(DOCKED_STACK_ID); 728051c5c89060906f5a3a1ca4adb3b53bb423e56bWale Ogunwale if (stack != null && stack.getStackVisibilityLocked(null) != STACK_INVISIBLE) { 7377d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski mWindowState = WINDOW_STATE_SIDE_BY_SIDE; 74caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski return; 75caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski } 76caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski mWindowState = WINDOW_STATE_INVALID; 77caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski stack = mSupervisor.getFocusedStack(); 78caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski if (stack.mStackId == PINNED_STACK_ID) { 79caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski stack = mSupervisor.findStackBehind(stack); 8077d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski } 81caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski if (stack.mStackId == HOME_STACK_ID 82caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski || stack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID) { 83caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski mWindowState = WINDOW_STATE_STANDARD; 84caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski } else if (stack.mStackId == DOCKED_STACK_ID) { 85f970410afef518003c84eef022194848b2a4f606Jorim Jaggi Slog.wtf(TAG, "Docked stack shouldn't be the focused stack, because it reported not" 86f970410afef518003c84eef022194848b2a4f606Jorim Jaggi + " being visible."); 87f970410afef518003c84eef022194848b2a4f606Jorim Jaggi mWindowState = WINDOW_STATE_INVALID; 88caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski } else if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) { 89caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski mWindowState = WINDOW_STATE_FREEFORM; 90caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski } else if (StackId.isStaticStack(stack.mStackId)) { 91caae14e478e115d01f9b32890cb31231575e65ddFilip Gruszczynski throw new IllegalStateException("Unknown stack=" + stack); 9277d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski } 9377d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski } 94275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 95275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi /** 96275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * Notifies the tracker at the earliest possible point when we are starting to launch an 97275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * activity. 98275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi */ 99275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi void notifyActivityLaunching() { 100275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi mCurrentTransitionStartTime = System.currentTimeMillis(); 101275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 102275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 103275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi /** 1041e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi * Notifies the tracker that the activity is actually launching. 1051e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi * 1061e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the 1071e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi * launch 1081e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi * @param launchedActivity the activity that is being launched 1091e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi */ 1101e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity) { 1111e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi final ProcessRecord processRecord = launchedActivity != null 1121e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi ? mSupervisor.mService.mProcessNames.get(launchedActivity.processName, 1131e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi launchedActivity.appInfo.uid) 1141e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi : null; 1151e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi final boolean processRunning = processRecord != null; 1161e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi final String componentName = launchedActivity != null 1171e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi ? launchedActivity.shortComponentName 1181e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi : null; 1191e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi 1201e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi // We consider this a "process switch" if the process of the activity that gets launched 1211e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi // didn't have an activity that was in started state. In this case, we assume that lot 1221e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi // of caches might be purged so the time until it produces the first frame is very 1231e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi // interesting. 1241e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi final boolean processSwitch = processRecord == null 1251e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi || !hasStartedActivity(processRecord, launchedActivity); 1261e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi 1271e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi notifyActivityLaunched(resultCode, componentName, processRunning, processSwitch); 1281e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi } 1291e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi 1301e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi private boolean hasStartedActivity(ProcessRecord record, ActivityRecord launchedActivity) { 1311e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi final ArrayList<ActivityRecord> activities = record.activities; 1321e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi for (int i = activities.size() - 1; i >= 0; i--) { 1331e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi final ActivityRecord activity = activities.get(i); 1341e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi if (launchedActivity == activity) { 1351e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi continue; 1361e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi } 1371e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi if (!activity.stopped) { 1381e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi return true; 1391e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi } 1401e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi } 1411e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi return false; 1421e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi } 1431e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi 1441e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi /** 145275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * Notifies the tracker the the activity is actually launching. 146275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * 147275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the 148275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * launch 149275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * @param componentName the component name of the activity being launched 150275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * @param processRunning whether the process that will contains the activity is already running 151be67c90f4c2255cab3bc036ecdc8d9636ed5e4b5Jorim Jaggi * @param processSwitch whether the process that will contain the activity didn't have any 152be67c90f4c2255cab3bc036ecdc8d9636ed5e4b5Jorim Jaggi * activity that was stopped, i.e. the started activity is "switching" 153be67c90f4c2255cab3bc036ecdc8d9636ed5e4b5Jorim Jaggi * processes 154275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi */ 1551e630c08296ec6cc311cc4e1c397f7ca50a1a735Jorim Jaggi private void notifyActivityLaunched(int resultCode, @Nullable String componentName, 156be67c90f4c2255cab3bc036ecdc8d9636ed5e4b5Jorim Jaggi boolean processRunning, boolean processSwitch) { 157275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 158be67c90f4c2255cab3bc036ecdc8d9636ed5e4b5Jorim Jaggi if (resultCode < 0 || componentName == null || !processSwitch) { 159275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 160be67c90f4c2255cab3bc036ecdc8d9636ed5e4b5Jorim Jaggi // Failed to launch or it was not a process switch, so we don't care about the timing. 161275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi reset(); 162275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi return; 163275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 164275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 165275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_COMPONENT_NAME, 166275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi componentName); 167275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_PROCESS_RUNNING, 168275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi processRunning); 169275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS, 170275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi (int) (SystemClock.uptimeMillis() / 1000)); 171275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 172275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 173275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi /** 174275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * Notifies the tracker that all windows of the app have been drawn. 175275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi */ 176275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi void notifyWindowsDrawn() { 177275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi if (!isTransitionActive() || mLoggedWindowsDrawn) { 178275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi return; 179275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 180275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, 181275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi calculateCurrentDelay()); 182275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi mLoggedWindowsDrawn = true; 183275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi if (mLoggedTransitionStarting) { 184275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi reset(); 185275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 186275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 187275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 188275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi /** 189275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * Notifies the tracker that the starting window was drawn. 190275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi */ 191275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi void notifyStartingWindowDrawn() { 192275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi if (!isTransitionActive() || mLoggedStartingWindowDrawn) { 193275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi return; 194275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 195275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi mLoggedStartingWindowDrawn = true; 196275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_STARTING_WINDOW_DELAY_MS, 197275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi calculateCurrentDelay()); 198275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 199275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 200275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi /** 201275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * Notifies the tracker that the app transition is starting. 202275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * 203275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * @param reason The reason why we started it. Must be on of 204275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi * ActivityManagerInternal.APP_TRANSITION_* reasons. 205275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi */ 206275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi void notifyTransitionStarting(int reason) { 207275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi if (!isTransitionActive() || mLoggedTransitionStarting) { 208275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi return; 209275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 210275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_REASON, reason); 211275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_DELAY_MS, 212275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi calculateCurrentDelay()); 213275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi mLoggedTransitionStarting = true; 214275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi if (mLoggedWindowsDrawn) { 215275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi reset(); 216275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 217275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 218275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 219275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi private boolean isTransitionActive() { 220275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi return mCurrentTransitionStartTime != INVALID_START_TIME; 221275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 222275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 223275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi private void reset() { 224275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi mCurrentTransitionStartTime = INVALID_START_TIME; 225275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi mLoggedWindowsDrawn = false; 226275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi mLoggedTransitionStarting = false; 227275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi mLoggedStartingWindowDrawn = false; 228275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 229275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 230275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi private int calculateCurrentDelay() { 231275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi 232275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi // Shouldn't take more than 25 days to launch an app, so int is fine here. 233275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi return (int) (System.currentTimeMillis() - mCurrentTransitionStartTime); 234275561a74677f9d6c8f3f2cebc3cfea416ca586dJorim Jaggi } 23577d9448e2d6dd8a45c5fedef43c8a1cf4afd28b9Filip Gruszczynski} 236