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 "NativeCamera"
19 #include <log/log.h>
20
21 #include <chrono>
22 #include <cinttypes>
23 #include <condition_variable>
24 #include <map>
25 #include <mutex>
26 #include <string>
27 #include <vector>
28 #include <unistd.h>
29 #include <assert.h>
30 #include <jni.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <set>
34
35 #include <android/native_window_jni.h>
36
37 #include "camera/NdkCameraError.h"
38 #include "camera/NdkCameraManager.h"
39 #include "camera/NdkCameraMetadata.h"
40 #include "camera/NdkCameraDevice.h"
41 #include "camera/NdkCameraCaptureSession.h"
42 #include "media/NdkImage.h"
43 #include "media/NdkImageReader.h"
44
45 #define LOG_ERROR(buf, ...) sprintf(buf, __VA_ARGS__); \
46 ALOGE("%s", buf);
47
48 namespace {
49 const int MAX_ERROR_STRING_LEN = 512;
50 char errorString[MAX_ERROR_STRING_LEN];
51 }
52
53 template <>
54 struct std::default_delete<ACameraMetadata> {
operator ()std::default_delete55 inline void operator()(ACameraMetadata* chars) const { ACameraMetadata_free(chars); }
56 };
57
58 class CameraServiceListener {
59 public:
60 typedef std::set<std::pair<std::string, std::string>> StringPairSet;
61
onAvailable(void * obj,const char * cameraId)62 static void onAvailable(void* obj, const char* cameraId) {
63 ALOGV("Camera %s onAvailable", cameraId);
64 if (obj == nullptr) {
65 return;
66 }
67 CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
68 std::lock_guard<std::mutex> lock(thiz->mMutex);
69 thiz->mOnAvailableCount++;
70 thiz->mAvailableMap[cameraId] = true;
71 return;
72 }
73
onUnavailable(void * obj,const char * cameraId)74 static void onUnavailable(void* obj, const char* cameraId) {
75 ALOGV("Camera %s onUnavailable", cameraId);
76 if (obj == nullptr) {
77 return;
78 }
79 CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
80 std::lock_guard<std::mutex> lock(thiz->mMutex);
81 thiz->mOnUnavailableCount++;
82 thiz->mAvailableMap[cameraId] = false;
83 return;
84 }
85
86
onCameraAccessPrioritiesChanged(void * obj)87 static void onCameraAccessPrioritiesChanged(void* obj) {
88 ALOGV("onCameraAccessPrioritiesChanged");
89 if (obj == nullptr) {
90 return;
91 }
92 CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
93 std::lock_guard<std::mutex> lock(thiz->mMutex);
94 thiz->mOnCameraAccessPrioritiesChangedCount++;
95 return;
96 }
97
onPhysicalCameraAvailable(void * obj,const char * cameraId,const char * physicalCameraId)98 static void onPhysicalCameraAvailable(void* obj, const char* cameraId,
99 const char* physicalCameraId) {
100 ALOGV("Camera %s : %s onAvailable", cameraId, physicalCameraId);
101 if (obj == nullptr) {
102 return;
103 }
104 CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
105 std::lock_guard<std::mutex> lock(thiz->mMutex);
106 thiz->mOnPhysicalCameraAvailableCount++;
107 return;
108 }
109
onPhysicalCameraUnavailable(void * obj,const char * cameraId,const char * physicalCameraId)110 static void onPhysicalCameraUnavailable(void* obj, const char* cameraId,
111 const char* physicalCameraId) {
112 ALOGV("Camera %s : %s onUnavailable", cameraId, physicalCameraId);
113 if (obj == nullptr) {
114 return;
115 }
116 CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
117 std::lock_guard<std::mutex> lock(thiz->mMutex);
118 thiz->mUnavailablePhysicalCameras.emplace(cameraId, physicalCameraId);
119 return;
120 }
121
122
resetCount()123 void resetCount() {
124 std::lock_guard<std::mutex> lock(mMutex);
125 mOnAvailableCount = 0;
126 mOnUnavailableCount = 0;
127 mOnCameraAccessPrioritiesChangedCount = 0;
128 mOnPhysicalCameraAvailableCount = 0;
129 mUnavailablePhysicalCameras.clear();
130 return;
131 }
132
getAvailableCount()133 int getAvailableCount() {
134 std::lock_guard<std::mutex> lock(mMutex);
135 return mOnAvailableCount;
136 }
137
getUnavailableCount()138 int getUnavailableCount() {
139 std::lock_guard<std::mutex> lock(mMutex);
140 return mOnUnavailableCount;
141 }
142
getCameraAccessPrioritiesChangedCount()143 int getCameraAccessPrioritiesChangedCount() {
144 std::lock_guard<std::mutex> lock(mMutex);
145 return mOnCameraAccessPrioritiesChangedCount;
146 }
147
getPhysicalCameraAvailableCount()148 int getPhysicalCameraAvailableCount() {
149 std::lock_guard<std::mutex> lock(mMutex);
150 return mOnPhysicalCameraAvailableCount;
151 }
152
getUnavailablePhysicalCameras()153 StringPairSet getUnavailablePhysicalCameras() {
154 std::lock_guard<std::mutex> lock(mMutex);
155 return mUnavailablePhysicalCameras;
156 }
157
isAvailable(const char * cameraId)158 bool isAvailable(const char* cameraId) {
159 std::lock_guard<std::mutex> lock(mMutex);
160 if (mAvailableMap.count(cameraId) == 0) {
161 return false;
162 }
163 return mAvailableMap[cameraId];
164 }
165
166 private:
167 std::mutex mMutex;
168 int mOnAvailableCount = 0;
169 int mOnUnavailableCount = 0;
170 int mOnCameraAccessPrioritiesChangedCount = 0;
171 int mOnPhysicalCameraAvailableCount = 0;
172 std::map<std::string, bool> mAvailableMap;
173 StringPairSet mUnavailablePhysicalCameras;
174 };
175
176 class CameraDeviceListener {
177 public:
onDisconnected(void * obj,ACameraDevice * device)178 static void onDisconnected(void* obj, ACameraDevice* device) {
179 ALOGV("Camera %s is disconnected!", ACameraDevice_getId(device));
180 if (obj == nullptr) {
181 return;
182 }
183 CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
184 std::lock_guard<std::mutex> lock(thiz->mMutex);
185 thiz->mOnDisconnect++;
186 return;
187 }
188
onError(void * obj,ACameraDevice * device,int errorCode)189 static void onError(void* obj, ACameraDevice* device, int errorCode) {
190 ALOGV("Camera %s receive error %d!", ACameraDevice_getId(device), errorCode);
191 if (obj == nullptr) {
192 return;
193 }
194 CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
195 std::lock_guard<std::mutex> lock(thiz->mMutex);
196 thiz->mOnError++;
197 thiz->mLatestError = errorCode;
198 return;
199 }
200
201 private:
202 std::mutex mMutex;
203 int mOnDisconnect = 0;
204 int mOnError = 0;
205 int mLatestError = 0;
206 };
207
208 class CaptureSessionListener {
209
210 public:
onClosed(void * obj,ACameraCaptureSession * session)211 static void onClosed(void* obj, ACameraCaptureSession *session) {
212 // TODO: might want an API to query cameraId even session is closed?
213 ALOGV("Session %p is closed!", session);
214 if (obj == nullptr) {
215 return;
216 }
217 CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
218 std::lock_guard<std::mutex> lock(thiz->mMutex);
219 thiz->mIsClosed = true;
220 thiz->mOnClosed++; // Should never > 1
221 }
222
onReady(void * obj,ACameraCaptureSession * session)223 static void onReady(void* obj, ACameraCaptureSession *session) {
224 ALOGV("%s", __FUNCTION__);
225 if (obj == nullptr) {
226 return;
227 }
228 CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
229 std::lock_guard<std::mutex> lock(thiz->mMutex);
230 ACameraDevice* device = nullptr;
231 camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
232 // There will be one onReady fired after session closed
233 if (ret != ACAMERA_OK && !thiz->mIsClosed) {
234 ALOGE("%s Getting camera device from session callback failed!",
235 __FUNCTION__);
236 thiz->mInError = true;
237 }
238 ALOGV("Session for camera %s is ready!", ACameraDevice_getId(device));
239 thiz->mIsIdle = true;
240 thiz->mOnReady++;
241 }
242
onActive(void * obj,ACameraCaptureSession * session)243 static void onActive(void* obj, ACameraCaptureSession *session) {
244 ALOGV("%s", __FUNCTION__);
245 if (obj == nullptr) {
246 return;
247 }
248 CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
249 std::lock_guard<std::mutex> lock(thiz->mMutex);
250 ACameraDevice* device = nullptr;
251 camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
252 if (ret != ACAMERA_OK) {
253 ALOGE("%s Getting camera device from session callback failed!",
254 __FUNCTION__);
255 thiz->mInError = true;
256 }
257 ALOGV("Session for camera %s is busy!", ACameraDevice_getId(device));
258 thiz->mIsIdle = false;
259 thiz->mOnActive;
260 }
261
isClosed()262 bool isClosed() {
263 std::lock_guard<std::mutex> lock(mMutex);
264 return mIsClosed;
265 }
266
isIdle()267 bool isIdle() {
268 std::lock_guard<std::mutex> lock(mMutex);
269 return mIsIdle;
270 }
271
isInError()272 bool isInError() {
273 std::lock_guard<std::mutex> lock(mMutex);
274 return mInError;
275 }
276
onClosedCount()277 int onClosedCount() {
278 std::lock_guard<std::mutex> lock(mMutex);
279 return mOnClosed;
280 }
281
onReadyCount()282 int onReadyCount() {
283 std::lock_guard<std::mutex> lock(mMutex);
284 return mOnReady;
285 }
286
onActiveCount()287 int onActiveCount() {
288 std::lock_guard<std::mutex> lock(mMutex);
289 return mOnActive;
290 }
291
reset()292 void reset() {
293 std::lock_guard<std::mutex> lock(mMutex);
294 mIsClosed = false;
295 mIsIdle = true;
296 mInError = false;
297 mOnClosed = 0;
298 mOnReady = 0;
299 mOnActive = 0;
300 }
301
302 private:
303 std::mutex mMutex;
304 bool mIsClosed = false;
305 bool mIsIdle = true;
306 bool mInError = false; // should always stay false
307 int mOnClosed = 0;
308 int mOnReady = 0;
309 int mOnActive = 0;
310 };
311
312 class CaptureResultListener {
313 public:
~CaptureResultListener()314 ~CaptureResultListener() {
315 std::unique_lock<std::mutex> l(mMutex);
316 clearSavedRequestsLocked();
317 mCompletedFrameNumbers.clear();
318 clearFailedLostFrameNumbersLocked();
319 }
320
onCaptureStart(void *,ACameraCaptureSession *,const ACaptureRequest *,int64_t)321 static void onCaptureStart(void* /*obj*/, ACameraCaptureSession* /*session*/,
322 const ACaptureRequest* /*request*/, int64_t /*timestamp*/) {
323 //Not used for now
324 }
325
onCaptureProgressed(void *,ACameraCaptureSession *,ACaptureRequest *,const ACameraMetadata *)326 static void onCaptureProgressed(void* /*obj*/, ACameraCaptureSession* /*session*/,
327 ACaptureRequest* /*request*/, const ACameraMetadata* /*result*/) {
328 //Not used for now
329 }
330
onCaptureCompleted(void * obj,ACameraCaptureSession *,ACaptureRequest * request,const ACameraMetadata * result)331 static void onCaptureCompleted(void* obj, ACameraCaptureSession* /*session*/,
332 ACaptureRequest* request, const ACameraMetadata* result) {
333 ALOGV("%s", __FUNCTION__);
334 if ((obj == nullptr) || (result == nullptr)) {
335 return;
336 }
337 CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
338 std::lock_guard<std::mutex> lock(thiz->mMutex);
339 ACameraMetadata_const_entry entry;
340 auto ret = ACameraMetadata_getConstEntry(result, ACAMERA_SYNC_FRAME_NUMBER, &entry);
341 if (ret != ACAMERA_OK) {
342 ALOGE("Error: Sync frame number missing from result!");
343 return;
344 }
345
346 ACameraMetadata* copy = ACameraMetadata_copy(result);
347 ACameraMetadata_const_entry entryCopy;
348 ret = ACameraMetadata_getConstEntry(copy, ACAMERA_SYNC_FRAME_NUMBER, &entryCopy);
349 if (ret != ACAMERA_OK) {
350 ALOGE("Error: Sync frame number missing from result copy!");
351 return;
352 }
353
354 if (entry.data.i64[0] != entryCopy.data.i64[0]) {
355 ALOGE("Error: Sync frame number %" PRId64 " mismatch result copy %" PRId64,
356 entry.data.i64[0], entryCopy.data.i64[0]);
357 return;
358 }
359 ACameraMetadata_free(copy);
360
361 if (thiz->mSaveCompletedRequests) {
362 thiz->mCompletedRequests.push_back(ACaptureRequest_copy(request));
363 }
364
365 thiz->mCompletedFrameNumbers.insert(entry.data.i64[0]);
366 thiz->mResultCondition.notify_one();
367 }
368
onLogicalCameraCaptureCompleted(void * obj,ACameraCaptureSession *,ACaptureRequest * request,const ACameraMetadata * result,size_t physicalResultCount,const char ** physicalCameraIds,const ACameraMetadata ** physicalResults)369 static void onLogicalCameraCaptureCompleted(void* obj, ACameraCaptureSession* /*session*/,
370 ACaptureRequest* request, const ACameraMetadata* result,
371 size_t physicalResultCount, const char** physicalCameraIds,
372 const ACameraMetadata** physicalResults) {
373 ALOGV("%s", __FUNCTION__);
374 if ((obj == nullptr) || (result == nullptr)) {
375 return;
376 }
377 CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
378 std::lock_guard<std::mutex> lock(thiz->mMutex);
379 ACameraMetadata_const_entry entry;
380 auto ret = ACameraMetadata_getConstEntry(result, ACAMERA_SYNC_FRAME_NUMBER, &entry);
381 if (ret != ACAMERA_OK) {
382 ALOGE("Error: Sync frame number missing from result!");
383 return;
384 }
385
386 ACameraMetadata* copy = ACameraMetadata_copy(result);
387 ACameraMetadata_const_entry entryCopy;
388 ret = ACameraMetadata_getConstEntry(copy, ACAMERA_SYNC_FRAME_NUMBER, &entryCopy);
389 if (ret != ACAMERA_OK) {
390 ALOGE("Error: Sync frame number missing from result copy!");
391 return;
392 }
393
394 if (entry.data.i64[0] != entryCopy.data.i64[0]) {
395 ALOGE("Error: Sync frame number %" PRId64 " mismatch result copy %" PRId64,
396 entry.data.i64[0], entryCopy.data.i64[0]);
397 return;
398 }
399
400 if (thiz->mRegisteredPhysicalIds.size() != physicalResultCount) {
401 ALOGE("Error: Number of registered physical camera Ids %zu is different than received"
402 " physical camera Ids %zu", thiz->mRegisteredPhysicalIds.size(),
403 physicalResultCount);
404 return;
405 }
406 for (size_t i = 0; i < physicalResultCount; i++) {
407 if (physicalCameraIds[i] == nullptr) {
408 ALOGE("Error: Invalid physical camera id in capture result");
409 return;
410 }
411 if (physicalResults[i] == nullptr) {
412 ALOGE("Error: Invalid physical camera metadata in capture result");
413 return;
414 }
415 ACameraMetadata_const_entry physicalEntry;
416 auto ret = ACameraMetadata_getConstEntry(physicalResults[i], ACAMERA_SYNC_FRAME_NUMBER,
417 &physicalEntry);
418 if (ret != ACAMERA_OK) {
419 ALOGE("Error: Sync frame number missing from physical camera result metadata!");
420 return;
421 }
422 if (physicalEntry.data.i64[0] != entryCopy.data.i64[0]) {
423 ALOGE("Error: Physical camera sync frame number %" PRId64
424 " mismatch result copy %" PRId64,
425 physicalEntry.data.i64[0], entryCopy.data.i64[0]);
426 return;
427 }
428
429 auto foundId = std::find(thiz->mRegisteredPhysicalIds.begin(),
430 thiz->mRegisteredPhysicalIds.end(), physicalCameraIds[i]);
431 if (foundId == thiz->mRegisteredPhysicalIds.end()) {
432 ALOGE("Error: Returned physical camera Id %s is not registered",
433 physicalCameraIds[i]);
434 return;
435 }
436 }
437 ACameraMetadata_free(copy);
438
439 if (thiz->mSaveCompletedRequests) {
440 thiz->mCompletedRequests.push_back(ACaptureRequest_copy(request));
441 }
442
443 thiz->mCompletedFrameNumbers.insert(entry.data.i64[0]);
444 thiz->mResultCondition.notify_one();
445 }
446
onCaptureFailed(void * obj,ACameraCaptureSession *,ACaptureRequest *,ACameraCaptureFailure * failure)447 static void onCaptureFailed(void* obj, ACameraCaptureSession* /*session*/,
448 ACaptureRequest* /*request*/, ACameraCaptureFailure* failure) {
449 ALOGV("%s", __FUNCTION__);
450 if ((obj == nullptr) || (failure == nullptr)) {
451 return;
452 }
453 CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
454 std::lock_guard<std::mutex> lock(thiz->mMutex);
455 thiz->mFailedFrameNumbers.insert(failure->frameNumber);
456 thiz->mResultCondition.notify_one();
457 }
458
onLogicalCameraCaptureFailed(void * obj,ACameraCaptureSession *,ACaptureRequest *,ALogicalCameraCaptureFailure * failure)459 static void onLogicalCameraCaptureFailed(void* obj, ACameraCaptureSession* /*session*/,
460 ACaptureRequest* /*request*/, ALogicalCameraCaptureFailure* failure) {
461 ALOGV("%s", __FUNCTION__);
462 if ((obj == nullptr) || (failure == nullptr)) {
463 return;
464 }
465 if (failure->physicalCameraId != nullptr) {
466 ALOGV("%s: physicalCameraId: %s", __FUNCTION__, failure->physicalCameraId);
467 }
468 CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
469 std::lock_guard<std::mutex> lock(thiz->mMutex);
470 thiz->mFailedFrameNumbers.insert(failure->captureFailure.frameNumber);
471 thiz->mResultCondition.notify_one();
472 }
473
onCaptureSequenceCompleted(void * obj,ACameraCaptureSession *,int sequenceId,int64_t frameNumber)474 static void onCaptureSequenceCompleted(void* obj, ACameraCaptureSession* /*session*/,
475 int sequenceId, int64_t frameNumber) {
476 ALOGV("%s", __FUNCTION__);
477 if (obj == nullptr) {
478 return;
479 }
480 CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
481 std::lock_guard<std::mutex> lock(thiz->mMutex);
482 thiz->mLastSequenceIdCompleted = sequenceId;
483 thiz->mLastSequenceFrameNumber = frameNumber;
484 thiz->mResultCondition.notify_one();
485 }
486
onCaptureSequenceAborted(void *,ACameraCaptureSession *,int)487 static void onCaptureSequenceAborted(void* /*obj*/, ACameraCaptureSession* /*session*/,
488 int /*sequenceId*/) {
489 //Not used for now
490 }
491
onCaptureBufferLost(void * obj,ACameraCaptureSession *,ACaptureRequest *,ANativeWindow *,int64_t frameNumber)492 static void onCaptureBufferLost(void* obj, ACameraCaptureSession* /*session*/,
493 ACaptureRequest* /*request*/, ANativeWindow* /*window*/, int64_t frameNumber) {
494 ALOGV("%s", __FUNCTION__);
495 if (obj == nullptr) {
496 return;
497 }
498 CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
499 std::lock_guard<std::mutex> lock(thiz->mMutex);
500 thiz->mBufferLostFrameNumbers.insert(frameNumber);
501 thiz->mResultCondition.notify_one();
502 }
503
getCaptureSequenceLastFrameNumber(int64_t sequenceId,uint32_t timeoutSec)504 int64_t getCaptureSequenceLastFrameNumber(int64_t sequenceId, uint32_t timeoutSec) {
505 int64_t ret = -1;
506 std::unique_lock<std::mutex> l(mMutex);
507
508 while (mLastSequenceIdCompleted != sequenceId) {
509 auto timeout = std::chrono::system_clock::now() +
510 std::chrono::seconds(timeoutSec);
511 if (std::cv_status::timeout == mResultCondition.wait_until(l, timeout)) {
512 break;
513 }
514 }
515
516 if (mLastSequenceIdCompleted == sequenceId) {
517 ret = mLastSequenceFrameNumber;
518 }
519
520 return ret;
521 }
522
waitForFrameNumber(int64_t frameNumber,uint32_t timeoutSec)523 bool waitForFrameNumber(int64_t frameNumber, uint32_t timeoutSec) {
524 bool ret = false;
525 std::unique_lock<std::mutex> l(mMutex);
526
527 while ((mCompletedFrameNumbers.find(frameNumber) == mCompletedFrameNumbers.end()) &&
528 !checkForFailureOrLossLocked(frameNumber)) {
529 auto timeout = std::chrono::system_clock::now() +
530 std::chrono::seconds(timeoutSec);
531 if (std::cv_status::timeout == mResultCondition.wait_until(l, timeout)) {
532 break;
533 }
534 }
535
536 if ((mCompletedFrameNumbers.find(frameNumber) != mCompletedFrameNumbers.end()) ||
537 checkForFailureOrLossLocked(frameNumber)) {
538 ret = true;
539 }
540
541 return ret;
542 }
543
setRequestSave(bool enable)544 void setRequestSave(bool enable) {
545 std::unique_lock<std::mutex> l(mMutex);
546 if (!enable) {
547 clearSavedRequestsLocked();
548 }
549 mSaveCompletedRequests = enable;
550 }
551
552 // The lifecycle of returned ACaptureRequest* is still managed by CaptureResultListener
getCompletedRequests(std::vector<ACaptureRequest * > * out)553 void getCompletedRequests(std::vector<ACaptureRequest*>* out) {
554 std::unique_lock<std::mutex> l(mMutex);
555 *out = mCompletedRequests;
556 }
557
registerPhysicalResults(size_t physicalIdCnt,const char * const * physicalOutputs)558 void registerPhysicalResults(size_t physicalIdCnt, const char*const* physicalOutputs) {
559 std::unique_lock<std::mutex> l(mMutex);
560 mRegisteredPhysicalIds.clear();
561 for (size_t i = 0; i < physicalIdCnt; i++) {
562 mRegisteredPhysicalIds.push_back(physicalOutputs[i]);
563 }
564 }
565
checkForFailureOrLoss(int64_t frameNumber)566 bool checkForFailureOrLoss(int64_t frameNumber) {
567 std::lock_guard<std::mutex> lock(mMutex);
568 return checkForFailureOrLossLocked(frameNumber);
569 }
570
reset()571 void reset() {
572 std::lock_guard<std::mutex> lock(mMutex);
573 mLastSequenceIdCompleted = -1;
574 mLastSequenceFrameNumber = -1;
575 mSaveCompletedRequests = false;
576 clearSavedRequestsLocked();
577 mCompletedFrameNumbers.clear();
578 clearFailedLostFrameNumbersLocked();
579 }
580
581 private:
582 std::mutex mMutex;
583 std::condition_variable mResultCondition;
584 int mLastSequenceIdCompleted = -1;
585 int64_t mLastSequenceFrameNumber = -1;
586 std::set<int64_t> mCompletedFrameNumbers;
587 std::set<int64_t> mFailedFrameNumbers, mBufferLostFrameNumbers;
588 bool mSaveCompletedRequests = false;
589 std::vector<ACaptureRequest*> mCompletedRequests;
590 // Registered physical camera Ids that are being requested upon.
591 std::vector<std::string> mRegisteredPhysicalIds;
592
clearSavedRequestsLocked()593 void clearSavedRequestsLocked() {
594 for (ACaptureRequest* req : mCompletedRequests) {
595 ACaptureRequest_free(req);
596 }
597 mCompletedRequests.clear();
598 }
599
clearFailedLostFrameNumbersLocked()600 void clearFailedLostFrameNumbersLocked() {
601 mFailedFrameNumbers.clear();
602 mBufferLostFrameNumbers.clear();
603 }
604
checkForFailureOrLossLocked(int64_t frameNumber)605 bool checkForFailureOrLossLocked(int64_t frameNumber) {
606 return (mFailedFrameNumbers.find(frameNumber) != mFailedFrameNumbers.end()) ||
607 (mBufferLostFrameNumbers.find(frameNumber) != mBufferLostFrameNumbers.end());
608 }
609 };
610
611 class ImageReaderListener {
612 public:
ImageReaderListener()613 ImageReaderListener() {
614 mBufferTs.insert(mLastBufferTs);
615 }
616
617 // count, acquire, validate, and delete AImage when a new image is available
validateImageCb(void * obj,AImageReader * reader)618 static void validateImageCb(void* obj, AImageReader* reader) {
619 ALOGV("%s", __FUNCTION__);
620 if (obj == nullptr) {
621 return;
622 }
623 ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
624 std::lock_guard<std::mutex> lock(thiz->mMutex);
625 thiz->mOnImageAvailableCount++;
626
627 AImage* img = nullptr;
628 media_status_t ret = AImageReader_acquireNextImage(reader, &img);
629 if (ret != AMEDIA_OK || img == nullptr) {
630 ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
631 __FUNCTION__, reader, ret, img);
632 return;
633 }
634
635 // TODO: validate image content
636 int32_t format = -1;
637 ret = AImage_getFormat(img, &format);
638 if (ret != AMEDIA_OK || format == -1) {
639 ALOGE("%s: get format for image %p failed! ret: %d, format %d",
640 __FUNCTION__, img, ret, format);
641 }
642
643 // Save jpeg to SD card
644 if (thiz->mDumpFilePathBase && format == AIMAGE_FORMAT_JPEG) {
645 int32_t numPlanes = 0;
646 ret = AImage_getNumberOfPlanes(img, &numPlanes);
647 if (ret != AMEDIA_OK || numPlanes != 1) {
648 ALOGE("%s: get numPlanes for image %p failed! ret: %d, numPlanes %d",
649 __FUNCTION__, img, ret, numPlanes);
650 AImage_delete(img);
651 return;
652 }
653
654 int32_t width = -1, height = -1;
655 ret = AImage_getWidth(img, &width);
656 if (ret != AMEDIA_OK || width <= 0) {
657 ALOGE("%s: get width for image %p failed! ret: %d, width %d",
658 __FUNCTION__, img, ret, width);
659 AImage_delete(img);
660 return;
661 }
662
663 ret = AImage_getHeight(img, &height);
664 if (ret != AMEDIA_OK || height <= 0) {
665 ALOGE("%s: get height for image %p failed! ret: %d, height %d",
666 __FUNCTION__, img, ret, height);
667 AImage_delete(img);
668 return;
669 }
670
671 uint8_t* data = nullptr;
672 int dataLength = 0;
673 ret = AImage_getPlaneData(img, /*planeIdx*/0, &data, &dataLength);
674 if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
675 ALOGE("%s: get jpeg data for image %p failed! ret: %d, data %p, len %d",
676 __FUNCTION__, img, ret, data, dataLength);
677 AImage_delete(img);
678 return;
679 }
680
681 #if 0
682 char dumpFilePath[512];
683 sprintf(dumpFilePath, "%s/%dx%d.jpg", thiz->mDumpFilePathBase, width, height);
684 ALOGI("Writing jpeg file to %s", dumpFilePath);
685 FILE* file = fopen(dumpFilePath,"w+");
686
687 if (file != nullptr) {
688 fwrite(data, 1, dataLength, file);
689 fflush(file);
690 fclose(file);
691 }
692 #endif
693 }
694
695 AImage_delete(img);
696 }
697
698 // count, acquire image but not delete the image
acquireImageCb(void * obj,AImageReader * reader)699 static void acquireImageCb(void* obj, AImageReader* reader) {
700 ALOGV("%s", __FUNCTION__);
701 if (obj == nullptr) {
702 return;
703 }
704 ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
705 std::lock_guard<std::mutex> lock(thiz->mMutex);
706 thiz->mOnImageAvailableCount++;
707
708 // Acquire, but not closing.
709 AImage* img = nullptr;
710 media_status_t ret = AImageReader_acquireNextImage(reader, &img);
711 if (ret != AMEDIA_OK || img == nullptr) {
712 ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
713 __FUNCTION__, reader, ret, img);
714 return;
715 }
716 return;
717 }
718
onImageAvailableCount()719 int onImageAvailableCount() {
720 std::lock_guard<std::mutex> lock(mMutex);
721 return mOnImageAvailableCount;
722 }
723
setDumpFilePathBase(const char * path)724 void setDumpFilePathBase(const char* path) {
725 std::lock_guard<std::mutex> lock(mMutex);
726 mDumpFilePathBase = path;
727 }
728
729 // acquire image, query the corresponding timestamp but not delete the image
signalImageCb(void * obj,AImageReader * reader)730 static void signalImageCb(void* obj, AImageReader* reader) {
731 ALOGV("%s", __FUNCTION__);
732 if (obj == nullptr) {
733 return;
734 }
735 ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
736 std::lock_guard<std::mutex> lock(thiz->mMutex);
737
738 AImage* img = nullptr;
739 media_status_t ret = AImageReader_acquireNextImage(reader, &img);
740 if (ret != AMEDIA_OK || img == nullptr) {
741 ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
742 __FUNCTION__, reader, ret, img);
743 thiz->mBufferCondition.notify_one();
744 return;
745 }
746
747 int64_t currentTs = -1;
748 ret = AImage_getTimestamp(img, ¤tTs);
749 if (ret != AMEDIA_OK || currentTs == -1) {
750 ALOGE("%s: acquire image from reader %p failed! ret: %d", __FUNCTION__, reader, ret);
751 AImage_delete(img);
752 thiz->mBufferCondition.notify_one();
753 return;
754 }
755
756 thiz->mBufferTs.insert(currentTs);
757 thiz->mBufferCondition.notify_one();
758 return;
759 }
760
waitForNextBuffer(uint32_t timeoutSec)761 bool waitForNextBuffer(uint32_t timeoutSec) {
762 bool ret = false;
763 std::unique_lock<std::mutex> l(mMutex);
764
765 auto it = mBufferTs.find(mLastBufferTs);
766 if (it == mBufferTs.end()) {
767 ALOGE("%s: Last buffer timestamp: %" PRId64 " not found!", __FUNCTION__, mLastBufferTs);
768 return false;
769 }
770 it++;
771
772 if (it == mBufferTs.end()) {
773 auto timeout = std::chrono::system_clock::now() + std::chrono::seconds(timeoutSec);
774 if (std::cv_status::no_timeout == mBufferCondition.wait_until(l, timeout)) {
775 it = mBufferTs.find(mLastBufferTs);
776 it++;
777 }
778 }
779
780 if (it != mBufferTs.end()) {
781 mLastBufferTs = *it;
782 ret = true;
783 }
784
785 return ret;
786 }
787
788 private:
789 // TODO: add mReader to make sure each listener is associated to one reader?
790 std::mutex mMutex;
791 int mOnImageAvailableCount = 0;
792 const char* mDumpFilePathBase = nullptr;
793 std::condition_variable mBufferCondition;
794 int64_t mLastBufferTs = -1;
795 std::set<int64_t> mBufferTs;
796 };
797
798 class StaticInfo {
799 public:
StaticInfo(ACameraMetadata * chars)800 explicit StaticInfo(ACameraMetadata* chars) : mChars(chars) {}
801
isColorOutputSupported()802 bool isColorOutputSupported() {
803 return isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
804 }
805
isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap)806 bool isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap) {
807 ACameraMetadata_const_entry entry;
808 ACameraMetadata_getConstEntry(mChars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
809 for (uint32_t i = 0; i < entry.count; i++) {
810 if (entry.data.u8[i] == cap) {
811 return true;
812 }
813 }
814 return false;
815 }
816
getMinFrameDurationFor(int64_t format,int64_t width,int64_t height)817 int64_t getMinFrameDurationFor(int64_t format, int64_t width, int64_t height) {
818 int32_t minFrameDurationTag = (format == AIMAGE_FORMAT_HEIC) ?
819 ACAMERA_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS :
820 (format == AIMAGE_FORMAT_DEPTH_JPEG) ?
821 ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS :
822 ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
823 return getDurationFor(minFrameDurationTag, format, width, height);
824 }
825
getStallDurationFor(int64_t format,int64_t width,int64_t height)826 int64_t getStallDurationFor(int64_t format, int64_t width, int64_t height) {
827 int32_t stallDurationTag = (format == AIMAGE_FORMAT_HEIC) ?
828 ACAMERA_HEIC_AVAILABLE_HEIC_STALL_DURATIONS : (format == AIMAGE_FORMAT_DEPTH_JPEG) ?
829 ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS :
830 ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS;
831 return getDurationFor(stallDurationTag, format, width, height);
832 }
833
getMaxSizeForFormat(int32_t format,int32_t * width,int32_t * height)834 bool getMaxSizeForFormat(int32_t format, int32_t *width, int32_t *height) {
835 ACameraMetadata_const_entry entry;
836
837 int32_t streamConfigTag, streamConfigOutputTag;
838 switch (format) {
839 case AIMAGE_FORMAT_HEIC:
840 streamConfigTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS;
841 streamConfigOutputTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT;
842 break;
843 case AIMAGE_FORMAT_DEPTH_JPEG:
844 streamConfigTag = ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS;
845 streamConfigOutputTag =
846 ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT;
847 break;
848 case AIMAGE_FORMAT_JPEG:
849 case AIMAGE_FORMAT_Y8:
850 default:
851 streamConfigTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
852 streamConfigOutputTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
853 break;
854 }
855
856 bool supported = false;
857 camera_status_t status = ACameraMetadata_getConstEntry(mChars, streamConfigTag, &entry);
858 if (status == ACAMERA_ERROR_METADATA_NOT_FOUND) {
859 return supported;
860 }
861
862 int32_t w = 0, h = 0;
863 for (uint32_t i = 0; i < entry.count; i += 4) {
864 if (entry.data.i32[i] == format &&
865 entry.data.i32[i+3] == streamConfigOutputTag &&
866 entry.data.i32[i+1] * entry.data.i32[i+2] > w * h) {
867 w = entry.data.i32[i+1];
868 h = entry.data.i32[i+2];
869 supported = true;
870 }
871 }
872
873 if (supported) {
874 *width = w;
875 *height = h;
876 }
877 return supported;
878 }
879
isSizeSupportedForFormat(int32_t format,int32_t width,int32_t height)880 bool isSizeSupportedForFormat(int32_t format, int32_t width, int32_t height) {
881 ACameraMetadata_const_entry entry;
882
883 int32_t streamConfigTag, streamConfigOutputTag;
884 switch (format) {
885 case AIMAGE_FORMAT_HEIC:
886 streamConfigTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS;
887 streamConfigOutputTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT;
888 break;
889 case AIMAGE_FORMAT_JPEG:
890 case AIMAGE_FORMAT_Y8:
891 default:
892 streamConfigTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
893 streamConfigOutputTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
894 break;
895 }
896
897 auto ret = ACameraMetadata_getConstEntry(mChars, streamConfigTag, &entry);
898 if (ret != ACAMERA_OK) {
899 return false;
900 }
901 for (uint32_t i = 0; i < entry.count; i += 4) {
902 if (entry.data.i32[i] == format &&
903 entry.data.i32[i+3] == streamConfigOutputTag &&
904 entry.data.i32[i+1] == width &&
905 entry.data.i32[i+2] == height) {
906 return true;
907 }
908 }
909 return false;
910 }
911 private:
getDurationFor(uint32_t tag,int64_t format,int64_t width,int64_t height)912 int64_t getDurationFor(uint32_t tag, int64_t format, int64_t width, int64_t height) {
913 if (tag != ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS &&
914 tag != ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS &&
915 tag != ACAMERA_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS &&
916 tag != ACAMERA_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS &&
917 tag != ACAMERA_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS &&
918 tag != ACAMERA_HEIC_AVAILABLE_HEIC_STALL_DURATIONS &&
919 tag != ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS &&
920 tag != ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS) {
921 return -1;
922 }
923 ACameraMetadata_const_entry entry;
924 ACameraMetadata_getConstEntry(mChars, tag, &entry);
925 for (uint32_t i = 0; i < entry.count; i += 4) {
926 if (entry.data.i64[i] == format &&
927 entry.data.i64[i+1] == width &&
928 entry.data.i64[i+2] == height) {
929 return entry.data.i64[i+3];
930 }
931 }
932 return -1;
933 }
934 const ACameraMetadata* mChars;
935 };
936
937 class PreviewTestCase {
938 public:
~PreviewTestCase()939 ~PreviewTestCase() {
940 resetCamera();
941 deInit();
942 if (mCameraManager) {
943 ACameraManager_delete(mCameraManager);
944 mCameraManager = nullptr;
945 }
946 }
947
PreviewTestCase()948 PreviewTestCase() {
949 // create is guaranteed to succeed;
950 createManager();
951 }
952
953 // Free all resources except camera manager
resetCamera()954 void resetCamera() {
955 mSessionListener.reset();
956 mResultListener.reset();
957 if (mSession) {
958 ACameraCaptureSession_close(mSession);
959 mSession = nullptr;
960 }
961 if (mDevice) {
962 ACameraDevice_close(mDevice);
963 mDevice = nullptr;
964 }
965 if (mImgReader) {
966 AImageReader_delete(mImgReader);
967 // No need to call ANativeWindow_release on imageReaderAnw
968 mImgReaderAnw = nullptr;
969 mImgReader = nullptr;
970 }
971 if (mPreviewAnw) {
972 ANativeWindow_release(mPreviewAnw);
973 mPreviewAnw = nullptr;
974 }
975 if (mOutputs) {
976 ACaptureSessionOutputContainer_free(mOutputs);
977 mOutputs = nullptr;
978 }
979 if (mPreviewOutput) {
980 ACaptureSessionOutput_free(mPreviewOutput);
981 mPreviewOutput = nullptr;
982 }
983 if (mImgReaderOutput) {
984 ACaptureSessionOutput_free(mImgReaderOutput);
985 mImgReaderOutput = nullptr;
986 }
987 if (mPreviewRequest) {
988 ACaptureRequest_free(mPreviewRequest);
989 mPreviewRequest = nullptr;
990 }
991 if (mStillRequest) {
992 ACaptureRequest_free(mStillRequest);
993 mStillRequest = nullptr;
994 }
995 if (mReqPreviewOutput) {
996 ACameraOutputTarget_free(mReqPreviewOutput);
997 mReqPreviewOutput = nullptr;
998 }
999 if (mReqImgReaderOutput) {
1000 ACameraOutputTarget_free(mReqImgReaderOutput);
1001 mReqImgReaderOutput = nullptr;
1002 }
1003
1004 mImgReaderInited = false;
1005 mPreviewInited = false;
1006 }
1007
initWithErrorLog()1008 camera_status_t initWithErrorLog() {
1009 return initWithErrorLog(nullptr /*env*/, nullptr /*jOverrideCameraId*/);
1010 }
1011
initWithErrorLog(JNIEnv * env,jstring jOverrideCameraId)1012 camera_status_t initWithErrorLog(JNIEnv* env, jstring jOverrideCameraId) {
1013 camera_status_t ret = ACameraManager_getCameraIdList(
1014 mCameraManager, &mCameraIdList);
1015 if (ret != ACAMERA_OK) {
1016 LOG_ERROR(errorString, "Get camera id list failed: ret %d", ret);
1017 return ret;
1018 }
1019
1020 if (env != nullptr && jOverrideCameraId != nullptr) {
1021 mOverrideCameraId = env->GetStringUTFChars(jOverrideCameraId, 0);
1022 }
1023 ret = ACameraManager_registerAvailabilityCallback(mCameraManager, &mServiceCb);
1024 if (ret != ACAMERA_OK) {
1025 LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
1026 return ret;
1027 }
1028 mMgrInited = true;
1029 mJOverrideCameraId = jOverrideCameraId;
1030 mJNIEnv = env;
1031 return ACAMERA_OK;
1032 }
1033
deInit()1034 camera_status_t deInit () {
1035 if (!mMgrInited) {
1036 return ACAMERA_OK;
1037 }
1038
1039 camera_status_t ret = ACameraManager_unregisterAvailabilityCallback(
1040 mCameraManager, &mServiceCb);
1041 if (ret != ACAMERA_OK) {
1042 ALOGE("Unregister availability callback failed: ret %d", ret);
1043 return ret;
1044 }
1045
1046 if (mCameraIdList) {
1047 ACameraManager_deleteCameraIdList(mCameraIdList);
1048 mCameraIdList = nullptr;
1049 }
1050 mMgrInited = false;
1051 if (mOverrideCameraId != nullptr && mJNIEnv != nullptr) {
1052 mJNIEnv->ReleaseStringUTFChars(mJOverrideCameraId, mOverrideCameraId);
1053 mOverrideCameraId = nullptr;
1054 mJOverrideCameraId = nullptr;
1055 mJNIEnv = nullptr;
1056 }
1057 return ACAMERA_OK;
1058 }
1059
getNumCameras()1060 int getNumCameras() {
1061 if (!mMgrInited || !mCameraIdList) {
1062 return -1;
1063 }
1064 if (mOverrideCameraId != nullptr) {
1065 return 1;
1066 }
1067 return mCameraIdList->numCameras;
1068 }
1069
getCameraId(int idx)1070 const char* getCameraId(int idx) {
1071 if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
1072 return nullptr;
1073 }
1074 if (mOverrideCameraId != nullptr) {
1075 if (idx >= 1) {
1076 return nullptr;
1077 } else {
1078 return mOverrideCameraId;
1079 }
1080 }
1081 return mCameraIdList->cameraIds[idx];
1082 }
1083
1084 // Caller is responsible to free returned characteristics metadata
getCameraChars(int idx)1085 ACameraMetadata* getCameraChars(int idx) {
1086 if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
1087 return nullptr;
1088 }
1089 const char* cameraId = mCameraIdList->cameraIds[idx];
1090 if (mOverrideCameraId != nullptr) {
1091 if (idx >= 1) {
1092 return nullptr;
1093 } else {
1094 cameraId = mOverrideCameraId;
1095 }
1096 }
1097
1098 ACameraMetadata* chars;
1099 camera_status_t ret = ACameraManager_getCameraCharacteristics(
1100 mCameraManager, cameraId, &chars);
1101 if (ret != ACAMERA_OK) {
1102 LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
1103 return nullptr;
1104 }
1105 return chars;
1106 }
1107
1108 // Caller is responsible to free returned characteristics metadata.
getCameraChars(const char * id)1109 ACameraMetadata* getCameraChars(const char* id) {
1110 if (!mMgrInited || id == nullptr) {
1111 return nullptr;
1112 }
1113
1114 ACameraMetadata* chars;
1115 camera_status_t ret = ACameraManager_getCameraCharacteristics(mCameraManager, id, &chars);
1116 if (ret != ACAMERA_OK) {
1117 LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
1118 return nullptr;
1119 }
1120 return chars;
1121 }
1122
updateOutput(JNIEnv * env,ACaptureSessionOutput * output)1123 camera_status_t updateOutput(JNIEnv* env, ACaptureSessionOutput *output) {
1124 if (mSession == nullptr) {
1125 ALOGE("Testcase cannot update output configuration session %p",
1126 mSession);
1127 return ACAMERA_ERROR_UNKNOWN;
1128 }
1129
1130 return ACameraCaptureSession_updateSharedOutput(mSession, output);
1131 }
1132
openCamera(const char * cameraId)1133 camera_status_t openCamera(const char* cameraId) {
1134 if (mDevice) {
1135 ALOGE("Cannot open camera before closing previously open one");
1136 return ACAMERA_ERROR_INVALID_PARAMETER;
1137 }
1138 mCameraId = cameraId;
1139 return ACameraManager_openCamera(mCameraManager, cameraId, &mDeviceCb, &mDevice);
1140 }
1141
closeCamera()1142 camera_status_t closeCamera() {
1143 camera_status_t ret = ACameraDevice_close(mDevice);
1144 mDevice = nullptr;
1145 return ret;
1146 }
1147
isCameraAvailable(const char * cameraId)1148 bool isCameraAvailable(const char* cameraId) {
1149 if (!mMgrInited) {
1150 ALOGE("Camera service listener has not been registered!");
1151 }
1152 return mServiceListener.isAvailable(cameraId);
1153 }
1154
initImageReaderWithErrorLog(int32_t width,int32_t height,int32_t format,int32_t maxImages,AImageReader_ImageListener * listener)1155 media_status_t initImageReaderWithErrorLog(
1156 int32_t width, int32_t height, int32_t format, int32_t maxImages,
1157 AImageReader_ImageListener* listener) {
1158 if (mImgReader || mImgReaderAnw) {
1159 LOG_ERROR(errorString, "Cannot init image reader before closing existing one");
1160 return AMEDIA_ERROR_UNKNOWN;
1161 }
1162
1163 media_status_t ret = initImageReaderWithErrorLog(
1164 width, height, format, maxImages, listener, &mImgReader,
1165 &mImgReaderAnw);
1166 if (ret != AMEDIA_OK) {
1167 return ret;
1168 }
1169
1170 mImgReaderInited = true;
1171 return AMEDIA_OK;
1172 }
1173
initImageReaderWithErrorLog(int32_t width,int32_t height,int32_t format,int32_t maxImages,AImageReader_ImageListener * listener,AImageReader ** imgReader,ANativeWindow ** imgReaderAnw)1174 media_status_t initImageReaderWithErrorLog(
1175 int32_t width, int32_t height, int32_t format, int32_t maxImages,
1176 AImageReader_ImageListener* listener, AImageReader **imgReader,
1177 ANativeWindow **imgReaderAnw) {
1178
1179 media_status_t ret = AImageReader_new(
1180 width, height, format,
1181 maxImages, imgReader);
1182 if (ret != AMEDIA_OK) {
1183 LOG_ERROR(errorString, "Create image reader. ret %d", ret);
1184 return ret;
1185 }
1186 if (*imgReader == nullptr) {
1187 LOG_ERROR(errorString, "null image reader created");
1188 return AMEDIA_ERROR_UNKNOWN;
1189 }
1190
1191 ret = AImageReader_setImageListener(*imgReader, listener);
1192 if (ret != AMEDIA_OK) {
1193 LOG_ERROR(errorString, "Set AImageReader listener failed. ret %d", ret);
1194 return ret;
1195 }
1196
1197 ret = AImageReader_getWindow(*imgReader, imgReaderAnw);
1198 if (ret != AMEDIA_OK) {
1199 LOG_ERROR(errorString, "AImageReader_getWindow failed. ret %d", ret);
1200 return ret;
1201 }
1202 if (*imgReaderAnw == nullptr) {
1203 LOG_ERROR(errorString, "Null ANW from AImageReader!");
1204 return AMEDIA_ERROR_UNKNOWN;
1205 }
1206 return AMEDIA_OK;
1207 }
1208
initPreviewAnw(JNIEnv * env,jobject jSurface)1209 ANativeWindow* initPreviewAnw(JNIEnv* env, jobject jSurface) {
1210 if (mPreviewAnw) {
1211 ALOGE("Cannot init preview twice!");
1212 return nullptr;
1213 }
1214 mPreviewAnw = ANativeWindow_fromSurface(env, jSurface);
1215 mPreviewInited = true;
1216 return mPreviewAnw;
1217 }
1218
createCaptureSessionWithLog(bool isPreviewShared=false,ACaptureRequest * sessionParameters=nullptr)1219 camera_status_t createCaptureSessionWithLog(bool isPreviewShared = false,
1220 ACaptureRequest *sessionParameters = nullptr) {
1221 std::vector<ACaptureSessionOutput*> extraOutputs;
1222 return createCaptureSessionWithLog(extraOutputs, isPreviewShared, sessionParameters);
1223 }
1224
createCaptureSessionOutputContainer(const std::vector<ACaptureSessionOutput * > extraOutputs,ACaptureSessionOutputContainer ** outputs,bool isPreviewShared=false,ACaptureRequest * sessionParameters=nullptr)1225 camera_status_t createCaptureSessionOutputContainer(
1226 const std::vector<ACaptureSessionOutput*> extraOutputs,
1227 ACaptureSessionOutputContainer** outputs,
1228 bool isPreviewShared = false, ACaptureRequest *sessionParameters = nullptr) {
1229 if (!mMgrInited || (!mImgReaderInited && !mPreviewInited) || !outputs) {
1230 LOG_ERROR(errorString, "Cannot create session output container. mgrInit %d "
1231 "readerInit %d previewInit %d outputs %p",
1232 mMgrInited, mImgReaderInited, mPreviewInited, outputs);
1233 return ACAMERA_ERROR_UNKNOWN;
1234 }
1235
1236 camera_status_t ret = ACaptureSessionOutputContainer_create(outputs);
1237 if (ret != ACAMERA_OK) {
1238 LOG_ERROR(errorString, "Create capture session output container failed. ret %d", ret);
1239 return ret;
1240 }
1241
1242 if (mImgReaderInited) {
1243 ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
1244 if (ret != ACAMERA_OK || mImgReaderOutput == nullptr) {
1245 LOG_ERROR(errorString,
1246 "Session image reader output create fail! ret %d output %p",
1247 ret, mImgReaderOutput);
1248 if (ret == ACAMERA_OK) {
1249 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
1250 }
1251 return ret;
1252 }
1253
1254 ret = ACaptureSessionOutputContainer_add(*outputs, mImgReaderOutput);
1255 if (ret != ACAMERA_OK) {
1256 LOG_ERROR(errorString, "Session image reader output add failed! ret %d", ret);
1257 return ret;
1258 }
1259 }
1260
1261 for (auto extraOutput : extraOutputs) {
1262 ret = ACaptureSessionOutputContainer_add(*outputs, extraOutput);
1263 if (ret != ACAMERA_OK) {
1264 LOG_ERROR(errorString, "Session image reader output add failed! ret %d", ret);
1265 return ret;
1266 }
1267 }
1268
1269 if (mPreviewInited) {
1270 if (isPreviewShared) {
1271 ret = ACaptureSessionSharedOutput_create(mPreviewAnw, &mPreviewOutput);
1272 } else {
1273 ret = ACaptureSessionOutput_create(mPreviewAnw, &mPreviewOutput);
1274 }
1275 if (ret != ACAMERA_OK || mPreviewOutput == nullptr) {
1276 LOG_ERROR(errorString,
1277 "Session preview output create fail! ret %d output %p",
1278 ret, mPreviewOutput);
1279 if (ret == ACAMERA_OK) {
1280 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
1281 }
1282 return ret;
1283 }
1284
1285 ret = ACaptureSessionOutputContainer_add(*outputs, mPreviewOutput);
1286 if (ret != ACAMERA_OK) {
1287 LOG_ERROR(errorString, "Session preview output add failed! ret %d", ret);
1288 return ret;
1289 }
1290 }
1291 return ret;
1292 }
1293
createCaptureSessionWithLog(const std::vector<ACaptureSessionOutput * > extraOutputs,bool isPreviewShared=false,ACaptureRequest * sessionParameters=nullptr,bool sessionConfigurationDefault=true)1294 camera_status_t createCaptureSessionWithLog(
1295 const std::vector<ACaptureSessionOutput*> extraOutputs,
1296 bool isPreviewShared = false, ACaptureRequest *sessionParameters = nullptr,
1297 bool sessionConfigurationDefault = true) {
1298 if (mSession) {
1299 LOG_ERROR(errorString, "Cannot create session before closing existing one");
1300 return ACAMERA_ERROR_UNKNOWN;
1301 }
1302
1303 camera_status_t ret = createCaptureSessionOutputContainer(
1304 extraOutputs, &mOutputs, isPreviewShared, sessionParameters);
1305 if (ret != ACAMERA_OK) {
1306 LOG_ERROR(errorString, "Failed to create session output container! ret %d", ret);
1307 return ret;
1308 }
1309
1310 ret = ACameraDevice_isSessionConfigurationSupported(mDevice, mOutputs);
1311 if (ret != ACAMERA_OK && ret != ACAMERA_ERROR_UNSUPPORTED_OPERATION &&
1312 ret != ACAMERA_ERROR_STREAM_CONFIGURE_FAIL) {
1313 LOG_ERROR(errorString, "isSessionConfigurationSupported must return either OK "
1314 ", UNSUPPORTED_OPERATION, or STREAM_CONFIGURE_FAIL, but returns %d", ret);
1315 return ret;
1316 }
1317
1318 // If session configuration is not supported by default, return early
1319 // when camera device doesn't explicitly claim support.
1320 if (ret != ACAMERA_OK && !sessionConfigurationDefault) {
1321 return ret;
1322 }
1323
1324 ret = ACameraDevice_createCaptureSessionWithSessionParameters(
1325 mDevice, mOutputs, sessionParameters, &mSessionCb, &mSession);
1326 if (ret != ACAMERA_OK || mSession == nullptr) {
1327 LOG_ERROR(errorString, "Create session for camera %s failed. ret %d session %p",
1328 mCameraId, ret, mSession);
1329 if (ret == ACAMERA_OK) {
1330 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but session is null
1331 }
1332 return ret;
1333 }
1334
1335 return ACAMERA_OK;
1336 }
1337
closeSession()1338 void closeSession() {
1339 if (mSession != nullptr) {
1340 ACameraCaptureSession_close(mSession);
1341 }
1342 if (mOutputs) {
1343 ACaptureSessionOutputContainer_free(mOutputs);
1344 mOutputs = nullptr;
1345 }
1346 if (mPreviewOutput) {
1347 ACaptureSessionOutput_free(mPreviewOutput);
1348 mPreviewOutput = nullptr;
1349 }
1350 if (mImgReaderOutput) {
1351 ACaptureSessionOutput_free(mImgReaderOutput);
1352 mImgReaderOutput = nullptr;
1353 }
1354 mSession = nullptr;
1355 }
1356
createRequestsWithErrorLog()1357 camera_status_t createRequestsWithErrorLog() {
1358 std::vector<ACameraOutputTarget*> extraOutputs;
1359 return createRequestsWithErrorLog(extraOutputs);
1360 }
1361
createRequestsWithErrorLog(const std::vector<ACameraOutputTarget * > extraOutputs,const ACameraIdList * physicalCameraIdList=nullptr)1362 camera_status_t createRequestsWithErrorLog(
1363 const std::vector<ACameraOutputTarget*> extraOutputs,
1364 const ACameraIdList* physicalCameraIdList = nullptr) {
1365 if (mPreviewRequest || mStillRequest) {
1366 LOG_ERROR(errorString, "Cannot create requests before deleteing existing one");
1367 return ACAMERA_ERROR_UNKNOWN;
1368 }
1369
1370 if (mDevice == nullptr || (!mPreviewInited && !mImgReaderInited)) {
1371 LOG_ERROR(errorString,
1372 "Cannot create request. device %p previewInit %d readeInit %d",
1373 mDevice, mPreviewInited, mImgReaderInited);
1374 return ACAMERA_ERROR_UNKNOWN;
1375 }
1376
1377 camera_status_t ret;
1378 bool usePhysicalSettings = (physicalCameraIdList != nullptr);
1379 if (mPreviewInited) {
1380 if (!usePhysicalSettings) {
1381 ret = ACameraDevice_createCaptureRequest(
1382 mDevice, TEMPLATE_PREVIEW, &mPreviewRequest);
1383 } else {
1384 ret = ACameraDevice_createCaptureRequest_withPhysicalIds(
1385 mDevice, TEMPLATE_PREVIEW, physicalCameraIdList, &mPreviewRequest);
1386 }
1387 if (ret != ACAMERA_OK) {
1388 LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
1389 mCameraId, ret);
1390 return ret;
1391 }
1392
1393 if (usePhysicalSettings) {
1394 for (int i = 0; i < physicalCameraIdList->numCameras; i++) {
1395 // Check physical camera specific metadata functions.
1396 uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
1397 ret = ACaptureRequest_setEntry_physicalCamera_u8(mPreviewRequest,
1398 physicalCameraIdList->cameraIds[i], ACAMERA_CONTROL_AE_MODE,
1399 1 /*count*/, &aeMode);
1400 if (ret != ACAMERA_OK) {
1401 LOG_ERROR(errorString,
1402 "Error: Camera %s update AE mode key fail. ret %d",
1403 physicalCameraIdList->cameraIds[i], ret);
1404 return ret;
1405 }
1406
1407 ACameraMetadata_const_entry entry;
1408 ret = ACaptureRequest_getConstEntry_physicalCamera(mPreviewRequest,
1409 physicalCameraIdList->cameraIds[i],
1410 ACAMERA_CONTROL_AE_MODE, &entry);
1411 if (ret != ACAMERA_OK) {
1412 LOG_ERROR(errorString, "Get AE mode key for physicalCamera %s failed."
1413 " ret %d", physicalCameraIdList->cameraIds[i], ret);
1414 return ret;
1415 }
1416 if (entry.data.u8[0] != aeMode) {
1417 LOG_ERROR(errorString,
1418 "Error: AE mode key is not updated. expect %d but get %d",
1419 aeMode, entry.data.u8[0]);
1420 return ACAMERA_ERROR_UNKNOWN;
1421 }
1422 }
1423 }
1424
1425 ret = ACameraOutputTarget_create(mPreviewAnw, &mReqPreviewOutput);
1426 if (ret != ACAMERA_OK) {
1427 LOG_ERROR(errorString,
1428 "Camera %s create request preview output target failed. ret %d",
1429 mCameraId, ret);
1430 return ret;
1431 }
1432
1433 ret = ACaptureRequest_addTarget(mPreviewRequest, mReqPreviewOutput);
1434 if (ret != ACAMERA_OK) {
1435 LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
1436 mCameraId, ret);
1437 return ret;
1438 }
1439
1440 // Add extraOutputs to the request
1441 for (auto extraOutput : extraOutputs) {
1442 ret = ACaptureRequest_addTarget(mPreviewRequest, extraOutput);
1443 if (ret != ACAMERA_OK) {
1444 LOG_ERROR(errorString, "Camera %s add extra request output failed. ret %d",
1445 mCameraId, ret);
1446 return ret;
1447 }
1448 }
1449 } else {
1450 ALOGI("Preview not inited. Will not create preview request!");
1451 }
1452
1453 if (mImgReaderInited) {
1454 ret = ACameraDevice_createCaptureRequest(
1455 mDevice, TEMPLATE_STILL_CAPTURE, &mStillRequest);
1456 if (ret != ACAMERA_OK) {
1457 LOG_ERROR(errorString, "Camera %s create still request failed. ret %d",
1458 mCameraId, ret);
1459 return ret;
1460 }
1461
1462 ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput);
1463 if (ret != ACAMERA_OK) {
1464 LOG_ERROR(errorString,
1465 "Camera %s create request reader output target failed. ret %d",
1466 mCameraId, ret);
1467 return ret;
1468 }
1469
1470 ret = ACaptureRequest_addTarget(mStillRequest, mReqImgReaderOutput);
1471 if (ret != ACAMERA_OK) {
1472 LOG_ERROR(errorString, "Camera %s add still request output failed. ret %d",
1473 mCameraId, ret);
1474 return ret;
1475 }
1476
1477 if (mPreviewInited) {
1478 ret = ACaptureRequest_addTarget(mStillRequest, mReqPreviewOutput);
1479 if (ret != ACAMERA_OK) {
1480 LOG_ERROR(errorString,
1481 "Camera %s add still request preview output failed. ret %d",
1482 mCameraId, ret);
1483 return ret;
1484 }
1485 }
1486 } else {
1487 ALOGI("AImageReader not inited. Will not create still request!");
1488 }
1489
1490 return ACAMERA_OK;
1491 }
1492
1493 // The output ACaptureRequest* is still managed by testcase class
getStillRequest(ACaptureRequest ** out)1494 camera_status_t getStillRequest(ACaptureRequest** out) {
1495 if (mStillRequest == nullptr) {
1496 ALOGE("Camera %s Still capture request hasn't been created", mCameraId);
1497 return ACAMERA_ERROR_INVALID_PARAMETER;
1498 }
1499 *out = mStillRequest;
1500 return ACAMERA_OK;
1501 }
1502
getPreviewRequest(ACaptureRequest ** out)1503 camera_status_t getPreviewRequest(ACaptureRequest** out) {
1504 if (mPreviewRequest == nullptr) {
1505 ALOGE("Camera %s Preview capture request hasn't been created", mCameraId);
1506 return ACAMERA_ERROR_INVALID_PARAMETER;
1507 }
1508 *out = mPreviewRequest;
1509 return ACAMERA_OK;
1510 }
1511
startPreview(int * sequenceId=nullptr,size_t physicalIdCnt=0,const char * const * extraPhysicalOutputs=nullptr)1512 camera_status_t startPreview(int *sequenceId = nullptr, size_t physicalIdCnt = 0,
1513 const char*const* extraPhysicalOutputs = nullptr) {
1514 if (mSession == nullptr || mPreviewRequest == nullptr) {
1515 ALOGE("Testcase cannot start preview: session %p, preview request %p",
1516 mSession, mPreviewRequest);
1517 return ACAMERA_ERROR_UNKNOWN;
1518 }
1519 int previewSeqId;
1520 camera_status_t ret;
1521 if (sequenceId == nullptr) {
1522 ret = ACameraCaptureSession_setRepeatingRequest(
1523 mSession, nullptr, 1, &mPreviewRequest, &previewSeqId);
1524 } else if (physicalIdCnt == 0) {
1525 ret = ACameraCaptureSession_setRepeatingRequest(
1526 mSession, &mResultCb, 1, &mPreviewRequest, sequenceId);
1527 } else {
1528 if (extraPhysicalOutputs == nullptr) {
1529 ALOGE("Testcase missing valid physical camera Ids for logical camera");
1530 return ACAMERA_ERROR_INVALID_PARAMETER;
1531 }
1532 CaptureResultListener* resultListener =
1533 static_cast<CaptureResultListener*>(mLogicalCameraResultCb.context);
1534 resultListener->registerPhysicalResults(physicalIdCnt, extraPhysicalOutputs);
1535 ret = ACameraCaptureSession_logicalCamera_setRepeatingRequest(
1536 mSession, &mLogicalCameraResultCb, 1, &mPreviewRequest, sequenceId);
1537 }
1538 return ret;
1539 }
1540
startRepeatingRequest(int * sequenceId,ACaptureRequest * request,ACameraCaptureSession_captureCallbacks * resultCb)1541 camera_status_t startRepeatingRequest(int *sequenceId, ACaptureRequest *request,
1542 ACameraCaptureSession_captureCallbacks *resultCb) {
1543 if (mSession == nullptr || request == nullptr || resultCb == nullptr) {
1544 ALOGE("Testcase cannot start repeating request: session %p, request %p resultCb %p",
1545 mSession, request, resultCb);
1546 return ACAMERA_ERROR_UNKNOWN;
1547 }
1548
1549 return ACameraCaptureSession_setRepeatingRequest(mSession, resultCb, 1, &request,
1550 sequenceId);
1551 }
1552
stopPreview()1553 camera_status_t stopPreview() {
1554 if (mSession == nullptr) {
1555 ALOGE("Testcase cannot stop preview: session %p", mSession);
1556 return ACAMERA_ERROR_UNKNOWN;
1557 }
1558 return ACameraCaptureSession_stopRepeating(mSession);
1559 }
1560
updateRepeatingRequest(ACaptureRequest * updatedRequest,int * sequenceId=nullptr)1561 camera_status_t updateRepeatingRequest(ACaptureRequest *updatedRequest,
1562 int *sequenceId = nullptr) {
1563 if (mSession == nullptr || updatedRequest == nullptr) {
1564 ALOGE("Testcase cannot update repeating request: session %p, updated request %p",
1565 mSession, updatedRequest);
1566 return ACAMERA_ERROR_UNKNOWN;
1567 }
1568
1569 int previewSeqId;
1570 camera_status_t ret;
1571 if (sequenceId == nullptr) {
1572 ret = ACameraCaptureSession_setRepeatingRequest(
1573 mSession, nullptr, 1, &updatedRequest, &previewSeqId);
1574 } else {
1575 ret = ACameraCaptureSession_setRepeatingRequest(
1576 mSession, &mResultCb, 1, &updatedRequest, sequenceId);
1577 }
1578 return ret;
1579 }
1580
getCaptureSequenceLastFrameNumber(int64_t sequenceId,uint32_t timeoutSec)1581 int64_t getCaptureSequenceLastFrameNumber(int64_t sequenceId, uint32_t timeoutSec) {
1582 return mResultListener.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
1583 }
1584
waitForFrameNumber(int64_t frameNumber,uint32_t timeoutSec)1585 bool waitForFrameNumber(int64_t frameNumber, uint32_t timeoutSec) {
1586 return mResultListener.waitForFrameNumber(frameNumber, timeoutSec);
1587 }
1588
takePicture()1589 camera_status_t takePicture() {
1590 if (mSession == nullptr || mStillRequest == nullptr) {
1591 ALOGE("Testcase cannot take picture: session %p, still request %p",
1592 mSession, mStillRequest);
1593 return ACAMERA_ERROR_UNKNOWN;
1594 }
1595 int seqId;
1596 return ACameraCaptureSession_capture(
1597 mSession, nullptr, 1, &mStillRequest, &seqId);
1598 }
1599
capture(ACaptureRequest * request,ACameraCaptureSession_captureCallbacks * listener,int * seqId)1600 camera_status_t capture(ACaptureRequest* request,
1601 ACameraCaptureSession_captureCallbacks* listener,
1602 /*out*/int* seqId) {
1603 if (mSession == nullptr || request == nullptr) {
1604 ALOGE("Testcase cannot capture session: session %p, request %p",
1605 mSession, request);
1606 return ACAMERA_ERROR_UNKNOWN;
1607 }
1608 return ACameraCaptureSession_capture(
1609 mSession, listener, 1, &request, seqId);
1610 }
1611
resetWithErrorLog()1612 camera_status_t resetWithErrorLog() {
1613 camera_status_t ret;
1614
1615 closeSession();
1616
1617 for (int i = 0; i < 50; i++) {
1618 usleep(100000); // sleep 100ms
1619 if (mSessionListener.isClosed()) {
1620 ALOGI("Session take ~%d ms to close", i*100);
1621 break;
1622 }
1623 }
1624
1625 if (!mSessionListener.isClosed() || mSessionListener.onClosedCount() != 1) {
1626 LOG_ERROR(errorString,
1627 "Session for camera %s close error. isClosde %d close count %d",
1628 mCameraId, mSessionListener.isClosed(), mSessionListener.onClosedCount());
1629 return ACAMERA_ERROR_UNKNOWN;
1630 }
1631 mSessionListener.reset();
1632 mResultListener.reset();
1633
1634 ret = closeCamera();
1635 if (ret != ACAMERA_OK) {
1636 LOG_ERROR(errorString, "Close camera device %s failure. ret %d", mCameraId, ret);
1637 return ret;
1638 }
1639
1640 resetCamera();
1641 return ACAMERA_OK;
1642 }
1643
getSessionListener()1644 CaptureSessionListener* getSessionListener() {
1645 return &mSessionListener;
1646 }
1647
getCameraDevice()1648 ACameraDevice* getCameraDevice() {
1649 return mDevice;
1650 }
1651
getPreviewOutput()1652 ACaptureSessionOutput *getPreviewOutput() {
1653 return mPreviewOutput;
1654 }
1655
1656 private:
createManager()1657 ACameraManager* createManager() {
1658 if (!mCameraManager) {
1659 mCameraManager = ACameraManager_create();
1660 }
1661 return mCameraManager;
1662 }
1663
1664 CameraServiceListener mServiceListener;
1665 ACameraManager_AvailabilityCallbacks mServiceCb {
1666 &mServiceListener,
1667 CameraServiceListener::onAvailable,
1668 CameraServiceListener::onUnavailable
1669 };
1670 CameraDeviceListener mDeviceListener;
1671 ACameraDevice_StateCallbacks mDeviceCb {
1672 &mDeviceListener,
1673 CameraDeviceListener::onDisconnected,
1674 CameraDeviceListener::onError
1675 };
1676 CaptureSessionListener mSessionListener;
1677 ACameraCaptureSession_stateCallbacks mSessionCb {
1678 &mSessionListener,
1679 CaptureSessionListener::onClosed,
1680 CaptureSessionListener::onReady,
1681 CaptureSessionListener::onActive
1682 };
1683
1684 CaptureResultListener mResultListener;
1685 ACameraCaptureSession_captureCallbacks mResultCb {
1686 &mResultListener,
1687 CaptureResultListener::onCaptureStart,
1688 CaptureResultListener::onCaptureProgressed,
1689 CaptureResultListener::onCaptureCompleted,
1690 CaptureResultListener::onCaptureFailed,
1691 CaptureResultListener::onCaptureSequenceCompleted,
1692 CaptureResultListener::onCaptureSequenceAborted,
1693 CaptureResultListener::onCaptureBufferLost
1694 };
1695
1696 ACameraCaptureSession_logicalCamera_captureCallbacks mLogicalCameraResultCb {
1697 &mResultListener,
1698 CaptureResultListener::onCaptureStart,
1699 CaptureResultListener::onCaptureProgressed,
1700 CaptureResultListener::onLogicalCameraCaptureCompleted,
1701 CaptureResultListener::onLogicalCameraCaptureFailed,
1702 CaptureResultListener::onCaptureSequenceCompleted,
1703 CaptureResultListener::onCaptureSequenceAborted,
1704 CaptureResultListener::onCaptureBufferLost
1705 };
1706
1707 ACameraIdList* mCameraIdList = nullptr;
1708 ACameraDevice* mDevice = nullptr;
1709 AImageReader* mImgReader = nullptr;
1710 ANativeWindow* mImgReaderAnw = nullptr;
1711 ANativeWindow* mPreviewAnw = nullptr;
1712 ACameraManager* mCameraManager = nullptr;
1713 ACaptureSessionOutputContainer* mOutputs = nullptr;
1714 ACaptureSessionOutput* mPreviewOutput = nullptr;
1715 ACaptureSessionOutput* mImgReaderOutput = nullptr;
1716 ACameraCaptureSession* mSession = nullptr;
1717 ACaptureRequest* mPreviewRequest = nullptr;
1718 ACaptureRequest* mStillRequest = nullptr;
1719 ACameraOutputTarget* mReqPreviewOutput = nullptr;
1720 ACameraOutputTarget* mReqImgReaderOutput = nullptr;
1721 const char* mCameraId;
1722 JNIEnv* mJNIEnv = nullptr;
1723 jstring mJOverrideCameraId;
1724 const char* mOverrideCameraId = nullptr;
1725
1726 bool mMgrInited = false; // cameraId, serviceListener
1727 bool mImgReaderInited = false;
1728 bool mPreviewInited = false;
1729 };
1730
throwAssertionError(JNIEnv * env,const char * message)1731 jint throwAssertionError(JNIEnv* env, const char* message)
1732 {
1733 jclass assertionClass;
1734 const char* className = "junit/framework/AssertionFailedError";
1735
1736 assertionClass = env->FindClass(className);
1737 if (assertionClass == nullptr) {
1738 ALOGE("Native throw error: cannot find class %s", className);
1739 return -1;
1740 }
1741 return env->ThrowNew(assertionClass, message);
1742 }
1743
1744 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetAndCloseNative(JNIEnv * env,jclass)1745 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1746 testCameraManagerGetAndCloseNative(
1747 JNIEnv* env, jclass /*clazz*/) {
1748 bool pass = false;
1749 ALOGV("%s", __FUNCTION__);
1750 ACameraManager* cameraManager2 = nullptr;
1751 ACameraManager* cameraManager3 = nullptr;
1752 ACameraManager* cameraManager4 = nullptr;
1753 camera_status_t ret = ACAMERA_OK;
1754 ACameraManager* cameraManager = ACameraManager_create();
1755 if (cameraManager == nullptr) {
1756 LOG_ERROR(errorString, "ACameraManager_create returns nullptr");
1757 goto cleanup;
1758 }
1759 ACameraManager_delete(cameraManager);
1760 cameraManager = nullptr;
1761
1762 // Test get/close multiple instances
1763 cameraManager = ACameraManager_create();
1764 cameraManager2 = ACameraManager_create();
1765 if (cameraManager2 == nullptr) {
1766 LOG_ERROR(errorString, "ACameraManager_create 2 returns nullptr");
1767 goto cleanup;
1768 }
1769 ACameraManager_delete(cameraManager);
1770 cameraManager = nullptr;
1771 cameraManager3 = ACameraManager_create();
1772 if (cameraManager3 == nullptr) {
1773 LOG_ERROR(errorString, "ACameraManager_create 3 returns nullptr");
1774 goto cleanup;
1775 }
1776 cameraManager4 = ACameraManager_create();
1777 if (cameraManager4 == nullptr) {
1778 LOG_ERROR(errorString, "ACameraManager_create 4 returns nullptr");
1779 goto cleanup;
1780 }
1781 ACameraManager_delete(cameraManager3);
1782 ACameraManager_delete(cameraManager2);
1783 ACameraManager_delete(cameraManager4);
1784
1785 pass = true;
1786 cleanup:
1787 if (cameraManager) {
1788 ACameraManager_delete(cameraManager);
1789 }
1790 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
1791 if (!pass) {
1792 throwAssertionError(env, errorString);
1793 }
1794 return pass;
1795 }
1796
1797 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetCameraIdsNative(JNIEnv * env,jclass)1798 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1799 testCameraManagerGetCameraIdsNative(
1800 JNIEnv* env, jclass /*clazz*/) {
1801 ALOGV("%s", __FUNCTION__);
1802 bool pass = false;
1803 ACameraManager* mgr = ACameraManager_create();
1804 ACameraIdList *cameraIdList = nullptr;
1805 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1806 if (ret != ACAMERA_OK || cameraIdList == nullptr) {
1807 LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
1808 ret, cameraIdList);
1809 goto cleanup;
1810 }
1811 ALOGI("Number of cameras: %d", cameraIdList->numCameras);
1812 for (int i = 0; i < cameraIdList->numCameras; i++) {
1813 ALOGI("Camera ID: %s", cameraIdList->cameraIds[i]);
1814 }
1815 ACameraManager_deleteCameraIdList(cameraIdList);
1816 cameraIdList = nullptr;
1817
1818 pass = true;
1819 cleanup:
1820 if (mgr) {
1821 ACameraManager_delete(mgr);
1822 }
1823 if (cameraIdList) {
1824 ACameraManager_deleteCameraIdList(cameraIdList);
1825 }
1826 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
1827 if (!pass) {
1828 throwAssertionError(env, errorString);
1829 }
1830 return pass;
1831 }
1832
1833 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerExtendedAvailabilityCallbackNative(JNIEnv * env,jclass)1834 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1835 testCameraManagerExtendedAvailabilityCallbackNative(
1836 JNIEnv* env, jclass /*clazz*/) {
1837 ALOGV("%s", __FUNCTION__);
1838 bool pass = false;
1839 ACameraManager* mgr = ACameraManager_create();
1840 ACameraIdList *cameraIdList = nullptr;
1841 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1842 int numCameras = cameraIdList->numCameras;
1843 CameraServiceListener listener;
1844 CameraServiceListener::StringPairSet unavailablePhysicalCameras;
1845 CameraServiceListener::StringPairSet physicalCameraIdPairs;
1846 ACameraManager_ExtendedAvailabilityCallbacks cbs {
1847 {
1848 &listener,
1849 CameraServiceListener::onAvailable,
1850 CameraServiceListener::onUnavailable
1851 },
1852 CameraServiceListener::onCameraAccessPrioritiesChanged,
1853 CameraServiceListener::onPhysicalCameraAvailable,
1854 CameraServiceListener::onPhysicalCameraUnavailable,
1855 {}
1856 };
1857
1858 ret = ACameraManager_registerExtendedAvailabilityCallback(mgr, &cbs);
1859 if (ret != ACAMERA_OK) {
1860 LOG_ERROR(errorString, "Register extended availability callback failed: ret %d", ret);
1861 goto cleanup;
1862 }
1863 sleep(1); // sleep a second to give some time for callbacks to happen
1864
1865 // Should at least get onAvailable for each camera once
1866 if (listener.getAvailableCount() < numCameras) {
1867 LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
1868 numCameras, listener.getAvailableCount());
1869 goto cleanup;
1870 }
1871
1872 {
1873 int availablePhysicalCamera = listener.getPhysicalCameraAvailableCount();
1874 if (availablePhysicalCamera > 0) {
1875 LOG_ERROR(errorString, "Expect no available callback, but got %d",
1876 availablePhysicalCamera);
1877 }
1878 }
1879
1880 unavailablePhysicalCameras = listener.getUnavailablePhysicalCameras();
1881 for (int i = 0; i < numCameras; i++) {
1882 const char* cameraId = cameraIdList->cameraIds[i];
1883 if (cameraId == nullptr) {
1884 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
1885 goto cleanup;
1886 }
1887 ACameraMetadata* c;
1888 ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &c);
1889 if (ret != ACAMERA_OK || c == nullptr) {
1890 LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
1891 goto cleanup;
1892 }
1893 std::unique_ptr<ACameraMetadata> chars(c);
1894
1895 size_t physicalCameraCnt = 0;
1896 const char *const* physicalCameraIds = nullptr;
1897 if (!ACameraMetadata_isLogicalMultiCamera(
1898 chars.get(), &physicalCameraCnt, &physicalCameraIds)) {
1899 continue;
1900 }
1901 for (size_t j = 0; j < physicalCameraCnt; j++) {
1902 physicalCameraIdPairs.emplace(cameraId, physicalCameraIds[j]);
1903 }
1904 }
1905 for (const auto& unavailIdPair : unavailablePhysicalCameras) {
1906 bool validPair = false;
1907 for (const auto& idPair : physicalCameraIdPairs) {
1908 if (idPair.first == unavailIdPair.first && idPair.second == unavailIdPair.second) {
1909 validPair = true;
1910 break;
1911 }
1912 }
1913 if (!validPair) {
1914 LOG_ERROR(errorString, "Expect valid unavailable physical cameras, but got %s : %s",
1915 unavailIdPair.first.c_str(), unavailIdPair.second.c_str());
1916 goto cleanup;
1917 }
1918 }
1919
1920 ret = ACameraManager_unregisterExtendedAvailabilityCallback(mgr, &cbs);
1921 if (ret != ACAMERA_OK) {
1922 LOG_ERROR(errorString, "Unregister extended availability callback failed: ret %d", ret);
1923 goto cleanup;
1924 }
1925 pass = true;
1926 cleanup:
1927 if (cameraIdList) {
1928 ACameraManager_deleteCameraIdList(cameraIdList);
1929 }
1930 if (mgr) {
1931 ACameraManager_delete(mgr);
1932 }
1933 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1934 if (!pass) {
1935 throwAssertionError(env, errorString);
1936 }
1937 return pass;
1938 }
1939
1940 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerAvailabilityCallbackNative(JNIEnv * env,jclass)1941 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1942 testCameraManagerAvailabilityCallbackNative(
1943 JNIEnv* env, jclass /*clazz*/) {
1944 ALOGV("%s", __FUNCTION__);
1945 bool pass = false;
1946 ACameraManager* mgr = ACameraManager_create();
1947 ACameraIdList *cameraIdList = nullptr;
1948 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1949 int numCameras = cameraIdList->numCameras;
1950 CameraServiceListener listener;
1951 ACameraManager_AvailabilityCallbacks cbs {
1952 &listener,
1953 CameraServiceListener::onAvailable,
1954 CameraServiceListener::onUnavailable};
1955 ret = ACameraManager_registerAvailabilityCallback(mgr, &cbs);
1956 if (ret != ACAMERA_OK) {
1957 LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
1958 goto cleanup;
1959 }
1960 sleep(1); // sleep a second to give some time for callbacks to happen
1961
1962 // Should at least get onAvailable for each camera once
1963 if (listener.getAvailableCount() < numCameras) {
1964 LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
1965 numCameras, listener.getAvailableCount());
1966 goto cleanup;
1967 }
1968
1969 ret = ACameraManager_unregisterAvailabilityCallback(mgr, &cbs);
1970 if (ret != ACAMERA_OK) {
1971 LOG_ERROR(errorString, "Unregister availability callback failed: ret %d", ret);
1972 goto cleanup;
1973 }
1974 pass = true;
1975 cleanup:
1976 if (cameraIdList) {
1977 ACameraManager_deleteCameraIdList(cameraIdList);
1978 }
1979 if (mgr) {
1980 ACameraManager_delete(mgr);
1981 }
1982 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1983 if (!pass) {
1984 throwAssertionError(env, errorString);
1985 }
1986 return pass;
1987 }
1988
1989 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerCharacteristicsNative(JNIEnv * env,jclass)1990 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1991 testCameraManagerCharacteristicsNative(
1992 JNIEnv* env, jclass /*clazz*/) {
1993 ALOGV("%s", __FUNCTION__);
1994 bool pass = false;
1995 ACameraManager* mgr = ACameraManager_create();
1996 ACameraIdList *cameraIdList = nullptr;
1997 ACameraMetadata* chars = nullptr;
1998 ACameraMetadata* copy = nullptr;
1999 int numCameras = 0;
2000 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
2001 if (ret != ACAMERA_OK || cameraIdList == nullptr) {
2002 LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
2003 ret, cameraIdList);
2004 goto cleanup;
2005 }
2006 numCameras = cameraIdList->numCameras;
2007
2008 for (int i = 0; i < numCameras; i++) {
2009 ret = ACameraManager_getCameraCharacteristics(
2010 mgr, cameraIdList->cameraIds[i], &chars);
2011 if (ret != ACAMERA_OK) {
2012 LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
2013 goto cleanup;
2014 }
2015
2016 int32_t numTags = 0;
2017 const uint32_t* tags = nullptr;
2018 ret = ACameraMetadata_getAllTags(chars, &numTags, &tags);
2019 if (ret != ACAMERA_OK) {
2020 LOG_ERROR(errorString, "Get camera characteristics tags failed: ret %d", ret);
2021 goto cleanup;
2022 }
2023
2024 for (int tid = 0; tid < numTags; tid++) {
2025 uint32_t tagId = tags[tid];
2026 ALOGV("%s camera characteristics contains key %u", __FUNCTION__, tagId);
2027 uint32_t sectionId = tagId >> 16;
2028 if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
2029 LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
2030 goto cleanup;
2031 }
2032 }
2033
2034 ACameraMetadata_const_entry entry;
2035 ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
2036 if (ret != ACAMERA_OK) {
2037 LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
2038 goto cleanup;
2039 }
2040
2041 // Check the entry is actually legit
2042 if (entry.tag != ACAMERA_REQUEST_AVAILABLE_CAPABILITIES ||
2043 entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE || entry.data.i32 == nullptr) {
2044 LOG_ERROR(errorString,
2045 "Bad available capabilities key: tag: %d (expected %d), count %u (expect > 0), "
2046 "type %d (expected %d), data %p (expected not null)",
2047 entry.tag, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, entry.count,
2048 entry.type, ACAMERA_TYPE_BYTE, entry.data.i32);
2049 goto cleanup;
2050 }
2051 // All camera supports BC except depth only cameras
2052 bool supportBC = false, supportDepth = false;
2053 for (uint32_t i = 0; i < entry.count; i++) {
2054 if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
2055 supportBC = true;
2056 }
2057 if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
2058 supportDepth = true;
2059 }
2060 }
2061 if (!(supportBC || supportDepth)) {
2062 LOG_ERROR(errorString, "Error: camera device %s does not support either BC or DEPTH",
2063 cameraIdList->cameraIds[i]);
2064 goto cleanup;
2065 }
2066
2067 // Check copy works
2068 copy = ACameraMetadata_copy(chars);
2069
2070 // Compare copy with original
2071 ACameraMetadata_const_entry entryCopy;
2072 ret = ACameraMetadata_getConstEntry(
2073 copy, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entryCopy);
2074 if (ret != ACAMERA_OK) {
2075 LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
2076 goto cleanup;
2077 }
2078 for (uint32_t i = 0; i < entry.count; i++) {
2079 if (entry.data.u8[i] != entryCopy.data.u8[i]) {
2080 LOG_ERROR(errorString,
2081 "Copy of available capability key[%d]: %d mismatches original %d",
2082 i, entryCopy.data.u8[i], entry.data.u8[i]);
2083 goto cleanup;
2084 }
2085 }
2086
2087 // Check get unknown value fails
2088 uint32_t badTag = (uint32_t) ACAMERA_VENDOR_START - 1;
2089 ret = ACameraMetadata_getConstEntry(chars, badTag, &entry);
2090 if (ret == ACAMERA_OK) {
2091 LOG_ERROR(errorString, "Error: get unknown tag should fail!");
2092 goto cleanup;
2093 }
2094
2095 ACameraMetadata_free(chars);
2096 ACameraMetadata_free(copy);
2097 chars = nullptr;
2098 copy = nullptr;
2099 }
2100
2101 pass = true;
2102 cleanup:
2103 if (chars) {
2104 ACameraMetadata_free(chars);
2105 }
2106 if (copy) {
2107 ACameraMetadata_free(copy);
2108 }
2109 ACameraManager_deleteCameraIdList(cameraIdList);
2110 ACameraManager_delete(mgr);
2111 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2112 if (!pass) {
2113 throwAssertionError(env, errorString);
2114 }
2115 return pass;
2116 }
2117
2118 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceOpenAndCloseNative(JNIEnv * env,jclass,jstring jOverrideCameraId)2119 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2120 testCameraDeviceOpenAndCloseNative(
2121 JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
2122 ALOGV("%s", __FUNCTION__);
2123 int numCameras = 0;
2124 bool pass = false;
2125 PreviewTestCase testCase;
2126
2127 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2128 if (ret != ACAMERA_OK) {
2129 // Don't log error here. testcase did it
2130 goto cleanup;
2131 }
2132
2133 numCameras = testCase.getNumCameras();
2134 if (numCameras < 0) {
2135 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2136 goto cleanup;
2137 }
2138
2139 for (int i = 0; i < numCameras; i++) {
2140 const char* cameraId = testCase.getCameraId(i);
2141 if (cameraId == nullptr) {
2142 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2143 goto cleanup;
2144 }
2145
2146 ret = testCase.openCamera(cameraId);
2147 if (ret != ACAMERA_OK) {
2148 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2149 goto cleanup;
2150 }
2151
2152 usleep(100000); // sleep to give some time for callbacks to happen
2153
2154 if (testCase.isCameraAvailable(cameraId)) {
2155 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2156 goto cleanup;
2157 }
2158
2159 ret = testCase.closeCamera();
2160 if (ret != ACAMERA_OK) {
2161 LOG_ERROR(errorString, "Close camera device %s failure. ret %d", cameraId, ret);
2162 goto cleanup;
2163 }
2164
2165 usleep(100000); // sleep to give some time for callbacks to happen
2166
2167 if (!testCase.isCameraAvailable(cameraId)) {
2168 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2169 goto cleanup;
2170 }
2171 }
2172
2173 ret = testCase.deInit();
2174 if (ret != ACAMERA_OK) {
2175 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2176 goto cleanup;
2177 }
2178
2179 pass = true;
2180 cleanup:
2181 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2182 if (!pass) {
2183 throwAssertionError(env, errorString);
2184 }
2185 return pass;
2186 }
2187
2188 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceCreateCaptureRequestNative(JNIEnv * env,jclass,jstring jOverrideCameraId)2189 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2190 testCameraDeviceCreateCaptureRequestNative(
2191 JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
2192 ALOGV("%s", __FUNCTION__);
2193 bool pass = false;
2194 ACameraManager* mgr = ACameraManager_create();
2195 ACameraIdList* cameraIdList = nullptr;
2196 ACameraDevice* device = nullptr;
2197 ACaptureRequest* request = nullptr;
2198 ACameraMetadata* chars = nullptr;
2199 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
2200
2201 int numCameras = cameraIdList->numCameras;
2202 const char* overrideCameraId = nullptr;
2203 if (jOverrideCameraId != nullptr) {
2204 overrideCameraId = env->GetStringUTFChars(jOverrideCameraId, nullptr);
2205 }
2206
2207 for (int i = 0; i < numCameras; i++) {
2208 CameraDeviceListener deviceListener;
2209 const char* cameraId = cameraIdList->cameraIds[i];
2210 if (overrideCameraId != nullptr && strcmp(overrideCameraId, cameraId)) {
2211 // Skip other cameras if overriding camera id to be tested.
2212 continue;
2213 }
2214 ACameraDevice_StateCallbacks deviceCb {
2215 &deviceListener,
2216 CameraDeviceListener::onDisconnected,
2217 CameraDeviceListener::onError
2218 };
2219 ret = ACameraManager_openCamera(mgr, cameraId, &deviceCb, &device);
2220 if (ret != ACAMERA_OK) {
2221 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2222 goto cleanup;
2223 }
2224
2225 ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &chars);
2226 if (ret != ACAMERA_OK || chars == nullptr) {
2227 LOG_ERROR(errorString, "Get camera %s characteristics failure. ret %d, chars %p",
2228 cameraId, ret, chars);
2229 goto cleanup;
2230 }
2231 StaticInfo staticInfo(chars);
2232
2233 for (int t = TEMPLATE_PREVIEW; t <= TEMPLATE_MANUAL; t++) {
2234 ACameraDevice_request_template templateId =
2235 static_cast<ACameraDevice_request_template>(t);
2236 ret = ACameraDevice_createCaptureRequest(device, templateId, &request);
2237 if (ret == ACAMERA_ERROR_INVALID_PARAMETER) {
2238 // template not supported. skip
2239 continue;
2240 }
2241
2242 if (ret != ACAMERA_OK) {
2243 LOG_ERROR(errorString, "Create capture request failed!: ret %d", ret);
2244 goto cleanup;
2245 }
2246
2247 int32_t numTags = 0;
2248 const uint32_t* tags = nullptr;
2249 ret = ACaptureRequest_getAllTags(request, &numTags, &tags);
2250 if (ret != ACAMERA_OK) {
2251 LOG_ERROR(errorString, "Get capture request tags failed: ret %d", ret);
2252 goto cleanup;
2253 }
2254
2255 for (int tid = 0; tid < numTags; tid++) {
2256 uint32_t tagId = tags[tid];
2257 ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
2258 uint32_t sectionId = tagId >> 16;
2259 if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
2260 LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
2261 goto cleanup;
2262 }
2263 }
2264
2265 void* context = nullptr;
2266 ret = ACaptureRequest_getUserContext(request, &context);
2267 if (ret != ACAMERA_OK) {
2268 LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
2269 goto cleanup;
2270 }
2271 if (context != nullptr) {
2272 LOG_ERROR(errorString, "Capture request context is not null: %p", context);
2273 goto cleanup;
2274 }
2275
2276 intptr_t magic_num = 0xBEEF;
2277 ret = ACaptureRequest_setUserContext(request, (void*) magic_num);
2278 if (ret != ACAMERA_OK) {
2279 LOG_ERROR(errorString, "Set capture request context failed: ret %d", ret);
2280 goto cleanup;
2281 }
2282
2283 ret = ACaptureRequest_getUserContext(request, &context);
2284 if (ret != ACAMERA_OK) {
2285 LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
2286 goto cleanup;
2287 }
2288 if (context != (void*) magic_num) {
2289 LOG_ERROR(errorString, "Capture request context is wrong: %p", context);
2290 goto cleanup;
2291 }
2292
2293 // try get/set capture request fields
2294 ACameraMetadata_const_entry entry;
2295 ret = ACaptureRequest_getConstEntry_physicalCamera(request, nullptr,
2296 ACAMERA_CONTROL_AE_MODE, &entry);
2297 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2298 LOG_ERROR(errorString, "Get AE mode key for null physical id should fail. ret %d",
2299 ret);
2300 goto cleanup;
2301 }
2302 ret = ACaptureRequest_getConstEntry_physicalCamera(request, cameraId,
2303 ACAMERA_CONTROL_AE_MODE, &entry);
2304 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2305 LOG_ERROR(errorString, "Get AE mode key for physical id should fail. ret %d",
2306 ret);
2307 goto cleanup;
2308 }
2309 ret = ACaptureRequest_getConstEntry(request, ACAMERA_CONTROL_AE_MODE, &entry);
2310 if (ret != ACAMERA_OK) {
2311 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2312 goto cleanup;
2313 }
2314
2315 if (entry.tag != ACAMERA_CONTROL_AE_MODE || entry.type != ACAMERA_TYPE_BYTE ||\
2316 entry.count != 1) {
2317 LOG_ERROR(errorString,
2318 "Bad AE mode key. tag 0x%x (expect 0x%x), type %d (expect %d), "
2319 "count %d (expect %d)",
2320 entry.tag, ACAMERA_CONTROL_AE_MODE, entry.type, ACAMERA_TYPE_BYTE,
2321 entry.count, 1);
2322 goto cleanup;
2323 }
2324 if (t == TEMPLATE_MANUAL) {
2325 if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_OFF) {
2326 LOG_ERROR(errorString, "Error: MANUAL template AE mode %d (expect %d)",
2327 entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_OFF);
2328 goto cleanup;
2329 }
2330 // try set AE_MODE_ON
2331 uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
2332 ret = ACaptureRequest_setEntry_physicalCamera_u8(
2333 request, nullptr, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2334 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2335 LOG_ERROR(errorString, "Error: camera %s setEntry_physicalCamera_u8 should "
2336 "fail. ret %d", cameraId, ret);
2337 goto cleanup;
2338 }
2339 ret = ACaptureRequest_setEntry_physicalCamera_u8(
2340 request, cameraId, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2341 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2342 LOG_ERROR(errorString, "Error: camera %s setEntry_physicalCamera_u8 should "
2343 "fail. ret %d", cameraId, ret);
2344 goto cleanup;
2345 }
2346 ret = ACaptureRequest_setEntry_u8(
2347 request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2348 if (ret != ACAMERA_OK) {
2349 LOG_ERROR(errorString,
2350 "Error: Camera %s template %d: update AE mode key fail. ret %d",
2351 cameraId, t, ret);
2352 goto cleanup;
2353 }
2354 ret = ACaptureRequest_getConstEntry(
2355 request, ACAMERA_CONTROL_AE_MODE, &entry);
2356 if (ret != ACAMERA_OK) {
2357 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2358 goto cleanup;
2359 }
2360 if (entry.data.u8[0] != aeMode) {
2361 LOG_ERROR(errorString,
2362 "Error: AE mode key is not updated. expect %d but get %d",
2363 aeMode, entry.data.u8[0]);
2364 goto cleanup;
2365 }
2366 } else {
2367 if (staticInfo.isColorOutputSupported()) {
2368 if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_ON) {
2369 LOG_ERROR(errorString,
2370 "Error: Template %d has wrong AE mode %d (expect %d)",
2371 t, entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_ON);
2372 goto cleanup;
2373 }
2374 // try set AE_MODE_OFF
2375 if (staticInfo.isCapabilitySupported(
2376 ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
2377 uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF;
2378 ret = ACaptureRequest_setEntry_u8(
2379 request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2380 if (ret != ACAMERA_OK) {
2381 LOG_ERROR(errorString,
2382 "Error: Camera %s template %d: update AE mode key fail. ret %d",
2383 cameraId, t, ret);
2384 goto cleanup;
2385 }
2386 ret = ACaptureRequest_getConstEntry(
2387 request, ACAMERA_CONTROL_AE_MODE, &entry);
2388 if (ret != ACAMERA_OK) {
2389 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2390 goto cleanup;
2391 }
2392 if (entry.data.u8[0] != aeMode) {
2393 LOG_ERROR(errorString,
2394 "Error: AE mode key is not updated. expect %d but get %d",
2395 aeMode, entry.data.u8[0]);
2396 goto cleanup;
2397 }
2398 }
2399 }
2400 }
2401 ACaptureRequest_free(request);
2402 request = nullptr;
2403 }
2404
2405 ACameraMetadata_free(chars);
2406 chars = nullptr;
2407 ACameraDevice_close(device);
2408 device = nullptr;
2409 }
2410
2411 pass = true;
2412 cleanup:
2413 if (cameraIdList) {
2414 ACameraManager_deleteCameraIdList(cameraIdList);
2415 }
2416 if (request) {
2417 ACaptureRequest_free(request);
2418 }
2419 if (chars) {
2420 ACameraMetadata_free(chars);
2421 }
2422 if (device) {
2423 ACameraDevice_close(device);
2424 }
2425 if (mgr) {
2426 ACameraManager_delete(mgr);
2427 }
2428 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2429 if (!pass) {
2430 throwAssertionError(env, errorString);
2431 }
2432 return pass;
2433 }
2434
2435 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSessionOpenAndCloseNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)2436 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2437 testCameraDeviceSessionOpenAndCloseNative(
2438 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
2439 jstring jOverrideCameraId) {
2440 ALOGV("%s", __FUNCTION__);
2441 int numCameras = 0;
2442 bool pass = false;
2443 PreviewTestCase testCase;
2444
2445 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2446 if (ret != ACAMERA_OK) {
2447 // Don't log error here. testcase did it
2448 goto cleanup;
2449 }
2450
2451 numCameras = testCase.getNumCameras();
2452 if (numCameras < 0) {
2453 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2454 goto cleanup;
2455 }
2456
2457 for (int i = 0; i < numCameras; i++) {
2458 const char* cameraId = testCase.getCameraId(i);
2459 if (cameraId == nullptr) {
2460 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2461 goto cleanup;
2462 }
2463
2464 {
2465 ACameraMetadata* chars = testCase.getCameraChars(cameraId);
2466 StaticInfo staticInfo(chars);
2467 if (!staticInfo.isColorOutputSupported()) {
2468 ALOGI("%s: camera %s does not support color output. skipping",
2469 __FUNCTION__, cameraId);
2470 ACameraMetadata_free(chars);
2471 continue;
2472 }
2473 ACameraMetadata_free(chars);
2474 }
2475
2476 ret = testCase.openCamera(cameraId);
2477 if (ret != ACAMERA_OK) {
2478 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2479 goto cleanup;
2480 }
2481
2482 usleep(100000); // sleep to give some time for callbacks to happen
2483
2484 if (testCase.isCameraAvailable(cameraId)) {
2485 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2486 goto cleanup;
2487 }
2488
2489 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2490 if (previewAnw == nullptr) {
2491 LOG_ERROR(errorString, "Null ANW from preview surface!");
2492 goto cleanup;
2493 }
2494
2495 CaptureSessionListener* sessionListener = testCase.getSessionListener();
2496 if (sessionListener == nullptr) {
2497 LOG_ERROR(errorString, "Session listener camera %s is null", cameraId);
2498 goto cleanup;
2499 }
2500
2501 // Try open/close session multiple times
2502 for (int j = 0; j < 5; j++) {
2503 ret = testCase.createCaptureSessionWithLog();
2504 if (ret != ACAMERA_OK) {
2505 // Don't log error here. testcase did it
2506 goto cleanup;
2507 }
2508
2509 usleep(100000); // sleep to give some time for callbacks to happen
2510
2511 if (!sessionListener->isIdle()) {
2512 LOG_ERROR(errorString, "Session for camera %s should be idle right after creation",
2513 cameraId);
2514 goto cleanup;
2515 }
2516
2517 testCase.closeSession();
2518
2519 usleep(100000); // sleep to give some time for callbacks to happen
2520 if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
2521 LOG_ERROR(errorString,
2522 "Session for camera %s close error. isClosde %d close count %d",
2523 cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
2524 goto cleanup;
2525 }
2526 sessionListener->reset();
2527 }
2528
2529 // Try open/close really fast
2530 ret = testCase.createCaptureSessionWithLog();
2531 if (ret != ACAMERA_OK) {
2532 LOG_ERROR(errorString, "Create session for camera %s failed. ret %d",
2533 cameraId, ret);
2534 goto cleanup;
2535 }
2536 testCase.closeSession();
2537 usleep(100000); // sleep to give some time for callbacks to happen
2538 if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
2539 LOG_ERROR(errorString,
2540 "Session for camera %s close error. isClosde %d close count %d",
2541 cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
2542 goto cleanup;
2543 }
2544
2545 ret = testCase.resetWithErrorLog();
2546 if (ret != ACAMERA_OK) {
2547 // Don't log error here. testcase did it
2548 goto cleanup;
2549 }
2550
2551 usleep(100000); // sleep to give some time for callbacks to happen
2552
2553 if (!testCase.isCameraAvailable(cameraId)) {
2554 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2555 goto cleanup;
2556 }
2557 }
2558
2559 ret = testCase.deInit();
2560 if (ret != ACAMERA_OK) {
2561 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2562 goto cleanup;
2563 }
2564
2565 pass = true;
2566 cleanup:
2567 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2568 if (!pass) {
2569 throwAssertionError(env, errorString);
2570 }
2571 return pass;
2572 }
2573
2574 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSharedOutputUpdate(JNIEnv * env,jclass,jobject jPreviewSurface,jobject jSharedSurface,jstring jOverrideCameraId)2575 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2576 testCameraDeviceSharedOutputUpdate(
2577 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface, jobject jSharedSurface,
2578 jstring jOverrideCameraId) {
2579 ALOGV("%s", __FUNCTION__);
2580 int numCameras = 0;
2581 bool pass = false;
2582 PreviewTestCase testCase;
2583 int sequenceId = -1;
2584 int64_t lastFrameNumber = 0;
2585 bool frameArrived = false;
2586 ANativeWindow* previewAnw = nullptr;
2587 ANativeWindow* sharedAnw = ANativeWindow_fromSurface(env, jSharedSurface);
2588 ACaptureRequest* updatedRequest = nullptr;
2589 ACameraOutputTarget* reqPreviewOutput = nullptr;
2590 ACameraOutputTarget* reqSharedOutput = nullptr;
2591 ACaptureSessionOutput *previewOutput = nullptr;
2592 uint32_t timeoutSec = 1;
2593 uint32_t runPreviewSec = 2;
2594
2595 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2596 if (ret != ACAMERA_OK) {
2597 // Don't log error here. testcase did it
2598 goto cleanup;
2599 }
2600
2601 numCameras = testCase.getNumCameras();
2602 if (numCameras < 0) {
2603 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2604 goto cleanup;
2605 }
2606
2607 for (int i = 0; i < numCameras; i++) {
2608 const char* cameraId = testCase.getCameraId(i);
2609 if (cameraId == nullptr) {
2610 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2611 goto cleanup;
2612 }
2613
2614 {
2615 ACameraMetadata* chars = testCase.getCameraChars(cameraId);
2616 StaticInfo staticInfo(chars);
2617 if (!staticInfo.isColorOutputSupported()) {
2618 ALOGI("%s: camera %s does not support color output. skipping",
2619 __FUNCTION__, cameraId);
2620 ACameraMetadata_free(chars);
2621 continue;
2622 }
2623 ACameraMetadata_free(chars);
2624 }
2625
2626 ret = testCase.openCamera(cameraId);
2627 if (ret != ACAMERA_OK) {
2628 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2629 goto cleanup;
2630 }
2631
2632 usleep(100000); // sleep to give some time for callbacks to happen
2633
2634 if (testCase.isCameraAvailable(cameraId)) {
2635 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2636 goto cleanup;
2637 }
2638
2639 previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2640 if (previewAnw == nullptr) {
2641 LOG_ERROR(errorString, "Null ANW from preview surface!");
2642 goto cleanup;
2643 }
2644
2645 ret = testCase.createCaptureSessionWithLog(true);
2646 if (ret != ACAMERA_OK) {
2647 // Don't log error here. testcase did it
2648 goto cleanup;
2649 }
2650
2651 ret = testCase.createRequestsWithErrorLog();
2652 if (ret != ACAMERA_OK) {
2653 // Don't log error here. testcase did it
2654 goto cleanup;
2655 }
2656
2657 ret = testCase.startPreview();
2658 if (ret != ACAMERA_OK) {
2659 LOG_ERROR(errorString, "Start preview failed!");
2660 goto cleanup;
2661 }
2662
2663 sleep(runPreviewSec);
2664
2665 previewOutput = testCase.getPreviewOutput();
2666 //Try some bad input
2667 ret = ACaptureSessionSharedOutput_add(previewOutput, previewAnw);
2668 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2669 LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add should return invalid "
2670 "parameter! %d", ret);
2671 goto cleanup;
2672 }
2673
2674 ret = ACaptureSessionSharedOutput_remove(previewOutput, previewAnw);
2675 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2676 LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove should return invalid "
2677 "parameter! %d", ret);
2678 goto cleanup;
2679 }
2680
2681 //Now try with valid input
2682 ret = ACaptureSessionSharedOutput_add(previewOutput, sharedAnw);
2683 if (ret != ACAMERA_OK) {
2684 LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add failed!")
2685 goto cleanup;
2686 }
2687
2688 ret = testCase.updateOutput(env, previewOutput);
2689 if (ret != ACAMERA_OK) {
2690 LOG_ERROR(errorString, "Failed to update output configuration!")
2691 goto cleanup;
2692 }
2693
2694 ret = ACameraDevice_createCaptureRequest(
2695 testCase.getCameraDevice(), TEMPLATE_PREVIEW, &updatedRequest);
2696 if (ret != ACAMERA_OK) {
2697 LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
2698 cameraId, ret);
2699 goto cleanup;
2700 }
2701
2702 ret = ACameraOutputTarget_create(previewAnw, &reqPreviewOutput);
2703 if (ret != ACAMERA_OK) {
2704 LOG_ERROR(errorString,
2705 "Camera %s create request preview output target failed. ret %d",
2706 cameraId, ret);
2707 goto cleanup;
2708 }
2709
2710 ret = ACaptureRequest_addTarget(updatedRequest, reqPreviewOutput);
2711 if (ret != ACAMERA_OK) {
2712 LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
2713 cameraId, ret);
2714 goto cleanup;
2715 }
2716
2717 ret = ACameraOutputTarget_create(sharedAnw, &reqSharedOutput);
2718 if (ret != ACAMERA_OK) {
2719 LOG_ERROR(errorString,
2720 "Camera %s create request preview output target failed. ret %d",
2721 cameraId, ret);
2722 goto cleanup;
2723 }
2724
2725 ret = ACaptureRequest_addTarget(updatedRequest, reqSharedOutput);
2726 if (ret != ACAMERA_OK) {
2727 LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
2728 cameraId, ret);
2729 goto cleanup;
2730 }
2731
2732 ret = testCase.updateRepeatingRequest(updatedRequest, &sequenceId);
2733 if (ret != ACAMERA_OK) {
2734 LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
2735 cameraId, ret);
2736 goto cleanup;
2737 }
2738
2739 sleep(runPreviewSec);
2740
2741 ret = ACaptureSessionSharedOutput_remove(previewOutput, sharedAnw);
2742 if (ret != ACAMERA_OK) {
2743 LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove failed!");
2744 goto cleanup;
2745 }
2746
2747 //Try removing shared output which still has pending camera requests
2748 ret = testCase.updateOutput(env, previewOutput);
2749 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2750 LOG_ERROR(errorString, "updateOutput should fail!");
2751 goto cleanup;
2752 }
2753
2754 //Remove the shared output correctly by updating the repeating request
2755 //first
2756 ret = ACaptureRequest_removeTarget(updatedRequest, reqSharedOutput);
2757 if (ret != ACAMERA_OK) {
2758 LOG_ERROR(errorString, "Camera %s remove target output failed. ret %d",
2759 cameraId, ret);
2760 goto cleanup;
2761 }
2762
2763 ret = testCase.updateRepeatingRequest(updatedRequest);
2764 if (ret != ACAMERA_OK) {
2765 LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
2766 cameraId, ret);
2767 goto cleanup;
2768 }
2769
2770 //Then wait for all old requests to flush
2771 lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
2772 if (lastFrameNumber < 0) {
2773 LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
2774 cameraId);
2775 goto cleanup;
2776 }
2777
2778 frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
2779 if (!frameArrived) {
2780 LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
2781 cameraId);
2782 goto cleanup;
2783 }
2784
2785 ret = testCase.updateOutput(env, previewOutput);
2786 if (ret != ACAMERA_OK) {
2787 LOG_ERROR(errorString, "updateOutput failed!");
2788 goto cleanup;
2789 }
2790
2791 sleep(runPreviewSec);
2792
2793 ret = testCase.resetWithErrorLog();
2794 if (ret != ACAMERA_OK) {
2795 // Don't log error here. testcase did it
2796 goto cleanup;
2797 }
2798
2799 usleep(100000); // sleep to give some time for callbacks to happen
2800
2801 if (!testCase.isCameraAvailable(cameraId)) {
2802 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2803 goto cleanup;
2804 }
2805 }
2806
2807 ret = testCase.deInit();
2808 if (ret != ACAMERA_OK) {
2809 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2810 goto cleanup;
2811 }
2812
2813 pass = true;
2814
2815 cleanup:
2816
2817 if (updatedRequest != nullptr) {
2818 ACaptureRequest_free(updatedRequest);
2819 updatedRequest = nullptr;
2820 }
2821
2822 if (reqPreviewOutput != nullptr) {
2823 ACameraOutputTarget_free(reqPreviewOutput);
2824 reqPreviewOutput = nullptr;
2825 }
2826
2827 if (reqSharedOutput != nullptr) {
2828 ACameraOutputTarget_free(reqSharedOutput);
2829 reqSharedOutput = nullptr;
2830 }
2831
2832 if (sharedAnw) {
2833 ANativeWindow_release(sharedAnw);
2834 sharedAnw = nullptr;
2835 }
2836
2837 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2838 if (!pass) {
2839 throwAssertionError(env, errorString);
2840 }
2841 return pass;
2842 }
2843
2844 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSimplePreviewNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)2845 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2846 testCameraDeviceSimplePreviewNative(
2847 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
2848 jstring jOverrideCameraId) {
2849 ALOGV("%s", __FUNCTION__);
2850 int numCameras = 0;
2851 bool pass = false;
2852 PreviewTestCase testCase;
2853
2854 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2855 if (ret != ACAMERA_OK) {
2856 // Don't log error here. testcase did it
2857 goto cleanup;
2858 }
2859
2860 numCameras = testCase.getNumCameras();
2861 if (numCameras < 0) {
2862 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2863 goto cleanup;
2864 }
2865
2866 for (int i = 0; i < numCameras; i++) {
2867 const char* cameraId = testCase.getCameraId(i);
2868 if (cameraId == nullptr) {
2869 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2870 goto cleanup;
2871 }
2872
2873 {
2874 ACameraMetadata* chars = testCase.getCameraChars(cameraId);
2875 StaticInfo staticInfo(chars);
2876 if (!staticInfo.isColorOutputSupported()) {
2877 ALOGI("%s: camera %s does not support color output. skipping",
2878 __FUNCTION__, cameraId);
2879 ACameraMetadata_free(chars);
2880 continue;
2881 }
2882 ACameraMetadata_free(chars);
2883 }
2884
2885 ret = testCase.openCamera(cameraId);
2886 if (ret != ACAMERA_OK) {
2887 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2888 goto cleanup;
2889 }
2890
2891 usleep(100000); // sleep to give some time for callbacks to happen
2892
2893 if (testCase.isCameraAvailable(cameraId)) {
2894 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2895 goto cleanup;
2896 }
2897
2898 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2899 if (previewAnw == nullptr) {
2900 LOG_ERROR(errorString, "Null ANW from preview surface!");
2901 goto cleanup;
2902 }
2903
2904 ret = testCase.createCaptureSessionWithLog();
2905 if (ret != ACAMERA_OK) {
2906 // Don't log error here. testcase did it
2907 goto cleanup;
2908 }
2909
2910 ret = testCase.createRequestsWithErrorLog();
2911 if (ret != ACAMERA_OK) {
2912 // Don't log error here. testcase did it
2913 goto cleanup;
2914 }
2915
2916 ret = testCase.startPreview();
2917 if (ret != ACAMERA_OK) {
2918 LOG_ERROR(errorString, "Start preview failed!");
2919 goto cleanup;
2920 }
2921
2922 sleep(3);
2923
2924 ret = testCase.resetWithErrorLog();
2925 if (ret != ACAMERA_OK) {
2926 // Don't log error here. testcase did it
2927 goto cleanup;
2928 }
2929
2930 usleep(100000); // sleep to give some time for callbacks to happen
2931
2932 if (!testCase.isCameraAvailable(cameraId)) {
2933 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2934 goto cleanup;
2935 }
2936 }
2937
2938 ret = testCase.deInit();
2939 if (ret != ACAMERA_OK) {
2940 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2941 goto cleanup;
2942 }
2943
2944 pass = true;
2945 cleanup:
2946 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2947 if (!pass) {
2948 throwAssertionError(env, errorString);
2949 }
2950 return pass;
2951 }
2952
2953 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDevicePreviewWithSessionParametersNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)2954 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2955 testCameraDevicePreviewWithSessionParametersNative(
2956 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
2957 jstring jOverrideCameraId) {
2958 ALOGV("%s", __FUNCTION__);
2959 int numCameras = 0;
2960 bool pass = false;
2961 ACameraManager* mgr = ACameraManager_create();
2962 ACameraMetadata* chars = nullptr;
2963 PreviewTestCase testCase;
2964
2965 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2966 if (ret != ACAMERA_OK) {
2967 // Don't log error here. testcase did it
2968 goto cleanup;
2969 }
2970
2971 numCameras = testCase.getNumCameras();
2972 if (numCameras < 0) {
2973 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2974 goto cleanup;
2975 }
2976
2977 for (int i = 0; i < numCameras; i++) {
2978 const char* cameraId = testCase.getCameraId(i);
2979 if (cameraId == nullptr) {
2980 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2981 goto cleanup;
2982 }
2983
2984 ret = ACameraManager_getCameraCharacteristics(
2985 mgr, cameraId, &chars);
2986 if (ret != ACAMERA_OK) {
2987 LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
2988 goto cleanup;
2989 }
2990
2991 StaticInfo staticInfo(chars);
2992 ACameraMetadata_const_entry sessionParamKeys{};
2993 ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_SESSION_KEYS,
2994 &sessionParamKeys);
2995 if ((ret != ACAMERA_OK) || (sessionParamKeys.count == 0) ||
2996 !staticInfo.isColorOutputSupported()) {
2997 ACameraMetadata_free(chars);
2998 chars = nullptr;
2999 continue;
3000 }
3001
3002 ret = testCase.openCamera(cameraId);
3003 if (ret != ACAMERA_OK) {
3004 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3005 goto cleanup;
3006 }
3007
3008 usleep(100000); // sleep to give some time for callbacks to happen
3009
3010 if (testCase.isCameraAvailable(cameraId)) {
3011 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3012 goto cleanup;
3013 }
3014
3015 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
3016 if (previewAnw == nullptr) {
3017 LOG_ERROR(errorString, "Null ANW from preview surface!");
3018 goto cleanup;
3019 }
3020
3021 ret = testCase.createRequestsWithErrorLog();
3022 if (ret != ACAMERA_OK) {
3023 // Don't log error here. testcase did it
3024 goto cleanup;
3025 }
3026
3027 ACaptureRequest *previewRequest = nullptr;
3028 ret = testCase.getPreviewRequest(&previewRequest);
3029 if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
3030 LOG_ERROR(errorString, "Preview request query failed!");
3031 goto cleanup;
3032 }
3033
3034 ret = testCase.createCaptureSessionWithLog(/*isPreviewShared*/ false, previewRequest);
3035 if (ret != ACAMERA_OK) {
3036 // Don't log error here. testcase did it
3037 goto cleanup;
3038 }
3039
3040 ret = testCase.startPreview();
3041 if (ret != ACAMERA_OK) {
3042 LOG_ERROR(errorString, "Start preview failed!");
3043 goto cleanup;
3044 }
3045
3046 sleep(3);
3047
3048 ret = testCase.resetWithErrorLog();
3049 if (ret != ACAMERA_OK) {
3050 // Don't log error here. testcase did it
3051 goto cleanup;
3052 }
3053
3054 usleep(100000); // sleep to give some time for callbacks to happen
3055
3056 if (!testCase.isCameraAvailable(cameraId)) {
3057 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3058 goto cleanup;
3059 }
3060
3061 ACameraMetadata_free(chars);
3062 chars = nullptr;
3063 }
3064
3065 ret = testCase.deInit();
3066 if (ret != ACAMERA_OK) {
3067 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3068 goto cleanup;
3069 }
3070
3071 pass = true;
3072 cleanup:
3073 if (chars) {
3074 ACameraMetadata_free(chars);
3075 }
3076 ACameraManager_delete(mgr);
3077 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3078 if (!pass) {
3079 throwAssertionError(env, errorString);
3080 }
3081 return pass;
3082 }
3083
nativeCameraDeviceLogicalPhysicalStreaming(JNIEnv * env,jobject jPreviewSurface,bool usePhysicalSettings,jstring jOverrideCameraId)3084 bool nativeCameraDeviceLogicalPhysicalStreaming(
3085 JNIEnv* env, jobject jPreviewSurface, bool usePhysicalSettings,
3086 jstring jOverrideCameraId) {
3087 const int NUM_TEST_IMAGES = 10;
3088 const int TEST_WIDTH = 640;
3089 const int TEST_HEIGHT = 480;
3090 ALOGV("%s", __FUNCTION__);
3091 int numCameras = 0;
3092 bool pass = false;
3093 ACameraManager* mgr = ACameraManager_create();
3094 ACameraMetadata* chars = nullptr;
3095 media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3096 PreviewTestCase testCase;
3097 int64_t lastFrameNumber = 0;
3098 bool frameArrived = false;
3099 uint32_t timeoutSec = 1;
3100 uint32_t runPreviewSec = 2;
3101
3102 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
3103 if (ret != ACAMERA_OK) {
3104 // Don't log error here. testcase did it
3105 goto cleanup;
3106 }
3107
3108 numCameras = testCase.getNumCameras();
3109 if (numCameras < 0) {
3110 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
3111 goto cleanup;
3112 }
3113
3114 for (int i = 0; i < numCameras; i++) {
3115 const char* cameraId = testCase.getCameraId(i);
3116 if (cameraId == nullptr) {
3117 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3118 goto cleanup;
3119 }
3120
3121 if (chars != nullptr) {
3122 ACameraMetadata_free(chars);
3123 chars = nullptr;
3124 }
3125 chars = testCase.getCameraChars(i);
3126 if (chars == nullptr) {
3127 LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3128 goto cleanup;
3129 }
3130
3131 size_t physicalCameraCnt = 0;
3132 const char *const* physicalCameraIds = nullptr;
3133 if (!ACameraMetadata_isLogicalMultiCamera(
3134 chars, &physicalCameraCnt, &physicalCameraIds)) {
3135 continue;
3136 }
3137 if (physicalCameraCnt < 2) {
3138 LOG_ERROR(errorString, "Logical camera device %s only has %zu physical cameras",
3139 cameraId, physicalCameraCnt);
3140 goto cleanup;
3141 }
3142
3143 std::vector<const char*> candidateIds;
3144 for (size_t i = 0; i < physicalCameraCnt && candidateIds.size() < 2; i++) {
3145 ACameraMetadata* physicalChars = testCase.getCameraChars(physicalCameraIds[i]);
3146 if (physicalChars == nullptr) {
3147 LOG_ERROR(errorString,
3148 "Get camera %s characteristics failure", physicalCameraIds[i]);
3149 goto cleanup;
3150 }
3151 StaticInfo info(physicalChars);
3152 bool testSizeSupported = info.isSizeSupportedForFormat(AIMAGE_FORMAT_YUV_420_888,
3153 TEST_WIDTH, TEST_HEIGHT);
3154 ACameraMetadata_free(physicalChars);
3155 if (!testSizeSupported) {
3156 continue;
3157 }
3158 candidateIds.push_back(physicalCameraIds[i]);
3159 }
3160 if (candidateIds.size() < 2) {
3161 continue;
3162 }
3163
3164 // Check physical camera request keys
3165 if (usePhysicalSettings) {
3166 ACameraMetadata_const_entry entry;
3167 camera_status_t status = ACameraMetadata_getConstEntry(
3168 chars, ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &entry);
3169 if (status == ACAMERA_ERROR_METADATA_NOT_FOUND) {
3170 // No supported PHYSICAL_CAMERA_REQUEST_KEYS, skip test
3171 continue;
3172 } else if (status != ACAMERA_OK) {
3173 // Do not log error here. testcase did it.
3174 goto cleanup;
3175 } else if (entry.count == 0) {
3176 // No supported PHYSICAL_CAMERA_REQUEST_KEYS, skip test
3177 continue;
3178 }
3179 }
3180
3181 ret = testCase.openCamera(cameraId);
3182 if (ret != ACAMERA_OK) {
3183 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3184 goto cleanup;
3185 }
3186
3187 usleep(100000); // sleep to give some time for callbacks to happen
3188
3189 if (testCase.isCameraAvailable(cameraId)) {
3190 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3191 goto cleanup;
3192 }
3193
3194 std::vector<ImageReaderListener> readerListeners(2);
3195 std::vector<AImageReader_ImageListener> readerCbs;
3196 std::vector<AImageReader*> readers;
3197 std::vector<ANativeWindow*> readerAnws;
3198 std::vector<ACaptureSessionOutput*> readerSessionOutputs;
3199 std::vector<ACameraOutputTarget*> readerOutputs;
3200 for (size_t i = 0; i < 2; i++) {
3201 AImageReader_ImageListener readerCb {
3202 &readerListeners[i],
3203 ImageReaderListener::validateImageCb
3204 };
3205 readerCbs.push_back(readerCb);
3206
3207 AImageReader* reader = nullptr;
3208 ANativeWindow* readerAnw = nullptr;
3209 ACaptureSessionOutput* readerSessionOutput = nullptr;
3210 ACameraOutputTarget* readerOutput = nullptr;
3211 mediaRet = testCase.initImageReaderWithErrorLog(
3212 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES,
3213 &readerCb, &reader, &readerAnw);
3214 if (mediaRet != AMEDIA_OK) {
3215 // Don't log error here. testcase did it
3216 goto cleanup;
3217 }
3218
3219 camera_status_t ret = ACaptureSessionPhysicalOutput_create(readerAnw,
3220 candidateIds[i], &readerSessionOutput);
3221 if (ret != ACAMERA_OK || readerSessionOutput == nullptr) {
3222 if (ret == ACAMERA_OK) {
3223 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
3224 }
3225 // Don't log error here. testcase did it
3226 goto cleanup;
3227 }
3228
3229 ret = ACameraOutputTarget_create(readerAnw, &readerOutput);
3230 if (ret != ACAMERA_OK) {
3231 // Don't log error here. testcase did it
3232 goto cleanup;
3233 }
3234
3235 readers.push_back(reader);
3236 readerAnws.push_back(readerAnw);
3237 readerSessionOutputs.push_back(readerSessionOutput);
3238 readerOutputs.push_back(readerOutput);
3239 }
3240
3241 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
3242 if (previewAnw == nullptr) {
3243 LOG_ERROR(errorString, "Null ANW from preview surface!");
3244 goto cleanup;
3245 }
3246
3247 ret = testCase.createCaptureSessionWithLog(readerSessionOutputs, false /*isPreviewShared*/,
3248 nullptr /*sessionParameters*/, false /*sessionConfigurationDefault*/);
3249 if (ret == ACAMERA_ERROR_UNSUPPORTED_OPERATION ||
3250 ret == ACAMERA_ERROR_STREAM_CONFIGURE_FAIL) {
3251 // Camera device doesn't support the stream combination, skip the
3252 // current camera.
3253 testCase.closeCamera();
3254 testCase.resetCamera();
3255 continue;
3256 } else if (ret != ACAMERA_OK) {
3257 // Don't log error here. testcase did it
3258 goto cleanup;
3259 }
3260
3261 if (usePhysicalSettings) {
3262 std::vector<const char*> twoNullStr = {nullptr, nullptr};
3263 ACameraIdList nullCameraIdList = {2, twoNullStr.data()};
3264 ret = testCase.createRequestsWithErrorLog(readerOutputs, &nullCameraIdList);
3265 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
3266 LOG_ERROR(errorString, "Null physical camera ids must fail createCaptureRequest. "
3267 "ret %d", ret);
3268 goto cleanup;
3269 }
3270
3271 std::string invalidId = "";
3272 std::vector<const char*> one0LengthStr = {invalidId.c_str()};
3273 ACameraIdList invalidCameraIdList = {1, one0LengthStr.data()};
3274 ret = testCase.createRequestsWithErrorLog(readerOutputs, &invalidCameraIdList);
3275 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
3276 LOG_ERROR(errorString, "zero-length physical camera ids must fail "
3277 "createCaptureRequest. ret %d", ret);
3278 goto cleanup;
3279 }
3280
3281 ACameraIdList physicalCameraIdList = {2, candidateIds.data()};
3282 ret = testCase.createRequestsWithErrorLog(readerOutputs, &physicalCameraIdList);
3283 } else {
3284 ret = testCase.createRequestsWithErrorLog(readerOutputs);
3285 }
3286 if (ret != ACAMERA_OK) {
3287 // Don't log error here. testcase did it
3288 goto cleanup;
3289 }
3290
3291 ACaptureRequest *previewRequest = nullptr;
3292 ret = testCase.getPreviewRequest(&previewRequest);
3293 if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
3294 LOG_ERROR(errorString, "Preview request query failed!");
3295 goto cleanup;
3296 }
3297
3298 int sequenceId = 0;
3299 ret = testCase.startPreview(&sequenceId, 2, candidateIds.data());
3300 if (ret != ACAMERA_OK) {
3301 LOG_ERROR(errorString, "Start preview failed!");
3302 goto cleanup;
3303 }
3304
3305 sleep(runPreviewSec);
3306
3307 ret = testCase.stopPreview();
3308 if (ret != ACAMERA_OK) {
3309 ALOGE("%s: stopPreview failed", __FUNCTION__);
3310 LOG_ERROR(errorString, "stopPreview failed!");
3311 goto cleanup;
3312 }
3313
3314 //Then wait for all old requests to flush
3315 lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
3316 if (lastFrameNumber < 0) {
3317 LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
3318 cameraId);
3319 goto cleanup;
3320 }
3321
3322 frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
3323 if (!frameArrived) {
3324 LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
3325 cameraId);
3326 goto cleanup;
3327 }
3328
3329 ret = testCase.resetWithErrorLog();
3330 if (ret != ACAMERA_OK) {
3331 // Don't log error here. testcase did it
3332 goto cleanup;
3333 }
3334
3335 usleep(100000); // sleep to give some time for callbacks to happen
3336
3337 if (!testCase.isCameraAvailable(cameraId)) {
3338 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3339 goto cleanup;
3340 }
3341 }
3342
3343 ret = testCase.deInit();
3344 if (ret != ACAMERA_OK) {
3345 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3346 goto cleanup;
3347 }
3348
3349 pass = true;
3350 cleanup:
3351 if (chars) {
3352 ACameraMetadata_free(chars);
3353 }
3354 ACameraManager_delete(mgr);
3355 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3356 if (!pass) {
3357 throwAssertionError(env, errorString);
3358 }
3359 return pass;
3360 }
3361
3362 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceLogicalPhysicalStreamingNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)3363 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3364 testCameraDeviceLogicalPhysicalStreamingNative(
3365 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
3366 jstring jOverrideCameraId) {
3367 return nativeCameraDeviceLogicalPhysicalStreaming(env,
3368 jPreviewSurface, false /*usePhysicalSettings*/,
3369 jOverrideCameraId);
3370 }
3371
3372 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceLogicalPhysicalSettingsNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)3373 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3374 testCameraDeviceLogicalPhysicalSettingsNative(
3375 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
3376 jstring jOverrideCameraId) {
3377 return nativeCameraDeviceLogicalPhysicalStreaming(env,
3378 jPreviewSurface, true /*usePhysicalSettings*/,
3379 jOverrideCameraId);
3380 }
3381
nativeImageReaderTestBase(JNIEnv * env,jstring jOutPath,jint format,AImageReader_ImageCallback cb,jstring jOverrideCameraId)3382 bool nativeImageReaderTestBase(
3383 JNIEnv* env, jstring jOutPath, jint format, AImageReader_ImageCallback cb,
3384 jstring jOverrideCameraId) {
3385 const int NUM_TEST_IMAGES = 10;
3386 media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3387 int numCameras = 0;
3388 bool pass = false;
3389 PreviewTestCase testCase;
3390 ACameraMetadata* chars = nullptr;
3391
3392 const char* outPath = (jOutPath == nullptr) ? nullptr :
3393 env->GetStringUTFChars(jOutPath, nullptr);
3394 if (outPath != nullptr) {
3395 ALOGI("%s: out path is %s", __FUNCTION__, outPath);
3396 }
3397
3398 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
3399 if (ret != ACAMERA_OK) {
3400 // Don't log error here. testcase did it
3401 goto cleanup;
3402 }
3403
3404 numCameras = testCase.getNumCameras();
3405 if (numCameras < 0) {
3406 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
3407 goto cleanup;
3408 }
3409
3410 for (int i = 0; i < numCameras; i++) {
3411 const char* cameraId = testCase.getCameraId(i);
3412 if (cameraId == nullptr) {
3413 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3414 goto cleanup;
3415 }
3416
3417 {
3418 ACameraMetadata* chars = testCase.getCameraChars(cameraId);
3419 StaticInfo staticInfo(chars);
3420 if (!staticInfo.isColorOutputSupported()) {
3421 ALOGI("%s: camera %s does not support color output. skipping",
3422 __FUNCTION__, cameraId);
3423 ACameraMetadata_free(chars);
3424 continue;
3425 }
3426 ACameraMetadata_free(chars);
3427 }
3428
3429 ret = testCase.openCamera(cameraId);
3430 if (ret != ACAMERA_OK) {
3431 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3432 goto cleanup;
3433 }
3434
3435 chars = testCase.getCameraChars(i);
3436 if (chars == nullptr) {
3437 LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3438 goto cleanup;
3439 }
3440 StaticInfo staticInfo(chars);
3441
3442 usleep(200000); // sleep to give some time for callbacks to happen
3443
3444 if (testCase.isCameraAvailable(cameraId)) {
3445 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3446 goto cleanup;
3447 }
3448
3449 ImageReaderListener readerListener;
3450 AImageReader_ImageListener readerCb { &readerListener, cb };
3451 readerListener.setDumpFilePathBase(outPath);
3452
3453 int32_t testWidth, testHeight;
3454 switch (format) {
3455 case AIMAGE_FORMAT_JPEG:
3456 case AIMAGE_FORMAT_Y8:
3457 case AIMAGE_FORMAT_HEIC:
3458 case AIMAGE_FORMAT_DEPTH_JPEG:
3459 if (!staticInfo.getMaxSizeForFormat(format, &testWidth, &testHeight)) {
3460 // No corresponding format support, skip this device.
3461 ACameraMetadata_free(chars);
3462 chars = nullptr;
3463 ret = testCase.closeCamera();
3464 if (ret != ACAMERA_OK) {
3465 LOG_ERROR(errorString, "Camera %s failed to close. ret %d ", cameraId, ret);
3466 goto cleanup;
3467 }
3468
3469 continue;
3470 }
3471 break;
3472 default:
3473 LOG_ERROR(errorString, "Testcase doesn't yet support format %d", format);
3474 goto cleanup;
3475 }
3476 mediaRet = testCase.initImageReaderWithErrorLog(
3477 testWidth, testHeight, format, NUM_TEST_IMAGES,
3478 &readerCb);
3479 if (mediaRet != AMEDIA_OK) {
3480 // Don't log error here. testcase did it
3481 goto cleanup;
3482 }
3483
3484 ret = testCase.createCaptureSessionWithLog();
3485 if (ret != ACAMERA_OK) {
3486 // Don't log error here. testcase did it
3487 goto cleanup;
3488 }
3489
3490 ret = testCase.createRequestsWithErrorLog();
3491 if (ret != ACAMERA_OK) {
3492 // Don't log error here. testcase did it
3493 goto cleanup;
3494 }
3495
3496 CaptureResultListener resultListener;
3497 ACameraCaptureSession_captureCallbacks resultCb {
3498 &resultListener,
3499 CaptureResultListener::onCaptureStart,
3500 CaptureResultListener::onCaptureProgressed,
3501 CaptureResultListener::onCaptureCompleted,
3502 CaptureResultListener::onCaptureFailed,
3503 CaptureResultListener::onCaptureSequenceCompleted,
3504 CaptureResultListener::onCaptureSequenceAborted,
3505 CaptureResultListener::onCaptureBufferLost
3506 };
3507 resultListener.setRequestSave(true);
3508 ACaptureRequest* requestTemplate = nullptr;
3509 ret = testCase.getStillRequest(&requestTemplate);
3510 if (ret != ACAMERA_OK || requestTemplate == nullptr) {
3511 // Don't log error here. testcase did it
3512 goto cleanup;
3513 }
3514
3515 // Do some still capture
3516 int lastSeqId = -1;
3517 for (intptr_t capture = 0; capture < NUM_TEST_IMAGES; capture++) {
3518 ACaptureRequest* req = ACaptureRequest_copy(requestTemplate);
3519 ACaptureRequest_setUserContext(req, (void*) capture);
3520 int seqId;
3521 ret = testCase.capture(req, &resultCb, &seqId);
3522 if (ret != ACAMERA_OK) {
3523 LOG_ERROR(errorString, "Camera %s capture(%" PRIdPTR ") failed. ret %d",
3524 cameraId, capture, ret);
3525 goto cleanup;
3526 }
3527 if (capture == NUM_TEST_IMAGES - 1) {
3528 lastSeqId = seqId;
3529 }
3530 ACaptureRequest_free(req);
3531 }
3532
3533 // wait until last sequence complete
3534 resultListener.getCaptureSequenceLastFrameNumber(lastSeqId, /*timeoutSec*/ 5);
3535
3536 std::vector<ACaptureRequest*> completedRequests;
3537 resultListener.getCompletedRequests(&completedRequests);
3538
3539 if (completedRequests.size() != NUM_TEST_IMAGES) {
3540 LOG_ERROR(errorString, "Camera %s fails to capture %d capture results. Got %zu",
3541 cameraId, NUM_TEST_IMAGES, completedRequests.size());
3542 goto cleanup;
3543 }
3544
3545 for (intptr_t i = 0; i < NUM_TEST_IMAGES; i++) {
3546 intptr_t userContext = -1;
3547 ret = ACaptureRequest_getUserContext(completedRequests[i], (void**) &userContext);
3548 if (ret != ACAMERA_OK) {
3549 LOG_ERROR(errorString, "Camera %s fails to get request user context", cameraId);
3550 goto cleanup;
3551 }
3552
3553 if (userContext != i) {
3554 LOG_ERROR(errorString, "Camera %s fails to return matching user context. "
3555 "Expect %" PRIdPTR ", got %" PRIdPTR, cameraId, i, userContext);
3556 goto cleanup;
3557 }
3558 }
3559
3560 int64_t minFrameDurationNs = staticInfo.getMinFrameDurationFor(
3561 format, testWidth, testHeight);
3562 if (minFrameDurationNs < 0) {
3563 LOG_ERROR(errorString, "Get camera %s minFrameDuration failed", cameraId);
3564 goto cleanup;
3565 }
3566 int64_t stallDurationNs = (format == AIMAGE_FORMAT_Y8) ? 0 :
3567 staticInfo.getStallDurationFor(format, testWidth, testHeight);
3568 if (stallDurationNs < 0) {
3569 LOG_ERROR(errorString, "Get camera %s stallDuration failed", cameraId);
3570 goto cleanup;
3571 }
3572
3573 int64_t expectedDurationNs = (minFrameDurationNs + stallDurationNs) * NUM_TEST_IMAGES;
3574 constexpr int64_t waitPerIterationUs = 100000;
3575 constexpr int64_t usToNs = 1000;
3576 int totalWaitIteration = 50;
3577
3578 // Allow 1.5x margin
3579 if (expectedDurationNs * 3 / 2 > totalWaitIteration * waitPerIterationUs * usToNs) {
3580 totalWaitIteration = expectedDurationNs * 3 / 2 / waitPerIterationUs / usToNs;
3581 }
3582
3583 // wait until all capture finished
3584 for (int i = 0; i < totalWaitIteration; i++) {
3585 usleep(waitPerIterationUs);
3586 if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
3587 ALOGI("Session take ~%d ms to capture %d images",
3588 i*100, NUM_TEST_IMAGES);
3589 break;
3590 }
3591 }
3592
3593 if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
3594 LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
3595 cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
3596 goto cleanup;
3597 }
3598
3599 ret = testCase.resetWithErrorLog();
3600 if (ret != ACAMERA_OK) {
3601 // Don't log error here. testcase did it
3602 goto cleanup;
3603 }
3604
3605 usleep(200000); // sleep to give some time for callbacks to happen
3606
3607 if (!testCase.isCameraAvailable(cameraId)) {
3608 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3609 goto cleanup;
3610 }
3611 }
3612
3613 ret = testCase.deInit();
3614 if (ret != ACAMERA_OK) {
3615 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3616 goto cleanup;
3617 }
3618
3619 pass = true;
3620
3621 cleanup:
3622 if (outPath != nullptr) {
3623 env->ReleaseStringUTFChars(jOutPath, outPath);
3624 }
3625
3626 if (chars != nullptr) {
3627 ACameraMetadata_free(chars);
3628 chars = nullptr;
3629 }
3630
3631 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3632 if (!pass) {
3633 throwAssertionError(env, errorString);
3634 }
3635 return pass;
3636 }
3637
3638 // Test the camera NDK capture failure path by acquiring the maximum amount of
3639 // ImageReader buffers available. Since there is no circulation of camera
3640 // images, the registered output surface will eventually run out of free buffers
3641 // and start reporting capture errors or lost buffers.
3642 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceCaptureFailureNative(JNIEnv * env,jclass,jstring jOverrideCameraId)3643 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3644 testCameraDeviceCaptureFailureNative(JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
3645 const size_t NUM_TEST_IMAGES = 10;
3646 const size_t NUM_FAILED_FRAMES = 3; // Wait for at least 3 consecutive failed capture requests
3647 const int64_t NUM_TOTAL_FRAMES = 60; // Avoid waiting for more than 60 frames
3648 const size_t TEST_WIDTH = 640;
3649 const size_t TEST_HEIGHT = 480;
3650 media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3651 int numCameras = 0;
3652 bool pass = false;
3653 PreviewTestCase testCase;
3654 uint32_t bufferTimeoutSec = 1;
3655 uint32_t timeoutSec = 10; // It is important to keep this timeout bigger than the framework
3656 // timeout
3657
3658 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
3659 if (ret != ACAMERA_OK) {
3660 // Don't log error here. testcase did it
3661 goto exit;
3662 }
3663
3664 numCameras = testCase.getNumCameras();
3665 if (numCameras < 0) {
3666 LOG_ERROR(errorString, "Testcase returned negative number of cameras: %d", numCameras);
3667 goto exit;
3668 }
3669
3670 for (int i = 0; i < numCameras; i++) {
3671 const char* cameraId = testCase.getCameraId(i);
3672 if (cameraId == nullptr) {
3673 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3674 goto exit;
3675 }
3676
3677 std::unique_ptr<ACameraMetadata> chars(testCase.getCameraChars(i));
3678 if (chars.get() == nullptr) {
3679 LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3680 goto exit;
3681 }
3682 StaticInfo staticInfo(chars.get());
3683
3684 if (!staticInfo.isColorOutputSupported()) {
3685 continue;
3686 }
3687
3688 ret = testCase.openCamera(cameraId);
3689 if (ret != ACAMERA_OK) {
3690 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3691 goto exit;
3692 }
3693
3694 usleep(100000); // sleep to give some time for callbacks to happen
3695
3696 if (testCase.isCameraAvailable(cameraId)) {
3697 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3698 goto exit;
3699 }
3700
3701 ImageReaderListener readerListener;
3702 AImageReader_ImageListener readerCb =
3703 { &readerListener, ImageReaderListener::signalImageCb };
3704 mediaRet = testCase.initImageReaderWithErrorLog(TEST_WIDTH, TEST_HEIGHT,
3705 AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES, &readerCb);
3706 if (mediaRet != AMEDIA_OK) {
3707 // Don't log error here. testcase did it
3708 goto exit;
3709 }
3710
3711 ret = testCase.createCaptureSessionWithLog();
3712 if (ret != ACAMERA_OK) {
3713 // Don't log error here. testcase did it
3714 goto exit;
3715 }
3716
3717 ret = testCase.createRequestsWithErrorLog();
3718 if (ret != ACAMERA_OK) {
3719 // Don't log error here. testcase did it
3720 goto exit;
3721 }
3722
3723 CaptureResultListener resultListener;
3724 ACameraCaptureSession_captureCallbacks resultCb {
3725 &resultListener,
3726 CaptureResultListener::onCaptureStart,
3727 CaptureResultListener::onCaptureProgressed,
3728 CaptureResultListener::onCaptureCompleted,
3729 CaptureResultListener::onCaptureFailed,
3730 CaptureResultListener::onCaptureSequenceCompleted,
3731 CaptureResultListener::onCaptureSequenceAborted,
3732 CaptureResultListener::onCaptureBufferLost
3733 };
3734 ACaptureRequest* requestTemplate = nullptr;
3735 ret = testCase.getStillRequest(&requestTemplate);
3736 if (ret != ACAMERA_OK || requestTemplate == nullptr) {
3737 // Don't log error here. testcase did it
3738 goto exit;
3739 }
3740
3741 int seqId;
3742 ret = testCase.startRepeatingRequest(&seqId, requestTemplate, &resultCb);
3743 if (ret != ACAMERA_OK) {
3744 // Don't log error here. testcase did it
3745 goto exit;
3746 }
3747
3748 size_t failedRequestCount;
3749 int64_t lastFrameNumber;
3750 int64_t lastFailedRequestNumber = -1;
3751 failedRequestCount = lastFrameNumber = 0;
3752 while ((failedRequestCount < NUM_FAILED_FRAMES) && (lastFrameNumber < NUM_TOTAL_FRAMES)) {
3753 auto frameArrived = resultListener.waitForFrameNumber(lastFrameNumber, timeoutSec);
3754 if (!frameArrived) {
3755 LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
3756 cameraId);
3757 goto exit;
3758 }
3759 readerListener.waitForNextBuffer(bufferTimeoutSec);
3760 auto failedFrameNumber = resultListener.checkForFailureOrLoss(lastFrameNumber) ?
3761 lastFrameNumber : -1;
3762 if (lastFailedRequestNumber != failedFrameNumber) {
3763 if ((lastFailedRequestNumber + 1) == failedFrameNumber) {
3764 failedRequestCount++;
3765 } else {
3766 failedRequestCount = 1;
3767 }
3768 lastFailedRequestNumber = failedFrameNumber;
3769 }
3770 lastFrameNumber++;
3771 }
3772
3773 ret = testCase.stopPreview();
3774 if (ret != ACAMERA_OK) {
3775 LOG_ERROR(errorString, "stopPreview failed!");
3776 goto exit;
3777 }
3778
3779 ret = testCase.resetWithErrorLog();
3780 if (ret != ACAMERA_OK) {
3781 // Don't log error here. testcase did it
3782 goto exit;
3783 }
3784
3785 usleep(100000); // sleep to give some time for callbacks to happen
3786
3787 if (!testCase.isCameraAvailable(cameraId)) {
3788 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3789 goto exit;
3790 }
3791
3792 if (failedRequestCount < NUM_FAILED_FRAMES) {
3793 LOG_ERROR(errorString, "Unable to receive %zu consecutive capture failures within"
3794 " %" PRId64 " capture requests", NUM_FAILED_FRAMES, NUM_TOTAL_FRAMES);
3795 goto exit;
3796 }
3797 }
3798
3799 ret = testCase.deInit();
3800 if (ret != ACAMERA_OK) {
3801 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3802 goto exit;
3803 }
3804
3805 pass = true;
3806
3807 exit:
3808
3809 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3810 if (!pass) {
3811 throwAssertionError(env, errorString);
3812 }
3813
3814 return pass;
3815 }
3816
3817 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testJpegNative(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)3818 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3819 testJpegNative(
3820 JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
3821 jstring jOverrideCameraId) {
3822 ALOGV("%s", __FUNCTION__);
3823 return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_JPEG,
3824 ImageReaderListener::validateImageCb, jOverrideCameraId);
3825 }
3826
3827 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testY8Native(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)3828 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3829 testY8Native(
3830 JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
3831 jstring jOverrideCameraId) {
3832 ALOGV("%s", __FUNCTION__);
3833 return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_Y8,
3834 ImageReaderListener::validateImageCb, jOverrideCameraId);
3835 }
3836
3837 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testHeicNative(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)3838 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3839 testHeicNative(
3840 JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
3841 jstring jOverrideCameraId) {
3842 ALOGV("%s", __FUNCTION__);
3843 return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_HEIC,
3844 ImageReaderListener::validateImageCb, jOverrideCameraId);
3845 }
3846
3847 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testDepthJpegNative(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)3848 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3849 testDepthJpegNative(
3850 JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
3851 jstring jOverrideCameraId) {
3852 ALOGV("%s", __FUNCTION__);
3853 return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_DEPTH_JPEG,
3854 ImageReaderListener::validateImageCb, jOverrideCameraId);
3855 }
3856
3857 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testImageReaderCloseAcquiredImagesNative(JNIEnv * env,jclass,jstring jOverrideCameraId)3858 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3859 testImageReaderCloseAcquiredImagesNative(
3860 JNIEnv* env, jclass /*clazz*/,
3861 jstring jOverrideCameraId) {
3862 ALOGV("%s", __FUNCTION__);
3863 return nativeImageReaderTestBase(env, nullptr, AIMAGE_FORMAT_JPEG,
3864 ImageReaderListener::acquireImageCb, jOverrideCameraId);
3865 }
3866
3867 template <>
3868 struct std::default_delete<ACameraManager> {
operator ()std::default_delete3869 inline void operator()(ACameraManager* manager) const { ACameraManager_delete(manager); }
3870 };
3871
3872 class AvailabilityContext {
3873 public:
3874 AvailabilityContext();
3875 ~AvailabilityContext();
3876
3877 camera_status_t initialize();
3878 int getAcessCallbackCountAndReset();
3879
3880 private:
3881 std::unique_ptr<ACameraManager> mCameraManager;
3882 std::unique_ptr<CameraServiceListener> mServiceListener;
3883 std::unique_ptr<ACameraManager_ExtendedAvailabilityCallbacks> mServiceCb;
3884 };
3885
AvailabilityContext()3886 AvailabilityContext::AvailabilityContext() :
3887 mCameraManager(ACameraManager_create()),
3888 mServiceListener(std::make_unique<CameraServiceListener>()),
3889 mServiceCb(std::make_unique<ACameraManager_ExtendedAvailabilityCallbacks>()) {
3890 mServiceCb->availabilityCallbacks.context = mServiceListener.get();
3891 mServiceCb->availabilityCallbacks.onCameraAvailable = CameraServiceListener::onAvailable;
3892 mServiceCb->availabilityCallbacks.onCameraUnavailable =
3893 CameraServiceListener::onUnavailable;
3894 mServiceCb->onCameraAccessPrioritiesChanged =
3895 CameraServiceListener::onCameraAccessPrioritiesChanged;
3896 mServiceCb->onPhysicalCameraAvailable =
3897 CameraServiceListener::onPhysicalCameraAvailable;
3898 mServiceCb->onPhysicalCameraUnavailable =
3899 CameraServiceListener::onPhysicalCameraUnavailable;
3900 }
3901
initialize()3902 camera_status_t AvailabilityContext::initialize() {
3903 auto rc = ACameraManager_registerExtendedAvailabilityCallback(mCameraManager.get(),
3904 mServiceCb.get());
3905 if (rc != ACAMERA_OK) {
3906 LOG_ERROR(errorString, "Register availability callback failed: rc %d", rc);
3907 return rc;
3908 }
3909
3910 ACameraIdList* cameraIdList = nullptr;
3911 rc = ACameraManager_getCameraIdList(mCameraManager.get(), &cameraIdList);
3912 if (rc != ACAMERA_OK) {
3913 LOG_ERROR(errorString, "Get camera id list failed: ret %d", rc);
3914 return rc;
3915 }
3916 ACameraManager_deleteCameraIdList(cameraIdList);
3917
3918 return rc;
3919 }
3920
getAcessCallbackCountAndReset()3921 int AvailabilityContext::getAcessCallbackCountAndReset() {
3922 auto ret = mServiceListener->getCameraAccessPrioritiesChangedCount();
3923 mServiceListener->resetCount();
3924 return ret;
3925 }
3926
~AvailabilityContext()3927 AvailabilityContext::~AvailabilityContext() {
3928 if (mServiceCb != nullptr) {
3929 camera_status_t ret = ACameraManager_unregisterExtendedAvailabilityCallback(
3930 mCameraManager.get(), mServiceCb.get());
3931 if (ret != ACAMERA_OK) {
3932 ALOGE("Unregister availability callback failed: ret %d", ret);
3933 }
3934 }
3935 }
3936
3937 extern "C" jlong
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_initializeAvailabilityCallbacksNative(JNIEnv * env,jclass)3938 Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
3939 initializeAvailabilityCallbacksNative(
3940 JNIEnv* env, jclass /*clazz*/) {
3941 ALOGV("%s", __FUNCTION__);
3942
3943 AvailabilityContext *ctx = new AvailabilityContext();
3944
3945 auto rc = ctx->initialize();
3946 if (rc != ACAMERA_OK) {
3947 LOG_ERROR(errorString, "Availability context initialization failed: %d", rc);
3948 return 0;
3949 }
3950
3951 return (jlong) ctx;
3952 }
3953
3954 extern "C" jint
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_getAccessCallbacksCountAndResetNative(JNIEnv * env,jclass,jlong context)3955 Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
3956 getAccessCallbacksCountAndResetNative(
3957 JNIEnv* env, jclass /*clazz*/, jlong context) {
3958 ALOGV("%s", __FUNCTION__);
3959
3960 if (context == 0) {
3961 LOG_ERROR(errorString, "Invalid availability context");
3962 return 0;
3963 }
3964
3965 AvailabilityContext* ctx = reinterpret_cast<AvailabilityContext*>(context);
3966 return ctx->getAcessCallbackCountAndReset();
3967 }
3968
3969 extern "C" void
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_releaseAvailabilityCallbacksNative(JNIEnv * env,jclass,jlong context)3970 Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
3971 releaseAvailabilityCallbacksNative(
3972 JNIEnv* env, jclass /*clazz*/, jlong context) {
3973 ALOGV("%s", __FUNCTION__);
3974
3975 if (context == 0) {
3976 return;
3977 }
3978
3979 AvailabilityContext* ctx = reinterpret_cast<AvailabilityContext*>(context);
3980 delete ctx;
3981 }
3982
3983 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeStillCaptureTest_testStillCaptureNative(JNIEnv * env,jclass,jstring jOutPath,jobject jPreviewSurface,jstring jOverrideCameraId)3984 Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
3985 testStillCaptureNative(
3986 JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface,
3987 jstring jOverrideCameraId) {
3988 ALOGV("%s", __FUNCTION__);
3989 const int NUM_TEST_IMAGES = 10;
3990 media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3991 int numCameras = 0;
3992 bool pass = false;
3993 PreviewTestCase testCase;
3994 ACameraMetadata* chars = nullptr;
3995
3996 const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
3997 ALOGI("%s: out path is %s", __FUNCTION__, outPath);
3998
3999 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
4000 if (ret != ACAMERA_OK) {
4001 // Don't log error here. testcase did it
4002 goto cleanup;
4003 }
4004
4005 numCameras = testCase.getNumCameras();
4006 if (numCameras < 0) {
4007 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
4008 goto cleanup;
4009 }
4010
4011 for (int i = 0; i < numCameras; i++) {
4012 const char* cameraId = testCase.getCameraId(i);
4013 if (cameraId == nullptr) {
4014 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
4015 goto cleanup;
4016 }
4017
4018 {
4019 ACameraMetadata* chars = testCase.getCameraChars(cameraId);
4020 StaticInfo staticInfo(chars);
4021 if (!staticInfo.isColorOutputSupported()) {
4022 ALOGI("%s: camera %s does not support color output. skipping",
4023 __FUNCTION__, cameraId);
4024 ACameraMetadata_free(chars);
4025 continue;
4026 }
4027 ACameraMetadata_free(chars);
4028 }
4029
4030 ret = testCase.openCamera(cameraId);
4031 if (ret != ACAMERA_OK) {
4032 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
4033 goto cleanup;
4034 }
4035
4036 chars = testCase.getCameraChars(i);
4037 if (chars == nullptr) {
4038 LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
4039 goto cleanup;
4040 }
4041 StaticInfo staticInfo(chars);
4042
4043 usleep(100000); // sleep to give some time for callbacks to happen
4044
4045 if (testCase.isCameraAvailable(cameraId)) {
4046 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
4047 goto cleanup;
4048 }
4049
4050 ImageReaderListener readerListener;
4051 AImageReader_ImageListener readerCb {
4052 &readerListener,
4053 ImageReaderListener::validateImageCb
4054 };
4055 readerListener.setDumpFilePathBase(outPath);
4056 int32_t testWidth, testHeight;
4057 if (!staticInfo.getMaxSizeForFormat(AIMAGE_FORMAT_JPEG, &testWidth, &testHeight)) {
4058 goto cleanup;
4059 }
4060 mediaRet = testCase.initImageReaderWithErrorLog(
4061 testWidth, testHeight, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES,
4062 &readerCb);
4063 if (mediaRet != AMEDIA_OK) {
4064 // Don't log error here. testcase did it
4065 goto cleanup;
4066 }
4067
4068 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
4069 if (previewAnw == nullptr) {
4070 LOG_ERROR(errorString, "Null ANW from preview surface!");
4071 goto cleanup;
4072 }
4073
4074 ret = testCase.createCaptureSessionWithLog();
4075 if (ret != ACAMERA_OK) {
4076 // Don't log error here. testcase did it
4077 goto cleanup;
4078 }
4079
4080 ret = testCase.createRequestsWithErrorLog();
4081 if (ret != ACAMERA_OK) {
4082 // Don't log error here. testcase did it
4083 goto cleanup;
4084 }
4085
4086 ret = testCase.startPreview();
4087 if (ret != ACAMERA_OK) {
4088 LOG_ERROR(errorString, "Start preview failed!");
4089 goto cleanup;
4090 }
4091
4092 // Let preview run some time
4093 sleep(3);
4094
4095 // Do some still capture
4096 for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
4097 ret = testCase.takePicture();
4098 if (ret != ACAMERA_OK) {
4099 LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
4100 cameraId, capture, ret);
4101 goto cleanup;
4102 }
4103 }
4104
4105 int64_t minFrameDurationNs = staticInfo.getMinFrameDurationFor(
4106 AIMAGE_FORMAT_JPEG, testWidth, testHeight);
4107 if (minFrameDurationNs < 0) {
4108 LOG_ERROR(errorString, "Get camera %s minFrameDuration failed", cameraId);
4109 goto cleanup;
4110 }
4111 int64_t stallDurationNs = staticInfo.getStallDurationFor(
4112 AIMAGE_FORMAT_JPEG, testWidth, testHeight);
4113 if (stallDurationNs < 0) {
4114 LOG_ERROR(errorString, "Get camera %s stallDuration failed", cameraId);
4115 goto cleanup;
4116 }
4117
4118 int64_t expectedDurationNs = (minFrameDurationNs + stallDurationNs) * NUM_TEST_IMAGES;
4119 constexpr int64_t waitPerIterationUs = 100000;
4120 constexpr int64_t usToNs = 1000;
4121 int totalWaitIteration = 50;
4122
4123 // Allow 1.5x margin
4124 if (expectedDurationNs * 3 / 2 > totalWaitIteration * waitPerIterationUs * usToNs) {
4125 totalWaitIteration = expectedDurationNs * 3 / 2 / waitPerIterationUs / usToNs;
4126 }
4127
4128 // wait until all capture finished
4129 for (int i = 0; i < totalWaitIteration; i++) {
4130 usleep(waitPerIterationUs);
4131 if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
4132 ALOGI("Session take ~%d ms to capture %d images",
4133 i*100, NUM_TEST_IMAGES);
4134 break;
4135 }
4136 }
4137
4138 if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
4139 LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
4140 cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
4141 goto cleanup;
4142 }
4143
4144 ret = testCase.resetWithErrorLog();
4145 if (ret != ACAMERA_OK) {
4146 // Don't log error here. testcase did it
4147 goto cleanup;
4148 }
4149
4150 usleep(100000); // sleep to give some time for callbacks to happen
4151
4152 if (!testCase.isCameraAvailable(cameraId)) {
4153 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
4154 goto cleanup;
4155 }
4156 }
4157
4158 ret = testCase.deInit();
4159 if (ret != ACAMERA_OK) {
4160 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
4161 goto cleanup;
4162 }
4163
4164 pass = true;
4165 cleanup:
4166 env->ReleaseStringUTFChars(jOutPath, outPath);
4167
4168 if (chars != nullptr) {
4169 ACameraMetadata_free(chars);
4170 chars = nullptr;
4171 }
4172
4173 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
4174 if (!pass) {
4175 throwAssertionError(env, errorString);
4176 }
4177 return pass;
4178 }
4179
4180 extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_validateACameraMetadataFromCameraMetadataCriticalTagsNative(JNIEnv * env,jclass,jobject captureResult,jlong javaTimestamp)4181 Java_android_hardware_camera2_cts_CaptureResultTest_\
4182 validateACameraMetadataFromCameraMetadataCriticalTagsNative(
4183 JNIEnv* env, jclass /*clazz*/, jobject captureResult,
4184 jlong javaTimestamp) {
4185 ALOGV("%s", __FUNCTION__);
4186 ACameraMetadata* ndkResult =
4187 ACameraMetadata_fromCameraMetadata(env, captureResult);
4188 if (!ndkResult) {
4189 ALOGE("validateCriticalTags failed: "
4190 "ACameraMetadata_fromCameraMetadata returned nullptr.");
4191 return false;
4192 }
4193
4194 camera_status_t ret;
4195 ACameraMetadata_const_entry entry;
4196
4197 ret = ACameraMetadata_getConstEntry(ndkResult, ACAMERA_SENSOR_TIMESTAMP,
4198 &entry);
4199
4200 if (ret != ACAMERA_OK) {
4201 ALOGE("validateCriticalTags failed: "
4202 "ACameraMetadata_getConstEntry returned %d.", ret);
4203 ACameraMetadata_free(ndkResult);
4204 return false;
4205 }
4206 if (entry.type != ACAMERA_TYPE_INT64) {
4207 ALOGE("validateCriticalTags failed: entry.type is %u but should be %u.",
4208 entry.type, ACAMERA_TYPE_INT64);
4209 ACameraMetadata_free(ndkResult);
4210 return false;
4211 }
4212 if (entry.count != 1) {
4213 ALOGE("validateCriticalTags failed: entry.count is %u but should be %u.",
4214 entry.count, 1);
4215 ACameraMetadata_free(ndkResult);
4216 return false;
4217 }
4218 if (entry.data.i64 == nullptr) {
4219 ALOGE("validateCriticalTags failed: entry.data.i64 is nullptr.");
4220 ACameraMetadata_free(ndkResult);
4221 return false;
4222 }
4223
4224 const int64_t javaTimestampI64 = static_cast<int64_t>(javaTimestamp);
4225 const int64_t ndkTimestampI64 = *(entry.data.i64);
4226 ALOGV("javaTimestampI64 = %" PRId64 ", ndkTimestampI64 = %" PRId64,
4227 javaTimestampI64, ndkTimestampI64);
4228
4229 ACameraMetadata_free(ndkResult);
4230
4231 return (javaTimestampI64 == ndkTimestampI64);
4232 }
4233
4234 static ACameraMetadata *sStashedMetadata = nullptr;
4235
4236 // Test holding on to a ACameraMetadata past a single local JNI call
4237 extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_stashACameraMetadataFromCameraMetadataNative(JNIEnv * env,jclass,jobject captureResult)4238 Java_android_hardware_camera2_cts_CaptureResultTest_\
4239 stashACameraMetadataFromCameraMetadataNative(
4240 JNIEnv* env, jclass /*clazz*/, jobject captureResult) {
4241 ALOGV("%s", __FUNCTION__);
4242 ACameraMetadata* ndkResult =
4243 ACameraMetadata_fromCameraMetadata(env, captureResult);
4244 if (ndkResult == nullptr) return false;
4245 sStashedMetadata = ndkResult;
4246
4247 return true;
4248 }
4249
4250 extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_validateStashedACameraMetadataFromCameraMetadataNative(JNIEnv * env,jclass,jlong timestamp)4251 Java_android_hardware_camera2_cts_CaptureResultTest_\
4252 validateStashedACameraMetadataFromCameraMetadataNative(
4253 JNIEnv* env, jclass /*clazz*/, jlong timestamp) {
4254 ALOGV("%s", __FUNCTION__);
4255 if (sStashedMetadata == nullptr) return false;
4256
4257 camera_status_t ret;
4258 ACameraMetadata_const_entry entry;
4259
4260 ret = ACameraMetadata_getConstEntry(sStashedMetadata, ACAMERA_SENSOR_TIMESTAMP,
4261 &entry);
4262
4263 if (ret != ACAMERA_OK) {
4264 ALOGE("validateStashed failed: "
4265 "ACameraMetadata_getConstEntry returned %d.", ret);
4266 ACameraMetadata_free(sStashedMetadata);
4267 sStashedMetadata = nullptr;
4268 return false;
4269 }
4270 if (entry.type != ACAMERA_TYPE_INT64) {
4271 ALOGE("validateStashed failed: entry.type is %u but should be %u.",
4272 entry.type, ACAMERA_TYPE_INT64);
4273 ACameraMetadata_free(sStashedMetadata);
4274 sStashedMetadata = nullptr;
4275 return false;
4276 }
4277 if (entry.count != 1) {
4278 ALOGE("validateStashed failed: entry.count is %u but should be %u.",
4279 entry.count, 1);
4280 ACameraMetadata_free(sStashedMetadata);
4281 sStashedMetadata = nullptr;
4282 return false;
4283 }
4284 if (entry.data.i64 == nullptr) {
4285 ALOGE("validateStashed failed: entry.data.i64 is nullptr.");
4286 ACameraMetadata_free(sStashedMetadata);
4287 sStashedMetadata = nullptr;
4288 return false;
4289 }
4290
4291 const int64_t javaTimestampI64 = static_cast<int64_t>(timestamp);
4292 const int64_t ndkTimestampI64 = *(entry.data.i64);
4293
4294 ACameraMetadata_free(sStashedMetadata);
4295 sStashedMetadata = nullptr;
4296 ALOGV("javaTimestampI64 = %" PRId64 ", ndkTimestampI64 = %" PRId64,
4297 javaTimestampI64, ndkTimestampI64);
4298 return (javaTimestampI64 == ndkTimestampI64);
4299
4300 }
4301
4302
4303
4304 extern "C" jboolean
Java_android_hardware_camera2_cts_CameraManagerTest_validateACameraMetadataFromCameraMetadataCriticalTagsNative(JNIEnv * env,jclass,jobject cameraCharacteristics,jint javaLensFacing)4305 Java_android_hardware_camera2_cts_CameraManagerTest_\
4306 validateACameraMetadataFromCameraMetadataCriticalTagsNative(
4307 JNIEnv* env, jclass /*clazz*/, jobject cameraCharacteristics,
4308 jint javaLensFacing) {
4309 ALOGV("%s", __FUNCTION__);
4310 ACameraMetadata* ndkCharacteristics =
4311 ACameraMetadata_fromCameraMetadata(env, cameraCharacteristics);
4312 if (!ndkCharacteristics) {
4313 ALOGE("validateCriticalTags failed: "
4314 "ACameraMetadata_fromCameraMetadata returned nullptr.");
4315 return false;
4316 }
4317
4318 camera_status_t ret;
4319 ACameraMetadata_const_entry entry;
4320
4321 ret = ACameraMetadata_getConstEntry(ndkCharacteristics,
4322 ACAMERA_LENS_FACING, &entry);
4323 ACameraMetadata_free(ndkCharacteristics);
4324
4325 if (ret != ACAMERA_OK) {
4326 ALOGE("validateCriticalTags failed: "
4327 "ACameraMetadata_getConstEntry returned %d", ret);
4328 return false;
4329 }
4330 if (entry.type != ACAMERA_TYPE_BYTE) {
4331 ALOGE("validateCriticalTags failed: entry.type is %u but should be %u.",
4332 entry.type, ACAMERA_TYPE_BYTE);
4333 return false;
4334 }
4335 if (entry.count != 1) {
4336 ALOGE("validateCriticalTags failed: entry.count is %u but should be %u.",
4337 entry.count, 1);
4338 return false;
4339 }
4340 if (entry.data.u8 == nullptr) {
4341 ALOGE("validateCriticalTags failed: entry.data.u8 is nullptr.");
4342 return false;
4343 }
4344
4345 const uint8_t javaLensFacingU8 = static_cast<uint8_t>(javaLensFacing);
4346 const uint8_t ndkLensFacingU8 = *(entry.data.u8);
4347 ALOGV("javaLensFacingU8 = %d, ndkLensFacingU8 = %d",
4348 javaLensFacingU8, ndkLensFacingU8);
4349 return (javaLensFacingU8 == ndkLensFacingU8);
4350 }
4351