1 /*
2 * Copyright 2020 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 "MockEvsCamera.h"
18
19 #include <stdlib.h>
20
21 namespace android {
22 namespace hardware {
23 namespace automotive {
24 namespace sv {
25 namespace V1_0 {
26 namespace implementation {
27
28 // TODO(b/159733690): the number should come from xml
29 const int kFramesCount = 4;
30 const int kFrameGenerationDelayMillis = 30;
31
MockEvsCamera(const string & cameraId,const Stream & streamCfg)32 MockEvsCamera::MockEvsCamera(const string& cameraId, const Stream& streamCfg) {
33 mConfigManager = ConfigManager::Create();
34
35 mStreamCfg.height = streamCfg.height;
36 mStreamCfg.width = streamCfg.width;
37
38 mCameraDesc.v1.cameraId = cameraId;
39 unique_ptr<ConfigManager::CameraGroupInfo>& cameraGroupInfo =
40 mConfigManager->getCameraGroupInfo(mCameraDesc.v1.cameraId);
41 if (cameraGroupInfo != nullptr) {
42 mCameraDesc.metadata.setToExternal(
43 (uint8_t*)cameraGroupInfo->characteristics,
44 get_camera_metadata_size(cameraGroupInfo->characteristics));
45 }
46 }
47
getCameraInfo(getCameraInfo_cb _hidl_cb)48 Return<void> MockEvsCamera::getCameraInfo(getCameraInfo_cb _hidl_cb) {
49 // Not implemented.
50
51 (void)_hidl_cb;
52 return {};
53 }
54
setMaxFramesInFlight(uint32_t bufferCount)55 Return<EvsResult> MockEvsCamera::setMaxFramesInFlight(uint32_t bufferCount) {
56 // Not implemented.
57
58 (void)bufferCount;
59 return EvsResult::OK;
60 }
61
startVideoStream(const::android::sp<IEvsCameraStream_1_0> & stream)62 Return<EvsResult> MockEvsCamera::startVideoStream(
63 const ::android::sp<IEvsCameraStream_1_0>& stream) {
64 LOG(INFO) << __FUNCTION__;
65 scoped_lock<mutex> lock(mAccessLock);
66
67 mStream = IEvsCameraStream_1_1::castFrom(stream).withDefault(nullptr);
68
69 if (mStreamState != STOPPED) {
70 LOG(ERROR) << "Ignoring startVideoStream call when a stream is "
71 << "already running.";
72 return EvsResult::STREAM_ALREADY_RUNNING;
73 }
74
75 // Start the frame generation thread
76 mStreamState = RUNNING;
77 mCaptureThread = thread([this]() { generateFrames(); });
78
79 return EvsResult::OK;
80 }
81
doneWithFrame(const BufferDesc_1_0 & buffer)82 Return<void> MockEvsCamera::doneWithFrame(const BufferDesc_1_0& buffer) {
83 // Not implemented.
84
85 (void)buffer;
86 return {};
87 }
88
stopVideoStream()89 Return<void> MockEvsCamera::stopVideoStream() {
90 LOG(INFO) << __FUNCTION__;
91
92 unique_lock<mutex> lock(mAccessLock);
93 if (mStreamState == RUNNING) {
94 // Tell the GenerateFrames loop we want it to stop
95 mStreamState = STOPPING;
96 // Block outside the mutex until the "stop" flag has been acknowledged
97 // We won't send any more frames, but the client might still get some
98 // already in flight
99 LOG(DEBUG) << __FUNCTION__ << ": Waiting for stream thread to end...";
100 lock.unlock();
101 mCaptureThread.join();
102 lock.lock();
103 mStreamState = STOPPED;
104 mStream = nullptr;
105 LOG(DEBUG) << "Stream marked STOPPED.";
106 }
107 return {};
108 }
109
getExtendedInfo(uint32_t opaqueIdentifier)110 Return<int32_t> MockEvsCamera::getExtendedInfo(uint32_t opaqueIdentifier) {
111 // Not implemented.
112
113 (void)opaqueIdentifier;
114 return 0;
115 }
116
setExtendedInfo(uint32_t opaqueIdentifier,int32_t opaqueValue)117 Return<EvsResult> MockEvsCamera::setExtendedInfo(uint32_t opaqueIdentifier,
118 int32_t opaqueValue) {
119 // Not implemented.
120
121 (void)opaqueIdentifier;
122 (void)opaqueValue;
123 return EvsResult::OK;
124 }
125
getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb)126 Return<void> MockEvsCamera::getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb) {
127 _hidl_cb(mCameraDesc);
128 return {};
129 }
130
getPhysicalCameraInfo(const hidl_string & deviceId,getPhysicalCameraInfo_cb _hidl_cb)131 Return<void> MockEvsCamera::getPhysicalCameraInfo(
132 const hidl_string& deviceId, getPhysicalCameraInfo_cb _hidl_cb) {
133 CameraDesc_1_1 desc = {};
134 desc.v1.cameraId = deviceId;
135
136 unique_ptr<ConfigManager::CameraInfo>& cameraInfo =
137 mConfigManager->getCameraInfo(deviceId);
138 if (cameraInfo != nullptr) {
139 desc.metadata.setToExternal(
140 (uint8_t*)cameraInfo->characteristics,
141 get_camera_metadata_size(cameraInfo->characteristics));
142 }
143
144 _hidl_cb(desc);
145
146 return {};
147 }
148
doneWithFrame_1_1(const hardware::hidl_vec<BufferDesc_1_1> & buffer)149 Return<EvsResult> MockEvsCamera::doneWithFrame_1_1(
150 const hardware::hidl_vec<BufferDesc_1_1>& buffer) {
151 // Not implemented.
152
153 (void)buffer;
154 return EvsResult::OK;
155 }
156
setMaster()157 Return<EvsResult> MockEvsCamera::setMaster() {
158 // Not implemented.
159
160 return EvsResult::OK;
161 }
162
forceMaster(const sp<IEvsDisplay_1_0> & display)163 Return<EvsResult> MockEvsCamera::forceMaster(
164 const sp<IEvsDisplay_1_0>& display) {
165 // Not implemented.
166
167 (void)display;
168 return EvsResult::OK;
169 }
170
unsetMaster()171 Return<EvsResult> MockEvsCamera::unsetMaster() {
172 // Not implemented.
173
174 return EvsResult::OK;
175 }
176
getParameterList(getParameterList_cb _hidl_cb)177 Return<void> MockEvsCamera::getParameterList(getParameterList_cb _hidl_cb) {
178 // Not implemented.
179
180 (void)_hidl_cb;
181 return {};
182 }
183
getIntParameterRange(CameraParam id,getIntParameterRange_cb _hidl_cb)184 Return<void> MockEvsCamera::getIntParameterRange(
185 CameraParam id, getIntParameterRange_cb _hidl_cb) {
186 // Not implemented.
187
188 (void)id;
189 (void)_hidl_cb;
190 return {};
191 }
192
setIntParameter(CameraParam id,int32_t value,setIntParameter_cb _hidl_cb)193 Return<void> MockEvsCamera::setIntParameter(CameraParam id, int32_t value,
194 setIntParameter_cb _hidl_cb) {
195 // Not implemented.
196
197 (void)id;
198 (void)value;
199 (void)_hidl_cb;
200 return {};
201 }
202
getIntParameter(CameraParam id,getIntParameter_cb _hidl_cb)203 Return<void> MockEvsCamera::getIntParameter(
204 CameraParam id, getIntParameter_cb _hidl_cb) {
205 // Not implemented.
206
207 (void)id;
208 (void)_hidl_cb;
209 return {};
210 }
211
setExtendedInfo_1_1(uint32_t opaqueIdentifier,const hidl_vec<uint8_t> & opaqueValue)212 Return<EvsResult> MockEvsCamera::setExtendedInfo_1_1(
213 uint32_t opaqueIdentifier, const hidl_vec<uint8_t>& opaqueValue) {
214 // Not implemented.
215
216 (void)opaqueIdentifier;
217 (void)opaqueValue;
218 return EvsResult::OK;
219 }
220
getExtendedInfo_1_1(uint32_t opaqueIdentifier,getExtendedInfo_1_1_cb _hidl_cb)221 Return<void> MockEvsCamera::getExtendedInfo_1_1(
222 uint32_t opaqueIdentifier, getExtendedInfo_1_1_cb _hidl_cb) {
223 // Not implemented.
224
225 (void)opaqueIdentifier;
226 (void)_hidl_cb;
227 return {};
228 }
229
importExternalBuffers(const hidl_vec<BufferDesc_1_1> & buffers,importExternalBuffers_cb _hidl_cb)230 Return<void> MockEvsCamera::importExternalBuffers(
231 const hidl_vec<BufferDesc_1_1>& buffers,
232 importExternalBuffers_cb _hidl_cb) {
233 // Not implemented.
234
235 (void)buffers;
236 (void)_hidl_cb;
237 return {};
238 }
239
initializeFrames(int framesCount)240 void MockEvsCamera::initializeFrames(int framesCount) {
241 LOG(INFO) << "StreamCfg width: " << mStreamCfg.width
242 << " height: " << mStreamCfg.height;
243
244 string label = "EmptyBuffer_";
245 mGraphicBuffers.resize(framesCount);
246 mBufferDescs.resize(framesCount);
247 for (int i = 0; i < framesCount; i++) {
248 mGraphicBuffers[i] = new GraphicBuffer(mStreamCfg.width,
249 mStreamCfg.height,
250 HAL_PIXEL_FORMAT_RGBA_8888,
251 1,
252 GRALLOC_USAGE_HW_TEXTURE,
253 label + (char)(i + 48));
254 mBufferDescs[i].buffer.nativeHandle =
255 mGraphicBuffers[i]->getNativeBuffer()->handle;
256 AHardwareBuffer_Desc* pDesc =
257 reinterpret_cast<AHardwareBuffer_Desc*>(
258 &mBufferDescs[i].buffer.description);
259 pDesc->width = mStreamCfg.width;
260 pDesc->height = mStreamCfg.height;
261 pDesc->layers = 1;
262 pDesc->usage = GRALLOC_USAGE_HW_TEXTURE;
263 pDesc->stride = mGraphicBuffers[i]->getStride();
264 pDesc->format = HAL_PIXEL_FORMAT_RGBA_8888;
265 }
266 }
267
generateFrames()268 void MockEvsCamera::generateFrames() {
269 initializeFrames(kFramesCount);
270
271 while (true) {
272 {
273 scoped_lock<mutex> lock(mAccessLock);
274 if (mStreamState != RUNNING) {
275 // Break out of our main thread loop
276 LOG(INFO) << "StreamState does not equal to RUNNING. "
277 << "Exiting the loop";
278 break;
279 }
280 }
281
282 mStream->deliverFrame_1_1(mBufferDescs);
283 std::this_thread::sleep_for(
284 std::chrono::milliseconds(kFrameGenerationDelayMillis));
285 }
286
287 {
288 scoped_lock<mutex> lock(mAccessLock);
289
290 if (mStream != nullptr) {
291 LOG(DEBUG) << "Notify EvsEventType::STREAM_STOPPED";
292
293 EvsEventDesc evsEventDesc;
294 evsEventDesc.aType = EvsEventType::STREAM_STOPPED;
295 mStream->notify(evsEventDesc);
296 } else {
297 LOG(WARNING) << "EVS stream is not valid any more. "
298 << "The notify call is ignored.";
299 }
300 }
301 }
302
303 } // namespace implementation
304 } // namespace V1_0
305 } // namespace sv
306 } // namespace automotive
307 } // namespace hardware
308 } // namespace android
309