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