* changes: cameraserver: Implement HIDL ICameraDeviceUser and ICameraDeviceCallbacks. cameraserver: Implement AIDL wrapper class for HIDL ICameraServiceListener. cameraserver: Implement HIDL ICameraService skeleton.gugelfrei
commit
f2f38ba77d
@ -0,0 +1,46 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
cc_binary {
|
||||
name: "cameraserver",
|
||||
|
||||
srcs: ["main_cameraserver.cpp"],
|
||||
|
||||
shared_libs: [
|
||||
"libcameraservice",
|
||||
"liblog",
|
||||
"libutils",
|
||||
"libui",
|
||||
"libgui",
|
||||
"libbinder",
|
||||
"libhidltransport",
|
||||
"android.hardware.camera.common@1.0",
|
||||
"android.hardware.camera.provider@2.4",
|
||||
"android.hardware.camera.device@1.0",
|
||||
"android.hardware.camera.device@3.2",
|
||||
],
|
||||
compile_multilib: "32",
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Werror",
|
||||
"-Wno-unused-parameter",
|
||||
],
|
||||
|
||||
init_rc: ["cameraserver.rc"],
|
||||
|
||||
vintf_fragments: [
|
||||
"manifest_android.frameworks.cameraservice.service@2.0.xml",
|
||||
],
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
# Copyright 2015 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.
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
main_cameraserver.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libcameraservice \
|
||||
liblog \
|
||||
libutils \
|
||||
libui \
|
||||
libgui \
|
||||
libbinder \
|
||||
libhidltransport \
|
||||
android.hardware.camera.common@1.0 \
|
||||
android.hardware.camera.provider@2.4 \
|
||||
android.hardware.camera.device@1.0 \
|
||||
android.hardware.camera.device@3.2
|
||||
|
||||
LOCAL_MODULE:= cameraserver
|
||||
LOCAL_32_BIT_ONLY := true
|
||||
|
||||
LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter
|
||||
|
||||
LOCAL_INIT_RC := cameraserver.rc
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
@ -0,0 +1,11 @@
|
||||
<manifest version="1.0" type="framework">
|
||||
<hal>
|
||||
<name>android.frameworks.cameraservice.service</name>
|
||||
<transport>hwbinder</transport>
|
||||
<version>2.0</version>
|
||||
<interface>
|
||||
<name>ICameraService</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
</manifest>
|
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
#include <hardware/camera.h>
|
||||
|
||||
#include <hidl/AidlCameraDeviceCallbacks.h>
|
||||
#include <hidl/Convert.h>
|
||||
|
||||
namespace android {
|
||||
namespace frameworks {
|
||||
namespace cameraservice {
|
||||
namespace device {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using hardware::hidl_vec;
|
||||
using HCaptureResultExtras = android::frameworks::cameraservice::device::V2_0::CaptureResultExtras;
|
||||
using HPhysicalCaptureResultInfo = android::frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo;
|
||||
using HCameraMetadata = android::frameworks::cameraservice::device::V2_0::CameraMetadata;
|
||||
|
||||
const char *H2BCameraDeviceCallbacks::kResultKey = "CaptureResult";
|
||||
|
||||
H2BCameraDeviceCallbacks::H2BCameraDeviceCallbacks(const sp<HalInterface>& base) : CBase(base) { }
|
||||
|
||||
bool H2BCameraDeviceCallbacks::initializeLooper() {
|
||||
mCbLooper = new ALooper;
|
||||
mCbLooper->setName("cs-looper");
|
||||
status_t err = mCbLooper->start(/*runOnCallingThread*/ false, /*canCallJava*/ false,
|
||||
PRIORITY_DEFAULT);
|
||||
if (err !=OK) {
|
||||
ALOGE("Unable to start camera device callback looper");
|
||||
return false;
|
||||
}
|
||||
mHandler = new CallbackHandler(this);
|
||||
mCbLooper->registerHandler(mHandler);
|
||||
return true;
|
||||
}
|
||||
|
||||
H2BCameraDeviceCallbacks::~H2BCameraDeviceCallbacks() {
|
||||
if (mCbLooper != nullptr) {
|
||||
if (mHandler != nullptr) {
|
||||
mCbLooper->unregisterHandler(mHandler->id());
|
||||
}
|
||||
mCbLooper->stop();
|
||||
}
|
||||
mCbLooper.clear();
|
||||
mHandler.clear();
|
||||
}
|
||||
|
||||
binder::Status H2BCameraDeviceCallbacks::onDeviceError(
|
||||
int32_t errorCode, const CaptureResultExtras& resultExtras) {
|
||||
using hardware::cameraservice::utils::conversion::convertToHidl;
|
||||
HCaptureResultExtras hCaptureResultExtras = convertToHidl(resultExtras);
|
||||
auto ret = mBase->onDeviceError(convertToHidl(errorCode), hCaptureResultExtras);
|
||||
if (!ret.isOk()) {
|
||||
ALOGE("%s OnDeviceError callback failed due to %s",__FUNCTION__,
|
||||
ret.description().c_str());
|
||||
}
|
||||
return binder::Status::ok();
|
||||
}
|
||||
|
||||
binder::Status H2BCameraDeviceCallbacks::onDeviceIdle() {
|
||||
auto ret = mBase->onDeviceIdle();
|
||||
if (!ret.isOk()) {
|
||||
ALOGE("%s OnDeviceIdle callback failed due to %s",__FUNCTION__,
|
||||
ret.description().c_str());
|
||||
}
|
||||
return binder::Status::ok();
|
||||
}
|
||||
|
||||
binder::Status H2BCameraDeviceCallbacks::onCaptureStarted(
|
||||
const CaptureResultExtras& resultExtras, int64_t timestamp) {
|
||||
using hardware::cameraservice::utils::conversion::convertToHidl;
|
||||
HCaptureResultExtras hCaptureResultExtras = convertToHidl(resultExtras);
|
||||
auto ret = mBase->onCaptureStarted(hCaptureResultExtras, timestamp);
|
||||
if (!ret.isOk()) {
|
||||
ALOGE("%s OnCaptureCallback failed due to %s",__FUNCTION__,
|
||||
ret.description().c_str());
|
||||
}
|
||||
return binder::Status::ok();
|
||||
}
|
||||
|
||||
void H2BCameraDeviceCallbacks::convertResultMetadataToHidl(const camera_metadata_t *rawMetadata,
|
||||
FmqSizeOrMetadata *hResultMetadata) {
|
||||
// First try writing to fmq.
|
||||
size_t metadata_size = get_camera_metadata_size(rawMetadata);
|
||||
if ((metadata_size > 0) &&
|
||||
(mCaptureResultMetadataQueue->availableToWrite() > 0)) {
|
||||
if (mCaptureResultMetadataQueue->write((uint8_t *)rawMetadata, metadata_size)) {
|
||||
hResultMetadata->fmqMetadataSize(metadata_size);
|
||||
} else {
|
||||
ALOGW("%s Couldn't use fmq, falling back to hwbinder", __FUNCTION__);
|
||||
HCameraMetadata metadata;
|
||||
hardware::cameraservice::utils::conversion::convertToHidl(rawMetadata, &metadata);
|
||||
hResultMetadata->metadata(std::move(metadata));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void H2BCameraDeviceCallbacks::CallbackHandler::onMessageReceived(const sp<AMessage> &msg) {
|
||||
sp<RefBase> obj = nullptr;
|
||||
sp<ResultWrapper> resultWrapper = nullptr;
|
||||
bool found = false;
|
||||
switch (msg->what()) {
|
||||
case kWhatResultReceived:
|
||||
found = msg->findObject(kResultKey, &obj);
|
||||
if (!found || obj == nullptr) {
|
||||
ALOGE("Cannot find result object in callback message");
|
||||
return;
|
||||
}
|
||||
resultWrapper = static_cast<ResultWrapper *>(obj.get());
|
||||
processResultMessage(resultWrapper);
|
||||
break;
|
||||
default:
|
||||
ALOGE("Unknown callback sent");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void H2BCameraDeviceCallbacks::CallbackHandler::processResultMessage(
|
||||
sp<ResultWrapper> &resultWrapper) {
|
||||
sp<H2BCameraDeviceCallbacks> converter = mConverter.promote();
|
||||
if (converter == nullptr) {
|
||||
ALOGE("Callback wrapper has died, result callback cannot be made");
|
||||
return;
|
||||
}
|
||||
CameraMetadataNative &result = resultWrapper->mResult;
|
||||
auto resultExtras = resultWrapper->mResultExtras;
|
||||
auto &physicalCaptureResultInfos = resultWrapper->mPhysicalCaptureResultInfos;
|
||||
HCaptureResultExtras hResultExtras =
|
||||
hardware::cameraservice::utils::conversion::convertToHidl(resultExtras);
|
||||
hidl_vec<HPhysicalCaptureResultInfo> hPhysicalCaptureResultInfos =
|
||||
hardware::cameraservice::utils::conversion::convertToHidl(
|
||||
physicalCaptureResultInfos, converter->mCaptureResultMetadataQueue);
|
||||
|
||||
// Convert Metadata into HCameraMetadata;
|
||||
FmqSizeOrMetadata hResult;
|
||||
const camera_metadata_t *rawMetadata = result.getAndLock();
|
||||
converter->convertResultMetadataToHidl(rawMetadata, &hResult);
|
||||
result.unlock(rawMetadata);
|
||||
auto ret = converter->mBase->onResultReceived(hResult, hResultExtras,
|
||||
hPhysicalCaptureResultInfos);
|
||||
if (!ret.isOk()) {
|
||||
ALOGE("%s OnResultReceived callback failed due to %s",__FUNCTION__,
|
||||
ret.description().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
binder::Status H2BCameraDeviceCallbacks::onResultReceived(
|
||||
const CameraMetadataNative& result,
|
||||
const CaptureResultExtras& resultExtras,
|
||||
const ::std::vector<PhysicalCaptureResultInfo>& physicalCaptureResultInfos) {
|
||||
// Wrap CameraMetadata, resultExtras and physicalCaptureResultInfos in on
|
||||
// sp<RefBase>-able structure and post it.
|
||||
sp<ResultWrapper> resultWrapper = new ResultWrapper(const_cast<CameraMetadataNative &>(result),
|
||||
resultExtras, physicalCaptureResultInfos);
|
||||
sp<AMessage> msg = new AMessage(kWhatResultReceived, mHandler);
|
||||
msg->setObject(kResultKey, resultWrapper);
|
||||
msg->post();
|
||||
return binder::Status::ok();
|
||||
}
|
||||
|
||||
binder::Status H2BCameraDeviceCallbacks::onPrepared(int32_t streamId) {
|
||||
// not implemented
|
||||
// To silence Wunused-parameter.
|
||||
(void) streamId;
|
||||
return binder::Status::ok();
|
||||
}
|
||||
|
||||
binder::Status H2BCameraDeviceCallbacks::onRepeatingRequestError(
|
||||
int64_t lastFrameNumber,
|
||||
int32_t repeatingRequestId) {
|
||||
auto ret =
|
||||
mBase->onRepeatingRequestError(lastFrameNumber, repeatingRequestId);
|
||||
if (!ret.isOk()) {
|
||||
ALOGE("%s OnRepeatingRequestEror callback failed due to %s",__FUNCTION__,
|
||||
ret.description().c_str());
|
||||
}
|
||||
return binder::Status::ok();
|
||||
}
|
||||
|
||||
binder::Status H2BCameraDeviceCallbacks::onRequestQueueEmpty() {
|
||||
// not implemented
|
||||
return binder::Status::ok();
|
||||
}
|
||||
|
||||
} // implementation
|
||||
} // V2_0
|
||||
} // device
|
||||
} // cameraservice
|
||||
} // frameworks
|
||||
} // android
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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_FRAMEWORKS_AIDL_CAMERADEVICECALLBACKS_H
|
||||
#define ANDROID_FRAMEWORKS_AIDL_CAMERADEVICECALLBACKS_H
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include <android/frameworks/cameraservice/common/2.0/types.h>
|
||||
#include <android/frameworks/cameraservice/service/2.0/types.h>
|
||||
#include <android/frameworks/cameraservice/device/2.0/ICameraDeviceCallback.h>
|
||||
#include <android/frameworks/cameraservice/device/2.0/types.h>
|
||||
#include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
|
||||
#include <media/stagefright/foundation/ALooper.h>
|
||||
#include <media/stagefright/foundation/AHandler.h>
|
||||
#include <media/stagefright/foundation/AMessage.h>
|
||||
#include <fmq/MessageQueue.h>
|
||||
#include <hidl/MQDescriptor.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <CameraService.h>
|
||||
#include <hidl/CameraHybridInterface.h>
|
||||
|
||||
namespace android {
|
||||
namespace frameworks {
|
||||
namespace cameraservice {
|
||||
namespace device {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using camerahybrid::H2BConverter;
|
||||
using HCameraDeviceCallback = cameraservice::device::V2_0::ICameraDeviceCallback;
|
||||
using HPhysicalCaptureResultInfo = cameraservice::device::V2_0::PhysicalCaptureResultInfo;
|
||||
using android::frameworks::cameraservice::device::V2_0::FmqSizeOrMetadata;
|
||||
|
||||
using hardware::camera2::BnCameraDeviceCallbacks;
|
||||
using hardware::camera2::ICameraDeviceCallbacks;
|
||||
using hardware::camera2::impl::CaptureResultExtras;
|
||||
using hardware::camera2::impl::CameraMetadataNative;
|
||||
using hardware::camera2::impl::PhysicalCaptureResultInfo;
|
||||
using hardware::kSynchronizedReadWrite;
|
||||
using hardware::MessageQueue;
|
||||
using CaptureResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
|
||||
|
||||
struct H2BCameraDeviceCallbacks :
|
||||
public H2BConverter<HCameraDeviceCallback, ICameraDeviceCallbacks, BnCameraDeviceCallbacks> {
|
||||
H2BCameraDeviceCallbacks(const sp<HalInterface>& base);
|
||||
|
||||
~H2BCameraDeviceCallbacks();
|
||||
|
||||
bool initializeLooper();
|
||||
|
||||
virtual binder::Status onDeviceError(int32_t errorCode,
|
||||
const CaptureResultExtras& resultExtras) override;
|
||||
|
||||
virtual binder::Status onDeviceIdle() override;
|
||||
|
||||
virtual binder::Status onCaptureStarted(const CaptureResultExtras& resultExtras,
|
||||
int64_t timestamp) override;
|
||||
|
||||
virtual binder::Status onResultReceived(
|
||||
const CameraMetadataNative& result, const CaptureResultExtras& resultExtras,
|
||||
const std::vector<PhysicalCaptureResultInfo>& physicalCaptureResultInfos) override;
|
||||
|
||||
virtual binder::Status onPrepared(int32_t streamId) override;
|
||||
|
||||
virtual binder::Status onRepeatingRequestError(int64_t lastFrameNumber,
|
||||
int32_t repeatingRequestId) override;
|
||||
|
||||
virtual binder::Status onRequestQueueEmpty() override;
|
||||
|
||||
void setCaptureResultMetadataQueue(std::shared_ptr<CaptureResultMetadataQueue> metadataQueue) {
|
||||
mCaptureResultMetadataQueue = metadataQueue;
|
||||
}
|
||||
|
||||
private:
|
||||
// Wrapper struct so that parameters to onResultReceived callback may be
|
||||
// sent through an AMessage.
|
||||
struct ResultWrapper : public RefBase {
|
||||
CameraMetadataNative mResult;
|
||||
CaptureResultExtras mResultExtras;
|
||||
std::vector<PhysicalCaptureResultInfo> mPhysicalCaptureResultInfos;
|
||||
ResultWrapper(CameraMetadataNative &result,
|
||||
const CaptureResultExtras resultExtras,
|
||||
const std::vector<PhysicalCaptureResultInfo> &physicalCaptureResultInfos) :
|
||||
// TODO: make this std::movable
|
||||
mResult(result), mResultExtras(resultExtras), mPhysicalCaptureResultInfos(physicalCaptureResultInfos) { }
|
||||
};
|
||||
|
||||
struct CallbackHandler : public AHandler {
|
||||
public:
|
||||
void onMessageReceived(const sp<AMessage> &msg) override;
|
||||
CallbackHandler(H2BCameraDeviceCallbacks *converter) : mConverter(converter) { }
|
||||
private:
|
||||
void processResultMessage(sp<ResultWrapper> &resultWrapper);
|
||||
wp<H2BCameraDeviceCallbacks> mConverter = nullptr;
|
||||
Mutex mMetadataQueueLock;
|
||||
};
|
||||
|
||||
void convertResultMetadataToHidl(const camera_metadata *rawMetadata,
|
||||
FmqSizeOrMetadata *resultMetadata);
|
||||
enum {
|
||||
kWhatResultReceived,
|
||||
};
|
||||
|
||||
static const char *kResultKey;
|
||||
|
||||
std::shared_ptr<CaptureResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
|
||||
sp<CallbackHandler> mHandler = nullptr;
|
||||
sp<ALooper> mCbLooper = nullptr;
|
||||
};
|
||||
|
||||
} // implementation
|
||||
} // V2_0
|
||||
} // device
|
||||
} // cameraservice
|
||||
} // frameworks
|
||||
} // android
|
||||
#endif // ANDROID_FRAMEWORKS_AIDL_CAMERADEVICECALLBACKS_H
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#include <hidl/AidlCameraServiceListener.h>
|
||||
#include <hidl/Convert.h>
|
||||
|
||||
namespace android {
|
||||
namespace frameworks {
|
||||
namespace cameraservice {
|
||||
namespace service {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using hardware::cameraservice::utils::conversion::convertToHidlCameraDeviceStatus;
|
||||
|
||||
binder::Status H2BCameraServiceListener::onStatusChanged(
|
||||
int32_t status, const ::android::String16& cameraId) {
|
||||
HCameraDeviceStatus hCameraDeviceStatus = convertToHidlCameraDeviceStatus(status);
|
||||
CameraStatusAndId cameraStatusAndId;
|
||||
cameraStatusAndId.deviceStatus = hCameraDeviceStatus;
|
||||
cameraStatusAndId.cameraId = String8(cameraId).string();
|
||||
auto ret = mBase->onStatusChanged(cameraStatusAndId);
|
||||
if (!ret.isOk()) {
|
||||
ALOGE("%s OnStatusChanged callback failed due to %s",__FUNCTION__,
|
||||
ret.description().c_str());
|
||||
}
|
||||
return binder::Status::ok();
|
||||
}
|
||||
|
||||
::android::binder::Status H2BCameraServiceListener::onTorchStatusChanged(
|
||||
int32_t, const ::android::String16&) {
|
||||
// We don't implement onTorchStatusChanged
|
||||
return binder::Status::ok();
|
||||
}
|
||||
|
||||
} // implementation
|
||||
} // V2_0
|
||||
} // common
|
||||
} // cameraservice
|
||||
} // frameworks
|
||||
} // android
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include <android/frameworks/cameraservice/common/2.0/types.h>
|
||||
#include <android/frameworks/cameraservice/service/2.0/ICameraServiceListener.h>
|
||||
#include <android/frameworks/cameraservice/device/2.0/types.h>
|
||||
#include <android/hardware/BnCameraServiceListener.h>
|
||||
#include <android/hardware/BpCameraServiceListener.h>
|
||||
|
||||
#include <hidl/Status.h>
|
||||
#include <hidl/CameraHybridInterface.h>
|
||||
|
||||
namespace android {
|
||||
namespace frameworks {
|
||||
namespace cameraservice {
|
||||
namespace service {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using hardware::BnCameraServiceListener;
|
||||
using hardware::BpCameraServiceListener;
|
||||
using camerahybrid::H2BConverter;
|
||||
using HCameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
|
||||
typedef frameworks::cameraservice::service::V2_0::ICameraServiceListener HCameraServiceListener;
|
||||
|
||||
struct H2BCameraServiceListener :
|
||||
public H2BConverter<HCameraServiceListener, ICameraServiceListener, BnCameraServiceListener> {
|
||||
H2BCameraServiceListener(const sp<HalInterface>& base) : CBase(base) { }
|
||||
|
||||
~H2BCameraServiceListener() { }
|
||||
|
||||
virtual ::android::binder::Status onStatusChanged(int32_t status,
|
||||
const ::android::String16& cameraId) override;
|
||||
|
||||
virtual ::android::binder::Status onTorchStatusChanged(
|
||||
int32_t status, const ::android::String16& cameraId) override;
|
||||
};
|
||||
|
||||
} // implementation
|
||||
} // V2_0
|
||||
} // service
|
||||
} // cameraservice
|
||||
} // frameworks
|
||||
} // android
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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_CAMERA_HYBRIDINTERFACE_H
|
||||
#define ANDROID_CAMERA_HYBRIDINTERFACE_H
|
||||
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
#include <binder/Parcel.h>
|
||||
#include <hidl/HidlSupport.h>
|
||||
|
||||
namespace android {
|
||||
namespace camerahybrid {
|
||||
typedef ::android::hidl::base::V1_0::IBase HInterface;
|
||||
|
||||
template <
|
||||
typename HINTERFACE,
|
||||
typename INTERFACE,
|
||||
typename BNINTERFACE >
|
||||
class H2BConverter : public BNINTERFACE {
|
||||
public:
|
||||
typedef H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE> CBase; // Converter Base
|
||||
typedef INTERFACE BaseInterface;
|
||||
typedef HINTERFACE HalInterface;
|
||||
|
||||
H2BConverter(const sp<HalInterface>& base) : mBase(base) {}
|
||||
virtual sp<HalInterface> getHalInterface() { return mBase; }
|
||||
virtual status_t linkToDeath(
|
||||
const sp<IBinder::DeathRecipient>& recipient,
|
||||
void* cookie = nullptr,
|
||||
uint32_t flags = 0);
|
||||
virtual status_t unlinkToDeath(
|
||||
const wp<IBinder::DeathRecipient>& recipient,
|
||||
void* cookie = nullptr,
|
||||
uint32_t flags = 0,
|
||||
wp<IBinder::DeathRecipient>* outRecipient = nullptr);
|
||||
|
||||
protected:
|
||||
sp<HalInterface> mBase;
|
||||
struct Obituary : public hardware::hidl_death_recipient {
|
||||
wp<IBinder::DeathRecipient> recipient;
|
||||
void* cookie;
|
||||
uint32_t flags;
|
||||
wp<IBinder> who;
|
||||
Obituary(
|
||||
const wp<IBinder::DeathRecipient>& r,
|
||||
void* c, uint32_t f,
|
||||
const wp<IBinder>& w) :
|
||||
recipient(r), cookie(c), flags(f), who(w) {
|
||||
}
|
||||
Obituary(const Obituary& o) :
|
||||
recipient(o.recipient),
|
||||
cookie(o.cookie),
|
||||
flags(o.flags),
|
||||
who(o.who) {
|
||||
}
|
||||
Obituary& operator=(const Obituary& o) {
|
||||
recipient = o.recipient;
|
||||
cookie = o.cookie;
|
||||
flags = o.flags;
|
||||
who = o.who;
|
||||
return *this;
|
||||
}
|
||||
void serviceDied(uint64_t, const wp<HInterface>&) override {
|
||||
sp<IBinder::DeathRecipient> dr = recipient.promote();
|
||||
if (dr != nullptr) {
|
||||
dr->binderDied(who);
|
||||
}
|
||||
}
|
||||
};
|
||||
std::mutex mObituariesLock;
|
||||
std::vector<sp<Obituary> > mObituaries;
|
||||
};
|
||||
|
||||
template <
|
||||
typename HINTERFACE,
|
||||
typename INTERFACE,
|
||||
typename BNINTERFACE>
|
||||
status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE>::
|
||||
linkToDeath(
|
||||
const sp<IBinder::DeathRecipient>& recipient,
|
||||
void* cookie, uint32_t flags) {
|
||||
LOG_ALWAYS_FATAL_IF(recipient == nullptr,
|
||||
"linkToDeath(): recipient must be non-nullptr");
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mObituariesLock);
|
||||
mObituaries.push_back(new Obituary(recipient, cookie, flags, this));
|
||||
if (!mBase->linkToDeath(mObituaries.back(), 0)) {
|
||||
return DEAD_OBJECT;
|
||||
}
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
template <
|
||||
typename HINTERFACE,
|
||||
typename INTERFACE,
|
||||
typename BNINTERFACE>
|
||||
status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE>::
|
||||
unlinkToDeath(
|
||||
const wp<IBinder::DeathRecipient>& recipient,
|
||||
void* cookie, uint32_t flags,
|
||||
wp<IBinder::DeathRecipient>* outRecipient) {
|
||||
std::lock_guard<std::mutex> lock(mObituariesLock);
|
||||
for (auto i = mObituaries.begin(); i != mObituaries.end(); ++i) {
|
||||
if ((flags = (*i)->flags) && (
|
||||
(recipient == (*i)->recipient) ||
|
||||
((recipient == nullptr) && (cookie == (*i)->cookie)))) {
|
||||
if (outRecipient != nullptr) {
|
||||
*outRecipient = (*i)->recipient;
|
||||
}
|
||||
bool success = mBase->unlinkToDeath(*i);
|
||||
mObituaries.erase(i);
|
||||
return success ? NO_ERROR : DEAD_OBJECT;
|
||||
}
|
||||
}
|
||||
return NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
} // namespace camerahybrid
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_CAMERA_HYBRIDINTERFACE_H
|
||||
|
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#include <hidl/Convert.h>
|
||||
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
|
||||
#include <NdkImageReaderPriv.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace cameraservice {
|
||||
namespace utils {
|
||||
namespace conversion {
|
||||
|
||||
using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
|
||||
|
||||
// Note: existing data in dst will be gone. Caller still owns the memory of src
|
||||
void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst) {
|
||||
if (src == nullptr) {
|
||||
ALOGW("%s:attempt to convert empty metadata to Hidl", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
size_t size = get_camera_metadata_size(src);
|
||||
dst->setToExternal((uint8_t *) src, size);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t convertFromHidl(HStreamConfigurationMode streamConfigurationMode) {
|
||||
switch (streamConfigurationMode) {
|
||||
case HStreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE:
|
||||
return camera2::ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE;
|
||||
case HStreamConfigurationMode::NORMAL_MODE:
|
||||
return camera2::ICameraDeviceUser::NORMAL_MODE;
|
||||
default:
|
||||
// TODO: Fix this
|
||||
return camera2::ICameraDeviceUser::VENDOR_MODE_START;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t convertFromHidl(HTemplateId templateId) {
|
||||
switch(templateId) {
|
||||
case HTemplateId::PREVIEW:
|
||||
return camera2::ICameraDeviceUser::TEMPLATE_PREVIEW;
|
||||
case HTemplateId::STILL_CAPTURE:
|
||||
return camera2::ICameraDeviceUser::TEMPLATE_STILL_CAPTURE;
|
||||
case HTemplateId::RECORD:
|
||||
return camera2::ICameraDeviceUser::TEMPLATE_RECORD;
|
||||
case HTemplateId::VIDEO_SNAPSHOT:
|
||||
return camera2::ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT;
|
||||
case HTemplateId::ZERO_SHUTTER_LAG:
|
||||
return camera2::ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG;
|
||||
case HTemplateId::MANUAL:
|
||||
return camera2::ICameraDeviceUser::TEMPLATE_MANUAL;
|
||||
}
|
||||
}
|
||||
|
||||
int convertFromHidl(HOutputConfiguration::Rotation rotation) {
|
||||
switch(rotation) {
|
||||
case HOutputConfiguration::Rotation::R0:
|
||||
return 0;
|
||||
case HOutputConfiguration::Rotation::R90:
|
||||
return 1;
|
||||
case HOutputConfiguration::Rotation::R180:
|
||||
return 2;
|
||||
case HOutputConfiguration::Rotation::R270:
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
hardware::camera2::params::OutputConfiguration convertFromHidl(
|
||||
const HOutputConfiguration &hOutputConfiguration) {
|
||||
std::vector<sp<IGraphicBufferProducer>> iGBPs;
|
||||
auto &windowHandles = hOutputConfiguration.windowHandles;
|
||||
iGBPs.reserve(windowHandles.size());
|
||||
for (auto &handle : windowHandles) {
|
||||
iGBPs.push_back(new H2BGraphicBufferProducer(AImageReader_getHGBPFromHandle(handle)));
|
||||
}
|
||||
hardware::camera2::params::OutputConfiguration outputConfiguration(
|
||||
iGBPs, convertFromHidl(hOutputConfiguration.rotation),
|
||||
hOutputConfiguration.windowGroupId, OutputConfiguration::SURFACE_TYPE_UNKNOWN, 0, 0,
|
||||
(windowHandles.size() > 1));
|
||||
return outputConfiguration;
|
||||
}
|
||||
|
||||
// The camera metadata here is cloned. Since we're reading metadata over
|
||||
// hwbinder we would need to clone it in order to avoid aligment issues.
|
||||
bool convertFromHidl(const HCameraMetadata &src, CameraMetadata *dst) {
|
||||
const camera_metadata_t *buffer = reinterpret_cast<const camera_metadata_t*>(src.data());
|
||||
size_t expectedSize = src.size();
|
||||
int res = validate_camera_metadata_structure(buffer, &expectedSize);
|
||||
if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
|
||||
*dst = buffer;
|
||||
} else {
|
||||
ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
HCameraDeviceStatus convertToHidlCameraDeviceStatus(int32_t status) {
|
||||
HCameraDeviceStatus deviceStatus = HCameraDeviceStatus::STATUS_UNKNOWN;
|
||||
switch(status) {
|
||||
case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
|
||||
deviceStatus = HCameraDeviceStatus::STATUS_NOT_PRESENT;
|
||||
break;
|
||||
case hardware::ICameraServiceListener::STATUS_PRESENT:
|
||||
deviceStatus = HCameraDeviceStatus::STATUS_PRESENT;
|
||||
break;
|
||||
case hardware::ICameraServiceListener::STATUS_ENUMERATING:
|
||||
deviceStatus = HCameraDeviceStatus::STATUS_ENUMERATING;
|
||||
break;
|
||||
case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
|
||||
deviceStatus = HCameraDeviceStatus::STATUS_NOT_AVAILABLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return deviceStatus;
|
||||
}
|
||||
|
||||
HCaptureResultExtras convertToHidl(const CaptureResultExtras &captureResultExtras) {
|
||||
HCaptureResultExtras hCaptureResultExtras;
|
||||
hCaptureResultExtras.burstId = captureResultExtras.burstId;
|
||||
hCaptureResultExtras.frameNumber = captureResultExtras.frameNumber;
|
||||
hCaptureResultExtras.partialResultCount = captureResultExtras.partialResultCount;
|
||||
hCaptureResultExtras.errorStreamId = captureResultExtras.errorStreamId;
|
||||
return hCaptureResultExtras;
|
||||
}
|
||||
|
||||
HErrorCode convertToHidl(int32_t errorCode) {
|
||||
switch(errorCode) {
|
||||
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED:
|
||||
return HErrorCode::CAMERA_DISCONNECTED;
|
||||
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
|
||||
return HErrorCode::CAMERA_DEVICE;
|
||||
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE:
|
||||
return HErrorCode::CAMERA_SERVICE;
|
||||
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
|
||||
return HErrorCode::CAMERA_REQUEST;
|
||||
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
|
||||
return HErrorCode::CAMERA_RESULT;
|
||||
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
|
||||
return HErrorCode::CAMERA_BUFFER;
|
||||
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED:
|
||||
return HErrorCode::CAMERA_DISABLED;
|
||||
case camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR:
|
||||
return HErrorCode::CAMERA_INVALID_ERROR;
|
||||
default:
|
||||
return HErrorCode::CAMERA_UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
void convertToHidl(const std::vector<hardware::CameraStatus> &src,
|
||||
hidl_vec<HCameraStatusAndId>* dst) {
|
||||
dst->resize(src.size());
|
||||
size_t i = 0;
|
||||
for (auto &statusAndId : src) {
|
||||
auto &a = (*dst)[i++];
|
||||
a.cameraId = statusAndId.cameraId.c_str();
|
||||
a.deviceStatus = convertToHidlCameraDeviceStatus(statusAndId.status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void convertToHidl(
|
||||
const hardware::camera2::utils::SubmitInfo &submitInfo,
|
||||
frameworks::cameraservice::device::V2_0::SubmitInfo *hSubmitInfo) {
|
||||
hSubmitInfo->requestId = submitInfo.mRequestId;
|
||||
hSubmitInfo->lastFrameNumber = submitInfo.mLastFrameNumber;
|
||||
}
|
||||
|
||||
HStatus B2HStatus(const binder::Status &bStatus) {
|
||||
HStatus status = HStatus::NO_ERROR;
|
||||
if (bStatus.isOk()) {
|
||||
// NO Error here
|
||||
return status;
|
||||
}
|
||||
switch(bStatus.serviceSpecificErrorCode()) {
|
||||
case hardware::ICameraService::ERROR_DISCONNECTED:
|
||||
status = HStatus::DISCONNECTED;
|
||||
break;
|
||||
case hardware::ICameraService::ERROR_CAMERA_IN_USE:
|
||||
status = HStatus::CAMERA_IN_USE;
|
||||
break;
|
||||
case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
|
||||
status = HStatus::MAX_CAMERAS_IN_USE;
|
||||
break;
|
||||
case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
|
||||
status = HStatus::ILLEGAL_ARGUMENT;
|
||||
break;
|
||||
case hardware::ICameraService::ERROR_DEPRECATED_HAL:
|
||||
// Should not reach here since we filtered legacy HALs earlier
|
||||
status = HStatus::DEPRECATED_HAL;
|
||||
break;
|
||||
case hardware::ICameraService::ERROR_DISABLED:
|
||||
status = HStatus::DISABLED;
|
||||
break;
|
||||
case hardware::ICameraService::ERROR_PERMISSION_DENIED:
|
||||
status = HStatus::PERMISSION_DENIED;
|
||||
break;
|
||||
case hardware::ICameraService::ERROR_INVALID_OPERATION:
|
||||
status = HStatus::INVALID_OPERATION;
|
||||
break;
|
||||
default:
|
||||
status = HStatus::UNKNOWN_ERROR;
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
HPhysicalCaptureResultInfo convertToHidl(
|
||||
const PhysicalCaptureResultInfo &physicalCaptureResultInfo,
|
||||
std::shared_ptr<CaptureResultMetadataQueue> &captureResultMetadataQueue) {
|
||||
HPhysicalCaptureResultInfo hPhysicalCaptureResultInfo;
|
||||
hPhysicalCaptureResultInfo.physicalCameraId =
|
||||
String8(physicalCaptureResultInfo.mPhysicalCameraId).string();
|
||||
const camera_metadata_t *rawMetadata =
|
||||
physicalCaptureResultInfo.mPhysicalCameraMetadata.getAndLock();
|
||||
// Try using fmq at first.
|
||||
size_t metadata_size = get_camera_metadata_size(rawMetadata);
|
||||
if ((metadata_size > 0) && (captureResultMetadataQueue->availableToWrite() > 0)) {
|
||||
if (captureResultMetadataQueue->write((uint8_t *)rawMetadata, metadata_size)) {
|
||||
hPhysicalCaptureResultInfo.physicalCameraMetadata.fmqMetadataSize(metadata_size);
|
||||
} else {
|
||||
ALOGW("%s Couldn't use fmq, falling back to hwbinder", __FUNCTION__);
|
||||
HCameraMetadata metadata;
|
||||
convertToHidl(rawMetadata, &metadata);
|
||||
hPhysicalCaptureResultInfo.physicalCameraMetadata.metadata(std::move(metadata));
|
||||
}
|
||||
}
|
||||
physicalCaptureResultInfo.mPhysicalCameraMetadata.unlock(rawMetadata);
|
||||
return hPhysicalCaptureResultInfo;
|
||||
}
|
||||
|
||||
hidl_vec<HPhysicalCaptureResultInfo> convertToHidl(
|
||||
const std::vector<PhysicalCaptureResultInfo> &physicalCaptureResultInfos,
|
||||
std::shared_ptr<CaptureResultMetadataQueue> &captureResultMetadataQueue) {
|
||||
hidl_vec<HPhysicalCaptureResultInfo> hPhysicalCaptureResultInfos;
|
||||
hPhysicalCaptureResultInfos.resize(physicalCaptureResultInfos.size());
|
||||
size_t i = 0;
|
||||
for (auto &physicalCaptureResultInfo : physicalCaptureResultInfos) {
|
||||
hPhysicalCaptureResultInfos[i++] = convertToHidl(physicalCaptureResultInfo,
|
||||
captureResultMetadataQueue);
|
||||
}
|
||||
return hPhysicalCaptureResultInfos;
|
||||
}
|
||||
|
||||
} //conversion
|
||||
} // utils
|
||||
} //cameraservice
|
||||
} // hardware
|
||||
} // android
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 CAMERASERVER_CONVERT_HIDL
|
||||
#define CAMERASERVER_CONVERT_HIDL
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
|
||||
#include <android/frameworks/cameraservice/device/2.0/ICameraDeviceUser.h>
|
||||
#include <android/frameworks/cameraservice/common/2.0/types.h>
|
||||
#include <android/frameworks/cameraservice/service/2.0/types.h>
|
||||
#include <android/frameworks/cameraservice/device/2.0/types.h>
|
||||
#include <android/hardware/camera/common/1.0/types.h>
|
||||
#include <android/hardware/camera2/ICameraDeviceUser.h>
|
||||
#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
|
||||
#include <android/hardware/ICameraService.h>
|
||||
#include <fmq/MessageQueue.h>
|
||||
#include <hardware/camera.h>
|
||||
#include <hidl/MQDescriptor.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace cameraservice {
|
||||
namespace utils {
|
||||
namespace conversion {
|
||||
|
||||
using hardware::camera2::impl::CaptureResultExtras;
|
||||
using hardware::camera2::impl::PhysicalCaptureResultInfo;
|
||||
|
||||
using CaptureResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
|
||||
using HCameraMetadata = frameworks::cameraservice::service::V2_0::CameraMetadata;
|
||||
using HCameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
|
||||
using HCameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
|
||||
using HCameraDeviceUser = frameworks::cameraservice::device::V2_0::ICameraDeviceUser;
|
||||
using HCaptureResultExtras = frameworks::cameraservice::device::V2_0::CaptureResultExtras;
|
||||
using HCaptureRequest = frameworks::cameraservice::device::V2_0::CaptureRequest;
|
||||
using HErrorCode = frameworks::cameraservice::device::V2_0::ErrorCode;
|
||||
using HGraphicBufferProducer = hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer;
|
||||
using HOutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration;
|
||||
using HPhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings;
|
||||
using HPhysicalCaptureResultInfo = frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo;
|
||||
using HSubmitInfo = frameworks::cameraservice::device::V2_0::SubmitInfo;
|
||||
using HStatus = frameworks::cameraservice::common::V2_0::Status;
|
||||
using HStreamConfigurationMode = frameworks::cameraservice::device::V2_0::StreamConfigurationMode;
|
||||
using HTemplateId = frameworks::cameraservice::device::V2_0::TemplateId;
|
||||
|
||||
// Note: existing data in dst will be gone. Caller still owns the memory of src
|
||||
void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst);
|
||||
|
||||
int32_t convertFromHidl(HStreamConfigurationMode streamConfigurationMode);
|
||||
|
||||
int32_t convertFromHidl(HTemplateId templateId);
|
||||
|
||||
bool convertFromHidl(const HCameraMetadata &src, CameraMetadata *dst);
|
||||
|
||||
hardware::camera2::params::OutputConfiguration convertFromHidl(
|
||||
const HOutputConfiguration &hOutputConfiguration);
|
||||
|
||||
HCameraDeviceStatus convertToHidlCameraDeviceStatus(int32_t status);
|
||||
|
||||
void convertToHidl(const std::vector<hardware::CameraStatus> &src,
|
||||
hidl_vec<HCameraStatusAndId>* dst);
|
||||
|
||||
void convertToHidl(const hardware::camera2::utils::SubmitInfo &submitInfo,
|
||||
HSubmitInfo *hSubmitInfo);
|
||||
|
||||
HErrorCode convertToHidl(int32_t errorCode);
|
||||
|
||||
HCaptureResultExtras convertToHidl(const CaptureResultExtras &captureResultExtras);
|
||||
|
||||
hidl_vec<HPhysicalCaptureResultInfo> convertToHidl(
|
||||
const std::vector<PhysicalCaptureResultInfo> &physicalCaptureResultInfos,
|
||||
std::shared_ptr<CaptureResultMetadataQueue> &captureResultMetadataQueue);
|
||||
|
||||
HStatus B2HStatus(const binder::Status &bStatus);
|
||||
|
||||
} // conversion
|
||||
} // utils
|
||||
} // cameraservice
|
||||
} // hardware
|
||||
} //android
|
||||
|
||||
#endif //CAMERASERVER_CONVERT_TO_HIDL
|
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#include <android/hardware/camera/device/3.2/types.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <gui/Surface.h>
|
||||
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
|
||||
|
||||
#include <hidl/AidlCameraDeviceCallbacks.h>
|
||||
#include <hidl/Convert.h>
|
||||
#include <hidl/HidlCameraDeviceUser.h>
|
||||
#include <android/hardware/camera/device/3.2/types.h>
|
||||
|
||||
namespace android {
|
||||
namespace frameworks {
|
||||
namespace cameraservice {
|
||||
namespace device {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using hardware::cameraservice::utils::conversion::convertToHidl;
|
||||
using hardware::cameraservice::utils::conversion::convertFromHidl;
|
||||
using hardware::cameraservice::utils::conversion::B2HStatus;
|
||||
|
||||
using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
|
||||
using hardware::hidl_vec;
|
||||
using hardware::Return;
|
||||
using hardware::Void;
|
||||
using HSubmitInfo = device::V2_0::SubmitInfo;
|
||||
using hardware::camera2::params::OutputConfiguration;
|
||||
|
||||
static constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
|
||||
static constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
|
||||
|
||||
Return<void> HidlCameraDeviceUser::disconnect() {
|
||||
mDeviceRemote->disconnect();
|
||||
return Void();
|
||||
}
|
||||
|
||||
HidlCameraDeviceUser::HidlCameraDeviceUser(
|
||||
const sp<hardware::camera2::ICameraDeviceUser> &deviceRemote)
|
||||
: mDeviceRemote(deviceRemote) {
|
||||
mInitSuccess = initDevice();
|
||||
}
|
||||
|
||||
bool HidlCameraDeviceUser::initDevice() {
|
||||
// TODO: Get request and result metadata queue size from a system property.
|
||||
int32_t reqFMQSize = CAMERA_REQUEST_METADATA_QUEUE_SIZE;
|
||||
|
||||
mCaptureRequestMetadataQueue =
|
||||
std::make_unique<CaptureRequestMetadataQueue>(static_cast<size_t>(reqFMQSize),
|
||||
false /* non blocking */);
|
||||
if (!mCaptureRequestMetadataQueue->isValid()) {
|
||||
ALOGE("%s: invalid request fmq", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t resFMQSize = CAMERA_RESULT_METADATA_QUEUE_SIZE;
|
||||
mCaptureResultMetadataQueue =
|
||||
std::make_shared<CaptureResultMetadataQueue>(static_cast<size_t>(resFMQSize),
|
||||
false /* non blocking */);
|
||||
if (!mCaptureResultMetadataQueue->isValid()) {
|
||||
ALOGE("%s: invalid result fmq", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Return<void> HidlCameraDeviceUser::getCaptureRequestMetadataQueue(
|
||||
getCaptureRequestMetadataQueue_cb _hidl_cb) {
|
||||
if (mInitSuccess) {
|
||||
_hidl_cb(*mCaptureRequestMetadataQueue->getDesc());
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> HidlCameraDeviceUser::getCaptureResultMetadataQueue(
|
||||
getCaptureResultMetadataQueue_cb _hidl_cb) {
|
||||
if (mInitSuccess) {
|
||||
_hidl_cb(*mCaptureResultMetadataQueue->getDesc());
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
/**
|
||||
* To be used only by submitRequestList implementation, since it requires
|
||||
* clients to call this method serially, incase fmq is used to send metadata.
|
||||
*/
|
||||
bool HidlCameraDeviceUser::copyPhysicalCameraSettings(
|
||||
const hidl_vec<HPhysicalCameraSettings> &hPhysicalCameraSettings,
|
||||
std::vector<CaptureRequest::PhysicalCameraSettings> *physicalCameraSettings) {
|
||||
bool converted = false;
|
||||
for (auto &e : hPhysicalCameraSettings) {
|
||||
physicalCameraSettings->emplace_back();
|
||||
CaptureRequest::PhysicalCameraSettings &physicalCameraSetting =
|
||||
physicalCameraSettings->back();
|
||||
physicalCameraSetting.id = e.id.c_str();
|
||||
|
||||
// Read the settings either from the fmq or straightaway from the
|
||||
// request. We don't need any synchronization, since submitRequestList
|
||||
// is guaranteed to be called serially by the client if it decides to
|
||||
// use fmq.
|
||||
if (e.settings.getDiscriminator() ==
|
||||
FmqSizeOrMetadata::hidl_discriminator::fmqMetadataSize) {
|
||||
/**
|
||||
* Get settings from the fmq.
|
||||
*/
|
||||
HCameraMetadata settingsFmq;
|
||||
settingsFmq.resize(e.settings.fmqMetadataSize());
|
||||
bool read = mCaptureRequestMetadataQueue->read(settingsFmq.data(),
|
||||
e.settings.fmqMetadataSize());
|
||||
if (!read) {
|
||||
ALOGE("%s capture request settings could't be read from fmq size",
|
||||
__FUNCTION__);
|
||||
converted = false;
|
||||
} else {
|
||||
converted = convertFromHidl(settingsFmq, &physicalCameraSetting.settings);
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* The settings metadata is contained in request settings field.
|
||||
*/
|
||||
converted =
|
||||
convertFromHidl(e.settings.metadata(),
|
||||
&physicalCameraSetting.settings);
|
||||
}
|
||||
if (!converted) {
|
||||
ALOGE("%s: Unable to convert physicalCameraSettings from HIDL to AIDL.", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HidlCameraDeviceUser::convertRequestFromHidl(const HCaptureRequest &hRequest,
|
||||
CaptureRequest *request) {
|
||||
// No reprocessing support.
|
||||
request->mIsReprocess = false;
|
||||
for (const auto &streamAndWindowId : hRequest.streamAndWindowIds) {
|
||||
request->mStreamIdxList.push_back(streamAndWindowId.streamId);
|
||||
request->mSurfaceIdxList.push_back(streamAndWindowId.windowId);
|
||||
}
|
||||
return copyPhysicalCameraSettings(hRequest.physicalCameraSettings,
|
||||
&(request->mPhysicalCameraSettings));
|
||||
}
|
||||
|
||||
Return<void> HidlCameraDeviceUser::submitRequestList(const hidl_vec<HCaptureRequest>& hRequestList,
|
||||
bool streaming,
|
||||
submitRequestList_cb _hidl_cb) {
|
||||
hardware::camera2::utils::SubmitInfo submitInfo;
|
||||
HSubmitInfo hSubmitInfo;
|
||||
/**
|
||||
* Create AIDL CaptureRequest from requestList and graphicBufferProducers.
|
||||
*/
|
||||
std::vector<hardware::camera2::CaptureRequest> requests;
|
||||
for (auto &hRequest : hRequestList) {
|
||||
requests.emplace_back();
|
||||
auto &request = requests.back();
|
||||
if (!convertRequestFromHidl(hRequest, &request)) {
|
||||
_hidl_cb(HStatus::ILLEGAL_ARGUMENT, hSubmitInfo);
|
||||
return Void();
|
||||
}
|
||||
}
|
||||
mDeviceRemote->submitRequestList(requests, streaming, &submitInfo);
|
||||
mRequestId = submitInfo.mRequestId;
|
||||
convertToHidl(submitInfo, &hSubmitInfo);
|
||||
_hidl_cb(HStatus::NO_ERROR, hSubmitInfo);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> HidlCameraDeviceUser::cancelRepeatingRequest(cancelRepeatingRequest_cb _hidl_cb) {
|
||||
int64_t lastFrameNumber = 0;
|
||||
binder::Status ret = mDeviceRemote->cancelRequest(mRequestId, &lastFrameNumber);
|
||||
_hidl_cb(B2HStatus(ret), lastFrameNumber);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<HStatus> HidlCameraDeviceUser::beginConfigure() {
|
||||
binder::Status ret = mDeviceRemote->beginConfigure();
|
||||
return B2HStatus(ret);
|
||||
}
|
||||
|
||||
Return<HStatus> HidlCameraDeviceUser::endConfigure(StreamConfigurationMode operatingMode,
|
||||
const hidl_vec<uint8_t>& sessionParams) {
|
||||
android::CameraMetadata cameraMetadata;
|
||||
if (!convertFromHidl(sessionParams, &cameraMetadata)) {
|
||||
return HStatus::ILLEGAL_ARGUMENT;
|
||||
}
|
||||
|
||||
binder::Status ret = mDeviceRemote->endConfigure(convertFromHidl(operatingMode),
|
||||
cameraMetadata);
|
||||
return B2HStatus(ret);
|
||||
}
|
||||
|
||||
Return<HStatus> HidlCameraDeviceUser::deleteStream(int32_t streamId) {
|
||||
binder::Status ret = mDeviceRemote->deleteStream(streamId);
|
||||
return B2HStatus(ret);
|
||||
}
|
||||
|
||||
Return<void> HidlCameraDeviceUser::createStream(const HOutputConfiguration& hOutputConfiguration,
|
||||
createStream_cb hidl_cb_) {
|
||||
OutputConfiguration outputConfiguration =
|
||||
convertFromHidl(hOutputConfiguration);
|
||||
int32_t newStreamId = 0;
|
||||
binder::Status ret = mDeviceRemote->createStream(outputConfiguration, &newStreamId);
|
||||
HStatus status = B2HStatus(ret);
|
||||
hidl_cb_(status, newStreamId);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> HidlCameraDeviceUser::createDefaultRequest(TemplateId templateId,
|
||||
createDefaultRequest_cb _hidl_cb) {
|
||||
android::CameraMetadata cameraMetadata;
|
||||
binder::Status ret = mDeviceRemote->createDefaultRequest(convertFromHidl(templateId),
|
||||
&cameraMetadata);
|
||||
HStatus hStatus = B2HStatus(ret);
|
||||
HCameraMetadata hidlMetadata;
|
||||
const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
|
||||
convertToHidl(rawMetadata, &hidlMetadata);
|
||||
_hidl_cb(hStatus, hidlMetadata);
|
||||
cameraMetadata.unlock(rawMetadata);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<HStatus> HidlCameraDeviceUser::waitUntilIdle() {
|
||||
binder::Status ret = mDeviceRemote->waitUntilIdle();
|
||||
return B2HStatus(ret);
|
||||
}
|
||||
|
||||
Return<void> HidlCameraDeviceUser::flush(flush_cb _hidl_cb) {
|
||||
int64_t lastFrameNumber = 0;
|
||||
binder::Status ret = mDeviceRemote->flush(&lastFrameNumber);
|
||||
_hidl_cb(B2HStatus(ret),lastFrameNumber);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<HStatus> HidlCameraDeviceUser::updateOutputConfiguration(
|
||||
int32_t streamId,
|
||||
const HOutputConfiguration& hOutputConfiguration) {
|
||||
OutputConfiguration outputConfiguration = convertFromHidl(hOutputConfiguration);
|
||||
binder::Status ret = mDeviceRemote->updateOutputConfiguration(streamId, outputConfiguration);
|
||||
return B2HStatus(ret);
|
||||
}
|
||||
|
||||
} // implementation
|
||||
} // V2_0
|
||||
} // device
|
||||
} // cameraservice
|
||||
} // frameworks
|
||||
} // android
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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_FRAMEWORKS_CAMERADEVICEUSER_V2_0_CAMERADEVICEUSER_H
|
||||
#define ANDROID_FRAMEWORKS_CAMERADEVICEUSER_V2_0_CAMERADEVICEUSER_H
|
||||
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include <android/frameworks/cameraservice/common/2.0/types.h>
|
||||
#include <android/frameworks/cameraservice/service/2.0/types.h>
|
||||
#include <android/frameworks/cameraservice/device/2.0/ICameraDeviceUser.h>
|
||||
#include <android/frameworks/cameraservice/device/2.0/types.h>
|
||||
#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
|
||||
#include <fmq/MessageQueue.h>
|
||||
#include <hidl/MQDescriptor.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
#include <CameraService.h>
|
||||
|
||||
namespace android {
|
||||
namespace frameworks {
|
||||
namespace cameraservice {
|
||||
namespace device {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using frameworks::cameraservice::device::V2_0::StreamConfigurationMode;
|
||||
using hardware::camera2::CaptureRequest;
|
||||
using hardware::hidl_vec;
|
||||
using hardware::kSynchronizedReadWrite;
|
||||
using hardware::MessageQueue;
|
||||
using hardware::MQDescriptorSync;
|
||||
using hardware::Return;
|
||||
using CaptureResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
|
||||
using CaptureRequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
|
||||
using TemplateId = frameworks::cameraservice::device::V2_0::TemplateId;
|
||||
|
||||
using HCameraDeviceUser = device::V2_0::ICameraDeviceUser;
|
||||
using HCameraMetadata = cameraservice::service::V2_0::CameraMetadata;
|
||||
using HCaptureRequest = device::V2_0::CaptureRequest;
|
||||
using HOutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration;
|
||||
using HPhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings;
|
||||
using HStatus = frameworks::cameraservice::common::V2_0::Status;
|
||||
|
||||
static constexpr int32_t REQUEST_ID_NONE = -1;
|
||||
|
||||
struct HidlCameraDeviceUser final : public HCameraDeviceUser {
|
||||
HidlCameraDeviceUser(const sp<hardware::camera2::ICameraDeviceUser> &deviceRemote);
|
||||
|
||||
~HidlCameraDeviceUser() { }
|
||||
|
||||
virtual Return<void> disconnect() override;
|
||||
|
||||
virtual Return<void> getCaptureRequestMetadataQueue(
|
||||
getCaptureRequestMetadataQueue_cb _hidl_cb) override;
|
||||
|
||||
virtual Return<void> getCaptureResultMetadataQueue(
|
||||
getCaptureResultMetadataQueue_cb _hidl_cb) override;
|
||||
|
||||
virtual Return<void> submitRequestList(const hidl_vec<HCaptureRequest>& requestList,
|
||||
bool streaming, submitRequestList_cb _hidl_cb) override;
|
||||
|
||||
virtual Return<void> cancelRepeatingRequest(cancelRepeatingRequest_cb _hidl_cb) override;
|
||||
|
||||
virtual Return<HStatus> beginConfigure() override;
|
||||
|
||||
virtual Return<HStatus> endConfigure(StreamConfigurationMode operatingMode,
|
||||
const hidl_vec<uint8_t>& sessionParams);
|
||||
|
||||
virtual Return<HStatus> deleteStream(int32_t streamId) override;
|
||||
|
||||
virtual Return<void> createStream(const HOutputConfiguration& outputConfiguration,
|
||||
createStream_cb _hidl_cb) override;
|
||||
|
||||
Return<void> createDefaultRequest(TemplateId templateId,
|
||||
createDefaultRequest_cb _hidl_cb) override;
|
||||
|
||||
virtual Return<HStatus> waitUntilIdle() override;
|
||||
|
||||
virtual Return<void> flush(flush_cb _hidl_cb) override;
|
||||
|
||||
virtual Return<HStatus> updateOutputConfiguration(
|
||||
int32_t streamId, const HOutputConfiguration& outputConfiguration) override;
|
||||
|
||||
bool initStatus() { return mInitSuccess; }
|
||||
|
||||
std::shared_ptr<CaptureResultMetadataQueue> getCaptureResultMetadataQueue() {
|
||||
return mCaptureResultMetadataQueue;
|
||||
}
|
||||
|
||||
private:
|
||||
bool initDevice();
|
||||
|
||||
bool convertRequestFromHidl(const HCaptureRequest &hRequest, CaptureRequest *request);
|
||||
|
||||
bool copyPhysicalCameraSettings(
|
||||
const hidl_vec<HPhysicalCameraSettings> &hPhysicalCameraSettings,
|
||||
std::vector<CaptureRequest::PhysicalCameraSettings> *physicalCameraSettings);
|
||||
|
||||
const sp<hardware::camera2::ICameraDeviceUser> mDeviceRemote;
|
||||
std::unique_ptr<CaptureRequestMetadataQueue> mCaptureRequestMetadataQueue = nullptr;
|
||||
std::shared_ptr<CaptureResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
|
||||
bool mInitSuccess = false;
|
||||
int32_t mRequestId = REQUEST_ID_NONE;
|
||||
};
|
||||
|
||||
} // implementation
|
||||
} // V2_0
|
||||
} // device
|
||||
} // cameraservice
|
||||
} // frameworks
|
||||
} // android
|
||||
#endif // ANDROID_FRAMEOWORKS_CAMERADEVICEUSER_V2_0_CAMERADEVICEUSER_H
|
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#include <hidl/Convert.h>
|
||||
|
||||
#include <hidl/HidlCameraService.h>
|
||||
|
||||
#include <hidl/HidlCameraDeviceUser.h>
|
||||
#include <hidl/AidlCameraDeviceCallbacks.h>
|
||||
#include <hidl/AidlCameraServiceListener.h>
|
||||
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
|
||||
namespace android {
|
||||
namespace frameworks {
|
||||
namespace cameraservice {
|
||||
namespace service {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
|
||||
using hardware::hidl_vec;
|
||||
using hardware::cameraservice::utils::conversion::convertToHidl;
|
||||
using hardware::cameraservice::utils::conversion::B2HStatus;
|
||||
using hardware::Void;
|
||||
|
||||
using device::V2_0::implementation::H2BCameraDeviceCallbacks;
|
||||
using device::V2_0::implementation::HidlCameraDeviceUser;
|
||||
using service::V2_0::implementation::H2BCameraServiceListener;
|
||||
using HCameraMetadataType = android::frameworks::cameraservice::common::V2_0::CameraMetadataType;
|
||||
using HVendorTag = android::frameworks::cameraservice::common::V2_0::VendorTag;
|
||||
using HVendorTagSection = android::frameworks::cameraservice::common::V2_0::VendorTagSection;
|
||||
|
||||
sp<HidlCameraService> gHidlCameraService;
|
||||
|
||||
sp<HidlCameraService> HidlCameraService::getInstance(android::CameraService *cs) {
|
||||
gHidlCameraService = new HidlCameraService(cs);
|
||||
return gHidlCameraService;
|
||||
}
|
||||
|
||||
Return<void>
|
||||
HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId,
|
||||
getCameraCharacteristics_cb _hidl_cb) {
|
||||
android::CameraMetadata cameraMetadata;
|
||||
HStatus status = HStatus::NO_ERROR;
|
||||
binder::Status serviceRet =
|
||||
mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()), &cameraMetadata);
|
||||
HCameraMetadata hidlMetadata;
|
||||
if (!serviceRet.isOk()) {
|
||||
switch(serviceRet.serviceSpecificErrorCode()) {
|
||||
// No ERROR_CAMERA_DISCONNECTED since we're in the same process.
|
||||
case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
|
||||
ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraId.c_str());
|
||||
status = HStatus::ILLEGAL_ARGUMENT;
|
||||
break;
|
||||
default:
|
||||
ALOGE("Get camera characteristics from camera service failed: %s",
|
||||
serviceRet.toString8().string());
|
||||
status = B2HStatus(serviceRet);
|
||||
}
|
||||
_hidl_cb(status, hidlMetadata);
|
||||
return Void();
|
||||
}
|
||||
const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
|
||||
convertToHidl(rawMetadata, &hidlMetadata);
|
||||
_hidl_cb(status, hidlMetadata);
|
||||
cameraMetadata.unlock(rawMetadata);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& hCallback,
|
||||
const hidl_string& cameraId,
|
||||
connectDevice_cb _hidl_cb) {
|
||||
// Here, we first get ICameraDeviceUser from mAidlICameraService, then save
|
||||
// that interface in the newly created HidlCameraDeviceUser impl class.
|
||||
if (mAidlICameraService == nullptr) {
|
||||
_hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
|
||||
return Void();
|
||||
}
|
||||
sp<hardware::camera2::ICameraDeviceUser> deviceRemote = nullptr;
|
||||
// Create a hardware::camera2::ICameraDeviceCallback object which internally
|
||||
// calls callback functions passed through hCallback.
|
||||
sp<H2BCameraDeviceCallbacks> hybridCallbacks = new H2BCameraDeviceCallbacks(hCallback);
|
||||
if (!hybridCallbacks->initializeLooper()) {
|
||||
ALOGE("Unable to handle callbacks on device, cannot connect");
|
||||
_hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
|
||||
return Void();
|
||||
}
|
||||
sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
|
||||
binder::Status serviceRet = mAidlICameraService->connectDevice(
|
||||
callbacks, String16(cameraId.c_str()), String16(""),
|
||||
hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
|
||||
HStatus status = HStatus::NO_ERROR;
|
||||
if (!serviceRet.isOk()) {
|
||||
ALOGE("%s: Unable to connect to camera device", __FUNCTION__);
|
||||
status = B2HStatus(serviceRet);
|
||||
_hidl_cb(status, nullptr);
|
||||
return Void();
|
||||
}
|
||||
// Now we create a HidlCameraDeviceUser class, store the deviceRemote in it,
|
||||
// and return that back. All calls on that interface will be forwarded to
|
||||
// the AIDL interface.
|
||||
sp<HidlCameraDeviceUser> hDeviceRemote = new HidlCameraDeviceUser(deviceRemote);
|
||||
if (!hDeviceRemote->initStatus()) {
|
||||
ALOGE("%s: Unable to initialize camera device HIDL wrapper", __FUNCTION__);
|
||||
_hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
|
||||
return Void();
|
||||
}
|
||||
hybridCallbacks->setCaptureResultMetadataQueue(hDeviceRemote->getCaptureResultMetadataQueue());
|
||||
_hidl_cb(status, hDeviceRemote);
|
||||
return Void();
|
||||
}
|
||||
|
||||
void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
|
||||
sp<hardware::ICameraServiceListener> csListener) {
|
||||
mListeners.emplace_back(std::make_pair(hListener, csListener));
|
||||
}
|
||||
|
||||
sp<hardware::ICameraServiceListener>
|
||||
HidlCameraService::searchListenerCacheLocked(sp<HCameraServiceListener> hListener,
|
||||
bool shouldRemove) {
|
||||
// Go through the mListeners list and compare the listener with the HIDL
|
||||
// listener registered.
|
||||
auto it = mListeners.begin();
|
||||
sp<ICameraServiceListener> csListener = nullptr;
|
||||
for (;it != mListeners.end(); it++) {
|
||||
if (hardware::interfacesEqual(it->first, hListener)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (it != mListeners.end()) {
|
||||
csListener = it->second;
|
||||
if (shouldRemove) {
|
||||
mListeners.erase(it);
|
||||
}
|
||||
}
|
||||
return csListener;
|
||||
}
|
||||
|
||||
Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
|
||||
addListener_cb _hidl_cb) {
|
||||
if (mAidlICameraService == nullptr) {
|
||||
_hidl_cb(HStatus::UNKNOWN_ERROR, {});
|
||||
return Void();
|
||||
}
|
||||
if (hCsListener == nullptr) {
|
||||
ALOGE("%s listener must not be NULL", __FUNCTION__);
|
||||
_hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
|
||||
return Void();
|
||||
}
|
||||
sp<hardware::ICameraServiceListener> csListener = nullptr;
|
||||
// Check the cache for previously registered callbacks
|
||||
{
|
||||
Mutex::Autolock l(mListenerListLock);
|
||||
csListener = searchListenerCacheLocked(hCsListener);
|
||||
if (csListener == nullptr) {
|
||||
// Wrap an hCsListener with AidlCameraServiceListener and pass it to
|
||||
// CameraService.
|
||||
csListener = new H2BCameraServiceListener(hCsListener);
|
||||
// Add to cache
|
||||
addToListenerCacheLocked(hCsListener, csListener);
|
||||
} else {
|
||||
ALOGE("%s: Trying to add a listener %p already registered",
|
||||
__FUNCTION__, hCsListener.get());
|
||||
_hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
|
||||
return Void();
|
||||
}
|
||||
}
|
||||
std::vector<hardware::CameraStatus> cameraStatusAndIds{};
|
||||
binder::Status serviceRet = mAidlICameraService->addListener(csListener, &cameraStatusAndIds);
|
||||
HStatus status = HStatus::NO_ERROR;
|
||||
if (!serviceRet.isOk()) {
|
||||
ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
|
||||
status = B2HStatus(serviceRet);
|
||||
_hidl_cb(status, {});
|
||||
return Void();
|
||||
}
|
||||
hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
|
||||
//Convert cameraStatusAndIds to HIDL and call callback
|
||||
convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
|
||||
_hidl_cb(status, hCameraStatusAndIds);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<HStatus> HidlCameraService::removeListener(const sp<HCameraServiceListener>& hCsListener) {
|
||||
if (hCsListener == nullptr) {
|
||||
ALOGE("%s listener must not be NULL", __FUNCTION__);
|
||||
return HStatus::ILLEGAL_ARGUMENT;
|
||||
}
|
||||
sp<ICameraServiceListener> csListener = nullptr;
|
||||
{
|
||||
Mutex::Autolock l(mListenerListLock);
|
||||
csListener = searchListenerCacheLocked(hCsListener, /*removeIfFound*/true);
|
||||
}
|
||||
if (csListener != nullptr) {
|
||||
mAidlICameraService->removeListener(csListener);
|
||||
} else {
|
||||
ALOGE("%s Removing unregistered listener %p", __FUNCTION__, hCsListener.get());
|
||||
return HStatus::ILLEGAL_ARGUMENT;
|
||||
}
|
||||
return HStatus::NO_ERROR;
|
||||
}
|
||||
|
||||
Return<void> HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) {
|
||||
hidl_vec<HVendorTagSection> hVendorTagSections;
|
||||
// TODO: Could this be just created on the stack since we don't set it to
|
||||
// global cache or anything ?
|
||||
HStatus hStatus = HStatus::NO_ERROR;
|
||||
sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
|
||||
binder::Status serviceRet = mAidlICameraService->getCameraVendorTagDescriptor(desc.get());
|
||||
|
||||
if (!serviceRet.isOk()) {
|
||||
ALOGE("%s: Failed to get VendorTagDescriptor", __FUNCTION__);
|
||||
_hidl_cb(B2HStatus(serviceRet), hVendorTagSections);
|
||||
return Void();
|
||||
}
|
||||
|
||||
const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
|
||||
size_t numSections = sectionNames->size();
|
||||
std::vector<std::vector<HVendorTag>> tagsBySection(numSections);
|
||||
int tagCount = desc->getTagCount();
|
||||
std::vector<uint32_t> tags(tagCount);
|
||||
desc->getTagArray(tags.data());
|
||||
for (int i = 0; i < tagCount; i++) {
|
||||
HVendorTag vt;
|
||||
vt.tagId = tags[i];
|
||||
vt.tagName = desc->getTagName(tags[i]);
|
||||
vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]);
|
||||
ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
|
||||
tagsBySection[sectionIdx].push_back(vt);
|
||||
}
|
||||
hVendorTagSections.resize(numSections);
|
||||
for (size_t s = 0; s < numSections; s++) {
|
||||
hVendorTagSections[s].sectionName = (*sectionNames)[s].string();
|
||||
hVendorTagSections[s].tags = tagsBySection[s];
|
||||
}
|
||||
_hidl_cb(hStatus, hVendorTagSections);
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // implementation
|
||||
} // V2_0
|
||||
} // service
|
||||
} // cameraservice
|
||||
} // frameworks
|
||||
} // android
|
||||
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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_FRAMEWORKS_CAMERASERVICE_V2_0_CAMERASERVICE_H
|
||||
#define ANDROID_FRAMEWORKS_CAMERASERVICE_V2_0_CAMERASERVICE_H
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include <android/frameworks/cameraservice/common/2.0/types.h>
|
||||
#include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
|
||||
#include <android/frameworks/cameraservice/service/2.0/types.h>
|
||||
#include <android/frameworks/cameraservice/device/2.0/types.h>
|
||||
|
||||
#include <hidl/Status.h>
|
||||
|
||||
#include <CameraService.h>
|
||||
|
||||
namespace android {
|
||||
namespace frameworks {
|
||||
namespace cameraservice {
|
||||
namespace service {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using hardware::hidl_string;
|
||||
using hardware::ICameraServiceListener;
|
||||
using hardware::Return;
|
||||
|
||||
using HCameraDeviceCallback = frameworks::cameraservice::device::V2_0::ICameraDeviceCallback;
|
||||
using HCameraMetadata = frameworks::cameraservice::service::V2_0::CameraMetadata;
|
||||
using HCameraService = frameworks::cameraservice::service::V2_0::ICameraService;
|
||||
using HCameraServiceListener = frameworks::cameraservice::service::V2_0::ICameraServiceListener;
|
||||
using HStatus = frameworks::cameraservice::common::V2_0::Status;
|
||||
using HCameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
|
||||
|
||||
struct HidlCameraService final : public HCameraService {
|
||||
|
||||
~HidlCameraService() { };
|
||||
|
||||
// Methods from ::android::frameworks::cameraservice::service::V2.0::ICameraService follow.
|
||||
|
||||
Return<void> connectDevice(const sp<HCameraDeviceCallback>& callback,
|
||||
const hidl_string& cameraId, connectDevice_cb _hidl_cb) override;
|
||||
|
||||
Return<void> addListener(const sp<HCameraServiceListener>& listener,
|
||||
addListener_cb _hidl_cb) override;
|
||||
|
||||
Return<HStatus> removeListener(const sp<HCameraServiceListener>& listener) override;
|
||||
|
||||
Return<void> getCameraCharacteristics(const hidl_string& cameraId,
|
||||
getCameraCharacteristics_cb _hidl_cb) override;
|
||||
|
||||
Return<void> getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) override;
|
||||
|
||||
// This method should only be called by the cameraservers main thread to
|
||||
// instantiate the hidl cameraserver.
|
||||
static sp<HidlCameraService> getInstance(android::CameraService *cs);
|
||||
|
||||
private:
|
||||
HidlCameraService(android::CameraService *cs) : mAidlICameraService(cs) { };
|
||||
|
||||
sp<hardware::ICameraServiceListener> searchListenerCacheLocked(
|
||||
sp<HCameraServiceListener> listener, /*removeIfFound*/ bool shouldRemove = false);
|
||||
|
||||
void addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
|
||||
sp<hardware::ICameraServiceListener> csListener);
|
||||
|
||||
android::CameraService *const mAidlICameraService = nullptr;
|
||||
|
||||
Mutex mListenerListLock;
|
||||
|
||||
using HIListeners =
|
||||
std::pair<sp<HCameraServiceListener>, sp<ICameraServiceListener>>;
|
||||
std::list<HIListeners> mListeners;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace service
|
||||
} // namespace cameraservice
|
||||
} // namespace frameworks
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_FRAMEWORKS_CAMERASERVICE_V2_0_CAMERASERVICE_H
|
Loading…
Reference in new issue