• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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_NDEBUG 0
18 #define LOG_TAG "CameraBinderTests"
19 
20 #include <binder/IInterface.h>
21 #include <binder/IServiceManager.h>
22 #include <binder/Parcel.h>
23 #include <binder/ProcessState.h>
24 #include <utils/Errors.h>
25 #include <utils/Log.h>
26 #include <utils/List.h>
27 #include <utils/String8.h>
28 #include <utils/String16.h>
29 #include <utils/Condition.h>
30 #include <utils/Mutex.h>
31 #include <system/graphics.h>
32 #include <hardware/gralloc.h>
33 
34 #include <camera/CameraMetadata.h>
35 #include <android/hardware/ICameraService.h>
36 #include <android/hardware/ICameraServiceListener.h>
37 #include <android/hardware/BnCameraServiceListener.h>
38 #include <android/hardware/camera2/ICameraDeviceUser.h>
39 #include <android/hardware/camera2/ICameraDeviceCallbacks.h>
40 #include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
41 #include <camera/camera2/CaptureRequest.h>
42 #include <camera/camera2/OutputConfiguration.h>
43 #include <camera/camera2/SubmitInfo.h>
44 
45 #include <gui/BufferItemConsumer.h>
46 #include <gui/IGraphicBufferProducer.h>
47 #include <gui/Surface.h>
48 
49 #include <gtest/gtest.h>
50 #include <unistd.h>
51 #include <stdint.h>
52 #include <utility>
53 #include <vector>
54 #include <map>
55 #include <algorithm>
56 
57 using namespace android;
58 
59 #define ASSERT_NOT_NULL(x) \
60     ASSERT_TRUE((x) != nullptr)
61 
62 #define SETUP_TIMEOUT 2000000000 // ns
63 #define IDLE_TIMEOUT 2000000000 // ns
64 
65 // Stub listener implementation
66 class TestCameraServiceListener : public hardware::BnCameraServiceListener {
67     std::map<String16, int32_t> mCameraTorchStatuses;
68     std::map<String16, int32_t> mCameraStatuses;
69     mutable Mutex mLock;
70     mutable Condition mCondition;
71     mutable Condition mTorchCondition;
72 public:
~TestCameraServiceListener()73     virtual ~TestCameraServiceListener() {};
74 
onStatusChanged(int32_t status,const String16 & cameraId)75     virtual binder::Status onStatusChanged(int32_t status, const String16& cameraId) {
76         Mutex::Autolock l(mLock);
77         mCameraStatuses[cameraId] = status;
78         mCondition.broadcast();
79         return binder::Status::ok();
80     };
81 
onTorchStatusChanged(int32_t status,const String16 & cameraId)82     virtual binder::Status onTorchStatusChanged(int32_t status, const String16& cameraId) {
83         Mutex::Autolock l(mLock);
84         mCameraTorchStatuses[cameraId] = status;
85         mTorchCondition.broadcast();
86         return binder::Status::ok();
87     };
88 
waitForNumCameras(size_t num) const89     bool waitForNumCameras(size_t num) const {
90         Mutex::Autolock l(mLock);
91 
92         if (mCameraStatuses.size() == num) {
93             return true;
94         }
95 
96         while (mCameraStatuses.size() < num) {
97             if (mCondition.waitRelative(mLock, SETUP_TIMEOUT) != OK) {
98                 return false;
99             }
100         }
101         return true;
102     };
103 
waitForTorchState(int32_t status,int32_t cameraId) const104     bool waitForTorchState(int32_t status, int32_t cameraId) const {
105         Mutex::Autolock l(mLock);
106 
107         const auto& iter = mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
108         if (iter != mCameraTorchStatuses.end() && iter->second == status) {
109             return true;
110         }
111 
112         bool foundStatus = false;
113         while (!foundStatus) {
114             if (mTorchCondition.waitRelative(mLock, SETUP_TIMEOUT) != OK) {
115                 return false;
116             }
117             const auto& iter =
118                     mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
119             foundStatus = (iter != mCameraTorchStatuses.end() && iter->second == status);
120         }
121         return true;
122     };
123 
getTorchStatus(int32_t cameraId) const124     int32_t getTorchStatus(int32_t cameraId) const {
125         Mutex::Autolock l(mLock);
126         const auto& iter = mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
127         if (iter == mCameraTorchStatuses.end()) {
128             return hardware::ICameraServiceListener::TORCH_STATUS_UNKNOWN;
129         }
130         return iter->second;
131     };
132 
getStatus(const String16 & cameraId) const133     int32_t getStatus(const String16& cameraId) const {
134         Mutex::Autolock l(mLock);
135         const auto& iter = mCameraStatuses.find(cameraId);
136         if (iter == mCameraStatuses.end()) {
137             return hardware::ICameraServiceListener::STATUS_UNKNOWN;
138         }
139         return iter->second;
140     };
141 };
142 
143 // Callback implementation
144 class TestCameraDeviceCallbacks : public hardware::camera2::BnCameraDeviceCallbacks {
145 public:
146     enum Status {
147         IDLE,
148         ERROR,
149         PREPARED,
150         RUNNING,
151         SENT_RESULT,
152         UNINITIALIZED,
153         REPEATING_REQUEST_ERROR,
154         REQUEST_QUEUE_EMPTY,
155     };
156 
157 protected:
158     bool mError;
159     int32_t mLastStatus;
160     mutable std::vector<int32_t> mStatusesHit;
161     mutable Mutex mLock;
162     mutable Condition mStatusCondition;
163 public:
TestCameraDeviceCallbacks()164     TestCameraDeviceCallbacks() : mError(false), mLastStatus(UNINITIALIZED) {}
165 
~TestCameraDeviceCallbacks()166     virtual ~TestCameraDeviceCallbacks() {}
167 
onDeviceError(int errorCode,const CaptureResultExtras & resultExtras)168     virtual binder::Status onDeviceError(int errorCode,
169             const CaptureResultExtras& resultExtras) {
170         (void) resultExtras;
171         ALOGE("%s: onDeviceError occurred with: %d", __FUNCTION__, static_cast<int>(errorCode));
172         Mutex::Autolock l(mLock);
173         mError = true;
174         mLastStatus = ERROR;
175         mStatusesHit.push_back(mLastStatus);
176         mStatusCondition.broadcast();
177         return binder::Status::ok();
178     }
179 
onDeviceIdle()180     virtual binder::Status onDeviceIdle() {
181         Mutex::Autolock l(mLock);
182         mLastStatus = IDLE;
183         mStatusesHit.push_back(mLastStatus);
184         mStatusCondition.broadcast();
185         return binder::Status::ok();
186     }
187 
onCaptureStarted(const CaptureResultExtras & resultExtras,int64_t timestamp)188     virtual binder::Status onCaptureStarted(const CaptureResultExtras& resultExtras,
189             int64_t timestamp) {
190         (void) resultExtras;
191         (void) timestamp;
192         Mutex::Autolock l(mLock);
193         mLastStatus = RUNNING;
194         mStatusesHit.push_back(mLastStatus);
195         mStatusCondition.broadcast();
196         return binder::Status::ok();
197     }
198 
199 
onResultReceived(const CameraMetadata & metadata,const CaptureResultExtras & resultExtras,const std::vector<PhysicalCaptureResultInfo> & physicalResultInfos)200     virtual binder::Status onResultReceived(const CameraMetadata& metadata,
201             const CaptureResultExtras& resultExtras,
202             const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
203         (void) metadata;
204         (void) resultExtras;
205         (void) physicalResultInfos;
206         Mutex::Autolock l(mLock);
207         mLastStatus = SENT_RESULT;
208         mStatusesHit.push_back(mLastStatus);
209         mStatusCondition.broadcast();
210         return binder::Status::ok();
211     }
212 
onPrepared(int streamId)213     virtual binder::Status onPrepared(int streamId) {
214         (void) streamId;
215         Mutex::Autolock l(mLock);
216         mLastStatus = PREPARED;
217         mStatusesHit.push_back(mLastStatus);
218         mStatusCondition.broadcast();
219         return binder::Status::ok();
220     }
221 
onRepeatingRequestError(int64_t lastFrameNumber,int32_t stoppedSequenceId)222     virtual binder::Status onRepeatingRequestError(
223             int64_t lastFrameNumber, int32_t stoppedSequenceId) {
224         (void) lastFrameNumber;
225         (void) stoppedSequenceId;
226         Mutex::Autolock l(mLock);
227         mLastStatus = REPEATING_REQUEST_ERROR;
228         mStatusesHit.push_back(mLastStatus);
229         mStatusCondition.broadcast();
230         return binder::Status::ok();
231     }
232 
onRequestQueueEmpty()233     virtual binder::Status onRequestQueueEmpty() {
234         Mutex::Autolock l(mLock);
235         mLastStatus = REQUEST_QUEUE_EMPTY;
236         mStatusesHit.push_back(mLastStatus);
237         mStatusCondition.broadcast();
238         return binder::Status::ok();
239     }
240 
241     // Test helper functions:
242 
hadError() const243     bool hadError() const {
244         Mutex::Autolock l(mLock);
245         return mError;
246     }
247 
waitForStatus(Status status) const248     bool waitForStatus(Status status) const {
249         Mutex::Autolock l(mLock);
250         if (mLastStatus == status) {
251             return true;
252         }
253 
254         while (std::find(mStatusesHit.begin(), mStatusesHit.end(), status)
255                 == mStatusesHit.end()) {
256 
257             if (mStatusCondition.waitRelative(mLock, IDLE_TIMEOUT) != OK) {
258                 mStatusesHit.clear();
259                 return false;
260             }
261         }
262         mStatusesHit.clear();
263 
264         return true;
265 
266     }
267 
clearStatus() const268     void clearStatus() const {
269         Mutex::Autolock l(mLock);
270         mStatusesHit.clear();
271     }
272 
waitForIdle() const273     bool waitForIdle() const {
274         return waitForStatus(IDLE);
275     }
276 
277 };
278 
279 namespace {
280     Mutex                     gLock;
281     class DeathNotifier : public IBinder::DeathRecipient
282     {
283     public:
DeathNotifier()284         DeathNotifier() {}
285 
binderDied(const wp<IBinder> &)286         virtual void binderDied(const wp<IBinder>& /*who*/) {
287             ALOGV("binderDied");
288             Mutex::Autolock _l(gLock);
289             ALOGW("Camera service died!");
290         }
291     };
292     sp<DeathNotifier>         gDeathNotifier;
293 }; // anonymous namespace
294 
295 // Exercise basic binder calls for the camera service
TEST(CameraServiceBinderTest,CheckBinderCameraService)296 TEST(CameraServiceBinderTest, CheckBinderCameraService) {
297     ProcessState::self()->startThreadPool();
298     sp<IServiceManager> sm = defaultServiceManager();
299     sp<IBinder> binder = sm->getService(String16("media.camera"));
300     ASSERT_NOT_NULL(binder);
301     if (gDeathNotifier == NULL) {
302         gDeathNotifier = new DeathNotifier();
303     }
304     binder->linkToDeath(gDeathNotifier);
305     sp<hardware::ICameraService> service =
306             interface_cast<hardware::ICameraService>(binder);
307 
308     binder::Status res;
309 
310     int32_t numCameras = 0;
311     res = service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_ALL, &numCameras);
312     EXPECT_TRUE(res.isOk()) << res;
313     EXPECT_LE(0, numCameras);
314 
315     // Check listener binder calls
316     sp<TestCameraServiceListener> listener(new TestCameraServiceListener());
317     std::vector<hardware::CameraStatus> statuses;
318     res = service->addListener(listener, &statuses);
319     EXPECT_TRUE(res.isOk()) << res;
320 
321     EXPECT_EQ(numCameras, static_cast<const int>(statuses.size()));
322     for (const auto &it : statuses) {
323         listener->onStatusChanged(it.status, String16(it.cameraId));
324     }
325 
326     for (int32_t i = 0; i < numCameras; i++) {
327         String16 cameraId = String16(String8::format("%d", i));
328         bool isSupported = false;
329         res = service->supportsCameraApi(cameraId,
330                 hardware::ICameraService::API_VERSION_2, &isSupported);
331         EXPECT_TRUE(res.isOk()) << res;
332 
333         // We only care about binder calls for the Camera2 API.  Camera1 is deprecated.
334         if (!isSupported) {
335             continue;
336         }
337 
338         // Check metadata binder call
339         CameraMetadata metadata;
340         res = service->getCameraCharacteristics(cameraId, &metadata);
341         EXPECT_TRUE(res.isOk()) << res;
342         EXPECT_FALSE(metadata.isEmpty());
343 
344         // Make sure we're available, or skip device tests otherwise
345         int32_t s = listener->getStatus(cameraId);
346         EXPECT_EQ(::android::hardware::ICameraServiceListener::STATUS_PRESENT, s);
347         if (s != ::android::hardware::ICameraServiceListener::STATUS_PRESENT) {
348             continue;
349         }
350 
351         // Check connect binder calls
352         sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
353         sp<hardware::camera2::ICameraDeviceUser> device;
354         res = service->connectDevice(callbacks, cameraId, String16("meeeeeeeee!"),
355                 hardware::ICameraService::USE_CALLING_UID, /*out*/&device);
356         EXPECT_TRUE(res.isOk()) << res;
357         ASSERT_NE(nullptr, device.get());
358         device->disconnect();
359         EXPECT_FALSE(callbacks->hadError());
360 
361         int32_t torchStatus = listener->getTorchStatus(i);
362         if (torchStatus == hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF) {
363             // Check torch calls
364             res = service->setTorchMode(cameraId,
365                     /*enabled*/true, callbacks);
366             EXPECT_TRUE(res.isOk()) << res;
367             EXPECT_TRUE(listener->waitForTorchState(
368                     hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON, i));
369             res = service->setTorchMode(cameraId,
370                     /*enabled*/false, callbacks);
371             EXPECT_TRUE(res.isOk()) << res;
372             EXPECT_TRUE(listener->waitForTorchState(
373                     hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF, i));
374         }
375     }
376 
377     res = service->removeListener(listener);
378     EXPECT_TRUE(res.isOk()) << res;
379 }
380 
381 // Test fixture for client focused binder tests
382 class CameraClientBinderTest : public testing::Test {
383 protected:
384     sp<hardware::ICameraService> service;
385     int32_t numCameras;
386     std::vector<std::pair<sp<TestCameraDeviceCallbacks>, sp<hardware::camera2::ICameraDeviceUser>>>
387             openDeviceList;
388     sp<TestCameraServiceListener> serviceListener;
389 
390     std::pair<sp<TestCameraDeviceCallbacks>, sp<hardware::camera2::ICameraDeviceUser>>
openNewDevice(const String16 & deviceId)391             openNewDevice(const String16& deviceId) {
392         sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
393         sp<hardware::camera2::ICameraDeviceUser> device;
394         {
395             SCOPED_TRACE("openNewDevice");
396             binder::Status res = service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"),
397                     hardware::ICameraService::USE_CALLING_UID, /*out*/&device);
398             EXPECT_TRUE(res.isOk()) << res;
399         }
400         auto p = std::make_pair(callbacks, device);
401         openDeviceList.push_back(p);
402         return p;
403     }
404 
closeDevice(std::pair<sp<TestCameraDeviceCallbacks>,sp<hardware::camera2::ICameraDeviceUser>> & p)405     void closeDevice(std::pair<sp<TestCameraDeviceCallbacks>,
406             sp<hardware::camera2::ICameraDeviceUser>>& p) {
407         if (p.second.get() != nullptr) {
408             binder::Status res = p.second->disconnect();
409             EXPECT_TRUE(res.isOk()) << res;
410             {
411                 SCOPED_TRACE("closeDevice");
412                 EXPECT_FALSE(p.first->hadError());
413             }
414         }
415         auto iter = std::find(openDeviceList.begin(), openDeviceList.end(), p);
416         if (iter != openDeviceList.end()) {
417             openDeviceList.erase(iter);
418         }
419     }
420 
SetUp()421     virtual void SetUp() {
422         ProcessState::self()->startThreadPool();
423         sp<IServiceManager> sm = defaultServiceManager();
424         sp<IBinder> binder = sm->getService(String16("media.camera"));
425         service = interface_cast<hardware::ICameraService>(binder);
426         serviceListener = new TestCameraServiceListener();
427         std::vector<hardware::CameraStatus> statuses;
428         service->addListener(serviceListener, &statuses);
429         for (const auto &it : statuses) {
430             serviceListener->onStatusChanged(it.status, String16(it.cameraId));
431         }
432         service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE,
433                 &numCameras);
434     }
435 
TearDown()436     virtual void TearDown() {
437         service = nullptr;
438         numCameras = 0;
439         for (auto& p : openDeviceList) {
440             closeDevice(p);
441         }
442     }
443 
444 };
445 
TEST_F(CameraClientBinderTest,CheckBinderCameraDeviceUser)446 TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) {
447     ASSERT_NOT_NULL(service);
448     EXPECT_TRUE(serviceListener->waitForNumCameras(numCameras));
449     for (int32_t i = 0; i < numCameras; i++) {
450         String8 cameraId8 = String8::format("%d", i);
451         // Make sure we're available, or skip device tests otherwise
452         String16 cameraId(cameraId8);
453         int32_t s = serviceListener->getStatus(cameraId);
454         EXPECT_EQ(hardware::ICameraServiceListener::STATUS_PRESENT, s);
455         if (s != hardware::ICameraServiceListener::STATUS_PRESENT) {
456             continue;
457         }
458         binder::Status res;
459         auto p = openNewDevice(cameraId);
460         sp<TestCameraDeviceCallbacks> callbacks = p.first;
461         sp<hardware::camera2::ICameraDeviceUser> device = p.second;
462 
463         // Setup a buffer queue; I'm just using the vendor opaque format here as that is
464         // guaranteed to be present
465         sp<IGraphicBufferProducer> gbProducer;
466         sp<IGraphicBufferConsumer> gbConsumer;
467         BufferQueue::createBufferQueue(&gbProducer, &gbConsumer);
468         sp<BufferItemConsumer> opaqueConsumer = new BufferItemConsumer(gbConsumer,
469                 GRALLOC_USAGE_SW_READ_NEVER, /*maxImages*/2, /*controlledByApp*/true);
470         EXPECT_TRUE(opaqueConsumer.get() != nullptr);
471         opaqueConsumer->setName(String8("nom nom nom"));
472 
473         // Set to VGA dimens for default, as that is guaranteed to be present
474         EXPECT_EQ(OK, gbConsumer->setDefaultBufferSize(640, 480));
475         EXPECT_EQ(OK, gbConsumer->setDefaultBufferFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED));
476 
477         sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false));
478 
479         OutputConfiguration output(gbProducer, /*rotation*/0);
480 
481         // Can we configure?
482         res = device->beginConfigure();
483         EXPECT_TRUE(res.isOk()) << res;
484         status_t streamId;
485         res = device->createStream(output, &streamId);
486         EXPECT_TRUE(res.isOk()) << res;
487         EXPECT_LE(0, streamId);
488         CameraMetadata sessionParams;
489         res = device->endConfigure(/*isConstrainedHighSpeed*/ false, sessionParams);
490         EXPECT_TRUE(res.isOk()) << res;
491         EXPECT_FALSE(callbacks->hadError());
492 
493         // Can we make requests?
494         CameraMetadata requestTemplate;
495         res = device->createDefaultRequest(/*preview template*/1,
496                 /*out*/&requestTemplate);
497         EXPECT_TRUE(res.isOk()) << res;
498 
499         hardware::camera2::CaptureRequest request;
500         request.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate});
501         request.mSurfaceList.add(surface);
502         request.mIsReprocess = false;
503         int64_t lastFrameNumber = 0;
504         int64_t lastFrameNumberPrev = 0;
505         callbacks->clearStatus();
506 
507         hardware::camera2::utils::SubmitInfo info;
508         res = device->submitRequest(request, /*streaming*/true, /*out*/&info);
509         EXPECT_TRUE(res.isOk()) << res;
510         EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT));
511         EXPECT_LE(0, info.mRequestId);
512 
513         // Can we stop requests?
514         res = device->cancelRequest(info.mRequestId, /*out*/&lastFrameNumber);
515         EXPECT_TRUE(res.isOk()) << res;
516         EXPECT_TRUE(callbacks->waitForIdle());
517         EXPECT_FALSE(callbacks->hadError());
518 
519         // Can we do it again?
520         lastFrameNumberPrev = info.mLastFrameNumber;
521         lastFrameNumber = 0;
522         requestTemplate.clear();
523         res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW,
524                 /*out*/&requestTemplate);
525         EXPECT_TRUE(res.isOk()) << res;
526         hardware::camera2::CaptureRequest request2;
527         request2.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate});
528         request2.mSurfaceList.add(surface);
529         request2.mIsReprocess = false;
530         callbacks->clearStatus();
531         hardware::camera2::utils::SubmitInfo info2;
532         res = device->submitRequest(request2, /*streaming*/true,
533                 /*out*/&info2);
534         EXPECT_TRUE(res.isOk()) << res;
535         EXPECT_EQ(hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES,
536                 info2.mLastFrameNumber);
537         lastFrameNumber = 0;
538         EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT));
539         EXPECT_LE(0, info2.mRequestId);
540         res = device->cancelRequest(info2.mRequestId, /*out*/&lastFrameNumber);
541         EXPECT_TRUE(res.isOk()) << res;
542         EXPECT_TRUE(callbacks->waitForIdle());
543         EXPECT_LE(lastFrameNumberPrev, lastFrameNumber);
544         sleep(/*second*/1); // allow some time for errors to show up, if any
545         EXPECT_FALSE(callbacks->hadError());
546 
547         // Can we do it with a request list?
548         lastFrameNumberPrev = lastFrameNumber;
549         lastFrameNumber = 0;
550         requestTemplate.clear();
551         CameraMetadata requestTemplate2;
552         res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW,
553                 /*out*/&requestTemplate);
554         EXPECT_TRUE(res.isOk()) << res;
555         res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW,
556                 /*out*/&requestTemplate2);
557         EXPECT_TRUE(res.isOk()) << res;
558         android::hardware::camera2::CaptureRequest request3;
559         android::hardware::camera2::CaptureRequest request4;
560         request3.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate});
561         request3.mSurfaceList.add(surface);
562         request3.mIsReprocess = false;
563         request4.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate2});
564         request4.mSurfaceList.add(surface);
565         request4.mIsReprocess = false;
566         std::vector<hardware::camera2::CaptureRequest> requestList;
567         requestList.push_back(request3);
568         requestList.push_back(request4);
569 
570         callbacks->clearStatus();
571         hardware::camera2::utils::SubmitInfo info3;
572         res = device->submitRequestList(requestList, /*streaming*/false,
573                 /*out*/&info3);
574         EXPECT_TRUE(res.isOk()) << res;
575         EXPECT_LE(0, info3.mRequestId);
576         EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT));
577         EXPECT_TRUE(callbacks->waitForIdle());
578         EXPECT_LE(lastFrameNumberPrev, info3.mLastFrameNumber);
579         sleep(/*second*/1); // allow some time for errors to show up, if any
580         EXPECT_FALSE(callbacks->hadError());
581 
582         // Can we unconfigure?
583         res = device->beginConfigure();
584         EXPECT_TRUE(res.isOk()) << res;
585         res = device->deleteStream(streamId);
586         EXPECT_TRUE(res.isOk()) << res;
587         res = device->endConfigure(/*isConstrainedHighSpeed*/ false, sessionParams);
588         EXPECT_TRUE(res.isOk()) << res;
589 
590         sleep(/*second*/1); // allow some time for errors to show up, if any
591         EXPECT_FALSE(callbacks->hadError());
592 
593         closeDevice(p);
594     }
595 
596 };
597 
TEST_F(CameraClientBinderTest,CheckBinderCaptureRequest)598 TEST_F(CameraClientBinderTest, CheckBinderCaptureRequest) {
599     sp<CaptureRequest> requestOriginal, requestParceled;
600     sp<IGraphicBufferProducer> gbProducer;
601     sp<IGraphicBufferConsumer> gbConsumer;
602     BufferQueue::createBufferQueue(&gbProducer, &gbConsumer);
603     sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false));
604     Vector<sp<Surface>> surfaceList;
605     surfaceList.push_back(surface);
606     std::string physicalDeviceId1 = "0";
607     std::string physicalDeviceId2 = "1";
608     CameraMetadata physicalDeviceSettings1, physicalDeviceSettings2;
609     uint8_t intent1 = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
610     uint8_t intent2 = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
611     EXPECT_EQ(OK, physicalDeviceSettings1.update(ANDROID_CONTROL_CAPTURE_INTENT, &intent1, 1));
612     EXPECT_EQ(OK, physicalDeviceSettings2.update(ANDROID_CONTROL_CAPTURE_INTENT, &intent2, 1));
613 
614     requestParceled = new CaptureRequest();
615     Parcel p;
616     EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK);
617     p.writeInt32(0);
618     p.setDataPosition(0);
619     EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK);
620     p.freeData();
621     p.writeInt32(-1);
622     p.setDataPosition(0);
623     EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK);
624     p.freeData();
625     p.writeInt32(1);
626     p.setDataPosition(0);
627     EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK);
628 
629     requestOriginal = new CaptureRequest();
630     requestOriginal->mPhysicalCameraSettings.push_back({physicalDeviceId1,
631             physicalDeviceSettings1});
632     requestOriginal->mPhysicalCameraSettings.push_back({physicalDeviceId2,
633             physicalDeviceSettings2});
634     requestOriginal->mSurfaceList.push_back(surface);
635     requestOriginal->mIsReprocess = false;
636     requestOriginal->mSurfaceConverted = false;
637 
638     p.freeData();
639     EXPECT_TRUE(requestOriginal->writeToParcel(&p) == OK);
640     p.setDataPosition(0);
641     EXPECT_TRUE(requestParceled->readFromParcel(&p) == OK);
642     EXPECT_EQ(requestParceled->mIsReprocess, false);
643     EXPECT_FALSE(requestParceled->mSurfaceList.empty());
644     EXPECT_EQ(2u, requestParceled->mPhysicalCameraSettings.size());
645     auto it = requestParceled->mPhysicalCameraSettings.begin();
646     EXPECT_EQ(physicalDeviceId1, it->id);
647     EXPECT_TRUE(it->settings.exists(ANDROID_CONTROL_CAPTURE_INTENT));
648     auto entry = it->settings.find(ANDROID_CONTROL_CAPTURE_INTENT);
649     EXPECT_EQ(entry.data.u8[0], intent1);
650     it++;
651     EXPECT_EQ(physicalDeviceId2, it->id);
652     EXPECT_TRUE(it->settings.exists(ANDROID_CONTROL_CAPTURE_INTENT));
653     entry = it->settings.find(ANDROID_CONTROL_CAPTURE_INTENT);
654     EXPECT_EQ(entry.data.u8[0], intent2);
655 };
656