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
abortCaptures()1561 camera_status_t abortCaptures() {
1562 if (mSession == nullptr) {
1563 ALOGE("Testcase cannot abort session %p", mSession);
1564 return ACAMERA_ERROR_UNKNOWN;
1565 }
1566 return ACameraCaptureSession_abortCaptures(mSession);
1567 }
1568
updateRepeatingRequest(ACaptureRequest * updatedRequest,int * sequenceId=nullptr)1569 camera_status_t updateRepeatingRequest(ACaptureRequest *updatedRequest,
1570 int *sequenceId = nullptr) {
1571 if (mSession == nullptr || updatedRequest == nullptr) {
1572 ALOGE("Testcase cannot update repeating request: session %p, updated request %p",
1573 mSession, updatedRequest);
1574 return ACAMERA_ERROR_UNKNOWN;
1575 }
1576
1577 int previewSeqId;
1578 camera_status_t ret;
1579 if (sequenceId == nullptr) {
1580 ret = ACameraCaptureSession_setRepeatingRequest(
1581 mSession, nullptr, 1, &updatedRequest, &previewSeqId);
1582 } else {
1583 ret = ACameraCaptureSession_setRepeatingRequest(
1584 mSession, &mResultCb, 1, &updatedRequest, sequenceId);
1585 }
1586 return ret;
1587 }
1588
getCaptureSequenceLastFrameNumber(int64_t sequenceId,uint32_t timeoutSec)1589 int64_t getCaptureSequenceLastFrameNumber(int64_t sequenceId, uint32_t timeoutSec) {
1590 return mResultListener.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
1591 }
1592
waitForFrameNumber(int64_t frameNumber,uint32_t timeoutSec)1593 bool waitForFrameNumber(int64_t frameNumber, uint32_t timeoutSec) {
1594 return mResultListener.waitForFrameNumber(frameNumber, timeoutSec);
1595 }
1596
takePicture()1597 camera_status_t takePicture() {
1598 if (mSession == nullptr || mStillRequest == nullptr) {
1599 ALOGE("Testcase cannot take picture: session %p, still request %p",
1600 mSession, mStillRequest);
1601 return ACAMERA_ERROR_UNKNOWN;
1602 }
1603 int seqId;
1604 return ACameraCaptureSession_capture(
1605 mSession, nullptr, 1, &mStillRequest, &seqId);
1606 }
1607
capture(ACaptureRequest * request,ACameraCaptureSession_captureCallbacks * listener,int * seqId)1608 camera_status_t capture(ACaptureRequest* request,
1609 ACameraCaptureSession_captureCallbacks* listener,
1610 /*out*/int* seqId) {
1611 if (mSession == nullptr || request == nullptr) {
1612 ALOGE("Testcase cannot capture session: session %p, request %p",
1613 mSession, request);
1614 return ACAMERA_ERROR_UNKNOWN;
1615 }
1616 return ACameraCaptureSession_capture(
1617 mSession, listener, 1, &request, seqId);
1618 }
1619
resetWithErrorLog()1620 camera_status_t resetWithErrorLog() {
1621 camera_status_t ret;
1622
1623 closeSession();
1624
1625 for (int i = 0; i < 50; i++) {
1626 usleep(100000); // sleep 100ms
1627 if (mSessionListener.isClosed()) {
1628 ALOGI("Session take ~%d ms to close", i*100);
1629 break;
1630 }
1631 }
1632
1633 if (!mSessionListener.isClosed() || mSessionListener.onClosedCount() != 1) {
1634 LOG_ERROR(errorString,
1635 "Session for camera %s close error. isClosde %d close count %d",
1636 mCameraId, mSessionListener.isClosed(), mSessionListener.onClosedCount());
1637 return ACAMERA_ERROR_UNKNOWN;
1638 }
1639 mSessionListener.reset();
1640 mResultListener.reset();
1641
1642 ret = closeCamera();
1643 if (ret != ACAMERA_OK) {
1644 LOG_ERROR(errorString, "Close camera device %s failure. ret %d", mCameraId, ret);
1645 return ret;
1646 }
1647
1648 resetCamera();
1649 return ACAMERA_OK;
1650 }
1651
getSessionListener()1652 CaptureSessionListener* getSessionListener() {
1653 return &mSessionListener;
1654 }
1655
getCameraDevice()1656 ACameraDevice* getCameraDevice() {
1657 return mDevice;
1658 }
1659
getPreviewOutput()1660 ACaptureSessionOutput *getPreviewOutput() {
1661 return mPreviewOutput;
1662 }
1663
1664 private:
createManager()1665 ACameraManager* createManager() {
1666 if (!mCameraManager) {
1667 mCameraManager = ACameraManager_create();
1668 }
1669 return mCameraManager;
1670 }
1671
1672 CameraServiceListener mServiceListener;
1673 ACameraManager_AvailabilityCallbacks mServiceCb {
1674 &mServiceListener,
1675 CameraServiceListener::onAvailable,
1676 CameraServiceListener::onUnavailable
1677 };
1678 CameraDeviceListener mDeviceListener;
1679 ACameraDevice_StateCallbacks mDeviceCb {
1680 &mDeviceListener,
1681 CameraDeviceListener::onDisconnected,
1682 CameraDeviceListener::onError
1683 };
1684 CaptureSessionListener mSessionListener;
1685 ACameraCaptureSession_stateCallbacks mSessionCb {
1686 &mSessionListener,
1687 CaptureSessionListener::onClosed,
1688 CaptureSessionListener::onReady,
1689 CaptureSessionListener::onActive
1690 };
1691
1692 CaptureResultListener mResultListener;
1693 ACameraCaptureSession_captureCallbacks mResultCb {
1694 &mResultListener,
1695 CaptureResultListener::onCaptureStart,
1696 CaptureResultListener::onCaptureProgressed,
1697 CaptureResultListener::onCaptureCompleted,
1698 CaptureResultListener::onCaptureFailed,
1699 CaptureResultListener::onCaptureSequenceCompleted,
1700 CaptureResultListener::onCaptureSequenceAborted,
1701 CaptureResultListener::onCaptureBufferLost
1702 };
1703
1704 ACameraCaptureSession_logicalCamera_captureCallbacks mLogicalCameraResultCb {
1705 &mResultListener,
1706 CaptureResultListener::onCaptureStart,
1707 CaptureResultListener::onCaptureProgressed,
1708 CaptureResultListener::onLogicalCameraCaptureCompleted,
1709 CaptureResultListener::onLogicalCameraCaptureFailed,
1710 CaptureResultListener::onCaptureSequenceCompleted,
1711 CaptureResultListener::onCaptureSequenceAborted,
1712 CaptureResultListener::onCaptureBufferLost
1713 };
1714
1715 ACameraIdList* mCameraIdList = nullptr;
1716 ACameraDevice* mDevice = nullptr;
1717 AImageReader* mImgReader = nullptr;
1718 ANativeWindow* mImgReaderAnw = nullptr;
1719 ANativeWindow* mPreviewAnw = nullptr;
1720 ACameraManager* mCameraManager = nullptr;
1721 ACaptureSessionOutputContainer* mOutputs = nullptr;
1722 ACaptureSessionOutput* mPreviewOutput = nullptr;
1723 ACaptureSessionOutput* mImgReaderOutput = nullptr;
1724 ACameraCaptureSession* mSession = nullptr;
1725 ACaptureRequest* mPreviewRequest = nullptr;
1726 ACaptureRequest* mStillRequest = nullptr;
1727 ACameraOutputTarget* mReqPreviewOutput = nullptr;
1728 ACameraOutputTarget* mReqImgReaderOutput = nullptr;
1729 const char* mCameraId;
1730 JNIEnv* mJNIEnv = nullptr;
1731 jstring mJOverrideCameraId;
1732 const char* mOverrideCameraId = nullptr;
1733
1734 bool mMgrInited = false; // cameraId, serviceListener
1735 bool mImgReaderInited = false;
1736 bool mPreviewInited = false;
1737 };
1738
throwAssertionError(JNIEnv * env,const char * message)1739 jint throwAssertionError(JNIEnv* env, const char* message)
1740 {
1741 jclass assertionClass;
1742 const char* className = "junit/framework/AssertionFailedError";
1743
1744 assertionClass = env->FindClass(className);
1745 if (assertionClass == nullptr) {
1746 ALOGE("Native throw error: cannot find class %s", className);
1747 return -1;
1748 }
1749 return env->ThrowNew(assertionClass, message);
1750 }
1751
1752 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetAndCloseNative(JNIEnv * env,jclass)1753 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1754 testCameraManagerGetAndCloseNative(
1755 JNIEnv* env, jclass /*clazz*/) {
1756 bool pass = false;
1757 ALOGV("%s", __FUNCTION__);
1758 ACameraManager* cameraManager2 = nullptr;
1759 ACameraManager* cameraManager3 = nullptr;
1760 ACameraManager* cameraManager4 = nullptr;
1761 camera_status_t ret = ACAMERA_OK;
1762 ACameraManager* cameraManager = ACameraManager_create();
1763 if (cameraManager == nullptr) {
1764 LOG_ERROR(errorString, "ACameraManager_create returns nullptr");
1765 goto cleanup;
1766 }
1767 ACameraManager_delete(cameraManager);
1768 cameraManager = nullptr;
1769
1770 // Test get/close multiple instances
1771 cameraManager = ACameraManager_create();
1772 cameraManager2 = ACameraManager_create();
1773 if (cameraManager2 == nullptr) {
1774 LOG_ERROR(errorString, "ACameraManager_create 2 returns nullptr");
1775 goto cleanup;
1776 }
1777 ACameraManager_delete(cameraManager);
1778 cameraManager = nullptr;
1779 cameraManager3 = ACameraManager_create();
1780 if (cameraManager3 == nullptr) {
1781 LOG_ERROR(errorString, "ACameraManager_create 3 returns nullptr");
1782 goto cleanup;
1783 }
1784 cameraManager4 = ACameraManager_create();
1785 if (cameraManager4 == nullptr) {
1786 LOG_ERROR(errorString, "ACameraManager_create 4 returns nullptr");
1787 goto cleanup;
1788 }
1789 ACameraManager_delete(cameraManager3);
1790 ACameraManager_delete(cameraManager2);
1791 ACameraManager_delete(cameraManager4);
1792
1793 pass = true;
1794 cleanup:
1795 if (cameraManager) {
1796 ACameraManager_delete(cameraManager);
1797 }
1798 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
1799 if (!pass) {
1800 throwAssertionError(env, errorString);
1801 }
1802 return pass;
1803 }
1804
1805 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetCameraIdsNative(JNIEnv * env,jclass)1806 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1807 testCameraManagerGetCameraIdsNative(
1808 JNIEnv* env, jclass /*clazz*/) {
1809 ALOGV("%s", __FUNCTION__);
1810 bool pass = false;
1811 ACameraManager* mgr = ACameraManager_create();
1812 ACameraIdList *cameraIdList = nullptr;
1813 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1814 if (ret != ACAMERA_OK || cameraIdList == nullptr) {
1815 LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
1816 ret, cameraIdList);
1817 goto cleanup;
1818 }
1819 ALOGI("Number of cameras: %d", cameraIdList->numCameras);
1820 for (int i = 0; i < cameraIdList->numCameras; i++) {
1821 ALOGI("Camera ID: %s", cameraIdList->cameraIds[i]);
1822 }
1823 ACameraManager_deleteCameraIdList(cameraIdList);
1824 cameraIdList = nullptr;
1825
1826 pass = true;
1827 cleanup:
1828 if (mgr) {
1829 ACameraManager_delete(mgr);
1830 }
1831 if (cameraIdList) {
1832 ACameraManager_deleteCameraIdList(cameraIdList);
1833 }
1834 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
1835 if (!pass) {
1836 throwAssertionError(env, errorString);
1837 }
1838 return pass;
1839 }
1840
1841 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerExtendedAvailabilityCallbackNative(JNIEnv * env,jclass)1842 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1843 testCameraManagerExtendedAvailabilityCallbackNative(
1844 JNIEnv* env, jclass /*clazz*/) {
1845 ALOGV("%s", __FUNCTION__);
1846 bool pass = false;
1847 ACameraManager* mgr = ACameraManager_create();
1848 ACameraIdList *cameraIdList = nullptr;
1849 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1850 int numCameras = cameraIdList->numCameras;
1851 CameraServiceListener listener;
1852 CameraServiceListener::StringPairSet unavailablePhysicalCameras;
1853 CameraServiceListener::StringPairSet physicalCameraIdPairs;
1854 ACameraManager_ExtendedAvailabilityCallbacks cbs {
1855 {
1856 &listener,
1857 CameraServiceListener::onAvailable,
1858 CameraServiceListener::onUnavailable
1859 },
1860 CameraServiceListener::onCameraAccessPrioritiesChanged,
1861 CameraServiceListener::onPhysicalCameraAvailable,
1862 CameraServiceListener::onPhysicalCameraUnavailable,
1863 {}
1864 };
1865
1866 ret = ACameraManager_registerExtendedAvailabilityCallback(mgr, &cbs);
1867 if (ret != ACAMERA_OK) {
1868 LOG_ERROR(errorString, "Register extended availability callback failed: ret %d", ret);
1869 goto cleanup;
1870 }
1871 sleep(1); // sleep a second to give some time for callbacks to happen
1872
1873 // Should at least get onAvailable for each camera once
1874 if (listener.getAvailableCount() < numCameras) {
1875 LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
1876 numCameras, listener.getAvailableCount());
1877 goto cleanup;
1878 }
1879
1880 {
1881 int availablePhysicalCamera = listener.getPhysicalCameraAvailableCount();
1882 if (availablePhysicalCamera > 0) {
1883 LOG_ERROR(errorString, "Expect no available callback, but got %d",
1884 availablePhysicalCamera);
1885 }
1886 }
1887
1888 unavailablePhysicalCameras = listener.getUnavailablePhysicalCameras();
1889 for (int i = 0; i < numCameras; i++) {
1890 const char* cameraId = cameraIdList->cameraIds[i];
1891 if (cameraId == nullptr) {
1892 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
1893 goto cleanup;
1894 }
1895 ACameraMetadata* c;
1896 ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &c);
1897 if (ret != ACAMERA_OK || c == nullptr) {
1898 LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
1899 goto cleanup;
1900 }
1901 std::unique_ptr<ACameraMetadata> chars(c);
1902
1903 size_t physicalCameraCnt = 0;
1904 const char *const* physicalCameraIds = nullptr;
1905 if (!ACameraMetadata_isLogicalMultiCamera(
1906 chars.get(), &physicalCameraCnt, &physicalCameraIds)) {
1907 continue;
1908 }
1909 for (size_t j = 0; j < physicalCameraCnt; j++) {
1910 physicalCameraIdPairs.emplace(cameraId, physicalCameraIds[j]);
1911 }
1912 }
1913 for (const auto& unavailIdPair : unavailablePhysicalCameras) {
1914 bool validPair = false;
1915 for (const auto& idPair : physicalCameraIdPairs) {
1916 if (idPair.first == unavailIdPair.first && idPair.second == unavailIdPair.second) {
1917 validPair = true;
1918 break;
1919 }
1920 }
1921 if (!validPair) {
1922 LOG_ERROR(errorString, "Expect valid unavailable physical cameras, but got %s : %s",
1923 unavailIdPair.first.c_str(), unavailIdPair.second.c_str());
1924 goto cleanup;
1925 }
1926 }
1927
1928 ret = ACameraManager_unregisterExtendedAvailabilityCallback(mgr, &cbs);
1929 if (ret != ACAMERA_OK) {
1930 LOG_ERROR(errorString, "Unregister extended availability callback failed: ret %d", ret);
1931 goto cleanup;
1932 }
1933 pass = true;
1934 cleanup:
1935 if (cameraIdList) {
1936 ACameraManager_deleteCameraIdList(cameraIdList);
1937 }
1938 if (mgr) {
1939 ACameraManager_delete(mgr);
1940 }
1941 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1942 if (!pass) {
1943 throwAssertionError(env, errorString);
1944 }
1945 return pass;
1946 }
1947
1948 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerAvailabilityCallbackNative(JNIEnv * env,jclass)1949 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1950 testCameraManagerAvailabilityCallbackNative(
1951 JNIEnv* env, jclass /*clazz*/) {
1952 ALOGV("%s", __FUNCTION__);
1953 bool pass = false;
1954 ACameraManager* mgr = ACameraManager_create();
1955 ACameraIdList *cameraIdList = nullptr;
1956 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1957 int numCameras = cameraIdList->numCameras;
1958 CameraServiceListener listener;
1959 ACameraManager_AvailabilityCallbacks cbs {
1960 &listener,
1961 CameraServiceListener::onAvailable,
1962 CameraServiceListener::onUnavailable};
1963 ret = ACameraManager_registerAvailabilityCallback(mgr, &cbs);
1964 if (ret != ACAMERA_OK) {
1965 LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
1966 goto cleanup;
1967 }
1968 sleep(1); // sleep a second to give some time for callbacks to happen
1969
1970 // Should at least get onAvailable for each camera once
1971 if (listener.getAvailableCount() < numCameras) {
1972 LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
1973 numCameras, listener.getAvailableCount());
1974 goto cleanup;
1975 }
1976
1977 ret = ACameraManager_unregisterAvailabilityCallback(mgr, &cbs);
1978 if (ret != ACAMERA_OK) {
1979 LOG_ERROR(errorString, "Unregister availability callback failed: ret %d", ret);
1980 goto cleanup;
1981 }
1982 pass = true;
1983 cleanup:
1984 if (cameraIdList) {
1985 ACameraManager_deleteCameraIdList(cameraIdList);
1986 }
1987 if (mgr) {
1988 ACameraManager_delete(mgr);
1989 }
1990 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1991 if (!pass) {
1992 throwAssertionError(env, errorString);
1993 }
1994 return pass;
1995 }
1996
1997 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerCharacteristicsNative(JNIEnv * env,jclass)1998 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1999 testCameraManagerCharacteristicsNative(
2000 JNIEnv* env, jclass /*clazz*/) {
2001 ALOGV("%s", __FUNCTION__);
2002 bool pass = false;
2003 ACameraManager* mgr = ACameraManager_create();
2004 ACameraIdList *cameraIdList = nullptr;
2005 ACameraMetadata* chars = nullptr;
2006 ACameraMetadata* copy = nullptr;
2007 int numCameras = 0;
2008 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
2009 if (ret != ACAMERA_OK || cameraIdList == nullptr) {
2010 LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
2011 ret, cameraIdList);
2012 goto cleanup;
2013 }
2014 numCameras = cameraIdList->numCameras;
2015
2016 for (int i = 0; i < numCameras; i++) {
2017 ret = ACameraManager_getCameraCharacteristics(
2018 mgr, cameraIdList->cameraIds[i], &chars);
2019 if (ret != ACAMERA_OK) {
2020 LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
2021 goto cleanup;
2022 }
2023
2024 int32_t numTags = 0;
2025 const uint32_t* tags = nullptr;
2026 ret = ACameraMetadata_getAllTags(chars, &numTags, &tags);
2027 if (ret != ACAMERA_OK) {
2028 LOG_ERROR(errorString, "Get camera characteristics tags failed: ret %d", ret);
2029 goto cleanup;
2030 }
2031
2032 for (int tid = 0; tid < numTags; tid++) {
2033 uint32_t tagId = tags[tid];
2034 ALOGV("%s camera characteristics contains key %u", __FUNCTION__, tagId);
2035 uint32_t sectionId = tagId >> 16;
2036 if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
2037 LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
2038 goto cleanup;
2039 }
2040 }
2041
2042 ACameraMetadata_const_entry entry;
2043 ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
2044 if (ret != ACAMERA_OK) {
2045 LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
2046 goto cleanup;
2047 }
2048
2049 // Check the entry is actually legit
2050 if (entry.tag != ACAMERA_REQUEST_AVAILABLE_CAPABILITIES ||
2051 entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE || entry.data.i32 == nullptr) {
2052 LOG_ERROR(errorString,
2053 "Bad available capabilities key: tag: %d (expected %d), count %u (expect > 0), "
2054 "type %d (expected %d), data %p (expected not null)",
2055 entry.tag, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, entry.count,
2056 entry.type, ACAMERA_TYPE_BYTE, entry.data.i32);
2057 goto cleanup;
2058 }
2059 // All camera supports BC except depth only cameras
2060 bool supportBC = false, supportDepth = false;
2061 for (uint32_t i = 0; i < entry.count; i++) {
2062 if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
2063 supportBC = true;
2064 }
2065 if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
2066 supportDepth = true;
2067 }
2068 }
2069 if (!(supportBC || supportDepth)) {
2070 LOG_ERROR(errorString, "Error: camera device %s does not support either BC or DEPTH",
2071 cameraIdList->cameraIds[i]);
2072 goto cleanup;
2073 }
2074
2075 // Check copy works
2076 copy = ACameraMetadata_copy(chars);
2077
2078 // Compare copy with original
2079 ACameraMetadata_const_entry entryCopy;
2080 ret = ACameraMetadata_getConstEntry(
2081 copy, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entryCopy);
2082 if (ret != ACAMERA_OK) {
2083 LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
2084 goto cleanup;
2085 }
2086 for (uint32_t i = 0; i < entry.count; i++) {
2087 if (entry.data.u8[i] != entryCopy.data.u8[i]) {
2088 LOG_ERROR(errorString,
2089 "Copy of available capability key[%d]: %d mismatches original %d",
2090 i, entryCopy.data.u8[i], entry.data.u8[i]);
2091 goto cleanup;
2092 }
2093 }
2094
2095 // Check get unknown value fails
2096 uint32_t badTag = (uint32_t) ACAMERA_VENDOR_START - 1;
2097 ret = ACameraMetadata_getConstEntry(chars, badTag, &entry);
2098 if (ret == ACAMERA_OK) {
2099 LOG_ERROR(errorString, "Error: get unknown tag should fail!");
2100 goto cleanup;
2101 }
2102
2103 ACameraMetadata_free(chars);
2104 ACameraMetadata_free(copy);
2105 chars = nullptr;
2106 copy = nullptr;
2107 }
2108
2109 pass = true;
2110 cleanup:
2111 if (chars) {
2112 ACameraMetadata_free(chars);
2113 }
2114 if (copy) {
2115 ACameraMetadata_free(copy);
2116 }
2117 ACameraManager_deleteCameraIdList(cameraIdList);
2118 ACameraManager_delete(mgr);
2119 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2120 if (!pass) {
2121 throwAssertionError(env, errorString);
2122 }
2123 return pass;
2124 }
2125
2126 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceOpenAndCloseNative(JNIEnv * env,jclass,jstring jOverrideCameraId)2127 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2128 testCameraDeviceOpenAndCloseNative(
2129 JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
2130 ALOGV("%s", __FUNCTION__);
2131 int numCameras = 0;
2132 bool pass = false;
2133 PreviewTestCase testCase;
2134
2135 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2136 if (ret != ACAMERA_OK) {
2137 // Don't log error here. testcase did it
2138 goto cleanup;
2139 }
2140
2141 numCameras = testCase.getNumCameras();
2142 if (numCameras < 0) {
2143 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2144 goto cleanup;
2145 }
2146
2147 for (int i = 0; i < numCameras; i++) {
2148 const char* cameraId = testCase.getCameraId(i);
2149 if (cameraId == nullptr) {
2150 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2151 goto cleanup;
2152 }
2153
2154 ret = testCase.openCamera(cameraId);
2155 if (ret != ACAMERA_OK) {
2156 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2157 goto cleanup;
2158 }
2159
2160 usleep(100000); // sleep to give some time for callbacks to happen
2161
2162 if (testCase.isCameraAvailable(cameraId)) {
2163 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2164 goto cleanup;
2165 }
2166
2167 ret = testCase.closeCamera();
2168 if (ret != ACAMERA_OK) {
2169 LOG_ERROR(errorString, "Close camera device %s failure. ret %d", cameraId, ret);
2170 goto cleanup;
2171 }
2172
2173 usleep(100000); // sleep to give some time for callbacks to happen
2174
2175 if (!testCase.isCameraAvailable(cameraId)) {
2176 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2177 goto cleanup;
2178 }
2179 }
2180
2181 ret = testCase.deInit();
2182 if (ret != ACAMERA_OK) {
2183 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2184 goto cleanup;
2185 }
2186
2187 pass = true;
2188 cleanup:
2189 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2190 if (!pass) {
2191 throwAssertionError(env, errorString);
2192 }
2193 return pass;
2194 }
2195
2196 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceCreateCaptureRequestNative(JNIEnv * env,jclass,jstring jOverrideCameraId)2197 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2198 testCameraDeviceCreateCaptureRequestNative(
2199 JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
2200 ALOGV("%s", __FUNCTION__);
2201 bool pass = false;
2202 ACameraManager* mgr = ACameraManager_create();
2203 ACameraIdList* cameraIdList = nullptr;
2204 ACameraDevice* device = nullptr;
2205 ACaptureRequest* request = nullptr;
2206 ACameraMetadata* chars = nullptr;
2207 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
2208
2209 int numCameras = cameraIdList->numCameras;
2210 const char* overrideCameraId = nullptr;
2211 if (jOverrideCameraId != nullptr) {
2212 overrideCameraId = env->GetStringUTFChars(jOverrideCameraId, nullptr);
2213 }
2214
2215 for (int i = 0; i < numCameras; i++) {
2216 CameraDeviceListener deviceListener;
2217 const char* cameraId = cameraIdList->cameraIds[i];
2218 if (overrideCameraId != nullptr && strcmp(overrideCameraId, cameraId)) {
2219 // Skip other cameras if overriding camera id to be tested.
2220 continue;
2221 }
2222 ACameraDevice_StateCallbacks deviceCb {
2223 &deviceListener,
2224 CameraDeviceListener::onDisconnected,
2225 CameraDeviceListener::onError
2226 };
2227 ret = ACameraManager_openCamera(mgr, cameraId, &deviceCb, &device);
2228 if (ret != ACAMERA_OK) {
2229 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2230 goto cleanup;
2231 }
2232
2233 ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &chars);
2234 if (ret != ACAMERA_OK || chars == nullptr) {
2235 LOG_ERROR(errorString, "Get camera %s characteristics failure. ret %d, chars %p",
2236 cameraId, ret, chars);
2237 goto cleanup;
2238 }
2239 StaticInfo staticInfo(chars);
2240
2241 for (int t = TEMPLATE_PREVIEW; t <= TEMPLATE_MANUAL; t++) {
2242 ACameraDevice_request_template templateId =
2243 static_cast<ACameraDevice_request_template>(t);
2244 ret = ACameraDevice_createCaptureRequest(device, templateId, &request);
2245 if (ret == ACAMERA_ERROR_INVALID_PARAMETER) {
2246 // template not supported. skip
2247 continue;
2248 }
2249
2250 if (ret != ACAMERA_OK) {
2251 LOG_ERROR(errorString, "Create capture request failed!: ret %d", ret);
2252 goto cleanup;
2253 }
2254
2255 int32_t numTags = 0;
2256 const uint32_t* tags = nullptr;
2257 ret = ACaptureRequest_getAllTags(request, &numTags, &tags);
2258 if (ret != ACAMERA_OK) {
2259 LOG_ERROR(errorString, "Get capture request tags failed: ret %d", ret);
2260 goto cleanup;
2261 }
2262
2263 for (int tid = 0; tid < numTags; tid++) {
2264 uint32_t tagId = tags[tid];
2265 ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
2266 uint32_t sectionId = tagId >> 16;
2267 if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
2268 LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
2269 goto cleanup;
2270 }
2271 }
2272
2273 void* context = nullptr;
2274 ret = ACaptureRequest_getUserContext(request, &context);
2275 if (ret != ACAMERA_OK) {
2276 LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
2277 goto cleanup;
2278 }
2279 if (context != nullptr) {
2280 LOG_ERROR(errorString, "Capture request context is not null: %p", context);
2281 goto cleanup;
2282 }
2283
2284 intptr_t magic_num = 0xBEEF;
2285 ret = ACaptureRequest_setUserContext(request, (void*) magic_num);
2286 if (ret != ACAMERA_OK) {
2287 LOG_ERROR(errorString, "Set capture request context failed: ret %d", ret);
2288 goto cleanup;
2289 }
2290
2291 ret = ACaptureRequest_getUserContext(request, &context);
2292 if (ret != ACAMERA_OK) {
2293 LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
2294 goto cleanup;
2295 }
2296 if (context != (void*) magic_num) {
2297 LOG_ERROR(errorString, "Capture request context is wrong: %p", context);
2298 goto cleanup;
2299 }
2300
2301 // try get/set capture request fields
2302 ACameraMetadata_const_entry entry;
2303 ret = ACaptureRequest_getConstEntry_physicalCamera(request, nullptr,
2304 ACAMERA_CONTROL_AE_MODE, &entry);
2305 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2306 LOG_ERROR(errorString, "Get AE mode key for null physical id should fail. ret %d",
2307 ret);
2308 goto cleanup;
2309 }
2310 ret = ACaptureRequest_getConstEntry_physicalCamera(request, cameraId,
2311 ACAMERA_CONTROL_AE_MODE, &entry);
2312 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2313 LOG_ERROR(errorString, "Get AE mode key for physical id should fail. ret %d",
2314 ret);
2315 goto cleanup;
2316 }
2317 ret = ACaptureRequest_getConstEntry(request, ACAMERA_CONTROL_AE_MODE, &entry);
2318 if (ret != ACAMERA_OK) {
2319 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2320 goto cleanup;
2321 }
2322
2323 if (entry.tag != ACAMERA_CONTROL_AE_MODE || entry.type != ACAMERA_TYPE_BYTE ||\
2324 entry.count != 1) {
2325 LOG_ERROR(errorString,
2326 "Bad AE mode key. tag 0x%x (expect 0x%x), type %d (expect %d), "
2327 "count %d (expect %d)",
2328 entry.tag, ACAMERA_CONTROL_AE_MODE, entry.type, ACAMERA_TYPE_BYTE,
2329 entry.count, 1);
2330 goto cleanup;
2331 }
2332 if (t == TEMPLATE_MANUAL) {
2333 if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_OFF) {
2334 LOG_ERROR(errorString, "Error: MANUAL template AE mode %d (expect %d)",
2335 entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_OFF);
2336 goto cleanup;
2337 }
2338 // try set AE_MODE_ON
2339 uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
2340 ret = ACaptureRequest_setEntry_physicalCamera_u8(
2341 request, nullptr, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2342 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2343 LOG_ERROR(errorString, "Error: camera %s setEntry_physicalCamera_u8 should "
2344 "fail. ret %d", cameraId, ret);
2345 goto cleanup;
2346 }
2347 ret = ACaptureRequest_setEntry_physicalCamera_u8(
2348 request, cameraId, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2349 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2350 LOG_ERROR(errorString, "Error: camera %s setEntry_physicalCamera_u8 should "
2351 "fail. ret %d", cameraId, ret);
2352 goto cleanup;
2353 }
2354 ret = ACaptureRequest_setEntry_u8(
2355 request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2356 if (ret != ACAMERA_OK) {
2357 LOG_ERROR(errorString,
2358 "Error: Camera %s template %d: update AE mode key fail. ret %d",
2359 cameraId, t, ret);
2360 goto cleanup;
2361 }
2362 ret = ACaptureRequest_getConstEntry(
2363 request, ACAMERA_CONTROL_AE_MODE, &entry);
2364 if (ret != ACAMERA_OK) {
2365 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2366 goto cleanup;
2367 }
2368 if (entry.data.u8[0] != aeMode) {
2369 LOG_ERROR(errorString,
2370 "Error: AE mode key is not updated. expect %d but get %d",
2371 aeMode, entry.data.u8[0]);
2372 goto cleanup;
2373 }
2374 } else {
2375 if (staticInfo.isColorOutputSupported()) {
2376 if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_ON) {
2377 LOG_ERROR(errorString,
2378 "Error: Template %d has wrong AE mode %d (expect %d)",
2379 t, entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_ON);
2380 goto cleanup;
2381 }
2382 // try set AE_MODE_OFF
2383 if (staticInfo.isCapabilitySupported(
2384 ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
2385 uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF;
2386 ret = ACaptureRequest_setEntry_u8(
2387 request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2388 if (ret != ACAMERA_OK) {
2389 LOG_ERROR(errorString,
2390 "Error: Camera %s template %d: update AE mode key fail. ret %d",
2391 cameraId, t, ret);
2392 goto cleanup;
2393 }
2394 ret = ACaptureRequest_getConstEntry(
2395 request, ACAMERA_CONTROL_AE_MODE, &entry);
2396 if (ret != ACAMERA_OK) {
2397 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2398 goto cleanup;
2399 }
2400 if (entry.data.u8[0] != aeMode) {
2401 LOG_ERROR(errorString,
2402 "Error: AE mode key is not updated. expect %d but get %d",
2403 aeMode, entry.data.u8[0]);
2404 goto cleanup;
2405 }
2406 }
2407 }
2408 }
2409 ACaptureRequest_free(request);
2410 request = nullptr;
2411 }
2412
2413 ACameraMetadata_free(chars);
2414 chars = nullptr;
2415 ACameraDevice_close(device);
2416 device = nullptr;
2417 }
2418
2419 pass = true;
2420 cleanup:
2421 if (cameraIdList) {
2422 ACameraManager_deleteCameraIdList(cameraIdList);
2423 }
2424 if (request) {
2425 ACaptureRequest_free(request);
2426 }
2427 if (chars) {
2428 ACameraMetadata_free(chars);
2429 }
2430 if (device) {
2431 ACameraDevice_close(device);
2432 }
2433 if (mgr) {
2434 ACameraManager_delete(mgr);
2435 }
2436 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2437 if (!pass) {
2438 throwAssertionError(env, errorString);
2439 }
2440 return pass;
2441 }
2442
2443 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSessionOpenAndCloseNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)2444 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2445 testCameraDeviceSessionOpenAndCloseNative(
2446 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
2447 jstring jOverrideCameraId) {
2448 ALOGV("%s", __FUNCTION__);
2449 int numCameras = 0;
2450 bool pass = false;
2451 PreviewTestCase testCase;
2452
2453 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2454 if (ret != ACAMERA_OK) {
2455 // Don't log error here. testcase did it
2456 goto cleanup;
2457 }
2458
2459 numCameras = testCase.getNumCameras();
2460 if (numCameras < 0) {
2461 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2462 goto cleanup;
2463 }
2464
2465 for (int i = 0; i < numCameras; i++) {
2466 const char* cameraId = testCase.getCameraId(i);
2467 if (cameraId == nullptr) {
2468 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2469 goto cleanup;
2470 }
2471
2472 {
2473 ACameraMetadata* chars = testCase.getCameraChars(cameraId);
2474 StaticInfo staticInfo(chars);
2475 if (!staticInfo.isColorOutputSupported()) {
2476 ALOGI("%s: camera %s does not support color output. skipping",
2477 __FUNCTION__, cameraId);
2478 ACameraMetadata_free(chars);
2479 continue;
2480 }
2481 ACameraMetadata_free(chars);
2482 }
2483
2484 ret = testCase.openCamera(cameraId);
2485 if (ret != ACAMERA_OK) {
2486 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2487 goto cleanup;
2488 }
2489
2490 usleep(100000); // sleep to give some time for callbacks to happen
2491
2492 if (testCase.isCameraAvailable(cameraId)) {
2493 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2494 goto cleanup;
2495 }
2496
2497 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2498 if (previewAnw == nullptr) {
2499 LOG_ERROR(errorString, "Null ANW from preview surface!");
2500 goto cleanup;
2501 }
2502
2503 CaptureSessionListener* sessionListener = testCase.getSessionListener();
2504 if (sessionListener == nullptr) {
2505 LOG_ERROR(errorString, "Session listener camera %s is null", cameraId);
2506 goto cleanup;
2507 }
2508
2509 // Try open/close session multiple times
2510 for (int j = 0; j < 5; j++) {
2511 ret = testCase.createCaptureSessionWithLog();
2512 if (ret != ACAMERA_OK) {
2513 // Don't log error here. testcase did it
2514 goto cleanup;
2515 }
2516
2517 usleep(100000); // sleep to give some time for callbacks to happen
2518
2519 if (!sessionListener->isIdle()) {
2520 LOG_ERROR(errorString, "Session for camera %s should be idle right after creation",
2521 cameraId);
2522 goto cleanup;
2523 }
2524
2525 testCase.closeSession();
2526
2527 usleep(100000); // sleep to give some time for callbacks to happen
2528 if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
2529 LOG_ERROR(errorString,
2530 "Session for camera %s close error. isClosde %d close count %d",
2531 cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
2532 goto cleanup;
2533 }
2534 sessionListener->reset();
2535 }
2536
2537 // Try open/close really fast
2538 ret = testCase.createCaptureSessionWithLog();
2539 if (ret != ACAMERA_OK) {
2540 LOG_ERROR(errorString, "Create session for camera %s failed. ret %d",
2541 cameraId, ret);
2542 goto cleanup;
2543 }
2544 testCase.closeSession();
2545 usleep(100000); // sleep to give some time for callbacks to happen
2546 if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
2547 LOG_ERROR(errorString,
2548 "Session for camera %s close error. isClosde %d close count %d",
2549 cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
2550 goto cleanup;
2551 }
2552
2553 ret = testCase.resetWithErrorLog();
2554 if (ret != ACAMERA_OK) {
2555 // Don't log error here. testcase did it
2556 goto cleanup;
2557 }
2558
2559 usleep(100000); // sleep to give some time for callbacks to happen
2560
2561 if (!testCase.isCameraAvailable(cameraId)) {
2562 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2563 goto cleanup;
2564 }
2565 }
2566
2567 ret = testCase.deInit();
2568 if (ret != ACAMERA_OK) {
2569 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2570 goto cleanup;
2571 }
2572
2573 pass = true;
2574 cleanup:
2575 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2576 if (!pass) {
2577 throwAssertionError(env, errorString);
2578 }
2579 return pass;
2580 }
2581
2582 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSharedOutputUpdate(JNIEnv * env,jclass,jobject jPreviewSurface,jobject jSharedSurface,jstring jOverrideCameraId)2583 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2584 testCameraDeviceSharedOutputUpdate(
2585 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface, jobject jSharedSurface,
2586 jstring jOverrideCameraId) {
2587 ALOGV("%s", __FUNCTION__);
2588 int numCameras = 0;
2589 bool pass = false;
2590 PreviewTestCase testCase;
2591 int sequenceId = -1;
2592 int64_t lastFrameNumber = 0;
2593 bool frameArrived = false;
2594 ANativeWindow* previewAnw = nullptr;
2595 ANativeWindow* sharedAnw = ANativeWindow_fromSurface(env, jSharedSurface);
2596 ACaptureRequest* updatedRequest = nullptr;
2597 ACameraOutputTarget* reqPreviewOutput = nullptr;
2598 ACameraOutputTarget* reqSharedOutput = nullptr;
2599 ACaptureSessionOutput *previewOutput = nullptr;
2600 uint32_t timeoutSec = 1;
2601 uint32_t runPreviewSec = 2;
2602
2603 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2604 if (ret != ACAMERA_OK) {
2605 // Don't log error here. testcase did it
2606 goto cleanup;
2607 }
2608
2609 numCameras = testCase.getNumCameras();
2610 if (numCameras < 0) {
2611 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2612 goto cleanup;
2613 }
2614
2615 for (int i = 0; i < numCameras; i++) {
2616 const char* cameraId = testCase.getCameraId(i);
2617 if (cameraId == nullptr) {
2618 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2619 goto cleanup;
2620 }
2621
2622 {
2623 ACameraMetadata* chars = testCase.getCameraChars(cameraId);
2624 StaticInfo staticInfo(chars);
2625 if (!staticInfo.isColorOutputSupported()) {
2626 ALOGI("%s: camera %s does not support color output. skipping",
2627 __FUNCTION__, cameraId);
2628 ACameraMetadata_free(chars);
2629 continue;
2630 }
2631 ACameraMetadata_free(chars);
2632 }
2633
2634 ret = testCase.openCamera(cameraId);
2635 if (ret != ACAMERA_OK) {
2636 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2637 goto cleanup;
2638 }
2639
2640 usleep(100000); // sleep to give some time for callbacks to happen
2641
2642 if (testCase.isCameraAvailable(cameraId)) {
2643 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2644 goto cleanup;
2645 }
2646
2647 previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2648 if (previewAnw == nullptr) {
2649 LOG_ERROR(errorString, "Null ANW from preview surface!");
2650 goto cleanup;
2651 }
2652
2653 ret = testCase.createCaptureSessionWithLog(true);
2654 if (ret != ACAMERA_OK) {
2655 // Don't log error here. testcase did it
2656 goto cleanup;
2657 }
2658
2659 ret = testCase.createRequestsWithErrorLog();
2660 if (ret != ACAMERA_OK) {
2661 // Don't log error here. testcase did it
2662 goto cleanup;
2663 }
2664
2665 ret = testCase.startPreview();
2666 if (ret != ACAMERA_OK) {
2667 LOG_ERROR(errorString, "Start preview failed!");
2668 goto cleanup;
2669 }
2670
2671 sleep(runPreviewSec);
2672
2673 previewOutput = testCase.getPreviewOutput();
2674 //Try some bad input
2675 ret = ACaptureSessionSharedOutput_add(previewOutput, previewAnw);
2676 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2677 LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add should return invalid "
2678 "parameter! %d", ret);
2679 goto cleanup;
2680 }
2681
2682 ret = ACaptureSessionSharedOutput_remove(previewOutput, previewAnw);
2683 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2684 LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove should return invalid "
2685 "parameter! %d", ret);
2686 goto cleanup;
2687 }
2688
2689 //Now try with valid input
2690 ret = ACaptureSessionSharedOutput_add(previewOutput, sharedAnw);
2691 if (ret != ACAMERA_OK) {
2692 LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add failed!")
2693 goto cleanup;
2694 }
2695
2696 ret = testCase.updateOutput(env, previewOutput);
2697 if (ret != ACAMERA_OK) {
2698 LOG_ERROR(errorString, "Failed to update output configuration!")
2699 goto cleanup;
2700 }
2701
2702 ret = ACameraDevice_createCaptureRequest(
2703 testCase.getCameraDevice(), TEMPLATE_PREVIEW, &updatedRequest);
2704 if (ret != ACAMERA_OK) {
2705 LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
2706 cameraId, ret);
2707 goto cleanup;
2708 }
2709
2710 ret = ACameraOutputTarget_create(previewAnw, &reqPreviewOutput);
2711 if (ret != ACAMERA_OK) {
2712 LOG_ERROR(errorString,
2713 "Camera %s create request preview output target failed. ret %d",
2714 cameraId, ret);
2715 goto cleanup;
2716 }
2717
2718 ret = ACaptureRequest_addTarget(updatedRequest, reqPreviewOutput);
2719 if (ret != ACAMERA_OK) {
2720 LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
2721 cameraId, ret);
2722 goto cleanup;
2723 }
2724
2725 ret = ACameraOutputTarget_create(sharedAnw, &reqSharedOutput);
2726 if (ret != ACAMERA_OK) {
2727 LOG_ERROR(errorString,
2728 "Camera %s create request preview output target failed. ret %d",
2729 cameraId, ret);
2730 goto cleanup;
2731 }
2732
2733 ret = ACaptureRequest_addTarget(updatedRequest, reqSharedOutput);
2734 if (ret != ACAMERA_OK) {
2735 LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
2736 cameraId, ret);
2737 goto cleanup;
2738 }
2739
2740 ret = testCase.updateRepeatingRequest(updatedRequest, &sequenceId);
2741 if (ret != ACAMERA_OK) {
2742 LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
2743 cameraId, ret);
2744 goto cleanup;
2745 }
2746
2747 sleep(runPreviewSec);
2748
2749 ret = ACaptureSessionSharedOutput_remove(previewOutput, sharedAnw);
2750 if (ret != ACAMERA_OK) {
2751 LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove failed!");
2752 goto cleanup;
2753 }
2754
2755 //Try removing shared output which still has pending camera requests
2756 ret = testCase.updateOutput(env, previewOutput);
2757 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2758 LOG_ERROR(errorString, "updateOutput should fail!");
2759 goto cleanup;
2760 }
2761
2762 //Remove the shared output correctly by updating the repeating request
2763 //first
2764 ret = ACaptureRequest_removeTarget(updatedRequest, reqSharedOutput);
2765 if (ret != ACAMERA_OK) {
2766 LOG_ERROR(errorString, "Camera %s remove target output failed. ret %d",
2767 cameraId, ret);
2768 goto cleanup;
2769 }
2770
2771 ret = testCase.updateRepeatingRequest(updatedRequest);
2772 if (ret != ACAMERA_OK) {
2773 LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
2774 cameraId, ret);
2775 goto cleanup;
2776 }
2777
2778 //Then wait for all old requests to flush
2779 lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
2780 if (lastFrameNumber < 0) {
2781 LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
2782 cameraId);
2783 goto cleanup;
2784 }
2785
2786 frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
2787 if (!frameArrived) {
2788 LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
2789 cameraId);
2790 goto cleanup;
2791 }
2792
2793 ret = testCase.updateOutput(env, previewOutput);
2794 if (ret != ACAMERA_OK) {
2795 LOG_ERROR(errorString, "updateOutput failed!");
2796 goto cleanup;
2797 }
2798
2799 sleep(runPreviewSec);
2800
2801 ret = testCase.resetWithErrorLog();
2802 if (ret != ACAMERA_OK) {
2803 // Don't log error here. testcase did it
2804 goto cleanup;
2805 }
2806
2807 usleep(100000); // sleep to give some time for callbacks to happen
2808
2809 if (!testCase.isCameraAvailable(cameraId)) {
2810 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2811 goto cleanup;
2812 }
2813 }
2814
2815 ret = testCase.deInit();
2816 if (ret != ACAMERA_OK) {
2817 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2818 goto cleanup;
2819 }
2820
2821 pass = true;
2822
2823 cleanup:
2824
2825 if (updatedRequest != nullptr) {
2826 ACaptureRequest_free(updatedRequest);
2827 updatedRequest = nullptr;
2828 }
2829
2830 if (reqPreviewOutput != nullptr) {
2831 ACameraOutputTarget_free(reqPreviewOutput);
2832 reqPreviewOutput = nullptr;
2833 }
2834
2835 if (reqSharedOutput != nullptr) {
2836 ACameraOutputTarget_free(reqSharedOutput);
2837 reqSharedOutput = nullptr;
2838 }
2839
2840 if (sharedAnw) {
2841 ANativeWindow_release(sharedAnw);
2842 sharedAnw = nullptr;
2843 }
2844
2845 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2846 if (!pass) {
2847 throwAssertionError(env, errorString);
2848 }
2849 return pass;
2850 }
2851
2852 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSimplePreviewNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)2853 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2854 testCameraDeviceSimplePreviewNative(
2855 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
2856 jstring jOverrideCameraId) {
2857 ALOGV("%s", __FUNCTION__);
2858 int numCameras = 0;
2859 bool pass = false;
2860 PreviewTestCase testCase;
2861
2862 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2863 if (ret != ACAMERA_OK) {
2864 // Don't log error here. testcase did it
2865 goto cleanup;
2866 }
2867
2868 numCameras = testCase.getNumCameras();
2869 if (numCameras < 0) {
2870 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2871 goto cleanup;
2872 }
2873
2874 for (int i = 0; i < numCameras; i++) {
2875 const char* cameraId = testCase.getCameraId(i);
2876 if (cameraId == nullptr) {
2877 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2878 goto cleanup;
2879 }
2880
2881 {
2882 ACameraMetadata* chars = testCase.getCameraChars(cameraId);
2883 StaticInfo staticInfo(chars);
2884 if (!staticInfo.isColorOutputSupported()) {
2885 ALOGI("%s: camera %s does not support color output. skipping",
2886 __FUNCTION__, cameraId);
2887 ACameraMetadata_free(chars);
2888 continue;
2889 }
2890 ACameraMetadata_free(chars);
2891 }
2892
2893 ret = testCase.openCamera(cameraId);
2894 if (ret != ACAMERA_OK) {
2895 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2896 goto cleanup;
2897 }
2898
2899 usleep(100000); // sleep to give some time for callbacks to happen
2900
2901 if (testCase.isCameraAvailable(cameraId)) {
2902 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2903 goto cleanup;
2904 }
2905
2906 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2907 if (previewAnw == nullptr) {
2908 LOG_ERROR(errorString, "Null ANW from preview surface!");
2909 goto cleanup;
2910 }
2911
2912 ret = testCase.createCaptureSessionWithLog();
2913 if (ret != ACAMERA_OK) {
2914 // Don't log error here. testcase did it
2915 goto cleanup;
2916 }
2917
2918 ret = testCase.createRequestsWithErrorLog();
2919 if (ret != ACAMERA_OK) {
2920 // Don't log error here. testcase did it
2921 goto cleanup;
2922 }
2923
2924 ret = testCase.startPreview();
2925 if (ret != ACAMERA_OK) {
2926 LOG_ERROR(errorString, "Start preview failed!");
2927 goto cleanup;
2928 }
2929
2930 sleep(3);
2931
2932 ret = testCase.resetWithErrorLog();
2933 if (ret != ACAMERA_OK) {
2934 // Don't log error here. testcase did it
2935 goto cleanup;
2936 }
2937
2938 usleep(100000); // sleep to give some time for callbacks to happen
2939
2940 if (!testCase.isCameraAvailable(cameraId)) {
2941 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2942 goto cleanup;
2943 }
2944 }
2945
2946 ret = testCase.deInit();
2947 if (ret != ACAMERA_OK) {
2948 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2949 goto cleanup;
2950 }
2951
2952 pass = true;
2953 cleanup:
2954 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2955 if (!pass) {
2956 throwAssertionError(env, errorString);
2957 }
2958 return pass;
2959 }
2960
2961 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDevicePreviewWithSessionParametersNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)2962 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2963 testCameraDevicePreviewWithSessionParametersNative(
2964 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
2965 jstring jOverrideCameraId) {
2966 ALOGV("%s", __FUNCTION__);
2967 int numCameras = 0;
2968 bool pass = false;
2969 ACameraManager* mgr = ACameraManager_create();
2970 ACameraMetadata* chars = nullptr;
2971 PreviewTestCase testCase;
2972
2973 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
2974 if (ret != ACAMERA_OK) {
2975 // Don't log error here. testcase did it
2976 goto cleanup;
2977 }
2978
2979 numCameras = testCase.getNumCameras();
2980 if (numCameras < 0) {
2981 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2982 goto cleanup;
2983 }
2984
2985 for (int i = 0; i < numCameras; i++) {
2986 const char* cameraId = testCase.getCameraId(i);
2987 if (cameraId == nullptr) {
2988 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2989 goto cleanup;
2990 }
2991
2992 ret = ACameraManager_getCameraCharacteristics(
2993 mgr, cameraId, &chars);
2994 if (ret != ACAMERA_OK) {
2995 LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
2996 goto cleanup;
2997 }
2998
2999 StaticInfo staticInfo(chars);
3000 ACameraMetadata_const_entry sessionParamKeys{};
3001 ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_SESSION_KEYS,
3002 &sessionParamKeys);
3003 if ((ret != ACAMERA_OK) || (sessionParamKeys.count == 0) ||
3004 !staticInfo.isColorOutputSupported()) {
3005 ACameraMetadata_free(chars);
3006 chars = nullptr;
3007 continue;
3008 }
3009
3010 ret = testCase.openCamera(cameraId);
3011 if (ret != ACAMERA_OK) {
3012 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3013 goto cleanup;
3014 }
3015
3016 usleep(100000); // sleep to give some time for callbacks to happen
3017
3018 if (testCase.isCameraAvailable(cameraId)) {
3019 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3020 goto cleanup;
3021 }
3022
3023 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
3024 if (previewAnw == nullptr) {
3025 LOG_ERROR(errorString, "Null ANW from preview surface!");
3026 goto cleanup;
3027 }
3028
3029 ret = testCase.createRequestsWithErrorLog();
3030 if (ret != ACAMERA_OK) {
3031 // Don't log error here. testcase did it
3032 goto cleanup;
3033 }
3034
3035 ACaptureRequest *previewRequest = nullptr;
3036 ret = testCase.getPreviewRequest(&previewRequest);
3037 if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
3038 LOG_ERROR(errorString, "Preview request query failed!");
3039 goto cleanup;
3040 }
3041
3042 ret = testCase.createCaptureSessionWithLog(/*isPreviewShared*/ false, previewRequest);
3043 if (ret != ACAMERA_OK) {
3044 // Don't log error here. testcase did it
3045 goto cleanup;
3046 }
3047
3048 ret = testCase.startPreview();
3049 if (ret != ACAMERA_OK) {
3050 LOG_ERROR(errorString, "Start preview failed!");
3051 goto cleanup;
3052 }
3053
3054 sleep(3);
3055
3056 ret = testCase.resetWithErrorLog();
3057 if (ret != ACAMERA_OK) {
3058 // Don't log error here. testcase did it
3059 goto cleanup;
3060 }
3061
3062 usleep(100000); // sleep to give some time for callbacks to happen
3063
3064 if (!testCase.isCameraAvailable(cameraId)) {
3065 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3066 goto cleanup;
3067 }
3068
3069 ACameraMetadata_free(chars);
3070 chars = nullptr;
3071 }
3072
3073 ret = testCase.deInit();
3074 if (ret != ACAMERA_OK) {
3075 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3076 goto cleanup;
3077 }
3078
3079 pass = true;
3080 cleanup:
3081 if (chars) {
3082 ACameraMetadata_free(chars);
3083 }
3084 ACameraManager_delete(mgr);
3085 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3086 if (!pass) {
3087 throwAssertionError(env, errorString);
3088 }
3089 return pass;
3090 }
3091
nativeCameraDeviceLogicalPhysicalStreaming(JNIEnv * env,jobject jPreviewSurface,bool usePhysicalSettings,jstring jOverrideCameraId)3092 bool nativeCameraDeviceLogicalPhysicalStreaming(
3093 JNIEnv* env, jobject jPreviewSurface, bool usePhysicalSettings,
3094 jstring jOverrideCameraId) {
3095 const int NUM_TEST_IMAGES = 10;
3096 const int TEST_WIDTH = 640;
3097 const int TEST_HEIGHT = 480;
3098 ALOGV("%s", __FUNCTION__);
3099 int numCameras = 0;
3100 bool pass = false;
3101 ACameraManager* mgr = ACameraManager_create();
3102 ACameraMetadata* chars = nullptr;
3103 media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3104 PreviewTestCase testCase;
3105 int64_t lastFrameNumber = 0;
3106 bool frameArrived = false;
3107 uint32_t timeoutSec = 1;
3108 uint32_t runPreviewSec = 2;
3109
3110 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
3111 if (ret != ACAMERA_OK) {
3112 // Don't log error here. testcase did it
3113 goto cleanup;
3114 }
3115
3116 numCameras = testCase.getNumCameras();
3117 if (numCameras < 0) {
3118 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
3119 goto cleanup;
3120 }
3121
3122 for (int i = 0; i < numCameras; i++) {
3123 const char* cameraId = testCase.getCameraId(i);
3124 if (cameraId == nullptr) {
3125 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3126 goto cleanup;
3127 }
3128
3129 if (chars != nullptr) {
3130 ACameraMetadata_free(chars);
3131 chars = nullptr;
3132 }
3133 chars = testCase.getCameraChars(i);
3134 if (chars == nullptr) {
3135 LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3136 goto cleanup;
3137 }
3138
3139 size_t physicalCameraCnt = 0;
3140 const char *const* physicalCameraIds = nullptr;
3141 if (!ACameraMetadata_isLogicalMultiCamera(
3142 chars, &physicalCameraCnt, &physicalCameraIds)) {
3143 continue;
3144 }
3145 if (physicalCameraCnt < 2) {
3146 LOG_ERROR(errorString, "Logical camera device %s only has %zu physical cameras",
3147 cameraId, physicalCameraCnt);
3148 goto cleanup;
3149 }
3150
3151 std::vector<const char*> candidateIds;
3152 for (size_t i = 0; i < physicalCameraCnt && candidateIds.size() < 2; i++) {
3153 ACameraMetadata* physicalChars = testCase.getCameraChars(physicalCameraIds[i]);
3154 if (physicalChars == nullptr) {
3155 LOG_ERROR(errorString,
3156 "Get camera %s characteristics failure", physicalCameraIds[i]);
3157 goto cleanup;
3158 }
3159 StaticInfo info(physicalChars);
3160 bool testSizeSupported = info.isSizeSupportedForFormat(AIMAGE_FORMAT_YUV_420_888,
3161 TEST_WIDTH, TEST_HEIGHT);
3162 ACameraMetadata_free(physicalChars);
3163 if (!testSizeSupported) {
3164 continue;
3165 }
3166 candidateIds.push_back(physicalCameraIds[i]);
3167 }
3168 if (candidateIds.size() < 2) {
3169 continue;
3170 }
3171
3172 // Check physical camera request keys
3173 if (usePhysicalSettings) {
3174 ACameraMetadata_const_entry entry;
3175 camera_status_t status = ACameraMetadata_getConstEntry(
3176 chars, ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &entry);
3177 if (status == ACAMERA_ERROR_METADATA_NOT_FOUND) {
3178 // No supported PHYSICAL_CAMERA_REQUEST_KEYS, skip test
3179 continue;
3180 } else if (status != ACAMERA_OK) {
3181 // Do not log error here. testcase did it.
3182 goto cleanup;
3183 } else if (entry.count == 0) {
3184 // No supported PHYSICAL_CAMERA_REQUEST_KEYS, skip test
3185 continue;
3186 }
3187 }
3188
3189 ret = testCase.openCamera(cameraId);
3190 if (ret != ACAMERA_OK) {
3191 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3192 goto cleanup;
3193 }
3194
3195 usleep(100000); // sleep to give some time for callbacks to happen
3196
3197 if (testCase.isCameraAvailable(cameraId)) {
3198 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3199 goto cleanup;
3200 }
3201
3202 std::vector<ImageReaderListener> readerListeners(2);
3203 std::vector<AImageReader_ImageListener> readerCbs;
3204 std::vector<AImageReader*> readers;
3205 std::vector<ANativeWindow*> readerAnws;
3206 std::vector<ACaptureSessionOutput*> readerSessionOutputs;
3207 std::vector<ACameraOutputTarget*> readerOutputs;
3208 for (size_t i = 0; i < 2; i++) {
3209 AImageReader_ImageListener readerCb {
3210 &readerListeners[i],
3211 ImageReaderListener::validateImageCb
3212 };
3213 readerCbs.push_back(readerCb);
3214
3215 AImageReader* reader = nullptr;
3216 ANativeWindow* readerAnw = nullptr;
3217 ACaptureSessionOutput* readerSessionOutput = nullptr;
3218 ACameraOutputTarget* readerOutput = nullptr;
3219 mediaRet = testCase.initImageReaderWithErrorLog(
3220 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES,
3221 &readerCb, &reader, &readerAnw);
3222 if (mediaRet != AMEDIA_OK) {
3223 // Don't log error here. testcase did it
3224 goto cleanup;
3225 }
3226
3227 camera_status_t ret = ACaptureSessionPhysicalOutput_create(readerAnw,
3228 candidateIds[i], &readerSessionOutput);
3229 if (ret != ACAMERA_OK || readerSessionOutput == nullptr) {
3230 if (ret == ACAMERA_OK) {
3231 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
3232 }
3233 // Don't log error here. testcase did it
3234 goto cleanup;
3235 }
3236
3237 ret = ACameraOutputTarget_create(readerAnw, &readerOutput);
3238 if (ret != ACAMERA_OK) {
3239 // Don't log error here. testcase did it
3240 goto cleanup;
3241 }
3242
3243 readers.push_back(reader);
3244 readerAnws.push_back(readerAnw);
3245 readerSessionOutputs.push_back(readerSessionOutput);
3246 readerOutputs.push_back(readerOutput);
3247 }
3248
3249 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
3250 if (previewAnw == nullptr) {
3251 LOG_ERROR(errorString, "Null ANW from preview surface!");
3252 goto cleanup;
3253 }
3254
3255 ret = testCase.createCaptureSessionWithLog(readerSessionOutputs, false /*isPreviewShared*/,
3256 nullptr /*sessionParameters*/, false /*sessionConfigurationDefault*/);
3257 if (ret == ACAMERA_ERROR_UNSUPPORTED_OPERATION ||
3258 ret == ACAMERA_ERROR_STREAM_CONFIGURE_FAIL) {
3259 // Camera device doesn't support the stream combination, skip the
3260 // current camera.
3261 testCase.closeCamera();
3262 testCase.resetCamera();
3263 continue;
3264 } else if (ret != ACAMERA_OK) {
3265 // Don't log error here. testcase did it
3266 goto cleanup;
3267 }
3268
3269 if (usePhysicalSettings) {
3270 std::vector<const char*> twoNullStr = {nullptr, nullptr};
3271 ACameraIdList nullCameraIdList = {2, twoNullStr.data()};
3272 ret = testCase.createRequestsWithErrorLog(readerOutputs, &nullCameraIdList);
3273 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
3274 LOG_ERROR(errorString, "Null physical camera ids must fail createCaptureRequest. "
3275 "ret %d", ret);
3276 goto cleanup;
3277 }
3278
3279 std::string invalidId = "";
3280 std::vector<const char*> one0LengthStr = {invalidId.c_str()};
3281 ACameraIdList invalidCameraIdList = {1, one0LengthStr.data()};
3282 ret = testCase.createRequestsWithErrorLog(readerOutputs, &invalidCameraIdList);
3283 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
3284 LOG_ERROR(errorString, "zero-length physical camera ids must fail "
3285 "createCaptureRequest. ret %d", ret);
3286 goto cleanup;
3287 }
3288
3289 ACameraIdList physicalCameraIdList = {2, candidateIds.data()};
3290 ret = testCase.createRequestsWithErrorLog(readerOutputs, &physicalCameraIdList);
3291 } else {
3292 ret = testCase.createRequestsWithErrorLog(readerOutputs);
3293 }
3294 if (ret != ACAMERA_OK) {
3295 // Don't log error here. testcase did it
3296 goto cleanup;
3297 }
3298
3299 ACaptureRequest *previewRequest = nullptr;
3300 ret = testCase.getPreviewRequest(&previewRequest);
3301 if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
3302 LOG_ERROR(errorString, "Preview request query failed!");
3303 goto cleanup;
3304 }
3305
3306 int sequenceId = 0;
3307 ret = testCase.startPreview(&sequenceId, 2, candidateIds.data());
3308 if (ret != ACAMERA_OK) {
3309 LOG_ERROR(errorString, "Start preview failed!");
3310 goto cleanup;
3311 }
3312
3313 sleep(runPreviewSec);
3314
3315 ret = testCase.stopPreview();
3316 if (ret != ACAMERA_OK) {
3317 ALOGE("%s: stopPreview failed", __FUNCTION__);
3318 LOG_ERROR(errorString, "stopPreview failed!");
3319 goto cleanup;
3320 }
3321
3322 //Then wait for all old requests to flush
3323 lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
3324 if (lastFrameNumber < 0) {
3325 LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
3326 cameraId);
3327 goto cleanup;
3328 }
3329
3330 frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
3331 if (!frameArrived) {
3332 LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
3333 cameraId);
3334 goto cleanup;
3335 }
3336
3337 ret = testCase.resetWithErrorLog();
3338 if (ret != ACAMERA_OK) {
3339 // Don't log error here. testcase did it
3340 goto cleanup;
3341 }
3342
3343 usleep(100000); // sleep to give some time for callbacks to happen
3344
3345 if (!testCase.isCameraAvailable(cameraId)) {
3346 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3347 goto cleanup;
3348 }
3349 }
3350
3351 ret = testCase.deInit();
3352 if (ret != ACAMERA_OK) {
3353 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3354 goto cleanup;
3355 }
3356
3357 pass = true;
3358 cleanup:
3359 if (chars) {
3360 ACameraMetadata_free(chars);
3361 }
3362 ACameraManager_delete(mgr);
3363 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3364 if (!pass) {
3365 throwAssertionError(env, errorString);
3366 }
3367 return pass;
3368 }
3369
3370 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceLogicalPhysicalStreamingNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)3371 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3372 testCameraDeviceLogicalPhysicalStreamingNative(
3373 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
3374 jstring jOverrideCameraId) {
3375 return nativeCameraDeviceLogicalPhysicalStreaming(env,
3376 jPreviewSurface, false /*usePhysicalSettings*/,
3377 jOverrideCameraId);
3378 }
3379
3380 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceLogicalPhysicalSettingsNative(JNIEnv * env,jclass,jobject jPreviewSurface,jstring jOverrideCameraId)3381 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3382 testCameraDeviceLogicalPhysicalSettingsNative(
3383 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
3384 jstring jOverrideCameraId) {
3385 return nativeCameraDeviceLogicalPhysicalStreaming(env,
3386 jPreviewSurface, true /*usePhysicalSettings*/,
3387 jOverrideCameraId);
3388 }
3389
nativeImageReaderTestBase(JNIEnv * env,jstring jOutPath,jint format,AImageReader_ImageCallback cb,jstring jOverrideCameraId)3390 bool nativeImageReaderTestBase(
3391 JNIEnv* env, jstring jOutPath, jint format, AImageReader_ImageCallback cb,
3392 jstring jOverrideCameraId) {
3393 const int NUM_TEST_IMAGES = 10;
3394 media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3395 int numCameras = 0;
3396 bool pass = false;
3397 PreviewTestCase testCase;
3398 ACameraMetadata* chars = nullptr;
3399
3400 const char* outPath = (jOutPath == nullptr) ? nullptr :
3401 env->GetStringUTFChars(jOutPath, nullptr);
3402 if (outPath != nullptr) {
3403 ALOGI("%s: out path is %s", __FUNCTION__, outPath);
3404 }
3405
3406 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
3407 if (ret != ACAMERA_OK) {
3408 // Don't log error here. testcase did it
3409 goto cleanup;
3410 }
3411
3412 numCameras = testCase.getNumCameras();
3413 if (numCameras < 0) {
3414 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
3415 goto cleanup;
3416 }
3417
3418 for (int i = 0; i < numCameras; i++) {
3419 const char* cameraId = testCase.getCameraId(i);
3420 if (cameraId == nullptr) {
3421 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3422 goto cleanup;
3423 }
3424
3425 {
3426 ACameraMetadata* chars = testCase.getCameraChars(cameraId);
3427 StaticInfo staticInfo(chars);
3428 if (!staticInfo.isColorOutputSupported()) {
3429 ALOGI("%s: camera %s does not support color output. skipping",
3430 __FUNCTION__, cameraId);
3431 ACameraMetadata_free(chars);
3432 continue;
3433 }
3434 ACameraMetadata_free(chars);
3435 }
3436
3437 ret = testCase.openCamera(cameraId);
3438 if (ret != ACAMERA_OK) {
3439 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3440 goto cleanup;
3441 }
3442
3443 chars = testCase.getCameraChars(i);
3444 if (chars == nullptr) {
3445 LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3446 goto cleanup;
3447 }
3448 StaticInfo staticInfo(chars);
3449
3450 usleep(200000); // sleep to give some time for callbacks to happen
3451
3452 if (testCase.isCameraAvailable(cameraId)) {
3453 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3454 goto cleanup;
3455 }
3456
3457 ImageReaderListener readerListener;
3458 AImageReader_ImageListener readerCb { &readerListener, cb };
3459 readerListener.setDumpFilePathBase(outPath);
3460
3461 int32_t testWidth, testHeight;
3462 switch (format) {
3463 case AIMAGE_FORMAT_JPEG:
3464 case AIMAGE_FORMAT_Y8:
3465 case AIMAGE_FORMAT_HEIC:
3466 case AIMAGE_FORMAT_DEPTH_JPEG:
3467 if (!staticInfo.getMaxSizeForFormat(format, &testWidth, &testHeight)) {
3468 // No corresponding format support, skip this device.
3469 ACameraMetadata_free(chars);
3470 chars = nullptr;
3471 ret = testCase.closeCamera();
3472 if (ret != ACAMERA_OK) {
3473 LOG_ERROR(errorString, "Camera %s failed to close. ret %d ", cameraId, ret);
3474 goto cleanup;
3475 }
3476
3477 continue;
3478 }
3479 break;
3480 default:
3481 LOG_ERROR(errorString, "Testcase doesn't yet support format %d", format);
3482 goto cleanup;
3483 }
3484 mediaRet = testCase.initImageReaderWithErrorLog(
3485 testWidth, testHeight, format, NUM_TEST_IMAGES,
3486 &readerCb);
3487 if (mediaRet != AMEDIA_OK) {
3488 // Don't log error here. testcase did it
3489 goto cleanup;
3490 }
3491
3492 ret = testCase.createCaptureSessionWithLog();
3493 if (ret != ACAMERA_OK) {
3494 // Don't log error here. testcase did it
3495 goto cleanup;
3496 }
3497
3498 ret = testCase.createRequestsWithErrorLog();
3499 if (ret != ACAMERA_OK) {
3500 // Don't log error here. testcase did it
3501 goto cleanup;
3502 }
3503
3504 CaptureResultListener resultListener;
3505 ACameraCaptureSession_captureCallbacks resultCb {
3506 &resultListener,
3507 CaptureResultListener::onCaptureStart,
3508 CaptureResultListener::onCaptureProgressed,
3509 CaptureResultListener::onCaptureCompleted,
3510 CaptureResultListener::onCaptureFailed,
3511 CaptureResultListener::onCaptureSequenceCompleted,
3512 CaptureResultListener::onCaptureSequenceAborted,
3513 CaptureResultListener::onCaptureBufferLost
3514 };
3515 resultListener.setRequestSave(true);
3516 ACaptureRequest* requestTemplate = nullptr;
3517 ret = testCase.getStillRequest(&requestTemplate);
3518 if (ret != ACAMERA_OK || requestTemplate == nullptr) {
3519 // Don't log error here. testcase did it
3520 goto cleanup;
3521 }
3522
3523 // Do some still capture
3524 int lastSeqId = -1;
3525 for (intptr_t capture = 0; capture < NUM_TEST_IMAGES; capture++) {
3526 ACaptureRequest* req = ACaptureRequest_copy(requestTemplate);
3527 ACaptureRequest_setUserContext(req, (void*) capture);
3528 int seqId;
3529 ret = testCase.capture(req, &resultCb, &seqId);
3530 if (ret != ACAMERA_OK) {
3531 LOG_ERROR(errorString, "Camera %s capture(%" PRIdPTR ") failed. ret %d",
3532 cameraId, capture, ret);
3533 goto cleanup;
3534 }
3535 if (capture == NUM_TEST_IMAGES - 1) {
3536 lastSeqId = seqId;
3537 }
3538 ACaptureRequest_free(req);
3539 }
3540
3541 // wait until last sequence complete
3542 resultListener.getCaptureSequenceLastFrameNumber(lastSeqId, /*timeoutSec*/ 5);
3543
3544 std::vector<ACaptureRequest*> completedRequests;
3545 resultListener.getCompletedRequests(&completedRequests);
3546
3547 if (completedRequests.size() != NUM_TEST_IMAGES) {
3548 LOG_ERROR(errorString, "Camera %s fails to capture %d capture results. Got %zu",
3549 cameraId, NUM_TEST_IMAGES, completedRequests.size());
3550 goto cleanup;
3551 }
3552
3553 for (intptr_t i = 0; i < NUM_TEST_IMAGES; i++) {
3554 intptr_t userContext = -1;
3555 ret = ACaptureRequest_getUserContext(completedRequests[i], (void**) &userContext);
3556 if (ret != ACAMERA_OK) {
3557 LOG_ERROR(errorString, "Camera %s fails to get request user context", cameraId);
3558 goto cleanup;
3559 }
3560
3561 if (userContext != i) {
3562 LOG_ERROR(errorString, "Camera %s fails to return matching user context. "
3563 "Expect %" PRIdPTR ", got %" PRIdPTR, cameraId, i, userContext);
3564 goto cleanup;
3565 }
3566 }
3567
3568 int64_t minFrameDurationNs = staticInfo.getMinFrameDurationFor(
3569 format, testWidth, testHeight);
3570 if (minFrameDurationNs < 0) {
3571 LOG_ERROR(errorString, "Get camera %s minFrameDuration failed", cameraId);
3572 goto cleanup;
3573 }
3574 int64_t stallDurationNs = (format == AIMAGE_FORMAT_Y8) ? 0 :
3575 staticInfo.getStallDurationFor(format, testWidth, testHeight);
3576 if (stallDurationNs < 0) {
3577 LOG_ERROR(errorString, "Get camera %s stallDuration failed", cameraId);
3578 goto cleanup;
3579 }
3580
3581 int64_t expectedDurationNs = (minFrameDurationNs + stallDurationNs) * NUM_TEST_IMAGES;
3582 constexpr int64_t waitPerIterationUs = 100000;
3583 constexpr int64_t usToNs = 1000;
3584 int totalWaitIteration = 50;
3585
3586 // Allow 1.5x margin
3587 if (expectedDurationNs * 3 / 2 > totalWaitIteration * waitPerIterationUs * usToNs) {
3588 totalWaitIteration = expectedDurationNs * 3 / 2 / waitPerIterationUs / usToNs;
3589 }
3590
3591 // wait until all capture finished
3592 for (int i = 0; i < totalWaitIteration; i++) {
3593 usleep(waitPerIterationUs);
3594 if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
3595 ALOGI("Session take ~%d ms to capture %d images",
3596 i*100, NUM_TEST_IMAGES);
3597 break;
3598 }
3599 }
3600
3601 if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
3602 LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
3603 cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
3604 goto cleanup;
3605 }
3606
3607 ret = testCase.resetWithErrorLog();
3608 if (ret != ACAMERA_OK) {
3609 // Don't log error here. testcase did it
3610 goto cleanup;
3611 }
3612
3613 usleep(200000); // sleep to give some time for callbacks to happen
3614
3615 if (!testCase.isCameraAvailable(cameraId)) {
3616 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3617 goto cleanup;
3618 }
3619 }
3620
3621 ret = testCase.deInit();
3622 if (ret != ACAMERA_OK) {
3623 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3624 goto cleanup;
3625 }
3626
3627 pass = true;
3628
3629 cleanup:
3630 if (outPath != nullptr) {
3631 env->ReleaseStringUTFChars(jOutPath, outPath);
3632 }
3633
3634 if (chars != nullptr) {
3635 ACameraMetadata_free(chars);
3636 chars = nullptr;
3637 }
3638
3639 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3640 if (!pass) {
3641 throwAssertionError(env, errorString);
3642 }
3643 return pass;
3644 }
3645
3646 // Test the camera NDK capture failure path by acquiring the maximum amount of
3647 // ImageReader buffers available. Since there is no circulation of camera
3648 // images, the registered output surface will eventually run out of free buffers
3649 // and start reporting capture errors or lost buffers.
3650 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceCaptureFailureNative(JNIEnv * env,jclass,jstring jOverrideCameraId)3651 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3652 testCameraDeviceCaptureFailureNative(JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
3653 const size_t NUM_TEST_IMAGES = 10;
3654 const size_t NUM_FAILED_FRAMES = 3; // Wait for at least 3 consecutive failed capture requests
3655 const int64_t NUM_TOTAL_FRAMES = 60; // Avoid waiting for more than 60 frames
3656 const size_t TEST_WIDTH = 640;
3657 const size_t TEST_HEIGHT = 480;
3658 media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3659 int numCameras = 0;
3660 bool pass = false;
3661 PreviewTestCase testCase;
3662 uint32_t bufferTimeoutSec = 1;
3663 uint32_t timeoutSec = 10; // It is important to keep this timeout bigger than the framework
3664 // timeout
3665
3666 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
3667 if (ret != ACAMERA_OK) {
3668 // Don't log error here. testcase did it
3669 goto exit;
3670 }
3671
3672 numCameras = testCase.getNumCameras();
3673 if (numCameras < 0) {
3674 LOG_ERROR(errorString, "Testcase returned negative number of cameras: %d", numCameras);
3675 goto exit;
3676 }
3677
3678 for (int i = 0; i < numCameras; i++) {
3679 const char* cameraId = testCase.getCameraId(i);
3680 if (cameraId == nullptr) {
3681 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3682 goto exit;
3683 }
3684
3685 std::unique_ptr<ACameraMetadata> chars(testCase.getCameraChars(i));
3686 if (chars.get() == nullptr) {
3687 LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3688 goto exit;
3689 }
3690 StaticInfo staticInfo(chars.get());
3691
3692 if (!staticInfo.isColorOutputSupported()) {
3693 continue;
3694 }
3695
3696 ret = testCase.openCamera(cameraId);
3697 if (ret != ACAMERA_OK) {
3698 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3699 goto exit;
3700 }
3701
3702 usleep(100000); // sleep to give some time for callbacks to happen
3703
3704 if (testCase.isCameraAvailable(cameraId)) {
3705 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3706 goto exit;
3707 }
3708
3709 ImageReaderListener readerListener;
3710 AImageReader_ImageListener readerCb =
3711 { &readerListener, ImageReaderListener::signalImageCb };
3712 mediaRet = testCase.initImageReaderWithErrorLog(TEST_WIDTH, TEST_HEIGHT,
3713 AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES, &readerCb);
3714 if (mediaRet != AMEDIA_OK) {
3715 // Don't log error here. testcase did it
3716 goto exit;
3717 }
3718
3719 ret = testCase.createCaptureSessionWithLog();
3720 if (ret != ACAMERA_OK) {
3721 // Don't log error here. testcase did it
3722 goto exit;
3723 }
3724
3725 ret = testCase.createRequestsWithErrorLog();
3726 if (ret != ACAMERA_OK) {
3727 // Don't log error here. testcase did it
3728 goto exit;
3729 }
3730
3731 CaptureResultListener resultListener;
3732 ACameraCaptureSession_captureCallbacks resultCb {
3733 &resultListener,
3734 CaptureResultListener::onCaptureStart,
3735 CaptureResultListener::onCaptureProgressed,
3736 CaptureResultListener::onCaptureCompleted,
3737 CaptureResultListener::onCaptureFailed,
3738 CaptureResultListener::onCaptureSequenceCompleted,
3739 CaptureResultListener::onCaptureSequenceAborted,
3740 CaptureResultListener::onCaptureBufferLost
3741 };
3742 ACaptureRequest* requestTemplate = nullptr;
3743 ret = testCase.getStillRequest(&requestTemplate);
3744 if (ret != ACAMERA_OK || requestTemplate == nullptr) {
3745 // Don't log error here. testcase did it
3746 goto exit;
3747 }
3748
3749 int seqId;
3750 ret = testCase.startRepeatingRequest(&seqId, requestTemplate, &resultCb);
3751 if (ret != ACAMERA_OK) {
3752 // Don't log error here. testcase did it
3753 goto exit;
3754 }
3755
3756 size_t failedRequestCount;
3757 int64_t lastFrameNumber;
3758 int64_t lastFailedRequestNumber = -1;
3759 failedRequestCount = lastFrameNumber = 0;
3760 while ((failedRequestCount < NUM_FAILED_FRAMES) && (lastFrameNumber < NUM_TOTAL_FRAMES)) {
3761 auto frameArrived = resultListener.waitForFrameNumber(lastFrameNumber, timeoutSec);
3762 if (!frameArrived) {
3763 LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
3764 cameraId);
3765 goto exit;
3766 }
3767 readerListener.waitForNextBuffer(bufferTimeoutSec);
3768 auto failedFrameNumber = resultListener.checkForFailureOrLoss(lastFrameNumber) ?
3769 lastFrameNumber : -1;
3770 if (lastFailedRequestNumber != failedFrameNumber) {
3771 if ((lastFailedRequestNumber + 1) == failedFrameNumber) {
3772 failedRequestCount++;
3773 } else {
3774 failedRequestCount = 1;
3775 }
3776 lastFailedRequestNumber = failedFrameNumber;
3777 }
3778 lastFrameNumber++;
3779 }
3780
3781 ret = testCase.abortCaptures();
3782 if (ret != ACAMERA_OK) {
3783 LOG_ERROR(errorString, "abort captures failed!");
3784 goto exit;
3785 }
3786
3787 ret = testCase.resetWithErrorLog();
3788 if (ret != ACAMERA_OK) {
3789 // Don't log error here. testcase did it
3790 goto exit;
3791 }
3792
3793 usleep(100000); // sleep to give some time for callbacks to happen
3794
3795 if (!testCase.isCameraAvailable(cameraId)) {
3796 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3797 goto exit;
3798 }
3799
3800 if (failedRequestCount < NUM_FAILED_FRAMES) {
3801 LOG_ERROR(errorString, "Unable to receive %zu consecutive capture failures within"
3802 " %" PRId64 " capture requests", NUM_FAILED_FRAMES, NUM_TOTAL_FRAMES);
3803 goto exit;
3804 }
3805 }
3806
3807 ret = testCase.deInit();
3808 if (ret != ACAMERA_OK) {
3809 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3810 goto exit;
3811 }
3812
3813 pass = true;
3814
3815 exit:
3816
3817 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3818 if (!pass) {
3819 throwAssertionError(env, errorString);
3820 }
3821
3822 return pass;
3823 }
3824
3825 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testJpegNative(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)3826 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3827 testJpegNative(
3828 JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
3829 jstring jOverrideCameraId) {
3830 ALOGV("%s", __FUNCTION__);
3831 return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_JPEG,
3832 ImageReaderListener::validateImageCb, jOverrideCameraId);
3833 }
3834
3835 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testY8Native(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)3836 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3837 testY8Native(
3838 JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
3839 jstring jOverrideCameraId) {
3840 ALOGV("%s", __FUNCTION__);
3841 return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_Y8,
3842 ImageReaderListener::validateImageCb, jOverrideCameraId);
3843 }
3844
3845 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testHeicNative(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)3846 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3847 testHeicNative(
3848 JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
3849 jstring jOverrideCameraId) {
3850 ALOGV("%s", __FUNCTION__);
3851 return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_HEIC,
3852 ImageReaderListener::validateImageCb, jOverrideCameraId);
3853 }
3854
3855 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testDepthJpegNative(JNIEnv * env,jclass,jstring jOutPath,jstring jOverrideCameraId)3856 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3857 testDepthJpegNative(
3858 JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
3859 jstring jOverrideCameraId) {
3860 ALOGV("%s", __FUNCTION__);
3861 return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_DEPTH_JPEG,
3862 ImageReaderListener::validateImageCb, jOverrideCameraId);
3863 }
3864
3865 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testImageReaderCloseAcquiredImagesNative(JNIEnv * env,jclass,jstring jOverrideCameraId)3866 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3867 testImageReaderCloseAcquiredImagesNative(
3868 JNIEnv* env, jclass /*clazz*/,
3869 jstring jOverrideCameraId) {
3870 ALOGV("%s", __FUNCTION__);
3871 return nativeImageReaderTestBase(env, nullptr, AIMAGE_FORMAT_JPEG,
3872 ImageReaderListener::acquireImageCb, jOverrideCameraId);
3873 }
3874
3875 template <>
3876 struct std::default_delete<ACameraManager> {
operator ()std::default_delete3877 inline void operator()(ACameraManager* manager) const { ACameraManager_delete(manager); }
3878 };
3879
3880 class AvailabilityContext {
3881 public:
3882 AvailabilityContext();
3883 ~AvailabilityContext();
3884
3885 camera_status_t initialize();
3886 int getAcessCallbackCountAndReset();
3887
3888 private:
3889 std::unique_ptr<ACameraManager> mCameraManager;
3890 std::unique_ptr<CameraServiceListener> mServiceListener;
3891 std::unique_ptr<ACameraManager_ExtendedAvailabilityCallbacks> mServiceCb;
3892 };
3893
AvailabilityContext()3894 AvailabilityContext::AvailabilityContext() :
3895 mCameraManager(ACameraManager_create()),
3896 mServiceListener(std::make_unique<CameraServiceListener>()),
3897 mServiceCb(std::make_unique<ACameraManager_ExtendedAvailabilityCallbacks>()) {
3898 mServiceCb->availabilityCallbacks.context = mServiceListener.get();
3899 mServiceCb->availabilityCallbacks.onCameraAvailable = CameraServiceListener::onAvailable;
3900 mServiceCb->availabilityCallbacks.onCameraUnavailable =
3901 CameraServiceListener::onUnavailable;
3902 mServiceCb->onCameraAccessPrioritiesChanged =
3903 CameraServiceListener::onCameraAccessPrioritiesChanged;
3904 mServiceCb->onPhysicalCameraAvailable =
3905 CameraServiceListener::onPhysicalCameraAvailable;
3906 mServiceCb->onPhysicalCameraUnavailable =
3907 CameraServiceListener::onPhysicalCameraUnavailable;
3908 }
3909
initialize()3910 camera_status_t AvailabilityContext::initialize() {
3911 auto rc = ACameraManager_registerExtendedAvailabilityCallback(mCameraManager.get(),
3912 mServiceCb.get());
3913 if (rc != ACAMERA_OK) {
3914 LOG_ERROR(errorString, "Register availability callback failed: rc %d", rc);
3915 return rc;
3916 }
3917
3918 ACameraIdList* cameraIdList = nullptr;
3919 rc = ACameraManager_getCameraIdList(mCameraManager.get(), &cameraIdList);
3920 if (rc != ACAMERA_OK) {
3921 LOG_ERROR(errorString, "Get camera id list failed: ret %d", rc);
3922 return rc;
3923 }
3924 ACameraManager_deleteCameraIdList(cameraIdList);
3925
3926 return rc;
3927 }
3928
getAcessCallbackCountAndReset()3929 int AvailabilityContext::getAcessCallbackCountAndReset() {
3930 auto ret = mServiceListener->getCameraAccessPrioritiesChangedCount();
3931 mServiceListener->resetCount();
3932 return ret;
3933 }
3934
~AvailabilityContext()3935 AvailabilityContext::~AvailabilityContext() {
3936 if (mServiceCb != nullptr) {
3937 camera_status_t ret = ACameraManager_unregisterExtendedAvailabilityCallback(
3938 mCameraManager.get(), mServiceCb.get());
3939 if (ret != ACAMERA_OK) {
3940 ALOGE("Unregister availability callback failed: ret %d", ret);
3941 }
3942 }
3943 }
3944
3945 extern "C" jlong
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_initializeAvailabilityCallbacksNative(JNIEnv * env,jclass)3946 Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
3947 initializeAvailabilityCallbacksNative(
3948 JNIEnv* env, jclass /*clazz*/) {
3949 ALOGV("%s", __FUNCTION__);
3950
3951 AvailabilityContext *ctx = new AvailabilityContext();
3952
3953 auto rc = ctx->initialize();
3954 if (rc != ACAMERA_OK) {
3955 LOG_ERROR(errorString, "Availability context initialization failed: %d", rc);
3956 return 0;
3957 }
3958
3959 return (jlong) ctx;
3960 }
3961
3962 extern "C" jint
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_getAccessCallbacksCountAndResetNative(JNIEnv * env,jclass,jlong context)3963 Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
3964 getAccessCallbacksCountAndResetNative(
3965 JNIEnv* env, jclass /*clazz*/, jlong context) {
3966 ALOGV("%s", __FUNCTION__);
3967
3968 if (context == 0) {
3969 LOG_ERROR(errorString, "Invalid availability context");
3970 return 0;
3971 }
3972
3973 AvailabilityContext* ctx = reinterpret_cast<AvailabilityContext*>(context);
3974 return ctx->getAcessCallbackCountAndReset();
3975 }
3976
3977 extern "C" void
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_releaseAvailabilityCallbacksNative(JNIEnv * env,jclass,jlong context)3978 Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
3979 releaseAvailabilityCallbacksNative(
3980 JNIEnv* env, jclass /*clazz*/, jlong context) {
3981 ALOGV("%s", __FUNCTION__);
3982
3983 if (context == 0) {
3984 return;
3985 }
3986
3987 AvailabilityContext* ctx = reinterpret_cast<AvailabilityContext*>(context);
3988 delete ctx;
3989 }
3990
3991 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeStillCaptureTest_testStillCaptureNative(JNIEnv * env,jclass,jstring jOutPath,jobject jPreviewSurface,jstring jOverrideCameraId)3992 Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
3993 testStillCaptureNative(
3994 JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface,
3995 jstring jOverrideCameraId) {
3996 ALOGV("%s", __FUNCTION__);
3997 const int NUM_TEST_IMAGES = 10;
3998 media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3999 int numCameras = 0;
4000 bool pass = false;
4001 PreviewTestCase testCase;
4002 ACameraMetadata* chars = nullptr;
4003
4004 const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
4005 ALOGI("%s: out path is %s", __FUNCTION__, outPath);
4006
4007 camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
4008 if (ret != ACAMERA_OK) {
4009 // Don't log error here. testcase did it
4010 goto cleanup;
4011 }
4012
4013 numCameras = testCase.getNumCameras();
4014 if (numCameras < 0) {
4015 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
4016 goto cleanup;
4017 }
4018
4019 for (int i = 0; i < numCameras; i++) {
4020 const char* cameraId = testCase.getCameraId(i);
4021 if (cameraId == nullptr) {
4022 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
4023 goto cleanup;
4024 }
4025
4026 {
4027 ACameraMetadata* chars = testCase.getCameraChars(cameraId);
4028 StaticInfo staticInfo(chars);
4029 if (!staticInfo.isColorOutputSupported()) {
4030 ALOGI("%s: camera %s does not support color output. skipping",
4031 __FUNCTION__, cameraId);
4032 ACameraMetadata_free(chars);
4033 continue;
4034 }
4035 ACameraMetadata_free(chars);
4036 }
4037
4038 ret = testCase.openCamera(cameraId);
4039 if (ret != ACAMERA_OK) {
4040 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
4041 goto cleanup;
4042 }
4043
4044 chars = testCase.getCameraChars(i);
4045 if (chars == nullptr) {
4046 LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
4047 goto cleanup;
4048 }
4049 StaticInfo staticInfo(chars);
4050
4051 usleep(100000); // sleep to give some time for callbacks to happen
4052
4053 if (testCase.isCameraAvailable(cameraId)) {
4054 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
4055 goto cleanup;
4056 }
4057
4058 ImageReaderListener readerListener;
4059 AImageReader_ImageListener readerCb {
4060 &readerListener,
4061 ImageReaderListener::validateImageCb
4062 };
4063 readerListener.setDumpFilePathBase(outPath);
4064 int32_t testWidth, testHeight;
4065 if (!staticInfo.getMaxSizeForFormat(AIMAGE_FORMAT_JPEG, &testWidth, &testHeight)) {
4066 goto cleanup;
4067 }
4068 mediaRet = testCase.initImageReaderWithErrorLog(
4069 testWidth, testHeight, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES,
4070 &readerCb);
4071 if (mediaRet != AMEDIA_OK) {
4072 // Don't log error here. testcase did it
4073 goto cleanup;
4074 }
4075
4076 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
4077 if (previewAnw == nullptr) {
4078 LOG_ERROR(errorString, "Null ANW from preview surface!");
4079 goto cleanup;
4080 }
4081
4082 ret = testCase.createCaptureSessionWithLog();
4083 if (ret != ACAMERA_OK) {
4084 // Don't log error here. testcase did it
4085 goto cleanup;
4086 }
4087
4088 ret = testCase.createRequestsWithErrorLog();
4089 if (ret != ACAMERA_OK) {
4090 // Don't log error here. testcase did it
4091 goto cleanup;
4092 }
4093
4094 ret = testCase.startPreview();
4095 if (ret != ACAMERA_OK) {
4096 LOG_ERROR(errorString, "Start preview failed!");
4097 goto cleanup;
4098 }
4099
4100 // Let preview run some time
4101 sleep(3);
4102
4103 // Do some still capture
4104 for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
4105 ret = testCase.takePicture();
4106 if (ret != ACAMERA_OK) {
4107 LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
4108 cameraId, capture, ret);
4109 goto cleanup;
4110 }
4111 }
4112
4113 int64_t minFrameDurationNs = staticInfo.getMinFrameDurationFor(
4114 AIMAGE_FORMAT_JPEG, testWidth, testHeight);
4115 if (minFrameDurationNs < 0) {
4116 LOG_ERROR(errorString, "Get camera %s minFrameDuration failed", cameraId);
4117 goto cleanup;
4118 }
4119 int64_t stallDurationNs = staticInfo.getStallDurationFor(
4120 AIMAGE_FORMAT_JPEG, testWidth, testHeight);
4121 if (stallDurationNs < 0) {
4122 LOG_ERROR(errorString, "Get camera %s stallDuration failed", cameraId);
4123 goto cleanup;
4124 }
4125
4126 int64_t expectedDurationNs = (minFrameDurationNs + stallDurationNs) * NUM_TEST_IMAGES;
4127 constexpr int64_t waitPerIterationUs = 100000;
4128 constexpr int64_t usToNs = 1000;
4129 int totalWaitIteration = 50;
4130
4131 // Allow 1.5x margin
4132 if (expectedDurationNs * 3 / 2 > totalWaitIteration * waitPerIterationUs * usToNs) {
4133 totalWaitIteration = expectedDurationNs * 3 / 2 / waitPerIterationUs / usToNs;
4134 }
4135
4136 // wait until all capture finished
4137 for (int i = 0; i < totalWaitIteration; i++) {
4138 usleep(waitPerIterationUs);
4139 if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
4140 ALOGI("Session take ~%d ms to capture %d images",
4141 i*100, NUM_TEST_IMAGES);
4142 break;
4143 }
4144 }
4145
4146 if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
4147 LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
4148 cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
4149 goto cleanup;
4150 }
4151
4152 ret = testCase.resetWithErrorLog();
4153 if (ret != ACAMERA_OK) {
4154 // Don't log error here. testcase did it
4155 goto cleanup;
4156 }
4157
4158 usleep(100000); // sleep to give some time for callbacks to happen
4159
4160 if (!testCase.isCameraAvailable(cameraId)) {
4161 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
4162 goto cleanup;
4163 }
4164 }
4165
4166 ret = testCase.deInit();
4167 if (ret != ACAMERA_OK) {
4168 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
4169 goto cleanup;
4170 }
4171
4172 pass = true;
4173 cleanup:
4174 env->ReleaseStringUTFChars(jOutPath, outPath);
4175
4176 if (chars != nullptr) {
4177 ACameraMetadata_free(chars);
4178 chars = nullptr;
4179 }
4180
4181 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
4182 if (!pass) {
4183 throwAssertionError(env, errorString);
4184 }
4185 return pass;
4186 }
4187
4188 extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_validateACameraMetadataFromCameraMetadataCriticalTagsNative(JNIEnv * env,jclass,jobject captureResult,jlong javaTimestamp)4189 Java_android_hardware_camera2_cts_CaptureResultTest_\
4190 validateACameraMetadataFromCameraMetadataCriticalTagsNative(
4191 JNIEnv* env, jclass /*clazz*/, jobject captureResult,
4192 jlong javaTimestamp) {
4193 ALOGV("%s", __FUNCTION__);
4194 ACameraMetadata* ndkResult =
4195 ACameraMetadata_fromCameraMetadata(env, captureResult);
4196 if (!ndkResult) {
4197 ALOGE("validateCriticalTags failed: "
4198 "ACameraMetadata_fromCameraMetadata returned nullptr.");
4199 return false;
4200 }
4201
4202 camera_status_t ret;
4203 ACameraMetadata_const_entry entry;
4204
4205 ret = ACameraMetadata_getConstEntry(ndkResult, ACAMERA_SENSOR_TIMESTAMP,
4206 &entry);
4207
4208 if (ret != ACAMERA_OK) {
4209 ALOGE("validateCriticalTags failed: "
4210 "ACameraMetadata_getConstEntry returned %d.", ret);
4211 ACameraMetadata_free(ndkResult);
4212 return false;
4213 }
4214 if (entry.type != ACAMERA_TYPE_INT64) {
4215 ALOGE("validateCriticalTags failed: entry.type is %u but should be %u.",
4216 entry.type, ACAMERA_TYPE_INT64);
4217 ACameraMetadata_free(ndkResult);
4218 return false;
4219 }
4220 if (entry.count != 1) {
4221 ALOGE("validateCriticalTags failed: entry.count is %u but should be %u.",
4222 entry.count, 1);
4223 ACameraMetadata_free(ndkResult);
4224 return false;
4225 }
4226 if (entry.data.i64 == nullptr) {
4227 ALOGE("validateCriticalTags failed: entry.data.i64 is nullptr.");
4228 ACameraMetadata_free(ndkResult);
4229 return false;
4230 }
4231
4232 const int64_t javaTimestampI64 = static_cast<int64_t>(javaTimestamp);
4233 const int64_t ndkTimestampI64 = *(entry.data.i64);
4234 ALOGV("javaTimestampI64 = %" PRId64 ", ndkTimestampI64 = %" PRId64,
4235 javaTimestampI64, ndkTimestampI64);
4236
4237 ACameraMetadata_free(ndkResult);
4238
4239 return (javaTimestampI64 == ndkTimestampI64);
4240 }
4241
4242 static ACameraMetadata *sStashedMetadata = nullptr;
4243
4244 // Test holding on to a ACameraMetadata past a single local JNI call
4245 extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_stashACameraMetadataFromCameraMetadataNative(JNIEnv * env,jclass,jobject captureResult)4246 Java_android_hardware_camera2_cts_CaptureResultTest_\
4247 stashACameraMetadataFromCameraMetadataNative(
4248 JNIEnv* env, jclass /*clazz*/, jobject captureResult) {
4249 ALOGV("%s", __FUNCTION__);
4250 ACameraMetadata* ndkResult =
4251 ACameraMetadata_fromCameraMetadata(env, captureResult);
4252 if (ndkResult == nullptr) return false;
4253 sStashedMetadata = ndkResult;
4254
4255 return true;
4256 }
4257
4258 extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_validateStashedACameraMetadataFromCameraMetadataNative(JNIEnv * env,jclass,jlong timestamp)4259 Java_android_hardware_camera2_cts_CaptureResultTest_\
4260 validateStashedACameraMetadataFromCameraMetadataNative(
4261 JNIEnv* env, jclass /*clazz*/, jlong timestamp) {
4262 ALOGV("%s", __FUNCTION__);
4263 if (sStashedMetadata == nullptr) return false;
4264
4265 camera_status_t ret;
4266 ACameraMetadata_const_entry entry;
4267
4268 ret = ACameraMetadata_getConstEntry(sStashedMetadata, ACAMERA_SENSOR_TIMESTAMP,
4269 &entry);
4270
4271 if (ret != ACAMERA_OK) {
4272 ALOGE("validateStashed failed: "
4273 "ACameraMetadata_getConstEntry returned %d.", ret);
4274 ACameraMetadata_free(sStashedMetadata);
4275 sStashedMetadata = nullptr;
4276 return false;
4277 }
4278 if (entry.type != ACAMERA_TYPE_INT64) {
4279 ALOGE("validateStashed failed: entry.type is %u but should be %u.",
4280 entry.type, ACAMERA_TYPE_INT64);
4281 ACameraMetadata_free(sStashedMetadata);
4282 sStashedMetadata = nullptr;
4283 return false;
4284 }
4285 if (entry.count != 1) {
4286 ALOGE("validateStashed failed: entry.count is %u but should be %u.",
4287 entry.count, 1);
4288 ACameraMetadata_free(sStashedMetadata);
4289 sStashedMetadata = nullptr;
4290 return false;
4291 }
4292 if (entry.data.i64 == nullptr) {
4293 ALOGE("validateStashed failed: entry.data.i64 is nullptr.");
4294 ACameraMetadata_free(sStashedMetadata);
4295 sStashedMetadata = nullptr;
4296 return false;
4297 }
4298
4299 const int64_t javaTimestampI64 = static_cast<int64_t>(timestamp);
4300 const int64_t ndkTimestampI64 = *(entry.data.i64);
4301
4302 ACameraMetadata_free(sStashedMetadata);
4303 sStashedMetadata = nullptr;
4304 ALOGV("javaTimestampI64 = %" PRId64 ", ndkTimestampI64 = %" PRId64,
4305 javaTimestampI64, ndkTimestampI64);
4306 return (javaTimestampI64 == ndkTimestampI64);
4307
4308 }
4309
4310
4311
4312 extern "C" jboolean
Java_android_hardware_camera2_cts_CameraManagerTest_validateACameraMetadataFromCameraMetadataCriticalTagsNative(JNIEnv * env,jclass,jobject cameraCharacteristics,jint javaLensFacing)4313 Java_android_hardware_camera2_cts_CameraManagerTest_\
4314 validateACameraMetadataFromCameraMetadataCriticalTagsNative(
4315 JNIEnv* env, jclass /*clazz*/, jobject cameraCharacteristics,
4316 jint javaLensFacing) {
4317 ALOGV("%s", __FUNCTION__);
4318 ACameraMetadata* ndkCharacteristics =
4319 ACameraMetadata_fromCameraMetadata(env, cameraCharacteristics);
4320 if (!ndkCharacteristics) {
4321 ALOGE("validateCriticalTags failed: "
4322 "ACameraMetadata_fromCameraMetadata returned nullptr.");
4323 return false;
4324 }
4325
4326 camera_status_t ret;
4327 ACameraMetadata_const_entry entry;
4328
4329 ret = ACameraMetadata_getConstEntry(ndkCharacteristics,
4330 ACAMERA_LENS_FACING, &entry);
4331 ACameraMetadata_free(ndkCharacteristics);
4332
4333 if (ret != ACAMERA_OK) {
4334 ALOGE("validateCriticalTags failed: "
4335 "ACameraMetadata_getConstEntry returned %d", ret);
4336 return false;
4337 }
4338 if (entry.type != ACAMERA_TYPE_BYTE) {
4339 ALOGE("validateCriticalTags failed: entry.type is %u but should be %u.",
4340 entry.type, ACAMERA_TYPE_BYTE);
4341 return false;
4342 }
4343 if (entry.count != 1) {
4344 ALOGE("validateCriticalTags failed: entry.count is %u but should be %u.",
4345 entry.count, 1);
4346 return false;
4347 }
4348 if (entry.data.u8 == nullptr) {
4349 ALOGE("validateCriticalTags failed: entry.data.u8 is nullptr.");
4350 return false;
4351 }
4352
4353 const uint8_t javaLensFacingU8 = static_cast<uint8_t>(javaLensFacing);
4354 const uint8_t ndkLensFacingU8 = *(entry.data.u8);
4355 ALOGV("javaLensFacingU8 = %d, ndkLensFacingU8 = %d",
4356 javaLensFacingU8, ndkLensFacingU8);
4357 return (javaLensFacingU8 == ndkLensFacingU8);
4358 }
4359