• 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 static org.mockito.ArgumentMatchers.any;
8 import static org.mockito.Mockito.atLeastOnce;
9 import static org.mockito.Mockito.never;
10 import static org.mockito.Mockito.verify;
11 import static org.mockito.Mockito.when;
12 
13 import android.app.Activity;
14 import android.view.Window;
15 
16 import org.junit.Before;
17 import org.junit.Test;
18 import org.junit.runner.RunWith;
19 import org.mockito.InOrder;
20 import org.mockito.Mock;
21 import org.mockito.Mockito;
22 import org.mockito.MockitoAnnotations;
23 
24 import org.chromium.base.ActivityState;
25 import org.chromium.base.ApplicationStatus;
26 import org.chromium.base.test.BaseRobolectricTestRunner;
27 
28 /** Tests for JankActivityTracker. */
29 @RunWith(BaseRobolectricTestRunner.class)
30 public class JankActivityTrackerTest {
31     @Mock private Activity mActivity;
32 
33     @Mock private Window mWindow;
34 
35     @Mock private FrameMetricsListener mFrameMetricsListener;
36 
37     @Mock private JankReportingScheduler mJankReportingScheduler;
38 
createJankActivityTracker(Activity activity)39     JankActivityTracker createJankActivityTracker(Activity activity) {
40         JankActivityTracker tracker =
41                 new JankActivityTracker(activity, mFrameMetricsListener, mJankReportingScheduler);
42 
43         return tracker;
44     }
45 
46     @Before
setUp()47     public void setUp() {
48         MockitoAnnotations.initMocks(this);
49 
50         when(mActivity.getWindow()).thenReturn(mWindow);
51 
52         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.CREATED);
53     }
54 
55     @Test
jankTrackerTest_TestInitialize()56     public void jankTrackerTest_TestInitialize() {
57         JankActivityTracker jankActivityTracker = createJankActivityTracker(mActivity);
58         jankActivityTracker.initialize();
59 
60         // Verify that we are listening to frame metrics.
61         // Initialize also starts listening to activity lifecycle events, but that's harder to
62         // verify.
63         verify(mWindow).addOnFrameMetricsAvailableListener(any(), any());
64     }
65 
66     @Test
jankTrackerTest_TestActivityResume()67     public void jankTrackerTest_TestActivityResume() {
68         JankActivityTracker jankActivityTracker = createJankActivityTracker(mActivity);
69         jankActivityTracker.initialize();
70 
71         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.STARTED);
72         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.RESUMED);
73 
74         // When an activity resumes we start reporting periodic metrics.
75         verify(mJankReportingScheduler, atLeastOnce()).startReportingPeriodicMetrics();
76         verify(mJankReportingScheduler, never()).stopReportingPeriodicMetrics();
77 
78         // When an activity resumes we start recording metrics.
79         verify(mFrameMetricsListener, atLeastOnce()).setIsListenerRecording(true);
80     }
81 
82     @Test
jankTrackerTest_TestActivityPause()83     public void jankTrackerTest_TestActivityPause() {
84         JankActivityTracker jankActivityTracker = createJankActivityTracker(mActivity);
85         jankActivityTracker.initialize();
86 
87         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.STARTED);
88         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.RESUMED);
89         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.PAUSED);
90 
91         // When an activity pauses the reporting task should still be looping.
92         verify(mJankReportingScheduler, atLeastOnce()).startReportingPeriodicMetrics();
93         verify(mJankReportingScheduler, never()).stopReportingPeriodicMetrics();
94 
95         InOrder orderVerifier = Mockito.inOrder(mFrameMetricsListener);
96 
97         orderVerifier.verify(mFrameMetricsListener, atLeastOnce()).setIsListenerRecording(true);
98         // When an activity pauses we stop recording metrics.
99         orderVerifier.verify(mFrameMetricsListener).setIsListenerRecording(false);
100     }
101 
102     @Test
jankTrackerTest_TestActivityStop()103     public void jankTrackerTest_TestActivityStop() {
104         JankActivityTracker jankActivityTracker = createJankActivityTracker(mActivity);
105         jankActivityTracker.initialize();
106 
107         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.STARTED);
108         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.RESUMED);
109         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.PAUSED);
110         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.STOPPED);
111 
112         // When an activity stops we stop reporting periodic metrics.
113         InOrder schedulerOrderVerifier = Mockito.inOrder(mJankReportingScheduler);
114         schedulerOrderVerifier
115                 .verify(mJankReportingScheduler, atLeastOnce())
116                 .startReportingPeriodicMetrics();
117         schedulerOrderVerifier.verify(mJankReportingScheduler).stopReportingPeriodicMetrics();
118     }
119 
120     @Test
jankTrackerTest_TestAttachTrackerOnResumedActivity()121     public void jankTrackerTest_TestAttachTrackerOnResumedActivity() {
122         // Modify the activity's state before attaching JankActivityTracker.
123         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.STARTED);
124         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.RESUMED);
125 
126         JankActivityTracker jankActivityTracker = createJankActivityTracker(mActivity);
127         jankActivityTracker.initialize();
128 
129         // Verify that JankActivityTracker is running as expected for the Resumed state.
130         // Periodic metric reporting should be enabled.
131         verify(mJankReportingScheduler).startReportingPeriodicMetrics();
132         // Metric recording should be enabled.
133         verify(mFrameMetricsListener, atLeastOnce()).setIsListenerRecording(true);
134     }
135 
136     @Test
jankTrackerTest_TestOutOfOrderStateChange()137     public void jankTrackerTest_TestOutOfOrderStateChange() {
138         JankActivityTracker jankActivityTracker = createJankActivityTracker(mActivity);
139         jankActivityTracker.initialize();
140 
141         // Move the activity from STOPPED to RESUMED without calling STARTED.
142         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.STOPPED);
143         ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.RESUMED);
144 
145         // Verify that JankActivityTracker is running as expected for the Resumed state.
146         // Reporting task should be running and looping.
147         verify(mJankReportingScheduler).startReportingPeriodicMetrics();
148         // Metric recording should be enabled.
149         verify(mFrameMetricsListener, atLeastOnce()).setIsListenerRecording(true);
150         verify(mFrameMetricsListener, atLeastOnce()).setIsListenerRecording(false);
151     }
152 }
153