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 #include <hardware/camera.h> 17 18 #include <hidl/AidlCameraDeviceCallbacks.h> 19 #include <hidl/Convert.h> 20 21 namespace android { 22 namespace frameworks { 23 namespace cameraservice { 24 namespace device { 25 namespace V2_0 { 26 namespace implementation { 27 28 using hardware::hidl_vec; 29 using HCaptureResultExtras = android::frameworks::cameraservice::device::V2_0::CaptureResultExtras; 30 using HPhysicalCaptureResultInfo = android::frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo; 31 using HCameraMetadata = android::frameworks::cameraservice::device::V2_0::CameraMetadata; 32 33 const char *H2BCameraDeviceCallbacks::kResultKey = "CaptureResult"; 34 35 H2BCameraDeviceCallbacks::H2BCameraDeviceCallbacks(const sp<HalInterface>& base) : CBase(base) { } 36 37 bool H2BCameraDeviceCallbacks::initializeLooper() { 38 mCbLooper = new ALooper; 39 mCbLooper->setName("cs-looper"); 40 status_t err = mCbLooper->start(/*runOnCallingThread*/ false, /*canCallJava*/ false, 41 PRIORITY_DEFAULT); 42 if (err !=OK) { 43 ALOGE("Unable to start camera device callback looper"); 44 return false; 45 } 46 mHandler = new CallbackHandler(this); 47 mCbLooper->registerHandler(mHandler); 48 return true; 49 } 50 51 H2BCameraDeviceCallbacks::~H2BCameraDeviceCallbacks() { 52 if (mCbLooper != nullptr) { 53 if (mHandler != nullptr) { 54 mCbLooper->unregisterHandler(mHandler->id()); 55 } 56 mCbLooper->stop(); 57 } 58 mCbLooper.clear(); 59 mHandler.clear(); 60 } 61 62 binder::Status H2BCameraDeviceCallbacks::onDeviceError( 63 int32_t errorCode, const CaptureResultExtras& resultExtras) { 64 using hardware::cameraservice::utils::conversion::convertToHidl; 65 HCaptureResultExtras hCaptureResultExtras = convertToHidl(resultExtras); 66 auto ret = mBase->onDeviceError(convertToHidl(errorCode), hCaptureResultExtras); 67 if (!ret.isOk()) { 68 ALOGE("%s OnDeviceError callback failed due to %s",__FUNCTION__, 69 ret.description().c_str()); 70 } 71 return binder::Status::ok(); 72 } 73 74 binder::Status H2BCameraDeviceCallbacks::onDeviceIdle() { 75 auto ret = mBase->onDeviceIdle(); 76 if (!ret.isOk()) { 77 ALOGE("%s OnDeviceIdle callback failed due to %s",__FUNCTION__, 78 ret.description().c_str()); 79 } 80 return binder::Status::ok(); 81 } 82 83 binder::Status H2BCameraDeviceCallbacks::onCaptureStarted( 84 const CaptureResultExtras& resultExtras, int64_t timestamp) { 85 using hardware::cameraservice::utils::conversion::convertToHidl; 86 HCaptureResultExtras hCaptureResultExtras = convertToHidl(resultExtras); 87 auto ret = mBase->onCaptureStarted(hCaptureResultExtras, timestamp); 88 if (!ret.isOk()) { 89 ALOGE("%s OnCaptureCallback failed due to %s",__FUNCTION__, 90 ret.description().c_str()); 91 } 92 return binder::Status::ok(); 93 } 94 95 void H2BCameraDeviceCallbacks::convertResultMetadataToHidl(const camera_metadata_t *rawMetadata, 96 FmqSizeOrMetadata *hResultMetadata) { 97 // First try writing to fmq. 98 size_t metadata_size = get_camera_metadata_size(rawMetadata); 99 if ((metadata_size > 0) && 100 (mCaptureResultMetadataQueue->availableToWrite() > 0)) { 101 if (mCaptureResultMetadataQueue->write((uint8_t *)rawMetadata, metadata_size)) { 102 hResultMetadata->fmqMetadataSize(metadata_size); 103 } else { 104 ALOGW("%s Couldn't use fmq, falling back to hwbinder", __FUNCTION__); 105 HCameraMetadata metadata; 106 hardware::cameraservice::utils::conversion::convertToHidl(rawMetadata, &metadata); 107 hResultMetadata->metadata(std::move(metadata)); 108 } 109 } 110 } 111 112 void H2BCameraDeviceCallbacks::CallbackHandler::onMessageReceived(const sp<AMessage> &msg) { 113 sp<RefBase> obj = nullptr; 114 sp<ResultWrapper> resultWrapper = nullptr; 115 bool found = false; 116 switch (msg->what()) { 117 case kWhatResultReceived: 118 found = msg->findObject(kResultKey, &obj); 119 if (!found || obj == nullptr) { 120 ALOGE("Cannot find result object in callback message"); 121 return; 122 } 123 resultWrapper = static_cast<ResultWrapper *>(obj.get()); 124 processResultMessage(resultWrapper); 125 break; 126 default: 127 ALOGE("Unknown callback sent"); 128 break; 129 } 130 return; 131 } 132 133 void H2BCameraDeviceCallbacks::CallbackHandler::processResultMessage( 134 sp<ResultWrapper> &resultWrapper) { 135 sp<H2BCameraDeviceCallbacks> converter = mConverter.promote(); 136 if (converter == nullptr) { 137 ALOGE("Callback wrapper has died, result callback cannot be made"); 138 return; 139 } 140 CameraMetadataNative &result = resultWrapper->mResult; 141 auto resultExtras = resultWrapper->mResultExtras; 142 HCaptureResultExtras hResultExtras = 143 hardware::cameraservice::utils::conversion::convertToHidl(resultExtras); 144 145 // Convert Metadata into HCameraMetadata; 146 FmqSizeOrMetadata hResult; 147 const camera_metadata_t *rawMetadata = result.getAndLock(); 148 converter->convertResultMetadataToHidl(rawMetadata, &hResult); 149 result.unlock(rawMetadata); 150 auto &physicalCaptureResultInfos = resultWrapper->mPhysicalCaptureResultInfos; 151 hidl_vec<HPhysicalCaptureResultInfo> hPhysicalCaptureResultInfos = 152 hardware::cameraservice::utils::conversion::convertToHidl( 153 physicalCaptureResultInfos, converter->mCaptureResultMetadataQueue); 154 auto ret = converter->mBase->onResultReceived(hResult, hResultExtras, 155 hPhysicalCaptureResultInfos); 156 if (!ret.isOk()) { 157 ALOGE("%s OnResultReceived callback failed due to %s",__FUNCTION__, 158 ret.description().c_str()); 159 } 160 } 161 162 binder::Status H2BCameraDeviceCallbacks::onResultReceived( 163 const CameraMetadataNative& result, 164 const CaptureResultExtras& resultExtras, 165 const ::std::vector<PhysicalCaptureResultInfo>& physicalCaptureResultInfos) { 166 // Wrap CameraMetadata, resultExtras and physicalCaptureResultInfos in on 167 // sp<RefBase>-able structure and post it. 168 sp<ResultWrapper> resultWrapper = new ResultWrapper(const_cast<CameraMetadataNative &>(result), 169 resultExtras, physicalCaptureResultInfos); 170 sp<AMessage> msg = new AMessage(kWhatResultReceived, mHandler); 171 msg->setObject(kResultKey, resultWrapper); 172 msg->post(); 173 return binder::Status::ok(); 174 } 175 176 binder::Status H2BCameraDeviceCallbacks::onPrepared(int32_t streamId) { 177 // not implemented 178 // To silence Wunused-parameter. 179 (void) streamId; 180 return binder::Status::ok(); 181 } 182 183 binder::Status H2BCameraDeviceCallbacks::onRepeatingRequestError( 184 int64_t lastFrameNumber, 185 int32_t repeatingRequestId) { 186 auto ret = 187 mBase->onRepeatingRequestError(lastFrameNumber, repeatingRequestId); 188 if (!ret.isOk()) { 189 ALOGE("%s OnRepeatingRequestEror callback failed due to %s",__FUNCTION__, 190 ret.description().c_str()); 191 } 192 return binder::Status::ok(); 193 } 194 195 binder::Status H2BCameraDeviceCallbacks::onRequestQueueEmpty() { 196 // not implemented 197 return binder::Status::ok(); 198 } 199 200 } // implementation 201 } // V2_0 202 } // device 203 } // cameraservice 204 } // frameworks 205 } // android 206