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