Home | History | Annotate | Download | only in hidl
      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