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

Commit de8305a5 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Track launch time per windowingMode

Some app launches go through different stacks. However, in P we
have one stack per task, which broke launch time tracking for
certain apps.

We fix this by tracking launch time per windowingMode, like we
do in ActivityMetricsLogger.

Test: Delete Chrome app data (to ensure FirstRunActivity gets
invoked, am start -n com.android.chrome/com.google.android.apps.chrome.Main -W
Fixes: 78302265
Change-Id: I739e63aeaf04d6336621e3d61f065259e518d9b4
parent 1b43af09
Loading
Loading
Loading
Loading
+12 −10
Original line number Diff line number Diff line
@@ -1927,11 +1927,12 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
        if (displayStartTime != 0) {
            reportLaunchTimeLocked(curTime);
        }
        final ActivityStack stack = getStack();
        if (fullyDrawnStartTime != 0 && stack != null) {
        final LaunchTimeTracker.Entry entry = mStackSupervisor.getLaunchTimeTracker().getEntry(
                getWindowingMode());
        if (fullyDrawnStartTime != 0 && entry != null) {
            final long thisTime = curTime - fullyDrawnStartTime;
            final long totalTime = stack.mFullyDrawnStartTime != 0
                    ? (curTime - stack.mFullyDrawnStartTime) : thisTime;
            final long totalTime = entry.mFullyDrawnStartTime != 0
                    ? (curTime - entry.mFullyDrawnStartTime) : thisTime;
            if (SHOW_ACTIVITY_START_TIME) {
                Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
                EventLog.writeEvent(AM_ACTIVITY_FULLY_DRAWN_TIME,
@@ -1953,7 +1954,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
            if (totalTime > 0) {
                //service.mUsageStatsService.noteFullyDrawnTime(realActivity, (int) totalTime);
            }
            stack.mFullyDrawnStartTime = 0;
            entry.mFullyDrawnStartTime = 0;
        }
        mStackSupervisor.getActivityMetricsLogger().logAppTransitionReportedDrawn(this,
                restoredFromBundle);
@@ -1961,13 +1962,14 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
    }

    private void reportLaunchTimeLocked(final long curTime) {
        final ActivityStack stack = getStack();
        if (stack == null) {
        final LaunchTimeTracker.Entry entry = mStackSupervisor.getLaunchTimeTracker().getEntry(
                getWindowingMode());
        if (entry == null) {
            return;
        }
        final long thisTime = curTime - displayStartTime;
        final long totalTime = stack.mLaunchStartTime != 0
                ? (curTime - stack.mLaunchStartTime) : thisTime;
        final long totalTime = entry.mLaunchStartTime != 0
                ? (curTime - entry.mLaunchStartTime) : thisTime;
        if (SHOW_ACTIVITY_START_TIME) {
            Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
            EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
@@ -1991,7 +1993,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
            //service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
        }
        displayStartTime = 0;
        stack.mLaunchStartTime = 0;
        entry.mLaunchStartTime = 0;
    }

    @Override
+2 −34
Original line number Diff line number Diff line
@@ -339,9 +339,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
    private final Rect mDeferredTaskBounds = new Rect();
    private final Rect mDeferredTaskInsetBounds = new Rect();

    long mLaunchStartTime = 0;
    long mFullyDrawnStartTime = 0;

    int mCurrentUser;

    final int mStackId;
@@ -1257,39 +1254,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                + " callers=" + Debug.getCallers(5));
        r.setState(RESUMED, "minimalResumeActivityLocked");
        r.completeResumeLocked();
        setLaunchTime(r);
        mStackSupervisor.getLaunchTimeTracker().setLaunchTime(r);
        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
                "Launch completed; removing icicle of " + r.icicle);
    }

    private void startLaunchTraces(String packageName) {
        if (mFullyDrawnStartTime != 0)  {
            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
        }
        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
    }

    private void stopFullyDrawnTraceIfNeeded() {
        if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
            mFullyDrawnStartTime = 0;
        }
    }

    void setLaunchTime(ActivityRecord r) {
        if (r.displayStartTime == 0) {
            r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
            if (mLaunchStartTime == 0) {
                startLaunchTraces(r.packageName);
                mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
            }
        } else if (mLaunchStartTime == 0) {
            startLaunchTraces(r.packageName);
            mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
        }
    }

    private void clearLaunchTime(ActivityRecord r) {
        // Make sure that there is no activity waiting for this to launch.
        if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
@@ -1477,9 +1446,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        prev.setState(PAUSING, "startPausingLocked");
        prev.getTask().touchActiveTime();
        clearLaunchTime(prev);
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();

        stopFullyDrawnTraceIfNeeded();
        mStackSupervisor.getLaunchTimeTracker().stopFullyDrawnTraceIfNeeded(getWindowingMode());

        mService.updateCpuStats();

+6 −1
Original line number Diff line number Diff line
@@ -445,6 +445,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
    private boolean mTaskLayersChanged = true;

    private ActivityMetricsLogger mActivityMetricsLogger;
    private LaunchTimeTracker mLaunchTimeTracker = new LaunchTimeTracker();

    private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>();

@@ -629,6 +630,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        return mActivityMetricsLogger;
    }

    LaunchTimeTracker getLaunchTimeTracker() {
        return mLaunchTimeTracker;
    }

    public KeyguardController getKeyguardController() {
        return mKeyguardController;
    }
@@ -1646,7 +1651,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.getStack().setLaunchTime(r);
        getLaunchTimeTracker().setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
+86 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.server.am;

import android.app.WaitResult;
import android.os.SystemClock;
import android.os.Trace;
import android.util.SparseArray;

/**
 * Tracks launch time of apps to be reported by {@link WaitResult}. Note that this is slightly
 * different from {@link ActivityMetricsLogger}, but should eventually merged with it.
 */
class LaunchTimeTracker {

    private final SparseArray<Entry> mWindowingModeLaunchTime = new SparseArray<>();

    void setLaunchTime(ActivityRecord r) {
        Entry entry = mWindowingModeLaunchTime.get(r.getWindowingMode());
        if (entry == null){
            entry = new Entry();
            mWindowingModeLaunchTime.append(r.getWindowingMode(), entry);
        }
        entry.setLaunchTime(r);
    }

    void stopFullyDrawnTraceIfNeeded(int windowingMode) {
        final Entry entry = mWindowingModeLaunchTime.get(windowingMode);
        if (entry == null) {
            return;
        }
        entry.stopFullyDrawnTraceIfNeeded();
    }

    Entry getEntry(int windowingMode) {
        return mWindowingModeLaunchTime.get(windowingMode);
    }

    static class Entry {

        long mLaunchStartTime;
        long mFullyDrawnStartTime;

        void setLaunchTime(ActivityRecord r) {
            if (r.displayStartTime == 0) {
                r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
                if (mLaunchStartTime == 0) {
                    startLaunchTraces(r.packageName);
                    mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
                }
            } else if (mLaunchStartTime == 0) {
                startLaunchTraces(r.packageName);
                mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
            }
        }

        private void startLaunchTraces(String packageName) {
            if (mFullyDrawnStartTime != 0)  {
                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
            }
            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
        }

        private void stopFullyDrawnTraceIfNeeded() {
            if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
                mFullyDrawnStartTime = 0;
            }
        }
    }
}