• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.base.jank_tracker;
6 
7 import android.app.Activity;
8 import android.os.Build.VERSION_CODES;
9 
10 import androidx.annotation.RequiresApi;
11 
12 import org.chromium.base.ActivityState;
13 import org.chromium.base.ApplicationStatus;
14 import org.chromium.base.ApplicationStatus.ActivityStateListener;
15 import org.chromium.base.ThreadUtils.ThreadChecker;
16 import org.chromium.base.lifetime.DestroyChecker;
17 
18 import java.lang.ref.WeakReference;
19 
20 /**
21  * This class takes an Activity and attaches a FrameMetricsListener to it, in addition it controls
22  * periodic jank metric reporting and frame metric recording based on the Activity's lifecycle
23  * events.
24  */
25 @RequiresApi(api = VERSION_CODES.N)
26 class JankActivityTracker extends JankTrackerStateController implements ActivityStateListener {
27     private final ThreadChecker mThreadChecker = new ThreadChecker();
28     private final DestroyChecker mDestroyChecker = new DestroyChecker();
29 
30     private WeakReference<Activity> mActivityReference;
31 
JankActivityTracker( Activity context, FrameMetricsListener listener, JankReportingScheduler reportingScheduler)32     JankActivityTracker(
33             Activity context,
34             FrameMetricsListener listener,
35             JankReportingScheduler reportingScheduler) {
36         super(listener, reportingScheduler);
37         mActivityReference = new WeakReference<>(context);
38     }
39 
40     @Override
initialize()41     public void initialize() {
42         assertValidState();
43         Activity activity = mActivityReference.get();
44         if (activity != null) {
45             ApplicationStatus.registerStateListenerForActivity(this, activity);
46             @ActivityState int activityState = ApplicationStatus.getStateForActivity(activity);
47             onActivityStateChange(activity, activityState);
48             startMetricCollection(activity.getWindow());
49         }
50     }
51 
52     @Override
destroy()53     public void destroy() {
54         mThreadChecker.assertOnValidThread();
55         ApplicationStatus.unregisterActivityStateListener(this);
56         stopPeriodicReporting();
57         Activity activity = mActivityReference.get();
58         if (activity != null) {
59             stopMetricCollection(activity.getWindow());
60         }
61         mDestroyChecker.destroy();
62     }
63 
assertValidState()64     private void assertValidState() {
65         mThreadChecker.assertOnValidThread();
66         mDestroyChecker.checkNotDestroyed();
67     }
68 
69     @Override
onActivityStateChange(Activity activity, @ActivityState int newState)70     public void onActivityStateChange(Activity activity, @ActivityState int newState) {
71         assertValidState();
72         switch (newState) {
73             case ActivityState.STARTED: // Intentional fallthrough.
74             case ActivityState.RESUMED:
75                 startPeriodicReporting();
76                 startMetricCollection(null);
77                 break;
78             case ActivityState.PAUSED:
79                 // This method can be called at any moment safely, we want to report metrics even
80                 // when the activity is paused.
81                 startPeriodicReporting();
82                 stopMetricCollection(null);
83                 break;
84             case ActivityState.STOPPED:
85                 stopPeriodicReporting();
86                 stopMetricCollection(null);
87                 break;
88         }
89     }
90 }
91