OSDN Git Service

Camera: Add default implementation of camera.device@3.3
authorEino-Ville Talvala <etalvala@google.com>
Tue, 22 Aug 2017 23:15:09 +0000 (16:15 -0700)
committerEino-Ville Talvala <etalvala@google.com>
Fri, 15 Sep 2017 18:08:48 +0000 (11:08 -0700)
Inherit as much as possible from camera.device@3.2

- Refactor CameraDeviceSession@3.2 implementation to separate out the
  HIDL session interface from the main implementation object. This
  avoids multiple inheritance issues
- Create CameraDeviceSession@3.3 with support for the new
  overrideDataspace field
- Add virtual factory method for CameraDevice to create the right version
  of Session.
- Create CameraDevice@3.3, which overrides createSession to return a
  CameraDeviceSession@3.3.
- Add system property to override selection of which minor HIDL
  version is used for legal HAL version 3.x; set the default to the
  newest available minor version.

Test: Camera CTS passes on device using @3.3.
Bug: 62358514
Change-Id: I497e4bc0de798b56ecdb2ea6467b79afccaf89f7

16 files changed:
camera/Android.bp
camera/device/3.2/default/CameraDevice.cpp
camera/device/3.2/default/CameraDeviceSession.cpp
camera/device/3.2/default/CameraDeviceSession.h
camera/device/3.2/default/CameraDevice_3_2.h
camera/device/3.3/default/Android.bp [new file with mode: 0644]
camera/device/3.3/default/CameraDevice.cpp [new file with mode: 0644]
camera/device/3.3/default/CameraDeviceSession.cpp [new file with mode: 0644]
camera/device/3.3/default/CameraDeviceSession.h [new file with mode: 0644]
camera/device/3.3/default/CameraDevice_3_3.h [new file with mode: 0644]
camera/device/3.3/default/OWNERS [new file with mode: 0644]
camera/device/3.3/default/convert.cpp [new file with mode: 0644]
camera/device/3.3/default/include/convert.h [new file with mode: 0644]
camera/provider/2.4/default/Android.bp
camera/provider/2.4/default/CameraProvider.cpp
camera/provider/2.4/default/CameraProvider.h

index 83a2803..0240751 100644 (file)
@@ -7,6 +7,7 @@ subdirs = [
     "device/3.2",
     "device/3.2/default",
     "device/3.3",
+    "device/3.3/default",
     "metadata/3.2",
     "provider/2.4",
     "provider/2.4/default",
index 637a1e6..295ee32 100644 (file)
@@ -177,7 +177,7 @@ Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback, open_
     if (callback == nullptr) {
         ALOGE("%s: cannot open camera %s. callback is null!",
                 __FUNCTION__, mCameraId.c_str());
-        _hidl_cb(Status::ILLEGAL_ARGUMENT, session);
+        _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
         return Void();
     }
 
@@ -186,7 +186,7 @@ Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback, open_
         // this must be a disconnected camera
         ALOGE("%s: cannot open camera %s. camera is disconnected!",
                 __FUNCTION__, mCameraId.c_str());
-        _hidl_cb(Status::CAMERA_DISCONNECTED, session);
+        _hidl_cb(Status::CAMERA_DISCONNECTED, nullptr);
         return Void();
     } else {
         mLock.lock();
@@ -239,7 +239,7 @@ Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback, open_
             return Void();
         }
 
-        session = new CameraDeviceSession(
+        session = createSession(
                 device, info.static_camera_characteristics, callback);
         if (session == nullptr) {
             ALOGE("%s: camera device session allocation failed", __FUNCTION__);
@@ -255,9 +255,19 @@ Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback, open_
             return Void();
         }
         mSession = session;
+
+        IF_ALOGV() {
+            session->getInterface()->interfaceChain([](
+                ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
+                    ALOGV("Session interface chain:");
+                    for (auto iface : interfaceChain) {
+                        ALOGV("  %s", iface.c_str());
+                    }
+                });
+        }
         mLock.unlock();
     }
-    _hidl_cb(status, session);
+    _hidl_cb(status, session->getInterface());
     return Void();
 }
 
@@ -286,6 +296,13 @@ Return<void> CameraDevice::dumpState(const ::android::hardware::hidl_handle& han
     session->dumpState(handle);
     return Void();
 }
+
+sp<CameraDeviceSession> CameraDevice::createSession(camera3_device_t* device,
+        const camera_metadata_t* deviceInfo,
+        const sp<ICameraDeviceCallback>& callback) {
+    return new CameraDeviceSession(device, deviceInfo, callback);
+}
+
 // End of methods from ::android::hardware::camera::device::V3_2::ICameraDevice.
 
 } // namespace implementation
index fcd134f..d6a04bc 100644 (file)
@@ -49,7 +49,6 @@ CameraDeviceSession::CameraDeviceSession(
         mDerivePostRawSensKey(false),
         mNumPartialResults(1),
         mResultBatcher(callback) {
-
     mDeviceInfo = deviceInfo;
     camera_metadata_entry partialResultsCount =
             mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
@@ -328,7 +327,8 @@ void CameraDeviceSession::ResultBatcher::setBatchedStreams(
     mStreamsToBatch = streamsToBatch;
 }
 
-void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q) {
+void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(
+        std::shared_ptr<ResultMetadataQueue> q) {
     Mutex::Autolock _l(mLock);
     mResultMetadataQueue = q;
 }
@@ -387,7 +387,8 @@ void CameraDeviceSession::ResultBatcher::checkAndRemoveFirstBatch() {
     }
 }
 
-void CameraDeviceSession::ResultBatcher::sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch) {
+void CameraDeviceSession::ResultBatcher::sendBatchShutterCbsLocked(
+        std::shared_ptr<InflightBatch> batch) {
     if (batch->mShutterDelivered) {
         ALOGW("%s: batch shutter callback already sent!", __FUNCTION__);
         return;
@@ -441,7 +442,8 @@ void CameraDeviceSession::ResultBatcher::pushStreamBuffer(
     }
 }
 
-void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch) {
+void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(
+        std::shared_ptr<InflightBatch> batch) {
     sendBatchBuffersLocked(batch, mStreamsToBatch);
 }
 
@@ -736,7 +738,7 @@ void CameraDeviceSession::ResultBatcher::processCaptureResult(CaptureResult& res
 
 // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
 Return<void> CameraDeviceSession::constructDefaultRequestSettings(
-        RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb)  {
+        RequestTemplate type, ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)  {
     Status status = initStatus();
     CameraMetadata outMetadata;
     const camera_metadata_t *rawRequest;
@@ -802,7 +804,8 @@ android_dataspace CameraDeviceSession::mapToLegacyDataspace(
 }
 
 Return<void> CameraDeviceSession::configureStreams(
-        const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb)  {
+        const StreamConfiguration& requestedConfiguration,
+        ICameraDeviceSession::configureStreams_cb _hidl_cb)  {
     Status status = initStatus();
     HalStreamConfiguration outStreams;
 
@@ -960,13 +963,13 @@ void CameraDeviceSession::updateBufferCaches(const hidl_vec<BufferCache>& caches
 }
 
 Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue(
-    getCaptureRequestMetadataQueue_cb _hidl_cb) {
+    ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) {
     _hidl_cb(*mRequestMetadataQueue->getDesc());
     return Void();
 }
 
 Return<void> CameraDeviceSession::getCaptureResultMetadataQueue(
-    getCaptureResultMetadataQueue_cb _hidl_cb) {
+    ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) {
     _hidl_cb(*mResultMetadataQueue->getDesc());
     return Void();
 }
@@ -974,7 +977,7 @@ Return<void> CameraDeviceSession::getCaptureResultMetadataQueue(
 Return<void> CameraDeviceSession::processCaptureRequest(
         const hidl_vec<CaptureRequest>& requests,
         const hidl_vec<BufferCache>& cachesToRemove,
-        processCaptureRequest_cb _hidl_cb)  {
+        ICameraDeviceSession::processCaptureRequest_cb _hidl_cb)  {
     updateBufferCaches(cachesToRemove);
 
     uint32_t numRequestProcessed = 0;
index 2fe189f..69e2e2c 100644 (file)
@@ -55,6 +55,8 @@ using ::android::hardware::hidl_string;
 using ::android::sp;
 using ::android::Mutex;
 
+struct Camera3Stream;
+
 /**
  * Function pointer types with C calling convention to
  * use for HAL callback functions.
@@ -69,12 +71,12 @@ extern "C" {
         const camera3_notify_msg_t *);
 }
 
-struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callback_ops  {
+struct CameraDeviceSession : public virtual RefBase, protected camera3_callback_ops  {
 
     CameraDeviceSession(camera3_device_t*,
                         const camera_metadata_t* deviceInfo,
                         const sp<ICameraDeviceCallback>&);
-    ~CameraDeviceSession();
+    virtual ~CameraDeviceSession();
     // Call by CameraDevice to dump active device states
     void dumpState(const native_handle_t* fd);
     // Caller must use this method to check if CameraDeviceSession ctor failed
@@ -83,23 +85,35 @@ struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callba
     void disconnect();
     bool isClosed();
 
-    // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
+    // Retrieve the HIDL interface, split into its own class to avoid inheritance issues when
+    // dealing with minor version revs and simultaneous implementation and interface inheritance
+    virtual sp<ICameraDeviceSession> getInterface() {
+        return new TrampolineSessionInterface_3_2(this);
+    }
+
+protected:
+
+    // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow
+
     Return<void> constructDefaultRequestSettings(
-            RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
+            RequestTemplate type,
+            ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb);
     Return<void> configureStreams(
-            const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
+            const StreamConfiguration& requestedConfiguration,
+            ICameraDeviceSession::configureStreams_cb _hidl_cb);
     Return<void> getCaptureRequestMetadataQueue(
-        getCaptureRequestMetadataQueue_cb _hidl_cb) override;
+        ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb);
     Return<void> getCaptureResultMetadataQueue(
-        getCaptureResultMetadataQueue_cb _hidl_cb) override;
+        ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb);
     Return<void> processCaptureRequest(
             const hidl_vec<CaptureRequest>& requests,
             const hidl_vec<BufferCache>& cachesToRemove,
-            processCaptureRequest_cb _hidl_cb) override;
-    Return<Status> flush() override;
-    Return<void> close() override;
+            ICameraDeviceSession::processCaptureRequest_cb _hidl_cb);
+    Return<Status> flush();
+    Return<void> close();
+
+protected:
 
-private:
     // protecting mClosed/mDisconnected/mInitFail
     mutable Mutex mStateLock;
     // device is closed either
@@ -302,6 +316,52 @@ private:
      */
     static callbacks_process_capture_result_t sProcessCaptureResult;
     static callbacks_notify_t sNotify;
+
+private:
+
+    struct TrampolineSessionInterface_3_2 : public ICameraDeviceSession {
+        TrampolineSessionInterface_3_2(sp<CameraDeviceSession> parent) :
+                mParent(parent) {}
+
+        virtual Return<void> constructDefaultRequestSettings(
+                V3_2::RequestTemplate type,
+                V3_2::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
+            return mParent->constructDefaultRequestSettings(type, _hidl_cb);
+        }
+
+        virtual Return<void> configureStreams(
+                const V3_2::StreamConfiguration& requestedConfiguration,
+                V3_2::ICameraDeviceSession::configureStreams_cb _hidl_cb) override {
+            return mParent->configureStreams(requestedConfiguration, _hidl_cb);
+        }
+
+        virtual Return<void> processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests,
+                const hidl_vec<V3_2::BufferCache>& cachesToRemove,
+                V3_2::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override {
+            return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb);
+        }
+
+        virtual Return<void> getCaptureRequestMetadataQueue(
+                V3_2::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override  {
+            return mParent->getCaptureRequestMetadataQueue(_hidl_cb);
+        }
+
+        virtual Return<void> getCaptureResultMetadataQueue(
+                V3_2::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override  {
+            return mParent->getCaptureResultMetadataQueue(_hidl_cb);
+        }
+
+        virtual Return<Status> flush() override {
+            return mParent->flush();
+        }
+
+        virtual Return<void> close() override {
+            return mParent->close();
+        }
+
+    private:
+        sp<CameraDeviceSession> mParent;
+    };
 };
 
 }  // namespace implementation
index 4e86067..9534707 100644 (file)
@@ -80,7 +80,13 @@ struct CameraDevice : public ICameraDevice {
     Return<void> dumpState(const ::android::hardware::hidl_handle& fd) override;
     /* End of Methods from ::android::hardware::camera::device::V3_2::ICameraDevice */
 
-private:
+protected:
+
+    // Overridden by child implementations for returning different versions of CameraDeviceSession
+    virtual sp<CameraDeviceSession> createSession(camera3_device_t*,
+            const camera_metadata_t* deviceInfo,
+            const sp<ICameraDeviceCallback>&);
+
     const sp<CameraModule> mModule;
     const std::string mCameraId;
     // const after ctor
diff --git a/camera/device/3.3/default/Android.bp b/camera/device/3.3/default/Android.bp
new file mode 100644 (file)
index 0000000..b1e9b46
--- /dev/null
@@ -0,0 +1,30 @@
+cc_library_shared {
+    name: "camera.device@3.3-impl",
+    defaults: ["hidl_defaults"],
+    proprietary: true,
+    srcs: ["CameraDevice.cpp",
+           "CameraDeviceSession.cpp",
+           "convert.cpp"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libutils",
+        "libcutils",
+        "camera.device@3.2-impl",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.graphics.mapper@2.0",
+        "liblog",
+        "libhardware",
+        "libcamera_metadata",
+        "libfmq"
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper"
+    ],
+    export_include_dirs: ["."],
+    export_shared_lib_headers: [
+        "libfmq",
+    ]
+}
diff --git a/camera/device/3.3/default/CameraDevice.cpp b/camera/device/3.3/default/CameraDevice.cpp
new file mode 100644 (file)
index 0000000..ce5e1de
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "CamDev@3.3-impl"
+#include <log/log.h>
+
+#include <utils/Vector.h>
+#include <utils/Trace.h>
+#include "CameraDevice_3_3.h"
+#include <include/convert.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace V3_3 {
+namespace implementation {
+
+using ::android::hardware::camera::common::V1_0::Status;
+using namespace ::android::hardware::camera::device;
+
+CameraDevice::CameraDevice(
+    sp<CameraModule> module, const std::string& cameraId,
+    const SortedVector<std::pair<std::string, std::string>>& cameraDeviceNames) :
+        V3_2::implementation::CameraDevice(module, cameraId, cameraDeviceNames) {
+}
+
+CameraDevice::~CameraDevice() {
+}
+
+sp<V3_2::implementation::CameraDeviceSession> CameraDevice::createSession(camera3_device_t* device,
+        const camera_metadata_t* deviceInfo,
+        const sp<V3_2::ICameraDeviceCallback>& callback) {
+    sp<CameraDeviceSession> session = new CameraDeviceSession(device, deviceInfo, callback);
+    IF_ALOGV() {
+        session->getInterface()->interfaceChain([](
+            ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
+                ALOGV("Session interface chain:");
+                for (auto iface : interfaceChain) {
+                    ALOGV("  %s", iface.c_str());
+                }
+            });
+    }
+    return session;
+}
+
+// End of methods from ::android::hardware::camera::device::V3_2::ICameraDevice.
+
+} // namespace implementation
+}  // namespace V3_3
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/device/3.3/default/CameraDeviceSession.cpp b/camera/device/3.3/default/CameraDeviceSession.cpp
new file mode 100644 (file)
index 0000000..f877895
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "CamDevSession@3.3-impl"
+#include <android/log.h>
+
+#include <set>
+#include <utils/Trace.h>
+#include <hardware/gralloc.h>
+#include <hardware/gralloc1.h>
+#include "CameraDeviceSession.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace V3_3 {
+namespace implementation {
+
+CameraDeviceSession::CameraDeviceSession(
+    camera3_device_t* device,
+    const camera_metadata_t* deviceInfo,
+    const sp<V3_2::ICameraDeviceCallback>& callback) :
+        V3_2::implementation::CameraDeviceSession(device, deviceInfo, callback) {
+}
+
+CameraDeviceSession::~CameraDeviceSession() {
+}
+
+Return<void> CameraDeviceSession::configureStreams_3_3(
+        const StreamConfiguration& requestedConfiguration,
+        ICameraDeviceSession::configureStreams_3_3_cb _hidl_cb)  {
+    Status status = initStatus();
+    HalStreamConfiguration outStreams;
+
+    // hold the inflight lock for entire configureStreams scope since there must not be any
+    // inflight request/results during stream configuration.
+    Mutex::Autolock _l(mInflightLock);
+    if (!mInflightBuffers.empty()) {
+        ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!",
+                __FUNCTION__, mInflightBuffers.size());
+        _hidl_cb(Status::INTERNAL_ERROR, outStreams);
+        return Void();
+    }
+
+    if (!mInflightAETriggerOverrides.empty()) {
+        ALOGE("%s: trying to configureStreams while there are still %zu inflight"
+                " trigger overrides!", __FUNCTION__,
+                mInflightAETriggerOverrides.size());
+        _hidl_cb(Status::INTERNAL_ERROR, outStreams);
+        return Void();
+    }
+
+    if (!mInflightRawBoostPresent.empty()) {
+        ALOGE("%s: trying to configureStreams while there are still %zu inflight"
+                " boost overrides!", __FUNCTION__,
+                mInflightRawBoostPresent.size());
+        _hidl_cb(Status::INTERNAL_ERROR, outStreams);
+        return Void();
+    }
+
+    if (status != Status::OK) {
+        _hidl_cb(status, outStreams);
+        return Void();
+    }
+
+    camera3_stream_configuration_t stream_list;
+    hidl_vec<camera3_stream_t*> streams;
+
+    stream_list.operation_mode = (uint32_t) requestedConfiguration.operationMode;
+    stream_list.num_streams = requestedConfiguration.streams.size();
+    streams.resize(stream_list.num_streams);
+    stream_list.streams = streams.data();
+
+    for (uint32_t i = 0; i < stream_list.num_streams; i++) {
+        int id = requestedConfiguration.streams[i].id;
+
+        if (mStreamMap.count(id) == 0) {
+            Camera3Stream stream;
+            V3_2::implementation::convertFromHidl(requestedConfiguration.streams[i], &stream);
+            mStreamMap[id] = stream;
+            mStreamMap[id].data_space = mapToLegacyDataspace(
+                    mStreamMap[id].data_space);
+            mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{});
+        } else {
+            // width/height/format must not change, but usage/rotation might need to change
+            if (mStreamMap[id].stream_type !=
+                    (int) requestedConfiguration.streams[i].streamType ||
+                    mStreamMap[id].width != requestedConfiguration.streams[i].width ||
+                    mStreamMap[id].height != requestedConfiguration.streams[i].height ||
+                    mStreamMap[id].format != (int) requestedConfiguration.streams[i].format ||
+                    mStreamMap[id].data_space !=
+                            mapToLegacyDataspace( static_cast<android_dataspace_t> (
+                                    requestedConfiguration.streams[i].dataSpace))) {
+                ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id);
+                _hidl_cb(Status::INTERNAL_ERROR, outStreams);
+                return Void();
+            }
+            mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation;
+            mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage;
+        }
+        streams[i] = &mStreamMap[id];
+    }
+
+    ATRACE_BEGIN("camera3->configure_streams");
+    status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
+    ATRACE_END();
+
+    // In case Hal returns error most likely it was not able to release
+    // the corresponding resources of the deleted streams.
+    if (ret == OK) {
+        // delete unused streams, note we do this after adding new streams to ensure new stream
+        // will not have the same address as deleted stream, and HAL has a chance to reference
+        // the to be deleted stream in configure_streams call
+        for(auto it = mStreamMap.begin(); it != mStreamMap.end();) {
+            int id = it->first;
+            bool found = false;
+            for (const auto& stream : requestedConfiguration.streams) {
+                if (id == stream.id) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                // Unmap all buffers of deleted stream
+                // in case the configuration call succeeds and HAL
+                // is able to release the corresponding resources too.
+                cleanupBuffersLocked(id);
+                it = mStreamMap.erase(it);
+            } else {
+                ++it;
+            }
+        }
+
+        // Track video streams
+        mVideoStreamIds.clear();
+        for (const auto& stream : requestedConfiguration.streams) {
+            if (stream.streamType == V3_2::StreamType::OUTPUT &&
+                stream.usage &
+                    graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) {
+                mVideoStreamIds.push_back(stream.id);
+            }
+        }
+        mResultBatcher.setBatchedStreams(mVideoStreamIds);
+    }
+
+    if (ret == -EINVAL) {
+        status = Status::ILLEGAL_ARGUMENT;
+    } else if (ret != OK) {
+        status = Status::INTERNAL_ERROR;
+    } else {
+        convertToHidl(stream_list, &outStreams);
+        mFirstRequest = true;
+    }
+
+    _hidl_cb(status, outStreams);
+    return Void();
+}
+
+} // namespace implementation
+}  // namespace V3_3
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/device/3.3/default/CameraDeviceSession.h b/camera/device/3.3/default/CameraDeviceSession.h
new file mode 100644 (file)
index 0000000..dd52b35
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE3SESSION_H
+#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE3SESSION_H
+
+#include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
+#include <../../3.2/default/CameraDeviceSession.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <include/convert.h>
+#include <deque>
+#include <map>
+#include <unordered_map>
+#include "CameraMetadata.h"
+#include "HandleImporter.h"
+#include "hardware/camera3.h"
+#include "hardware/camera_common.h"
+#include "utils/Mutex.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace V3_3 {
+namespace implementation {
+
+using namespace ::android::hardware::camera::device;
+using ::android::hardware::camera::device::V3_2::CaptureRequest;
+using ::android::hardware::camera::device::V3_2::StreamConfiguration;
+using ::android::hardware::camera::device::V3_3::HalStreamConfiguration;
+using ::android::hardware::camera::device::V3_3::ICameraDeviceSession;
+using ::android::hardware::camera::common::V1_0::Status;
+using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptorSync;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+using ::android::Mutex;
+
+struct CameraDeviceSession : public V3_2::implementation::CameraDeviceSession {
+
+    CameraDeviceSession(camera3_device_t*,
+            const camera_metadata_t* deviceInfo,
+            const sp<V3_2::ICameraDeviceCallback>&);
+    virtual ~CameraDeviceSession();
+
+    virtual sp<V3_2::ICameraDeviceSession> getInterface() override {
+        return new TrampolineSessionInterface_3_3(this);
+    }
+
+protected:
+    // Methods from v3.2 and earlier will trampoline to inherited implementation
+
+    // New methods for v3.3
+
+    Return<void> configureStreams_3_3(
+            const StreamConfiguration& requestedConfiguration,
+            ICameraDeviceSession::configureStreams_3_3_cb _hidl_cb);
+private:
+
+    struct TrampolineSessionInterface_3_3 : public ICameraDeviceSession {
+        TrampolineSessionInterface_3_3(sp<CameraDeviceSession> parent) :
+                mParent(parent) {}
+
+        virtual Return<void> constructDefaultRequestSettings(
+                V3_2::RequestTemplate type,
+                V3_3::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
+            return mParent->constructDefaultRequestSettings(type, _hidl_cb);
+        }
+
+        virtual Return<void> configureStreams(
+                const V3_2::StreamConfiguration& requestedConfiguration,
+                V3_3::ICameraDeviceSession::configureStreams_cb _hidl_cb) override {
+            return mParent->configureStreams(requestedConfiguration, _hidl_cb);
+        }
+
+        virtual Return<void> processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests,
+                const hidl_vec<V3_2::BufferCache>& cachesToRemove,
+                V3_3::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override {
+            return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb);
+        }
+
+        virtual Return<void> getCaptureRequestMetadataQueue(
+                V3_3::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override  {
+            return mParent->getCaptureRequestMetadataQueue(_hidl_cb);
+        }
+
+        virtual Return<void> getCaptureResultMetadataQueue(
+                V3_3::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override  {
+            return mParent->getCaptureResultMetadataQueue(_hidl_cb);
+        }
+
+        virtual Return<Status> flush() override {
+            return mParent->flush();
+        }
+
+        virtual Return<void> close() override {
+            return mParent->close();
+        }
+
+        virtual Return<void> configureStreams_3_3(
+                const StreamConfiguration& requestedConfiguration, configureStreams_3_3_cb _hidl_cb) override {
+            return mParent->configureStreams_3_3(requestedConfiguration, _hidl_cb);
+        }
+
+    private:
+        sp<CameraDeviceSession> mParent;
+    };
+};
+
+}  // namespace implementation
+}  // namespace V3_3
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE3SESSION_H
diff --git a/camera/device/3.3/default/CameraDevice_3_3.h b/camera/device/3.3/default/CameraDevice_3_3.h
new file mode 100644 (file)
index 0000000..18b3fe8
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE_H
+#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE_H
+
+#include "utils/Mutex.h"
+#include "CameraModule.h"
+#include "CameraMetadata.h"
+#include "CameraDeviceSession.h"
+#include <../../3.2/default/CameraDevice_3_2.h>
+
+#include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <hidl/Status.h>
+#include <hidl/MQDescriptor.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace V3_3 {
+namespace implementation {
+
+using namespace ::android::hardware::camera::device;
+using ::android::hardware::camera::common::V1_0::helper::CameraModule;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * The camera device HAL implementation is opened lazily (via the open call)
+ */
+struct CameraDevice : public V3_2::implementation::CameraDevice {
+
+    // Called by provider HAL.
+    // Provider HAL must ensure the uniqueness of CameraDevice object per cameraId, or there could
+    // be multiple CameraDevice trying to access the same physical camera.  Also, provider will have
+    // to keep track of all CameraDevice objects in order to notify CameraDevice when the underlying
+    // camera is detached.
+    // Delegates nearly all work to CameraDevice_3_2
+    CameraDevice(sp<CameraModule> module,
+                 const std::string& cameraId,
+                 const SortedVector<std::pair<std::string, std::string>>& cameraDeviceNames);
+    ~CameraDevice();
+
+protected:
+    virtual sp<V3_2::implementation::CameraDeviceSession> createSession(camera3_device_t*,
+            const camera_metadata_t* deviceInfo,
+            const sp<V3_2::ICameraDeviceCallback>&) override;
+
+};
+
+}  // namespace implementation
+}  // namespace V3_3
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CAMERA_DEVICE_V3_3_CAMERADEVICE_H
diff --git a/camera/device/3.3/default/OWNERS b/camera/device/3.3/default/OWNERS
new file mode 100644 (file)
index 0000000..18acfee
--- /dev/null
@@ -0,0 +1,6 @@
+cychen@google.com
+epeev@google.com
+etalvala@google.com
+shuzhenwang@google.com
+yinchiayeh@google.com
+zhijunhe@google.com
diff --git a/camera/device/3.3/default/convert.cpp b/camera/device/3.3/default/convert.cpp
new file mode 100644 (file)
index 0000000..dae190b
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.camera.device@3.3-convert-impl"
+#include <log/log.h>
+
+#include "include/convert.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace V3_3 {
+namespace implementation {
+
+using ::android::hardware::graphics::common::V1_0::Dataspace;
+using ::android::hardware::graphics::common::V1_0::PixelFormat;
+using ::android::hardware::camera::device::V3_2::BufferUsageFlags;
+
+void convertToHidl(const Camera3Stream* src, HalStream* dst) {
+    dst->overrideDataSpace = src->data_space;
+    dst->v3_2.id = src->mId;
+    dst->v3_2.overrideFormat = (PixelFormat) src->format;
+    dst->v3_2.maxBuffers = src->max_buffers;
+    if (src->stream_type == CAMERA3_STREAM_OUTPUT) {
+        dst->v3_2.consumerUsage = (BufferUsageFlags)0;
+        dst->v3_2.producerUsage = (BufferUsageFlags)src->usage;
+    } else if (src->stream_type == CAMERA3_STREAM_INPUT) {
+        dst->v3_2.producerUsage = (BufferUsageFlags)0;
+        dst->v3_2.consumerUsage = (BufferUsageFlags)src->usage;
+    } else {
+        //Should not reach here per current HIDL spec, but we might end up adding
+        // bi-directional stream to HIDL.
+        ALOGW("%s: Stream type %d is not currently supported!",
+                __FUNCTION__, src->stream_type);
+    }
+}
+
+void convertToHidl(const camera3_stream_configuration_t& src, HalStreamConfiguration* dst) {
+    dst->streams.resize(src.num_streams);
+    for (uint32_t i = 0; i < src.num_streams; i++) {
+        convertToHidl(static_cast<Camera3Stream*>(src.streams[i]), &dst->streams[i]);
+    }
+    return;
+}
+
+}  // namespace implementation
+}  // namespace V3_3
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/device/3.3/default/include/convert.h b/camera/device/3.3/default/include/convert.h
new file mode 100644 (file)
index 0000000..23bb797
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_V3_3_DEFAULT_INCLUDE_CONVERT_H_
+
+#define HARDWARE_INTERFACES_CAMERA_DEVICE_V3_3_DEFAULT_INCLUDE_CONVERT_H_
+
+#include <set>
+
+
+#include <android/hardware/graphics/common/1.0/types.h>
+#include <android/hardware/camera/device/3.3/types.h>
+#include "hardware/camera3.h"
+#include "../../3.2/default/include/convert.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace V3_3 {
+namespace implementation {
+
+using ::android::hardware::camera::device::V3_2::implementation::Camera3Stream;
+
+void convertToHidl(const Camera3Stream* src, HalStream* dst);
+
+void convertToHidl(const camera3_stream_configuration_t& src, HalStreamConfiguration* dst);
+
+}  // namespace implementation
+}  // namespace V3_3
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_CAMERA_DEVICE_V3_3_DEFAULT_INCLUDE_CONVERT_H_
index f2a2d2e..c0b3591 100644 (file)
@@ -11,8 +11,10 @@ cc_library_shared {
         "libcutils",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
         "camera.device@1.0-impl",
         "camera.device@3.2-impl",
+        "camera.device@3.3-impl",
         "android.hardware.camera.provider@2.4",
         "android.hardware.camera.common@1.0",
         "android.hardware.graphics.mapper@2.0",
@@ -43,6 +45,7 @@ cc_binary {
         "libutils",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
         "android.hardware.camera.provider@2.4",
         "android.hardware.camera.common@1.0",
     ],
index 19f7bdd..d50168a 100644 (file)
  */
 
 #define LOG_TAG "CamProvider@2.4-impl"
+//#define LOG_NDEBUG 0
 #include <android/log.h>
 
 #include "CameraProvider.h"
 #include "CameraDevice_1_0.h"
-#include "CameraDevice_3_2.h"
+#include "CameraDevice_3_3.h"
+#include <cutils/properties.h>
 #include <string.h>
 #include <utils/Trace.h>
 
@@ -36,6 +38,7 @@ const char *kLegacyProviderName = "legacy/0";
 // "device@<version>/legacy/<id>"
 const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
 const char *kHAL3_2 = "3.2";
+const char *kHAL3_3 = "3.3";
 const char *kHAL1_0 = "1.0";
 const int kMaxCameraDeviceNameLen = 128;
 const int kMaxCameraIdLen = 16;
@@ -140,8 +143,9 @@ int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
     if (!match) {
         return -1;
     }
-    if (deviceVersion == kHAL3_2) {
-        // maybe switched to 3.4 or define the hidl version enum later
+    if (deviceVersion == kHAL3_3) {
+        return CAMERA_DEVICE_API_VERSION_3_3;
+    } else if (deviceVersion == kHAL3_2) {
         return CAMERA_DEVICE_API_VERSION_3_2;
     } else if (deviceVersion == kHAL1_0) {
         return CAMERA_DEVICE_API_VERSION_1_0;
@@ -158,10 +162,12 @@ std::string CameraProvider::getHidlDeviceName(
             deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) {
         return hidl_string("");
     }
-    const char* versionStr = (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) ? kHAL1_0 : kHAL3_2;
+    bool isV1 = deviceVersion == CAMERA_DEVICE_API_VERSION_1_0;
+    int versionMajor = isV1 ? 1 : 3;
+    int versionMinor = isV1 ? 0 : mPreferredHal3MinorVersion;
     char deviceName[kMaxCameraDeviceNameLen];
-    snprintf(deviceName, sizeof(deviceName), "device@%s/legacy/%s",
-            versionStr, cameraId.c_str());
+    snprintf(deviceName, sizeof(deviceName), "device@%d.%d/legacy/%s",
+            versionMajor, versionMinor, cameraId.c_str());
     return deviceName;
 }
 
@@ -205,6 +211,19 @@ bool CameraProvider::initialize() {
         return true;
     }
 
+    mPreferredHal3MinorVersion = property_get_int32("ro.camera.wrapper.hal3TrebleMinorVersion", 3);
+    ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
+    switch(mPreferredHal3MinorVersion) {
+        case 2:
+        case 3:
+            // OK
+            break;
+        default:
+            ALOGW("Unknown minor camera device HAL version %d in property "
+                    "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3", mPreferredHal3MinorVersion);
+            mPreferredHal3MinorVersion = 3;
+    }
+
     mNumberOfLegacyCameras = mModule->getNumberOfCameras();
     for (int i = 0; i < mNumberOfLegacyCameras; i++) {
         struct camera_info info;
@@ -461,23 +480,45 @@ Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
         return Void();
     }
 
-    sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> device =
-            new android::hardware::camera::device::V3_2::implementation::CameraDevice(
+    // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
+    // to the newest possible Treble HAL revision, but allow for override if needed via
+    // system property.
+    sp<android::hardware::camera::device::V3_2::ICameraDevice> device;
+    switch (mPreferredHal3MinorVersion) {
+        case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
+            ALOGV("Constructing v3.2 camera device");
+            sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
+                    new android::hardware::camera::device::V3_2::implementation::CameraDevice(
                     mModule, cameraId, mCameraDeviceNames);
-
-    if (device == nullptr) {
-        ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
-        _hidl_cb(Status::INTERNAL_ERROR, nullptr);
-        return Void();
-    }
-
-    if (device->isInitFailed()) {
-        ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
-        device = nullptr;
-        _hidl_cb(Status::INTERNAL_ERROR, nullptr);
-        return Void();
+            if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
+                ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
+                device = nullptr;
+                _hidl_cb(Status::INTERNAL_ERROR, nullptr);
+                return Void();
+            }
+            device = deviceImpl;
+            break;
+        }
+        case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
+            ALOGV("Constructing v3.3 camera device");
+            sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
+                    new android::hardware::camera::device::V3_3::implementation::CameraDevice(
+                    mModule, cameraId, mCameraDeviceNames);
+            if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
+                ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
+                device = nullptr;
+                _hidl_cb(Status::INTERNAL_ERROR, nullptr);
+                return Void();
+            }
+            device = deviceImpl;
+            break;
+        }
+        default:
+            ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion);
+            device = nullptr;
+            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
+            return Void();
     }
-
     _hidl_cb (Status::OK, device);
     return Void();
 }
index 75971fa..4980711 100644 (file)
@@ -82,6 +82,8 @@ private:
     // (cameraId string, hidl device name) pairs
     SortedVector<std::pair<std::string, std::string>> mCameraDeviceNames;
 
+    int mPreferredHal3MinorVersion;
+
     // Must be queried before using any APIs.
     // APIs will only work when this returns true
     bool mInitFailed;
@@ -91,13 +93,13 @@ private:
     bool setUpVendorTags();
     int checkCameraVersion(int id, camera_info info);
 
+    // create HIDL device name from camera ID and legacy device version
+    std::string getHidlDeviceName(std::string cameraId, int deviceVersion);
+
     // extract legacy camera ID/device version from a HIDL device name
     static std::string getLegacyCameraId(const hidl_string& deviceName);
     static int getCameraDeviceVersion(const hidl_string& deviceName);
 
-    // create HIDL device name from camera ID and device version
-    static std::string getHidlDeviceName(std::string cameraId, int deviceVersion);
-
     // convert conventional HAL status to HIDL Status
     static Status getHidlStatus(int);