xref: /aosp_15_r20/frameworks/native/libs/nativewindow/tests/ANativeWindowTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2019 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "ANativeWindow_test"
18*38e8c45fSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*38e8c45fSAndroid Build Coastguard Worker 
20*38e8c45fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <gui/BufferItemConsumer.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <gui/BufferQueue.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <gui/Surface.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <sync/sync.h>
26*38e8c45fSAndroid Build Coastguard Worker // We need to use the private system apis since not everything is visible to
27*38e8c45fSAndroid Build Coastguard Worker // apexes yet.
28*38e8c45fSAndroid Build Coastguard Worker #include <system/window.h>
29*38e8c45fSAndroid Build Coastguard Worker 
30*38e8c45fSAndroid Build Coastguard Worker using namespace android;
31*38e8c45fSAndroid Build Coastguard Worker 
32*38e8c45fSAndroid Build Coastguard Worker class TestableSurface final : public Surface {
33*38e8c45fSAndroid Build Coastguard Worker public:
TestableSurface(const sp<IGraphicBufferProducer> & bufferProducer)34*38e8c45fSAndroid Build Coastguard Worker     explicit TestableSurface(const sp<IGraphicBufferProducer>& bufferProducer)
35*38e8c45fSAndroid Build Coastguard Worker           : Surface(bufferProducer) {}
36*38e8c45fSAndroid Build Coastguard Worker 
37*38e8c45fSAndroid Build Coastguard Worker     // Exposes the internal last dequeue duration that's stored on the Surface.
getLastDequeueDuration() const38*38e8c45fSAndroid Build Coastguard Worker     nsecs_t getLastDequeueDuration() const { return mLastDequeueDuration; }
39*38e8c45fSAndroid Build Coastguard Worker 
40*38e8c45fSAndroid Build Coastguard Worker     // Exposes the internal last queue duration that's stored on the Surface.
getLastQueueDuration() const41*38e8c45fSAndroid Build Coastguard Worker     nsecs_t getLastQueueDuration() const { return mLastQueueDuration; }
42*38e8c45fSAndroid Build Coastguard Worker 
43*38e8c45fSAndroid Build Coastguard Worker     // Exposes the internal last dequeue start time that's stored on the Surface.
getLastDequeueStartTime() const44*38e8c45fSAndroid Build Coastguard Worker     nsecs_t getLastDequeueStartTime() const { return mLastDequeueStartTime; }
45*38e8c45fSAndroid Build Coastguard Worker };
46*38e8c45fSAndroid Build Coastguard Worker 
47*38e8c45fSAndroid Build Coastguard Worker class ANativeWindowTest : public ::testing::Test {
48*38e8c45fSAndroid Build Coastguard Worker protected:
SetUp()49*38e8c45fSAndroid Build Coastguard Worker     void SetUp() override {
50*38e8c45fSAndroid Build Coastguard Worker         const ::testing::TestInfo* const test_info =
51*38e8c45fSAndroid Build Coastguard Worker                 ::testing::UnitTest::GetInstance()->current_test_info();
52*38e8c45fSAndroid Build Coastguard Worker         ALOGV("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
53*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
54*38e8c45fSAndroid Build Coastguard Worker         mItemConsumer = new BufferItemConsumer(GRALLOC_USAGE_SW_READ_OFTEN);
55*38e8c45fSAndroid Build Coastguard Worker         mWindow = new TestableSurface(mItemConsumer->getSurface()->getIGraphicBufferProducer());
56*38e8c45fSAndroid Build Coastguard Worker #else
57*38e8c45fSAndroid Build Coastguard Worker         BufferQueue::createBufferQueue(&mProducer, &mConsumer);
58*38e8c45fSAndroid Build Coastguard Worker         mItemConsumer = new BufferItemConsumer(mConsumer, GRALLOC_USAGE_SW_READ_OFTEN);
59*38e8c45fSAndroid Build Coastguard Worker         mWindow = new TestableSurface(mProducer);
60*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
61*38e8c45fSAndroid Build Coastguard Worker         const int success = native_window_api_connect(mWindow.get(), NATIVE_WINDOW_API_CPU);
62*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0, success);
63*38e8c45fSAndroid Build Coastguard Worker     }
64*38e8c45fSAndroid Build Coastguard Worker 
TearDown()65*38e8c45fSAndroid Build Coastguard Worker     void TearDown() override {
66*38e8c45fSAndroid Build Coastguard Worker         const ::testing::TestInfo* const test_info =
67*38e8c45fSAndroid Build Coastguard Worker                 ::testing::UnitTest::GetInstance()->current_test_info();
68*38e8c45fSAndroid Build Coastguard Worker         ALOGV("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
69*38e8c45fSAndroid Build Coastguard Worker         const int success = native_window_api_disconnect(mWindow.get(), NATIVE_WINDOW_API_CPU);
70*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0, success);
71*38e8c45fSAndroid Build Coastguard Worker     }
72*38e8c45fSAndroid Build Coastguard Worker 
73*38e8c45fSAndroid Build Coastguard Worker #if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
74*38e8c45fSAndroid Build Coastguard Worker     sp<IGraphicBufferProducer> mProducer;
75*38e8c45fSAndroid Build Coastguard Worker     sp<IGraphicBufferConsumer> mConsumer;
76*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
77*38e8c45fSAndroid Build Coastguard Worker     sp<BufferItemConsumer> mItemConsumer;
78*38e8c45fSAndroid Build Coastguard Worker     sp<TestableSurface> mWindow;
79*38e8c45fSAndroid Build Coastguard Worker };
80*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(ANativeWindowTest,getLastDequeueDuration_noDequeue_returnsZero)81*38e8c45fSAndroid Build Coastguard Worker TEST_F(ANativeWindowTest, getLastDequeueDuration_noDequeue_returnsZero) {
82*38e8c45fSAndroid Build Coastguard Worker     int result = ANativeWindow_getLastDequeueDuration(mWindow.get());
83*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, result);
84*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, mWindow->getLastDequeueDuration());
85*38e8c45fSAndroid Build Coastguard Worker }
86*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(ANativeWindowTest,getLastDequeueDuration_withDequeue_returnsTime)87*38e8c45fSAndroid Build Coastguard Worker TEST_F(ANativeWindowTest, getLastDequeueDuration_withDequeue_returnsTime) {
88*38e8c45fSAndroid Build Coastguard Worker     ANativeWindowBuffer* buffer;
89*38e8c45fSAndroid Build Coastguard Worker     int fd;
90*38e8c45fSAndroid Build Coastguard Worker     int result = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd);
91*38e8c45fSAndroid Build Coastguard Worker     close(fd);
92*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, result);
93*38e8c45fSAndroid Build Coastguard Worker 
94*38e8c45fSAndroid Build Coastguard Worker     result = ANativeWindow_getLastDequeueDuration(mWindow.get());
95*38e8c45fSAndroid Build Coastguard Worker     EXPECT_GT(result, 0);
96*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(result, mWindow->getLastDequeueDuration());
97*38e8c45fSAndroid Build Coastguard Worker }
98*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(ANativeWindowTest,getLastQueueDuration_noDequeue_returnsZero)99*38e8c45fSAndroid Build Coastguard Worker TEST_F(ANativeWindowTest, getLastQueueDuration_noDequeue_returnsZero) {
100*38e8c45fSAndroid Build Coastguard Worker     int result = ANativeWindow_getLastQueueDuration(mWindow.get());
101*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, result);
102*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, mWindow->getLastQueueDuration());
103*38e8c45fSAndroid Build Coastguard Worker }
104*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(ANativeWindowTest,getLastQueueDuration_noQueue_returnsZero)105*38e8c45fSAndroid Build Coastguard Worker TEST_F(ANativeWindowTest, getLastQueueDuration_noQueue_returnsZero) {
106*38e8c45fSAndroid Build Coastguard Worker     ANativeWindowBuffer* buffer;
107*38e8c45fSAndroid Build Coastguard Worker     int fd;
108*38e8c45fSAndroid Build Coastguard Worker     int result = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd);
109*38e8c45fSAndroid Build Coastguard Worker     close(fd);
110*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, result);
111*38e8c45fSAndroid Build Coastguard Worker 
112*38e8c45fSAndroid Build Coastguard Worker     result = ANativeWindow_getLastQueueDuration(mWindow.get());
113*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(result, 0);
114*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(result, mWindow->getLastQueueDuration());
115*38e8c45fSAndroid Build Coastguard Worker }
116*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(ANativeWindowTest,getLastQueueDuration_withQueue_returnsTime)117*38e8c45fSAndroid Build Coastguard Worker TEST_F(ANativeWindowTest, getLastQueueDuration_withQueue_returnsTime) {
118*38e8c45fSAndroid Build Coastguard Worker     ANativeWindowBuffer* buffer;
119*38e8c45fSAndroid Build Coastguard Worker     int fd;
120*38e8c45fSAndroid Build Coastguard Worker     int result = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd);
121*38e8c45fSAndroid Build Coastguard Worker     close(fd);
122*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, result);
123*38e8c45fSAndroid Build Coastguard Worker 
124*38e8c45fSAndroid Build Coastguard Worker     result = ANativeWindow_queueBuffer(mWindow.get(), buffer, 0);
125*38e8c45fSAndroid Build Coastguard Worker 
126*38e8c45fSAndroid Build Coastguard Worker     result = ANativeWindow_getLastQueueDuration(mWindow.get());
127*38e8c45fSAndroid Build Coastguard Worker     EXPECT_GT(result, 0);
128*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(result, mWindow->getLastQueueDuration());
129*38e8c45fSAndroid Build Coastguard Worker }
130*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(ANativeWindowTest,getLastDequeueStartTime_noDequeue_returnsZero)131*38e8c45fSAndroid Build Coastguard Worker TEST_F(ANativeWindowTest, getLastDequeueStartTime_noDequeue_returnsZero) {
132*38e8c45fSAndroid Build Coastguard Worker     int64_t result = ANativeWindow_getLastDequeueStartTime(mWindow.get());
133*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, result);
134*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, mWindow->getLastQueueDuration());
135*38e8c45fSAndroid Build Coastguard Worker }
136*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(ANativeWindowTest,getLastDequeueStartTime_withDequeue_returnsTime)137*38e8c45fSAndroid Build Coastguard Worker TEST_F(ANativeWindowTest, getLastDequeueStartTime_withDequeue_returnsTime) {
138*38e8c45fSAndroid Build Coastguard Worker     ANativeWindowBuffer* buffer;
139*38e8c45fSAndroid Build Coastguard Worker     int fd;
140*38e8c45fSAndroid Build Coastguard Worker     int dequeueResult = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd);
141*38e8c45fSAndroid Build Coastguard Worker     close(fd);
142*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, dequeueResult);
143*38e8c45fSAndroid Build Coastguard Worker 
144*38e8c45fSAndroid Build Coastguard Worker     int64_t result = ANativeWindow_getLastDequeueStartTime(mWindow.get());
145*38e8c45fSAndroid Build Coastguard Worker     EXPECT_GT(result, 0);
146*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(result, mWindow->getLastDequeueStartTime());
147*38e8c45fSAndroid Build Coastguard Worker }
148*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(ANativeWindowTest,setDequeueTimeout_causesDequeueTimeout)149*38e8c45fSAndroid Build Coastguard Worker TEST_F(ANativeWindowTest, setDequeueTimeout_causesDequeueTimeout) {
150*38e8c45fSAndroid Build Coastguard Worker     nsecs_t timeout = milliseconds_to_nanoseconds(100);
151*38e8c45fSAndroid Build Coastguard Worker     int result = ANativeWindow_setDequeueTimeout(mWindow.get(), timeout);
152*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, result);
153*38e8c45fSAndroid Build Coastguard Worker 
154*38e8c45fSAndroid Build Coastguard Worker     // The two dequeues should not timeout...
155*38e8c45fSAndroid Build Coastguard Worker     ANativeWindowBuffer* buffer;
156*38e8c45fSAndroid Build Coastguard Worker     int fd;
157*38e8c45fSAndroid Build Coastguard Worker     int dequeueResult = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd);
158*38e8c45fSAndroid Build Coastguard Worker     close(fd);
159*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, dequeueResult);
160*38e8c45fSAndroid Build Coastguard Worker     int queueResult = ANativeWindow_queueBuffer(mWindow.get(), buffer, -1);
161*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, queueResult);
162*38e8c45fSAndroid Build Coastguard Worker     dequeueResult = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd);
163*38e8c45fSAndroid Build Coastguard Worker     close(fd);
164*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, dequeueResult);
165*38e8c45fSAndroid Build Coastguard Worker     queueResult = ANativeWindow_queueBuffer(mWindow.get(), buffer, -1);
166*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(0, queueResult);
167*38e8c45fSAndroid Build Coastguard Worker 
168*38e8c45fSAndroid Build Coastguard Worker     // ...but the third one should since the queue depth is too deep.
169*38e8c45fSAndroid Build Coastguard Worker     nsecs_t start = systemTime(SYSTEM_TIME_MONOTONIC);
170*38e8c45fSAndroid Build Coastguard Worker     dequeueResult = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd);
171*38e8c45fSAndroid Build Coastguard Worker     nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC);
172*38e8c45fSAndroid Build Coastguard Worker     close(fd);
173*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(TIMED_OUT, dequeueResult);
174*38e8c45fSAndroid Build Coastguard Worker     EXPECT_GE(end - start, timeout);
175*38e8c45fSAndroid Build Coastguard Worker }
176