• 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;
9 
10 /**
11  * Class for recording janky frame metrics for a specific Activity.
12  *
13  * It should be constructed when the activity is created, recording starts and stops automatically
14  * based on activity state. When the activity is being destroyed {@link #destroy()} should be called
15  * to clear the activity state observer. All methods should be called from the UI thread.
16  */
17 public class JankTrackerImpl implements JankTracker {
18     // We use the DEADLINE field in the Android FrameMetrics which was added in S.
19     private static final boolean IS_TRACKING_ENABLED =
20             Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
21 
22     private JankTrackerStateController mController;
23     private JankReportingScheduler mReportingScheduler;
24 
25     /**
26      * Creates a new JankTracker instance tracking UI rendering of an activity. Metric recording
27      * starts when the activity starts, and it's paused when the activity stops.
28      */
JankTrackerImpl(Activity activity)29     public JankTrackerImpl(Activity activity) {
30         FrameMetricsStore metricsStore = new FrameMetricsStore();
31         if (!constructInternalPreController(new JankReportingScheduler(metricsStore))) return;
32 
33         constructInternalFinal(
34                 new JankActivityTracker(
35                         activity, new FrameMetricsListener(metricsStore), mReportingScheduler));
36     }
37 
38     /**
39      * Creates a new JankTracker which allows the controller to determine when it should start and
40      * stop metric scenarios/collection.
41      */
JankTrackerImpl(JankTrackerStateController controller)42     public JankTrackerImpl(JankTrackerStateController controller) {
43         if (!constructInternalPreController(controller.mReportingScheduler)) return;
44         constructInternalFinal(controller);
45     }
46 
constructInternalPreController(JankReportingScheduler scheduler)47     private boolean constructInternalPreController(JankReportingScheduler scheduler) {
48         if (!IS_TRACKING_ENABLED) {
49             mReportingScheduler = null;
50             mController = null;
51             return false;
52         }
53         mReportingScheduler = scheduler;
54         return true;
55     }
56 
constructInternalFinal(JankTrackerStateController controller)57     private void constructInternalFinal(JankTrackerStateController controller) {
58         mController = controller;
59         mController.initialize();
60     }
61 
62     @Override
startTrackingScenario(@ankScenario int scenario)63     public void startTrackingScenario(@JankScenario int scenario) {
64         if (!IS_TRACKING_ENABLED) return;
65 
66         mReportingScheduler.startTrackingScenario(scenario);
67     }
68 
69     @Override
finishTrackingScenario(@ankScenario int scenario)70     public void finishTrackingScenario(@JankScenario int scenario) {
71         finishTrackingScenario(scenario, -1);
72     }
73 
74     @Override
finishTrackingScenario(@ankScenario int scenario, long endScenarioTimeNs)75     public void finishTrackingScenario(@JankScenario int scenario, long endScenarioTimeNs) {
76         if (!IS_TRACKING_ENABLED) return;
77 
78         mReportingScheduler.finishTrackingScenario(scenario, endScenarioTimeNs);
79     }
80 
81     /** Stops listening for Activity state changes. */
82     @Override
destroy()83     public void destroy() {
84         if (!IS_TRACKING_ENABLED) return;
85 
86         mController.destroy();
87     }
88 }
89