Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d37f28b8 authored by Jorim Jaggi's avatar Jorim Jaggi Committed by Android (Google) Code Review
Browse files

Merge "Fix issues with TRON app transition logging"

parents c9666de1 172e99f4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4443,6 +4443,10 @@ message MetricsEvent {
    // OS: O MR
    COLOR_MODE_SETTINGS = 1143;

    // Enclosing category for group of APP_TRANSITION_FOO events,
    // logged when we cancel an app transition.
    APP_TRANSITION_CANCELLED = 1144;

    // ---- End O-MR1 Constants, all O-MR1 constants go above this line ----

    // OPEN: Settings > Network & Internet > Mobile network
+1 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ class ActivityManagerDebugConfig {
    static final boolean DEBUG_USAGE_STATS = DEBUG_ALL || false;
    static final boolean DEBUG_PERMISSIONS_REVIEW = DEBUG_ALL || false;
    static final boolean DEBUG_WHITELISTS = DEBUG_ALL || false;
    static final boolean DEBUG_METRICS = DEBUG_ALL || false;

    static final String POSTFIX_ADD_REMOVE = (APPEND_CATEGORY_NAME) ? "_AddRemove" : "";
    static final String POSTFIX_APP = (APPEND_CATEGORY_NAME) ? "_App" : "";
+82 −9
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_BIND_APPLICATION_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CALLING_PACKAGE_NAME;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CANCELLED;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_IS_EPHEMERAL;
@@ -28,16 +29,22 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_T
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_WARM_LAUNCH;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_METRICS;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;

import android.content.Context;
import android.metrics.LogMaker;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.SomeArgs;

import java.util.ArrayList;

@@ -58,6 +65,8 @@ class ActivityMetricsLogger {

    private static final long INVALID_START_TIME = -1;

    private static final int MSG_CHECK_VISIBILITY = 0;

    // Preallocated strings we are sending to tron, so we don't have to allocate a new one every
    // time we log.
    private static final String[] TRON_WINDOW_STATE_VARZ_STRINGS = {
@@ -78,6 +87,23 @@ class ActivityMetricsLogger {

    private final SparseArray<StackTransitionInfo> mStackTransitionInfo = new SparseArray<>();
    private final SparseArray<StackTransitionInfo> mLastStackTransitionInfo = new SparseArray<>();
    private final H mHandler;
    private final class H extends Handler {

        public H(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_CHECK_VISIBILITY:
                    final SomeArgs args = (SomeArgs) msg.obj;
                    checkVisibility((TaskRecord) args.arg1, (ActivityRecord) args.arg2);
                    break;
            }
        }
    };

    private final class StackTransitionInfo {
        private ActivityRecord launchedActivity;
@@ -91,10 +117,11 @@ class ActivityMetricsLogger {
        private boolean loggedStartingWindowDrawn;
    }

    ActivityMetricsLogger(ActivityStackSupervisor supervisor, Context context) {
    ActivityMetricsLogger(ActivityStackSupervisor supervisor, Context context, Looper looper) {
        mLastLogTimeSecs = SystemClock.elapsedRealtime() / 1000;
        mSupervisor = supervisor;
        mContext = context;
        mHandler = new H(looper);
    }

    void logWindowState() {
@@ -145,6 +172,7 @@ class ActivityMetricsLogger {
     */
    void notifyActivityLaunching() {
        if (!isAnyTransitionActive()) {
            if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunching");
            mCurrentTransitionStartTime = SystemClock.uptimeMillis();
            mLastTransitionStartTime = mCurrentTransitionStartTime;
        }
@@ -202,6 +230,12 @@ class ActivityMetricsLogger {
    private void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity,
            boolean processRunning, boolean processSwitch) {

        if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched"
                + " resultCode=" + resultCode
                + " launchedActivity=" + launchedActivity
                + " processRunning=" + processRunning
                + " processSwitch=" + processSwitch);

        // If we are already in an existing transition, only update the activity name, but not the
        // other attributes.
        final int stackId = launchedActivity != null && launchedActivity.getStack() != null
@@ -230,6 +264,8 @@ class ActivityMetricsLogger {
            return;
        }

        if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched successful");

        final StackTransitionInfo newInfo = new StackTransitionInfo();
        newInfo.launchedActivity = launchedActivity;
        newInfo.currentTransitionProcessRunning = processRunning;
@@ -243,6 +279,8 @@ class ActivityMetricsLogger {
     * Notifies the tracker that all windows of the app have been drawn.
     */
    void notifyWindowsDrawn(int stackId, long timestamp) {
        if (DEBUG_METRICS) Slog.i(TAG, "notifyWindowsDrawn stackId=" + stackId);

        final StackTransitionInfo info = mStackTransitionInfo.get(stackId);
        if (info == null || info.loggedWindowsDrawn) {
            return;
@@ -276,6 +314,7 @@ class ActivityMetricsLogger {
        if (!isAnyTransitionActive() || mLoggedTransitionStarting) {
            return;
        }
        if (DEBUG_METRICS) Slog.i(TAG, "notifyTransitionStarting");
        mCurrentTransitionDelayMs = calculateDelay(timestamp);
        mLoggedTransitionStarting = true;
        for (int index = stackIdReasons.size() - 1; index >= 0; index--) {
@@ -295,20 +334,40 @@ class ActivityMetricsLogger {
     * Notifies the tracker that the visibility of an app is changing.
     *
     * @param activityRecord the app that is changing its visibility
     * @param visible whether it's going to be visible or not
     */
    void notifyVisibilityChanged(ActivityRecord activityRecord, boolean visible) {
    void notifyVisibilityChanged(ActivityRecord activityRecord) {
        final StackTransitionInfo info = mStackTransitionInfo.get(activityRecord.getStackId());
        if (info == null) {
            return;
        }
        if (info.launchedActivity != activityRecord) {
            return;
        }
        final TaskRecord t = activityRecord.getTask();
        final SomeArgs args = SomeArgs.obtain();
        args.arg1 = t;
        args.arg2 = activityRecord;
        mHandler.obtainMessage(MSG_CHECK_VISIBILITY, args).sendToTarget();
    }

    private void checkVisibility(TaskRecord t, ActivityRecord r) {
        synchronized (mSupervisor.mService) {

            final StackTransitionInfo info = mStackTransitionInfo.get(r.getStackId());

            // If we have an active transition that's waiting on a certain activity that will be
            // invisible now, we'll never get onWindowsDrawn, so abort the transition if necessary.
        if (info != null && !visible && info.launchedActivity == activityRecord) {
            mStackTransitionInfo.remove(activityRecord.getStackId());
            if (info != null && !t.isVisible()) {
                if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible"
                        + " activity=" + r);
                logAppTransitionCancel(info);
                mStackTransitionInfo.remove(r.getStackId());
                if (mStackTransitionInfo.size() == 0) {
                    reset(true /* abort */);
                }
            }
        }
    }

    /**
     * Notifies the tracker that we called immediately before we call bindApplication on the client.
@@ -341,6 +400,7 @@ class ActivityMetricsLogger {
    }

    private void reset(boolean abort) {
        if (DEBUG_METRICS) Slog.i(TAG, "reset abort=" + abort);
        if (!abort && isAnyTransitionActive()) {
            logAppTransitionMultiEvents();
        }
@@ -361,7 +421,20 @@ class ActivityMetricsLogger {
        return (int) (timestamp - mCurrentTransitionStartTime);
    }

    private void logAppTransitionCancel(StackTransitionInfo info) {
        final int type = getTransitionType(info);
        if (type == -1) {
            return;
        }
        final LogMaker builder = new LogMaker(APP_TRANSITION_CANCELLED);
        builder.setPackageName(info.launchedActivity.packageName);
        builder.setType(type);
        builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivity.info.name);
        mMetricsLogger.write(builder);
    }

    private void logAppTransitionMultiEvents() {
        if (DEBUG_METRICS) Slog.i(TAG, "logging transition events");
        for (int index = mStackTransitionInfo.size() - 1; index >= 0; index--) {
            final StackTransitionInfo info = mStackTransitionInfo.valueAt(index);
            final int type = getTransitionType(info);
+1 −1
Original line number Diff line number Diff line
@@ -1526,7 +1526,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo

    void setVisibility(boolean visible) {
        mWindowContainerController.setVisibility(visible, mDeferHidingClient);
        mStackSupervisor.mActivityMetricsLogger.notifyVisibilityChanged(this, visible);
        mStackSupervisor.mActivityMetricsLogger.notifyVisibilityChanged(this);
    }

    // TODO: Look into merging with #setVisibility()
+8 −4
Original line number Diff line number Diff line
@@ -575,7 +575,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        mService = service;
        mHandler = new ActivityStackSupervisorHandler(looper);
        mRunningTasks = createRunningTasks();
        mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext);
        mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext, looper);
        mKeyguardController = new KeyguardController(service, this);

        mLaunchingBoundsController = new LaunchingBoundsController();
@@ -4502,9 +4502,13 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */,
                        targetActivity);
                mActivityMetricsLogger.notifyActivityLaunching();
                mService.moveTaskToFrontLocked(task.taskId, 0, bOptions, true /* fromRecents */);
                mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
                try {
                    mService.moveTaskToFrontLocked(task.taskId, 0, bOptions,
                            true /* fromRecents */);
                } finally {
                    mActivityMetricsLogger.notifyActivityLaunched(START_TASK_TO_FRONT,
                            targetActivity);
                }

                // If we are launching the task in the docked stack, put it into resizing mode so
                // the window renders full-screen with the background filling the void. Also only
Loading