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 
     17 #include <android/hardware/camera/device/3.2/types.h>
     18 #include <cutils/properties.h>
     19 #include <gui/Surface.h>
     20 #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
     21 
     22 #include <hidl/AidlCameraDeviceCallbacks.h>
     23 #include <hidl/Convert.h>
     24 #include <hidl/HidlCameraDeviceUser.h>
     25 #include <android/hardware/camera/device/3.2/types.h>
     26 
     27 namespace android {
     28 namespace frameworks {
     29 namespace cameraservice {
     30 namespace device {
     31 namespace V2_0 {
     32 namespace implementation {
     33 
     34 using hardware::cameraservice::utils::conversion::convertToHidl;
     35 using hardware::cameraservice::utils::conversion::convertFromHidl;
     36 using hardware::cameraservice::utils::conversion::B2HStatus;
     37 
     38 using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
     39 using hardware::hidl_vec;
     40 using hardware::Return;
     41 using hardware::Void;
     42 using HSubmitInfo = device::V2_0::SubmitInfo;
     43 using hardware::camera2::params::OutputConfiguration;
     44 using hardware::camera2::params::SessionConfiguration;
     45 
     46 static constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
     47 static constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
     48 
     49 Return<void> HidlCameraDeviceUser::disconnect() {
     50     mDeviceRemote->disconnect();
     51     return Void();
     52 }
     53 
     54 HidlCameraDeviceUser::HidlCameraDeviceUser(
     55     const sp<hardware::camera2::ICameraDeviceUser> &deviceRemote)
     56   : mDeviceRemote(deviceRemote) {
     57     mInitSuccess = initDevice();
     58 }
     59 
     60 bool HidlCameraDeviceUser::initDevice() {
     61     // TODO: Get request and result metadata queue size from a system property.
     62     int32_t reqFMQSize = CAMERA_REQUEST_METADATA_QUEUE_SIZE;
     63 
     64     mCaptureRequestMetadataQueue =
     65         std::make_unique<CaptureRequestMetadataQueue>(static_cast<size_t>(reqFMQSize),
     66                                                       false /* non blocking */);
     67     if (!mCaptureRequestMetadataQueue->isValid()) {
     68         ALOGE("%s: invalid request fmq", __FUNCTION__);
     69         return false;
     70     }
     71 
     72     int32_t resFMQSize = CAMERA_RESULT_METADATA_QUEUE_SIZE;
     73     mCaptureResultMetadataQueue =
     74         std::make_shared<CaptureResultMetadataQueue>(static_cast<size_t>(resFMQSize),
     75                                                      false /* non blocking */);
     76     if (!mCaptureResultMetadataQueue->isValid()) {
     77         ALOGE("%s: invalid result fmq", __FUNCTION__);
     78         return false;
     79     }
     80     return true;
     81 }
     82 
     83 Return<void> HidlCameraDeviceUser::getCaptureRequestMetadataQueue(
     84     getCaptureRequestMetadataQueue_cb _hidl_cb) {
     85     if (mInitSuccess) {
     86         _hidl_cb(*mCaptureRequestMetadataQueue->getDesc());
     87     }
     88     return Void();
     89 }
     90 
     91 Return<void> HidlCameraDeviceUser::getCaptureResultMetadataQueue(
     92     getCaptureResultMetadataQueue_cb _hidl_cb) {
     93     if (mInitSuccess) {
     94         _hidl_cb(*mCaptureResultMetadataQueue->getDesc());
     95     }
     96     return Void();
     97 }
     98 
     99 /**
    100  * To be used only by submitRequestList implementation, since it requires
    101  * clients to call this method serially, incase fmq is used to send metadata.
    102  */
    103 bool HidlCameraDeviceUser::copyPhysicalCameraSettings(
    104     const hidl_vec<HPhysicalCameraSettings> &hPhysicalCameraSettings,
    105     std::vector<CaptureRequest::PhysicalCameraSettings> *physicalCameraSettings) {
    106     bool converted = false;
    107     for (auto &e : hPhysicalCameraSettings) {
    108         physicalCameraSettings->emplace_back();
    109         CaptureRequest::PhysicalCameraSettings &physicalCameraSetting =
    110             physicalCameraSettings->back();
    111         physicalCameraSetting.id = e.id.c_str();
    112 
    113         // Read the settings either from the fmq or straightaway from the
    114         // request. We don't need any synchronization, since submitRequestList
    115         // is guaranteed to be called serially by the client if it decides to
    116         // use fmq.
    117         if (e.settings.getDiscriminator() ==
    118             FmqSizeOrMetadata::hidl_discriminator::fmqMetadataSize) {
    119             /**
    120              * Get settings from the fmq.
    121              */
    122             HCameraMetadata settingsFmq;
    123             settingsFmq.resize(e.settings.fmqMetadataSize());
    124             bool read = mCaptureRequestMetadataQueue->read(settingsFmq.data(),
    125                                                            e.settings.fmqMetadataSize());
    126             if (!read) {
    127                 ALOGE("%s capture request settings could't be read from fmq size",
    128                       __FUNCTION__);
    129                 converted = false;
    130             } else {
    131                 converted = convertFromHidl(settingsFmq, &physicalCameraSetting.settings);
    132             }
    133         } else {
    134             /**
    135              * The settings metadata is contained in request settings field.
    136              */
    137             converted =
    138                 convertFromHidl(e.settings.metadata(),
    139                                 &physicalCameraSetting.settings);
    140         }
    141         if (!converted) {
    142           ALOGE("%s: Unable to convert physicalCameraSettings from HIDL to AIDL.", __FUNCTION__);
    143           return false;
    144         }
    145     }
    146     return true;
    147 }
    148 
    149 bool HidlCameraDeviceUser::convertRequestFromHidl(const HCaptureRequest &hRequest,
    150                                                   CaptureRequest *request) {
    151     // No reprocessing support.
    152     request->mIsReprocess = false;
    153     for (const auto &streamAndWindowId : hRequest.streamAndWindowIds) {
    154         request->mStreamIdxList.push_back(streamAndWindowId.streamId);
    155         request->mSurfaceIdxList.push_back(streamAndWindowId.windowId);
    156     }
    157     return copyPhysicalCameraSettings(hRequest.physicalCameraSettings,
    158                                       &(request->mPhysicalCameraSettings));
    159 }
    160 
    161 Return<void> HidlCameraDeviceUser::submitRequestList(const hidl_vec<HCaptureRequest>& hRequestList,
    162                                                      bool streaming,
    163                                                      submitRequestList_cb _hidl_cb) {
    164     hardware::camera2::utils::SubmitInfo submitInfo;
    165     HSubmitInfo hSubmitInfo;
    166     /**
    167      * Create AIDL CaptureRequest from requestList and graphicBufferProducers.
    168      */
    169     std::vector<hardware::camera2::CaptureRequest> requests;
    170     for (auto &hRequest : hRequestList) {
    171         requests.emplace_back();
    172         auto &request = requests.back();
    173         if (!convertRequestFromHidl(hRequest, &request)) {
    174             _hidl_cb(HStatus::ILLEGAL_ARGUMENT, hSubmitInfo);
    175             return Void();
    176         }
    177     }
    178     mDeviceRemote->submitRequestList(requests, streaming, &submitInfo);
    179     mRequestId = submitInfo.mRequestId;
    180     convertToHidl(submitInfo, &hSubmitInfo);
    181     _hidl_cb(HStatus::NO_ERROR, hSubmitInfo);
    182     return Void();
    183 }
    184 
    185 Return<void> HidlCameraDeviceUser::cancelRepeatingRequest(cancelRepeatingRequest_cb _hidl_cb) {
    186     int64_t lastFrameNumber = 0;
    187     binder::Status ret = mDeviceRemote->cancelRequest(mRequestId, &lastFrameNumber);
    188     _hidl_cb(B2HStatus(ret), lastFrameNumber);
    189     return Void();
    190 }
    191 
    192 Return<HStatus> HidlCameraDeviceUser::beginConfigure() {
    193     binder::Status ret = mDeviceRemote->beginConfigure();
    194     return B2HStatus(ret);
    195 }
    196 
    197 Return<HStatus> HidlCameraDeviceUser::endConfigure(StreamConfigurationMode operatingMode,
    198                                                    const hidl_vec<uint8_t>& sessionParams) {
    199     android::CameraMetadata cameraMetadata;
    200     if (!convertFromHidl(sessionParams, &cameraMetadata)) {
    201         return HStatus::ILLEGAL_ARGUMENT;
    202     }
    203 
    204     binder::Status ret = mDeviceRemote->endConfigure(convertFromHidl(operatingMode),
    205                                                      cameraMetadata);
    206     return B2HStatus(ret);
    207 }
    208 
    209 Return<HStatus> HidlCameraDeviceUser::deleteStream(int32_t streamId) {
    210     binder::Status ret = mDeviceRemote->deleteStream(streamId);
    211     return B2HStatus(ret);
    212 }
    213 
    214 Return<void> HidlCameraDeviceUser::createStream(const HOutputConfiguration& hOutputConfiguration,
    215                                                 createStream_cb hidl_cb_) {
    216     OutputConfiguration outputConfiguration =
    217         convertFromHidl(hOutputConfiguration);
    218     int32_t newStreamId = 0;
    219     binder::Status ret = mDeviceRemote->createStream(outputConfiguration, &newStreamId);
    220     HStatus status = B2HStatus(ret);
    221     hidl_cb_(status, newStreamId);
    222     return Void();
    223 }
    224 
    225 Return<void> HidlCameraDeviceUser::createDefaultRequest(TemplateId templateId,
    226                                                         createDefaultRequest_cb _hidl_cb) {
    227     android::CameraMetadata cameraMetadata;
    228     binder::Status ret = mDeviceRemote->createDefaultRequest(convertFromHidl(templateId),
    229                                                              &cameraMetadata);
    230     HStatus hStatus = B2HStatus(ret);
    231     HCameraMetadata hidlMetadata;
    232     const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
    233     convertToHidl(rawMetadata, &hidlMetadata);
    234     _hidl_cb(hStatus, hidlMetadata);
    235     cameraMetadata.unlock(rawMetadata);
    236     return Void();
    237 }
    238 
    239 Return<HStatus> HidlCameraDeviceUser::waitUntilIdle() {
    240     binder::Status ret = mDeviceRemote->waitUntilIdle();
    241     return B2HStatus(ret);
    242 }
    243 
    244 Return<void> HidlCameraDeviceUser::flush(flush_cb _hidl_cb) {
    245     int64_t lastFrameNumber = 0;
    246     binder::Status ret = mDeviceRemote->flush(&lastFrameNumber);
    247     _hidl_cb(B2HStatus(ret),lastFrameNumber);
    248     return Void();
    249 }
    250 
    251 Return<HStatus> HidlCameraDeviceUser::updateOutputConfiguration(
    252     int32_t streamId,
    253     const HOutputConfiguration& hOutputConfiguration) {
    254     OutputConfiguration outputConfiguration = convertFromHidl(hOutputConfiguration);
    255     binder::Status ret = mDeviceRemote->updateOutputConfiguration(streamId, outputConfiguration);
    256     return B2HStatus(ret);
    257 }
    258 
    259 Return<void> HidlCameraDeviceUser::isSessionConfigurationSupported(
    260     const HSessionConfiguration& hSessionConfiguration,
    261     isSessionConfigurationSupported_cb _hidl_cb) {
    262     bool supported = false;
    263     SessionConfiguration sessionConfiguration = convertFromHidl(hSessionConfiguration);
    264     binder::Status ret = mDeviceRemote->isSessionConfigurationSupported(
    265             sessionConfiguration, &supported);
    266     HStatus status = B2HStatus(ret);
    267     _hidl_cb(status, supported);
    268     return Void();
    269 }
    270 
    271 } // implementation
    272 } // V2_0
    273 } // device
    274 } // cameraservice
    275 } // frameworks
    276 } // android
    277