1/* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "ACameraCaptureSession.h" 18#include "ACameraMetadata.h" 19#include "ACaptureRequest.h" 20#include "utils.h" 21#include <CameraMetadata.h> 22#include <inttypes.h> 23#include <ndk_vendor/impl/ACameraDevice.h> 24#include <vector> 25 26using namespace android; 27 28namespace android { 29namespace acam { 30 31template<class T> 32camera_status_t CameraDevice::captureLocked( 33 sp<ACameraCaptureSession> session, 34 /*optional*/T* cbs, 35 int numRequests, 36 ACaptureRequest** requests, 37 /*optional*/int* captureSequenceId) { 38 return submitRequestsLocked( 39 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false); 40} 41 42template<class T> 43camera_status_t CameraDevice::setRepeatingRequestsLocked( 44 sp<ACameraCaptureSession> session, 45 /*optional*/T* cbs, 46 int numRequests, 47 ACaptureRequest** requests, 48 /*optional*/int* captureSequenceId) { 49 return submitRequestsLocked( 50 session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true); 51} 52 53template<class T> 54camera_status_t CameraDevice::submitRequestsLocked( 55 sp<ACameraCaptureSession> session, 56 /*optional*/T* cbs, int numRequests, 57 ACaptureRequest** requests, 58 /*out*/int* captureSequenceId, 59 bool isRepeating) { 60 camera_status_t ret = checkCameraClosedOrErrorLocked(); 61 if (ret != ACAMERA_OK) { 62 ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret); 63 return ret; 64 } 65 66 // Form two vectors of capture request, one for internal tracking 67 68 std::vector<::aidl::android::frameworks::cameraservice::device::CaptureRequest> requestList; 69 std::vector<sp<CaptureRequest>> requestsV; 70 requestsV.reserve(numRequests); 71 for (int i = 0; i < numRequests; i++) { 72 sp<CaptureRequest> req; 73 ret = allocateCaptureRequestLocked(requests[i], req); 74 // We need to call this method since after submitRequestList is called, 75 // the request metadata queue might have removed the capture request 76 // metadata. Therefore we simply add the metadata to its wrapper class, 77 // so that it can be retrieved later. 78 addRequestSettingsMetadata(requests[i], req); 79 if (ret != ACAMERA_OK) { 80 ALOGE("Convert capture request to internal format failure! ret %d", ret); 81 return ret; 82 } 83 if (req->mCaptureRequest.streamAndWindowIds.size() == 0) { 84 ALOGE("Capture request without output target cannot be submitted!"); 85 return ACAMERA_ERROR_INVALID_PARAMETER; 86 } 87 requestList.push_back(utils::convertToAidl(req.get())); 88 requestsV.push_back(req); 89 } 90 if (isRepeating) { 91 ret = stopRepeatingLocked(); 92 if (ret != ACAMERA_OK) { 93 ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret); 94 return ret; 95 } 96 } 97 98 SubmitInfo info; 99 Status status; 100 ndk::ScopedAStatus remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info); 101 if (!remoteRet.isOk()) { 102 if (remoteRet.getExceptionCode() == EX_SERVICE_SPECIFIC) { 103 Status errStatus = static_cast<Status>(remoteRet.getServiceSpecificError()); 104 ALOGE("%s: submitRequestList call failed: %s", 105 __FUNCTION__, toString(errStatus).c_str()); 106 return utils::convertFromAidl(errStatus); 107 } else { 108 ALOGE("%s: Transaction error for submitRequestList call: %d", __FUNCTION__, 109 remoteRet.getExceptionCode()); 110 return ACAMERA_ERROR_UNKNOWN; 111 } 112 } 113 114 int32_t sequenceId = info.requestId; 115 int64_t lastFrameNumber = info.lastFrameNumber; 116 if (sequenceId < 0) { 117 ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId); 118 return ACAMERA_ERROR_UNKNOWN; 119 } 120 121 CallbackHolder cbHolder(session, requestsV, isRepeating, cbs); 122 mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder)); 123 if (isRepeating) { 124 // stopRepeating above should have cleanup repeating sequence id 125 if (mRepeatingSequenceId != REQUEST_ID_NONE) { 126 setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE); 127 return ACAMERA_ERROR_CAMERA_DEVICE; 128 } 129 mRepeatingSequenceId = sequenceId; 130 } else { 131 mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber)); 132 } 133 134 if (mIdle) { 135 sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler); 136 msg->setPointer(kContextKey, session->mUserSessionCallback.context); 137 msg->setObject(kSessionSpKey, session); 138 msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive); 139 postSessionMsgAndCleanup(msg); 140 } 141 mIdle = false; 142 mBusySession = session; 143 144 if (captureSequenceId) { 145 *captureSequenceId = sequenceId; 146 } 147 return ACAMERA_OK; 148} 149 150} // namespace acam 151} // namespace android 152