blob: 25286eb7f987341e087a1d8ff399f857d075be63 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base.jank_tracker;
import android.app.Activity;
import android.os.Build.VERSION_CODES;
import androidx.annotation.RequiresApi;
import org.chromium.base.ActivityState;
import org.chromium.base.ApplicationStatus;
import org.chromium.base.ApplicationStatus.ActivityStateListener;
import org.chromium.base.ThreadUtils.ThreadChecker;
import org.chromium.base.lifetime.DestroyChecker;
import java.lang.ref.WeakReference;
/**
* This class takes an Activity and attaches a FrameMetricsListener to it, in addition it controls
* periodic jank metric reporting and frame metric recording based on the Activity's lifecycle
* events.
*/
@RequiresApi(api = VERSION_CODES.N)
class JankActivityTracker extends JankTrackerStateController implements ActivityStateListener {
private final ThreadChecker mThreadChecker = new ThreadChecker();
private final DestroyChecker mDestroyChecker = new DestroyChecker();
private WeakReference<Activity> mActivityReference;
JankActivityTracker(
Activity context,
FrameMetricsListener listener,
JankReportingScheduler reportingScheduler) {
super(listener, reportingScheduler);
mActivityReference = new WeakReference<>(context);
}
@Override
public void initialize() {
assertValidState();
Activity activity = mActivityReference.get();
if (activity != null) {
ApplicationStatus.registerStateListenerForActivity(this, activity);
@ActivityState int activityState = ApplicationStatus.getStateForActivity(activity);
onActivityStateChange(activity, activityState);
startMetricCollection(activity.getWindow());
}
}
@Override
public void destroy() {
mThreadChecker.assertOnValidThread();
ApplicationStatus.unregisterActivityStateListener(this);
stopPeriodicReporting();
Activity activity = mActivityReference.get();
if (activity != null) {
stopMetricCollection(activity.getWindow());
}
mDestroyChecker.destroy();
}
private void assertValidState() {
mThreadChecker.assertOnValidThread();
mDestroyChecker.checkNotDestroyed();
}
@Override
public void onActivityStateChange(Activity activity, @ActivityState int newState) {
assertValidState();
switch (newState) {
case ActivityState.STARTED: // Intentional fallthrough.
case ActivityState.RESUMED:
startPeriodicReporting();
startMetricCollection(null);
break;
case ActivityState.PAUSED:
// This method can be called at any moment safely, we want to report metrics even
// when the activity is paused.
startPeriodicReporting();
stopMetricCollection(null);
break;
case ActivityState.STOPPED:
stopPeriodicReporting();
stopMetricCollection(null);
break;
}
}
}