- add sources.
[platform/framework/web/crosswalk.git] / src / content / public / android / javatests / src / org / chromium / content / browser / VSyncMonitorTest.java
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
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.content.browser;
6
7 import android.content.Context;
8 import android.test.InstrumentationTestCase;
9 import android.test.suitebuilder.annotation.MediumTest;
10 import java.util.Arrays;
11 import java.util.concurrent.Callable;
12
13 import org.chromium.base.ThreadUtils;
14
15 public class VSyncMonitorTest extends InstrumentationTestCase {
16     private static class VSyncDataCollector implements VSyncMonitor.Listener {
17         public long mFramePeriods[];
18         public int mFrameCount;
19
20         private final boolean mActivelyRequestUpdate;
21         private boolean mDone;
22         private long mPreviousVSyncTimeMicros;
23         private Object mSyncRoot = new Object();
24
25         VSyncDataCollector(int frames, boolean activelyRequestUpdate) {
26             mFramePeriods = new long[frames];
27             mActivelyRequestUpdate = activelyRequestUpdate;
28         }
29
30         public boolean isDone() {
31             synchronized (mSyncRoot) {
32                 return mDone;
33             }
34         }
35
36         @Override
37         public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros) {
38             if (mPreviousVSyncTimeMicros == 0) {
39                 mPreviousVSyncTimeMicros = vsyncTimeMicros;
40                 return;
41             }
42             if (mFrameCount >= mFramePeriods.length) {
43                 synchronized (mSyncRoot) {
44                     mDone = true;
45                     mSyncRoot.notify();
46                 }
47                 return;
48             }
49             mFramePeriods[mFrameCount++] = vsyncTimeMicros - mPreviousVSyncTimeMicros;
50             mPreviousVSyncTimeMicros = vsyncTimeMicros;
51             if (mActivelyRequestUpdate) monitor.requestUpdate();
52         }
53
54         public void waitTillDone() throws InterruptedException {
55             synchronized (mSyncRoot) {
56                 while (!isDone()) {
57                     mSyncRoot.wait();
58                 }
59             }
60         }
61     }
62
63     // The vsync monitor must be created on the UI thread to avoid associating the underlying
64     // Choreographer with the Looper from the test runner thread.
65     private VSyncMonitor createVSyncMonitor(
66             final VSyncMonitor.Listener listener, final boolean enableJBVSync) {
67         return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<VSyncMonitor>() {
68             @Override
69             public VSyncMonitor call() {
70                 Context context = getInstrumentation().getContext();
71                 return new VSyncMonitor(context, listener, enableJBVSync);
72             }
73         });
74     }
75
76     // Check that the vsync period roughly matches the timestamps that the monitor generates.
77     private void performVSyncPeriodTest(boolean enableJBVSync) throws InterruptedException {
78         // Collect roughly one second of data on a 60 fps display.
79         collectAndCheckVSync(enableJBVSync, 60, true);
80         collectAndCheckVSync(enableJBVSync, VSyncMonitor.MAX_AUTO_ONVSYNC_COUNT, false);
81     }
82
83     private void collectAndCheckVSync(
84             boolean enableJBVSync, final int totalFrames, final boolean activeFrames)
85             throws InterruptedException {
86         VSyncDataCollector collector = new VSyncDataCollector(totalFrames, activeFrames);
87         VSyncMonitor monitor = createVSyncMonitor(collector, enableJBVSync);
88
89         long reportedFramePeriod = monitor.getVSyncPeriodInMicroseconds();
90         assertTrue(reportedFramePeriod > 0);
91
92         assertFalse(collector.isDone());
93         monitor.requestUpdate();
94         collector.waitTillDone();
95         assertTrue(collector.isDone());
96         monitor.stop();
97
98         // Check that the median frame rate is within 10% of the reported frame period.
99         assertTrue(collector.mFrameCount == totalFrames);
100         Arrays.sort(collector.mFramePeriods, 0, collector.mFramePeriods.length);
101         long medianFramePeriod = collector.mFramePeriods[collector.mFramePeriods.length / 2];
102         if (Math.abs(medianFramePeriod - reportedFramePeriod) > reportedFramePeriod * .1) {
103             fail("Measured median frame period " + medianFramePeriod
104                     + " differs by more than 10% from the reported frame period "
105                     + reportedFramePeriod + " for "
106                     + (activeFrames ? "requested" : "automatically sent") + " frames");
107         }
108     }
109
110     // Check that the vsync period roughly matches the timestamps that the monitor generates.
111     @MediumTest
112     public void testVSyncPeriodAllowJBVSync() throws InterruptedException {
113         performVSyncPeriodTest(true);
114     }
115
116     // Check that the vsync period roughly matches the timestamps that the monitor generates.
117     @MediumTest
118     public void testVSyncPeriodDisallowJBVSync() throws InterruptedException {
119         performVSyncPeriodTest(false);
120     }
121 }