xref: /aosp_15_r20/hardware/interfaces/automotive/evs/aidl/impl/default/tests/EvsCameraBufferTest.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1  /*
2   * Copyright (C) 2023 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  #include "EvsCamera.h"
18  
19  #include <gmock/gmock.h>
20  #include <gtest/gtest.h>
21  
22  #include <cstdint>
23  #include <unordered_set>
24  #include <vector>
25  
26  namespace aidl::android::hardware::automotive::evs::implementation {
27  
28  class EvsCameraForTest : public EvsCamera {
29    public:
30      using EvsCamera::increaseAvailableFrames_unsafe;
31      using EvsCamera::returnBuffer_unsafe;
32      using EvsCamera::useBuffer_unsafe;
33  
~EvsCameraForTest()34      ~EvsCameraForTest() override { shutdown(); }
35  
allocateOneFrame(buffer_handle_t * handle)36      ::android::status_t allocateOneFrame(buffer_handle_t* handle) override {
37          static std::intptr_t handle_cnt = 0;
38          *handle = reinterpret_cast<buffer_handle_t>(++handle_cnt);
39          return ::android::OK;
40      }
41  
freeOneFrame(const buffer_handle_t)42      void freeOneFrame(const buffer_handle_t /* handle */) override {
43          // Nothing to free because the handles are fake.
44      }
45  
checkBufferOrder()46      void checkBufferOrder() {
47          for (std::size_t idx = 0; idx < mBuffers.size(); ++idx) {
48              const auto& buffer = mBuffers[idx];
49              EXPECT_EQ(idx < mFramesInUse, buffer.inUse);
50              EXPECT_EQ(idx < mAvailableFrames, buffer.handle != nullptr);
51              EXPECT_LE(mFramesInUse, mAvailableFrames);
52          }
53      }
54  
55      MOCK_METHOD(::ndk::ScopedAStatus, forcePrimaryClient,
56                  (const std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsDisplay>&
57                           in_display),
58                  (override));
59      MOCK_METHOD(::ndk::ScopedAStatus, getCameraInfo,
60                  (::aidl::android::hardware::automotive::evs::CameraDesc * _aidl_return),
61                  (override));
62      MOCK_METHOD(::ndk::ScopedAStatus, getExtendedInfo,
63                  (int32_t in_opaqueIdentifier, std::vector<uint8_t>* _aidl_return), (override));
64      MOCK_METHOD(::ndk::ScopedAStatus, getIntParameter,
65                  (::aidl::android::hardware::automotive::evs::CameraParam in_id,
66                   std::vector<int32_t>* _aidl_return),
67                  (override));
68      MOCK_METHOD(::ndk::ScopedAStatus, getIntParameterRange,
69                  (::aidl::android::hardware::automotive::evs::CameraParam in_id,
70                   ::aidl::android::hardware::automotive::evs::ParameterRange* _aidl_return),
71                  (override));
72      MOCK_METHOD(::ndk::ScopedAStatus, getParameterList,
73                  (std::vector<::aidl::android::hardware::automotive::evs::CameraParam> *
74                   _aidl_return),
75                  (override));
76      MOCK_METHOD(::ndk::ScopedAStatus, getPhysicalCameraInfo,
77                  (const std::string& in_deviceId,
78                   ::aidl::android::hardware::automotive::evs::CameraDesc* _aidl_return),
79                  (override));
80      MOCK_METHOD(::ndk::ScopedAStatus, setExtendedInfo,
81                  (int32_t in_opaqueIdentifier, const std::vector<uint8_t>& in_opaqueValue),
82                  (override));
83      MOCK_METHOD(::ndk::ScopedAStatus, setIntParameter,
84                  (::aidl::android::hardware::automotive::evs::CameraParam in_id, int32_t in_value,
85                   std::vector<int32_t>* _aidl_return),
86                  (override));
87      MOCK_METHOD(::ndk::ScopedAStatus, setPrimaryClient, (), (override));
88      MOCK_METHOD(::ndk::ScopedAStatus, unsetPrimaryClient, (), (override));
89      MOCK_METHOD(bool, startVideoStreamImpl_locked,
90                  (const std::shared_ptr<evs::IEvsCameraStream>& receiver, ndk::ScopedAStatus& status,
91                   std::unique_lock<std::mutex>& lck),
92                  (override));
93      MOCK_METHOD(bool, stopVideoStreamImpl_locked,
94                  (ndk::ScopedAStatus & status, std::unique_lock<std::mutex>& lck), (override));
95      MOCK_METHOD(std::string, getId, (), (override));
96  };
97  
TEST(EvsCameraBufferTest,ChangeBufferPoolSize)98  TEST(EvsCameraBufferTest, ChangeBufferPoolSize) {
99      auto evsCam = ndk::SharedRefBase::make<EvsCameraForTest>();
100      EXPECT_TRUE(evsCam->setMaxFramesInFlight(100).isOk());
101      evsCam->checkBufferOrder();
102      EXPECT_TRUE(evsCam->setMaxFramesInFlight(50).isOk());
103      evsCam->checkBufferOrder();
104  
105      // 2 buffers in use.
106      const auto [id1, handle1] = evsCam->useBuffer_unsafe();
107      const auto [id2, handle2] = evsCam->useBuffer_unsafe();
108      std::ignore = evsCam->useBuffer_unsafe();
109  
110      // It allows you to set the buffer pool size to 1, but it will keep the space for the in use
111      // buffers.
112      EXPECT_TRUE(evsCam->setMaxFramesInFlight(1).isOk());
113      evsCam->checkBufferOrder();
114  
115      evsCam->returnBuffer_unsafe(id1);
116      evsCam->checkBufferOrder();
117      evsCam->returnBuffer_unsafe(id2);
118      evsCam->checkBufferOrder();
119  }
120  
TEST(EvsCameraBufferTest,UseAndReturn)121  TEST(EvsCameraBufferTest, UseAndReturn) {
122      constexpr std::size_t kNumOfHandles = 20;
123      auto evsCam = ndk::SharedRefBase::make<EvsCameraForTest>();
124  
125      // Our "fake handles" of this test case is 1 to kNumOfHandles.
126      for (std::size_t i = 1; i <= kNumOfHandles; ++i) {
127          evsCam->increaseAvailableFrames_unsafe(reinterpret_cast<buffer_handle_t>(i));
128      }
129      evsCam->checkBufferOrder();
130  
131      {
132          std::vector<std::pair<std::size_t, std::intptr_t>> inUseIDHandlePairs;
133          std::unordered_set<std::size_t> inUseIDs;
134          std::unordered_set<std::intptr_t> inUseHandles;
135          for (std::size_t i = 0; i < kNumOfHandles; ++i) {
136              const auto [id, handle] = evsCam->useBuffer_unsafe();
137              const std::size_t handleInt = reinterpret_cast<std::size_t>(handle);
138              EXPECT_TRUE(EvsCamera::IsBufferIDValid(id));
139              EXPECT_NE(handle, nullptr);
140              EXPECT_LT(id, kNumOfHandles);
141  
142              // handleInt must be between [1, kNumOfHandles] as we "allocated" above.
143              EXPECT_LT(0u, handleInt);
144              EXPECT_LE(handleInt, kNumOfHandles);
145  
146              inUseIDHandlePairs.push_back({id, handleInt});
147              EXPECT_TRUE(inUseIDs.insert(id).second);
148              EXPECT_TRUE(inUseHandles.insert(handleInt).second);
149              evsCam->checkBufferOrder();
150          }
151          // Return buffers in the order of acquiring.
152          for (const auto [id, handleInt] : inUseIDHandlePairs) {
153              evsCam->returnBuffer_unsafe(id);
154              evsCam->checkBufferOrder();
155          }
156      }
157  
158      {
159          std::vector<std::pair<std::size_t, std::intptr_t>> inUseIDHandlePairs;
160          std::unordered_set<std::size_t> inUseIDs;
161          std::unordered_set<std::intptr_t> inUseHandles;
162          for (std::size_t i = 0; i < kNumOfHandles; ++i) {
163              const auto [id, handle] = evsCam->useBuffer_unsafe();
164              const std::size_t handleInt = reinterpret_cast<std::size_t>(handle);
165              EXPECT_TRUE(EvsCamera::IsBufferIDValid(id));
166              EXPECT_NE(handle, nullptr);
167              EXPECT_LT(id, kNumOfHandles);
168  
169              // handleInt must be between [1, kNumOfHandles] as we "allocated" above.
170              EXPECT_LT(0u, handleInt);
171              EXPECT_LE(handleInt, kNumOfHandles);
172  
173              inUseIDHandlePairs.push_back({id, handleInt});
174              EXPECT_TRUE(inUseIDs.insert(id).second);
175              EXPECT_TRUE(inUseHandles.insert(handleInt).second);
176              evsCam->checkBufferOrder();
177          }
178          // Return buffers in the reverse order of acquiring.
179          std::reverse(inUseIDHandlePairs.begin(), inUseIDHandlePairs.end());
180          for (const auto [id, handleInt] : inUseIDHandlePairs) {
181              evsCam->returnBuffer_unsafe(id);
182              evsCam->checkBufferOrder();
183          }
184      }
185  
186      {
187          // Making sure the handles are still in [1, kNumOfHandles] and IDs are still [0,
188          // kNumOfHandles). The mapping may be different, though.
189          std::vector<std::pair<std::size_t, std::intptr_t>> inUseIDHandlePairs;
190          std::unordered_set<std::size_t> inUseIDs;
191          std::unordered_set<std::intptr_t> inUseHandles;
192          for (std::size_t i = 0; i < kNumOfHandles; ++i) {
193              const auto [id, handle] = evsCam->useBuffer_unsafe();
194              const std::size_t handleInt = reinterpret_cast<std::size_t>(handle);
195              EXPECT_TRUE(EvsCamera::IsBufferIDValid(id));
196              EXPECT_NE(handle, nullptr);
197              EXPECT_LT(id, kNumOfHandles);
198  
199              // handleInt must be between [1, kNumOfHandles] as we "allocated" above.
200              EXPECT_LT(0u, handleInt);
201              EXPECT_LE(handleInt, kNumOfHandles);
202  
203              inUseIDHandlePairs.push_back({id, handleInt});
204              EXPECT_TRUE(inUseIDs.insert(id).second);
205              EXPECT_TRUE(inUseHandles.insert(handleInt).second);
206              evsCam->checkBufferOrder();
207          }
208      }
209  }
210  
211  }  // namespace aidl::android::hardware::automotive::evs::implementation
212