Android MTK Camera启动流程
第一篇长文博客,看了很多大神的分析流程,编改编写,写的太乱,我都看不懂了,有时间需要整理!!
总体架构
Android Camera架构从整体上看是一个Client/Service架构,主要有两个进程
1.Client进程:主要是Java、native C/C++代码
2.Service进程:是native C/C++代码,主要负责与linux kernel中的camera driver交互
Client和Service进程通过Binder机制通信,Client通过调用Serivice实现具体功能
Camera Framework文件目录
API1 alps/frameworks/base/core/java/android/hardware/Camera.java
API2 alps/frameworks/base/core/java/android/hardware/camera2
JNI alps/frameworks/base/core/jni
CameraService服务注册
alps/frameworks/av/media/mediaserver/main_mediaserver.cpp
有的camera注册是在这个函数MediaPlayerService::instantiate();中实现的,本次分析是分离开如下
alps/frameworks/av/camera/cameraserver/main_cameraserver.cpp
main_cameraserver.cpp//由init.rc在启动时调用,设备开机Camera注册服务,用作binder通信
CameraService::instantiate();
alps/frameworks/av/services/camera/libcameraservice/CameraService.cpp CameraService.h
class CameraService :
public BinderService<CameraService>,//BinderService是个模板类
alps/frameworks/native/libs/binder/include/binder/BinderService.h
class BinderService
static void instantiate() { publish(); } //CameraService在ServiceManager完成服务注册,同
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp<IServiceManager> sm(defaultServiceManager());//完成服务注册
//sp是个模板类,sm是对象,defaultServiceManager()是构造函数传参
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);
}
Client应用层到JNI(Camera APP → JNI)
alps/packages/apps/LegacyCamera/src/com/android/camera/Camera.java
public void onCreate(Bundle icicle) {
...
mCameraOpenThread.start();//mCameraOpenThread定义
Thread mCameraOpenThread = new Thread(new Runnable() {
public void run() {
try {
mCameraDevice = Util.openCamera(Camera.this, mCameraId);
} catch (CameraHardwareException e) {
mOpenCameraFail = true;
} catch (CameraDisabledException e) {
mCameraDisabled = true;
}
}
});
alps/packages/apps/LegacyCamera/src/com/android/camera/Util.java
public static android.hardware.Camera openCamera(Activity activity, int cameraId)
throws CameraHardwareException, CameraDisabledException {
...
try {
return CameraHolder.instance().open(cameraId);
} catch (CameraHardwareException e) {
// In eng build, we throw the exception so that test tool
// can detect it and report it
if ("eng".equals(Build.TYPE)) {
throw new RuntimeException("openCamera failed", e);
} else {
throw e;
}
}
}
alps/packages/apps/LegacyCamera/src/com/android/camera/CameraHolder.java
public static synchronized CameraHolder instance() {
if (sHolder == null) {
sHolder = new CameraHolder();
}
return sHolder;
}
private android.hardware.Camera mCameraDevice;
public synchronized android.hardware.Camera open(int cameraId)
...
if (mCameraDevice == null) {
try {
Log.v(TAG, "open camera " + cameraId);
mCameraDevice = android.hardware.Camera.open(cameraId);
mCameraId = cameraId;
}
...
return mCameraDevice;
}
alps/frameworks/base/core/java/android/hardware/Camera.java
public static Camera open(int cameraId) {
...
return new Camera(cameraId);
}
//创建对象,调用Camera的构造函数
Camera(int cameraId) {
int err = cameraInitNormal(cameraId);
...
initAppOps();
}
private int cameraInitNormal(int cameraId) {
return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);
}
private int cameraInitVersion(int cameraId, int halVersion) {
mShutterCallback = null;
mRawImageCallback = null;
...
//一些结构体的初始化
return native_setup(new WeakReference<Camera>(this), cameraId, halVersion,
ActivityThread.currentOpPackageName());
}
这里通过JNI调用到native_setup(),系统上电把JNI的一个对象注册成类Camera的Listener
native_setup接口在libandroid_runtime.so中实现,由Framework层通过JNI调用,该接口主要
实现两个功能:
1.实现Camera C/S架构的客户端和服务端的连接(通过connect进入libcamera_Client.so)
2.set一个监听类,用于处理底层Camera回调函数传来的数据和消息
alps/frameworks/base/core/jni/android_hardware_Camera.cpp
static const JNINativeMethod camMethods[] = {
{ "native_setup",
"(Ljava/lang/Object;IILjava/lang/String;)I",
(void*)android_hardware_Camera_native_setup },
...
通过Methods将native_setup()和android_hardware_Camera_native_setup关联起来
// connect to camera service
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
{
sp<Camera> camera;
if (halVersion == CAMERA_HAL_API_VERSION_NORMAL_CONNECT) { //CAMERA_HAL_API_VERSION_NORMAL_CONNECT = -2
// Default path: hal version is don't care, do normal camera connect.
camera = Camera::connect(cameraId, clientName,
Camera::USE_CALLING_UID, Camera::USE_CALLING_PID);
} else {
jint status = Camera::connectLegacy(cameraId, halVersion, clientName,
Camera::USE_CALLING_UID, camera);
if (status != NO_ERROR) {
return status;
}
}
...
// We use a weak reference so the Camera object can be garbage collected.
// The reference is only used as a proxy for callbacks.
sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);
context->incStrong((void*)android_hardware_Camera_native_setup);
camera->setListener(context);
...
JNI函数中,我们找到Camera C/S架构的客户端,它调用connect向服务器发送连接请求。JNICameraContext是一个监听类,用于处理底层Camera回调函数传来的数据和消息。
Client到Service的连接
Client端
alps/frameworks/av/camera/CameraBase.h
alps/frameworks/av/camera/Camera.cpp
typedef CameraBase<TCam> CameraBaseT;
sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
int clientUid, int clientPid)
{
return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);
}
alps/frameworks/av/cameraCameraBase.cpp
template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
const String16& clientPackageName,
int clientUid, int clientPid)
{
ALOGV("%s: connect", __FUNCTION__);
sp<TCam> c = new TCam(cameraId);
sp<TCamCallbacks> cl = c;
const sp<::android::hardware::ICameraService> cs = getCameraService();
TCamConnectService fnConnectService = TCamTraits::fnConnectService;//connect函数
其中getCameraService获取了CameraService的实例,进入getCameraService中分析
alps/frameworks/av/camera/CameraBase.cpp
template <typename TCam, typename TCamTraits>
const sp<::android::hardware::ICameraService> CameraBase<TCam, TCamTraits>::getCameraService()
{
...
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
binder = sm->getService(String16(kCameraServiceName));
binder->linkToDeath(gDeathNotifier);
gCameraService = interface_cast<::android::hardware::ICameraService>(binder);
return gCameraService;
}
CameraService实例通过binder获取,gCameraService即为CameraService的实例
Service端
回到Connect函数中 TCamConnectService fnConnectService = TCamTraits::fnConnectService;
alps/frameworks/av/camera/Camera.cpp
CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
&::android::hardware::ICameraService::connect;
alps/frameworks/av/services/camera/libcameraservice/CameraService.cpp
CameraService::connect
Status CameraService::connect(
const sp<ICameraClient>& cameraClient,
int api1CameraId,
const String16& clientPackageName,
int clientUid,
int clientPid,
/*out*/
sp<ICamera>* device) {
ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid,clientPid, API_1,
/*shimUpdateOnly*/ false, /*out*/client);
...
}
//Status CameraService::connectLegacy(
// const sp<ICameraClient>& cameraClient,
// int api1CameraId, int halVersion,
// const String16& clientPackageName,
// int clientUid,
// /*out*/
// sp<ICamera>* device) {
//ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId, halVersion,
// clientPackageName, clientUid, USE_CALLING_PID, API_1, /*shimUpdateOnly*/ false,
// /*out*/client);
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
int clientPid, apiLevel effectiveApiLevel, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device) {
if(!(ret = makeClient(this, cameraCb, clientPackageName,
cameraId, api1CameraId, facing,
clientPid, clientUid, getpid(),
halVersion, deviceVersion, effectiveApiLevel,
/*out*/&tmp)).isOk()) {
return ret;
}
err = client->initialize(mCameraProviderManager, mMonitorTags);
...
}
//connectHelper中调用makeClient函数
Status CameraService::makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName, int cameraId,
int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
/*out*/sp<BasicClient>* client) {
if (halVersion < 0 || halVersion == deviceVersion) {
// Default path: HAL version is unspecified by caller, create CameraClient
// based on device version reported by the HAL.
switch(deviceVersion) {
case CAMERA_DEVICE_API_VERSION_1_0:
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new CameraClient(cameraService, tmp, packageName,
api1CameraId, facing, clientPid, clientUid,
getpid());
}
...
case CAMERA_DEVICE_API_VERSION_3_5:
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new Camera2Client(cameraService, tmp, packageName,
cameraId, api1CameraId,
facing, clientPid, clientUid,
servicePid);
} else { // Camera2 API route
sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
*client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
facing, clientPid, clientUid, servicePid);
}
...
这里区分了不同的API调用不同HAL的函数,具体作用可参考API与HAL的对应参考 后续会有API1和API2两个的流程
alps/frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,int cameraId, int cameraFacing,
int clientPid, uid_t clientUid, int servicePid) :
Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, cameraFacing, clientPid, clientUid, servicePid),
mInputStream(),
mStreamingRequestId(REQUEST_ID_NONE),
mRequestIdCounter(0) {
ATRACE_CALL();
ALOGI("CameraDeviceClient %d: Opened", cameraId);
}
然后调用Camera2ClientBase进行初始化
alps/frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp
template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase(
const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
const String16& clientPackageName,
int cameraId, int cameraFacing,
int clientPid, uid_t clientUid, int servicePid):
TClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, cameraFacing, clientPid, clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
mDeviceVersion(cameraService->getDeviceVersion(cameraId)),
mDeviceActive(false){
ALOGI("Camera %d: Opened. Client: %s (PID %d, UID %d)", cameraId,
String8(clientPackageName).string(), clientPid, clientUid);
mInitialClientPid = clientPid;
mDevice = new Camera3Device(cameraId);
LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
}
创建mDevice = new Camera3Device();
alps/frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
Camera3Device::Camera3Device(const String8 &id):
mId(id),
mOperatingMode(NO_MODE),
mIsConstrainedHighSpeedConfiguration(false),
mStatus(STATUS_UNINITIALIZED),
mStatusWaiters(0),
mUsePartialResult(false),
mNumPartialResults(1),
mTimestampOffset(0),
mNextResultFrameNumber(0),
mNextReprocessResultFrameNumber(0),
mNextZslStillResultFrameNumber(0),
mNextShutterFrameNumber(0),
mNextReprocessShutterFrameNumber(0),
mNextZslStillShutterFrameNumber(0),
mListener(NULL),
mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID),
mLastTemplateId(-1),
mNeedFixupMonochromeTags(false)
{
ATRACE_CALL();
ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
char value[PROPERTY_VALUE_MAX];
property_get("camera.mtkfwk.debug", value, "1");
MTK_DEBUG_ENABLED = atoi(value);
ALOGI("%s: MTK framework debug log enabled:%d", __FUNCTION__, MTK_DEBUG_ENABLED);
}
CameraDeviceClient创建对象后CameraService.cpp中调用client->initialize(mCameraProviderManager, mMonitorTags)进行初始化
alps/frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
const String8& monitorTags) {
return initializeImpl(manager, monitorTags);
}
template<typename TProviderPtr>
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
ATRACE_CALL();
status_t res;
res = Camera2ClientBase::initialize(providerPtr, monitorTags);
if (res != OK) {
return res;
}
...
mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
FRAME_PROCESSOR_LISTENER_MAX_ID,
/*listener*/this, /*sendPartials*/true);
auto deviceInfo = mDevice->info();
...
mProviderManager = providerPtr;
return OK;
}
alps/frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp
template <typename TClientBase>
template <typename TProviderPtr>
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
const String8& monitorTags) {
ATRACE_CALL();
ALOGV("%s: Initializing client for camera %s", __FUNCTION__,
TClientBase::mCameraIdStr.string());
status_t res;
// Verify ops permissions
res = TClientBase::startCameraOps();
if (res != OK) {
return res;
}
...
res = mDevice->initialize(providerPtr, monitorTags);//调用具体设备初始化
...
res = mDevice->setNotifyCallback(weakThis);
return OK;
}
alps/frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
if (mStatus != STATUS_UNINITIALIZED) {
CLOGE("Already initialized!");
return INVALID_OPERATION;
}
if (manager == nullptr) return INVALID_OPERATION;
sp<ICameraDeviceSession> session;
ATRACE_BEGIN("CameraHal::openSession");
status_t res = manager->openSession(mId.string(), this,
/*out*/ &session);//通过session获取Device
ATRACE_END();
if (res != OK) {
SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
return res;
}
res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo);
if (res != OK) {
SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
session->close();
return res;
}
std::vector<std::string> physicalCameraIds;
bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
if (isLogical) {
for (auto& physicalId : physicalCameraIds) {
res = manager->getCameraCharacteristics(
physicalId, &mPhysicalDeviceInfoMap[physicalId]);
if (res != OK) {
SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)",
physicalId.c_str(), strerror(-res), res);
session->close();
return res;
}
...
}
}
std::shared_ptr<RequestMetadataQueue> queue;
auto requestQueueRet = session->getCaptureRequestMetadataQueue(//元数据捕获请求队列
[&queue](const auto& descriptor) {
queue = std::make_shared<RequestMetadataQueue>(descriptor);
if (!queue->isValid() || queue->availableToWrite() <= 0) {
ALOGE("HAL returns empty request metadata fmq, not use it");
queue = nullptr;
// don't use the queue onwards.
}
});
if (!requestQueueRet.isOk()) {
ALOGE("Transaction error when getting request metadata fmq: %s, not use it",
requestQueueRet.description().c_str());
return DEAD_OBJECT;
}
std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
auto resultQueueRet = session->getCaptureResultMetadataQueue(//元数据捕获结果队列
[&resQueue](const auto& descriptor) {
resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
ALOGE("HAL returns empty result metadata fmq, not use it");
resQueue = nullptr;
// Don't use the resQueue onwards.
}
});
if (!resultQueueRet.isOk()) {
ALOGE("Transaction error when getting result metadata queue from camera session: %s",
resultQueueRet.description().c_str());
return DEAD_OBJECT;
}
...
mInterface = new HalInterface(session, queue, mUseHalBufManager);//新建硬件抽象层接口实例
std::string providerType;
mVendorTagId = manager->getProviderTagIdLocked(mId.string());
mTagMonitor.initialize(mVendorTagId);
if (!monitorTags.isEmpty()) {
mTagMonitor.parseTagsToMonitor(String8(monitorTags));
}
// Metadata tags needs fixup for monochrome camera device version less
// than 3.5.
hardware::hidl_version maxVersion{0,0};
res = manager->getHighestSupportedVersion(mId.string(), &maxVersion);
if (res != OK) {
ALOGE("%s: Error in getting camera device version id: %s (%d)",
__FUNCTION__, strerror(-res), res);
return res;
}
int deviceVersion = HARDWARE_DEVICE_API_VERSION(
maxVersion.get_major(), maxVersion.get_minor());
...
return initializeCommonLocked();
}
//------------------------------------------------------------分割线--------------------------------------------------------------------
//以上是API2的流程 以下是AP1的流程
//------------------------------------------------------------分割线--------------------------------------------------------------------
alps/frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp
CameraClient::CameraClient(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
const String16& clientPackageName,
int cameraId, int cameraFacing,
int clientPid, int clientUid, int servicePid):
Client(cameraService, cameraClient, clientPackageName,
String8::format("%d", cameraId), cameraId, cameraFacing, clientPid,
clientUid, servicePid){
int callingPid = CameraThreadState::getCallingPid();
LOG1("CameraClient::CameraClient E (pid %d, id %d)", callingPid, cameraId);
mHardware = NULL;
mMsgEnabled = 0;
mSurface = 0;
mPreviewWindow = 0;
mDestructionStarted = false;
// Callback is disabled by default
mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
mPlayShutterSound = true;
LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId);
}
mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
mClientPid = callingPid;
mRemoteCallback = client;
LOG1("connect X (pid %d)", callingPid);
return NO_ERROR;
}
status_t CameraClient::initialize(sp<CameraProviderManager> manager,
const String8& /*monitorTags*/) {
int callingPid = CameraThreadState::getCallingPid();
status_t res;
LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId);
// Verify ops permissions
res = startCameraOps();
char camera_device_name[10];
snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);
mHardware = new CameraHardwareInterface(camera_device_name);
res = mHardware->initialize(manager);
if (res != OK) {
ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
mHardware.clear();
return res;
}
mHardware->setCallbacks(notifyCallback, dataCallback,
dataCallbackTimestamp, handleCallbackTimestampBatch,
(void *)(uintptr_t)mCameraId);
LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId);
return OK;
}
调用CameraHardwareInterface.cpp进行初始化进入HAL层
alps/frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
status_t CameraHardwareInterface::initialize(sp<CameraProviderManager> manager) {
ALOGI("Opening camera %s", mName.string());
status_t ret = manager->openSession(mName.string(), this, &mHidlDevice);
if (ret != OK) {
ALOGE("%s: openSession failed! %s (%d)", __FUNCTION__, strerror(-ret), ret);
}
return ret;
}
HAL层
由上述分析发现API1和API2最终都会调用CameraProviderMannager中的openSession去操作HAL
/alps/frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
status_t CameraProviderManager::openSession(const std::string &id,
const sp<device::V1_0::ICameraDeviceCallback>& callback,
/*out*/ sp<device::V1_0::ICameraDevice> *session) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id,
/*minVersion*/ {1,0}, /*maxVersion*/ {2,0});
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo);
const sp<provider::V2_4::ICameraProvider> provider =
deviceInfo->mParentProvider->startProviderInterface();
if (provider == nullptr) {
return DEAD_OBJECT;
}
saveRef(DeviceMode::CAMERA, id, provider);
auto interface = deviceInfo1->startDeviceInterface<
CameraProviderManager::ProviderInfo::DeviceInfo1::InterfaceT>();
if (interface == nullptr) {
return DEAD_OBJECT;
}
hardware::Return<Status> status = interface->open(callback);
if (!status.isOk()) {
removeRef(DeviceMode::CAMERA, id);
ALOGE("%s: Transaction error opening a session for camera device %s: %s",
__FUNCTION__, id.c_str(), status.description().c_str());
return DEAD_OBJECT;
}
if (status == Status::OK) {
*session = interface;
}
return mapToStatusT(status);
}
status_t CameraProviderManager::openSession(const std::string &id,
const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
/*out*/
sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
//通过传入最小最大版本号调用获取DeviceInfo对象,内部对成员变量mProviders进行遍历
//mProviders对象是在CameraService启动,初始化CameraProviderManager对象中,通过
//addProviderLocked的方法生成具体的DeviceInfo对象,添加到mProviders
auto deviceInfo = findDeviceInfoLocked(id,
/*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
Status status;
hardware::Return<void> ret;
ret = deviceInfo3->mInterface->open(callback, [&status, &session]
(Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
status = s;
if (status == Status::OK) {
*session = cameraSession;
}
});
if (!ret.isOk()) {
ALOGE("%s: Transaction error opening a session for camera device %s: %s",
__FUNCTION__, id.c_str(), ret.description().c_str());
return DEAD_OBJECT;
}
return mapToStatusT(status);
}
回到openSession方法当中,找到deviceInfo对象之后,然后调用deviceInfo3->mInterface->open,而它的成员变量mInterface就是在前面我们说构造ProviderInfo时获取到的binder对象了,它实际上是hardware\interfaces\camera\device\3.2\default\CameraDevice.cpp对象了,来到这里,我们就进入了CameraDaemon进程当中,两个进程的通信是通过HIDL,其实还是binder进程间通信机制,只是它是用来提供给HAL层服务的,所以和AIDL类似,取了个HIDL的名字。3.2是因为我们在调用openSession方法时,传入的第二个参数和第三个参数就可以非常明显的看出来,当前调用的版本是V3_2。接下来,我们就来看一下CameraDevice.cpp类的open方法的实现,源码如下:
alps/hardware/interfaces/camera/device/1.0/default/CameraDevice.cpp
Return<Status> CameraDevice::open(const sp<ICameraDeviceCallback>& callback) {
ALOGI("Opening camera %s", mCameraId.c_str());
Mutex::Autolock _l(mLock);
camera_info info;
status_t res = mModule->getCameraInfo(mCameraIdInt, &info);
if (res != OK) {
ALOGE("Could not get camera info: %s: %d", mCameraId.c_str(), res);
return getHidlStatus(res);
}
int rc = OK;
if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
// Open higher version camera device as HAL1.0 device.
rc = mModule->openLegacy(mCameraId.c_str(),
CAMERA_DEVICE_API_VERSION_1_0,
(hw_device_t **)&mDevice);
} else {
rc = mModule->open(mCameraId.c_str(), (hw_device_t **)&mDevice);
}
if (rc != OK) {
mDevice = nullptr;
ALOGE("Could not open camera %s: %d", mCameraId.c_str(), rc);
return getHidlStatus(rc);
}
initHalPreviewWindow(); //初始化预览窗口
mDeviceCallback = callback;
if (mDevice->ops->set_callbacks) {
mDevice->ops->set_callbacks(mDevice,
sNotifyCb, sDataCb, sDataCbTimestamp, sGetMemory, this);
}
return getHidlStatus(rc);
}
alps/hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp
Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback,
ICameraDevice::open_cb _hidl_cb) {
Status status = initStatus();
sp<CameraDeviceSession> session = nullptr;
if (callback == nullptr) {
ALOGE("%s: cannot open camera %s. callback is null!",
__FUNCTION__, mCameraId.c_str());
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}
if (status != Status::OK) {
// Provider will never pass initFailed device to client, so
// this must be a disconnected camera
ALOGE("%s: cannot open camera %s. camera is disconnected!",
__FUNCTION__, mCameraId.c_str());
_hidl_cb(Status::CAMERA_DISCONNECTED, nullptr);
return Void();
} else {
mLock.lock();
ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);
session = mSession.promote();
if (session != nullptr && !session->isClosed()) {
ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
mLock.unlock();
_hidl_cb(Status::CAMERA_IN_USE, nullptr);
return Void();
}
/** Open HAL device */
status_t res;
camera3_device_t *device;
ATRACE_BEGIN("camera3->open");
res = mModule->open(mCameraId.c_str(),
reinterpret_cast<hw_device_t**>(&device));
ATRACE_END();
if (res != OK) {
ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraId.c_str());
mLock.unlock();
_hidl_cb(getHidlStatus(res), nullptr);
return Void();
}
/** Cross-check device version */
if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
ALOGE("%s: Could not open camera: "
"Camera device should be at least %x, reports %x instead",
__FUNCTION__, CAMERA_DEVICE_API_VERSION_3_2,
device->common.version);
device->common.close(&device->common);
mLock.unlock();
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}
struct camera_info info;
res = mModule->getCameraInfo(mCameraIdInt, &info);
if (res != OK) {
ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
device->common.close(&device->common);
mLock.unlock();
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}
session = createSession(device, info.static_camera_characteristics, callback);
if (session == nullptr) {
ALOGE("%s: camera device session allocation failed", __FUNCTION__);
mLock.unlock();
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
}
if (session->isInitFailed()) {
ALOGE("%s: camera device session init failed", __FUNCTION__);
session = nullptr;
mLock.unlock();
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
}
mSession = session;
...
mLock.unlock();
}
_hidl_cb(status, session->getInterface());
return Void();
}
alps/hardware/interfaces/camera/common/1.0/default/CameraModule.cpp
int CameraModule::open(const char* id, struct hw_device_t** device) {
int res;
ATRACE_BEGIN("camera_module->open");
res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
ATRACE_END();
return res;
}
CameraModule::CameraModule(camera_module_t *module) : mNumberOfCameras(0) {
if (module == NULL) {
ALOGE("%s: camera hardware module must not be null", __FUNCTION__);
assert(0);
}
mModule = module;
}
//int CameraModule::openLegacy(
// const char* id, uint32_t halVersion, struct hw_device_t** device) {
// int res;
// ATRACE_BEGIN("camera_module->open_legacy");
// res = mModule->open_legacy(&mModule->common, id, halVersion, device);//这里就是设计到具体厂商代码所生成的so
// ATRACE_END();
// return res;
//}
module是在CameraModule在 alps/hardware/interfaces/camera/provider/2.4/default/构造的时候赋值的
alps/proprietary/hardware/mtkcam3/main/hal/devicemgr/depend/entry.cpp
static hw_module_methods_t* get_module_methods(){
static hw_module_methods_t _methods =
{
.open = open_device
};
return &_methods;
}
static int open_device(hw_module_t const* module, const char* name, hw_device_t** device){
return getCameraDeviceManager()->open(device, module, name);
}
/******************************************************************************
* Implementation of camera_module
******************************************************************************/
camera_module_t HAL_MODULE_INFO_SYM __attribute__ ((visibility("default"))) = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = CAMERA_MODULE_API_VERSION_2_5,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = CAMERA_HARDWARE_MODULE_ID,
.name = "MediaTek Camera Module",
.author = "MediaTek",
.methods = get_module_methods(),
.dso = NULL,
.reserved = {0},
},
.get_number_of_cameras = get_number_of_cameras,
.get_camera_info = get_camera_info,
.set_callbacks = set_callbacks,
.get_vendor_tag_ops = get_vendor_tag_ops,
.open_legacy = NULL,
.set_torch_mode = set_torch_mode,
.init = init,
.get_physical_camera_info = get_physical_camera_info,
.is_stream_combination_supported = is_stream_combination_supported,
.notify_device_state_change = notify_device_state_change,
.reserved = {0},
};
static int open_legacy(const struct hw_module_t* module, const char* id,
uint32_t halVersion, struct hw_device_t** device){
MY_LOGD("+");
return getCameraDeviceManager()->open(device, module, id, halVersion);
}
HAL—>Driver层
alps/vendor/mediatek/proprietary/hardware/mtkcam/main/hal/service/service.cpp
Camerahaleservice服务main函数,通过registerPassthroughServiceImplementation来注册CameraProvider,之后通过getservice来获取CameraProvider实例对象
Android HIDL之CameraProvider
int main()
{
ALOGI("Camera HAL Server is starting..., ADV_CAM_SUPPORT(%d)", MTKCAM_ADV_CAM_SUPPORT);
signal(SIGPIPE, SIG_IGN);
// The camera HAL may communicate to other vendor components via
// /dev/vndbinder
android::ProcessState::initWithDriver("/dev/vndbinder");
configureRpcThreadpool(16, true /*callerWillJoin*/);
// AOSP ICameraProvider HAL Interface
{
using android::hardware::camera::provider::V2_4::ICameraProvider;
registerPassthroughServiceImplementation<ICameraProvider>("internal/0" /*"internal" for binderized mode*/);
}
// MTK IAdvCamControl HAL Interface
...
joinRpcThreadpool();
return 0;
}
alps/vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/service/service.cpp
int main()
{
NSCam::Utils::ULog::ULogInitializer __ulogInitializer;
ALOGI("Camera HAL Server is starting..., ADV_CAM_SUPPORT(%d)", MTKCAM_ADV_CAM_SUPPORT);
signal(SIGPIPE, SIG_IGN);
// The camera HAL may communicate to other vendor components via
// /dev/vndbinder
android::ProcessState::initWithDriver("/dev/vndbinder");
configureRpcThreadpool(16, true /*callerWillJoin*/);
// AOSP ICameraProvider HAL Interface
{
using android::hardware::camera::provider::V2_4::ICameraProvider;
auto err = registerPassthroughServiceImplementation<ICameraProvider>("internal/0" /*"internal" for binderized mode*/);
MY_LOGW_IF( err!=OK, "%s: register ICameraProvider err:%d(%s)", __FUNCTION__, err, ::strerror(-err));
}
//
// MTK IAdvCamControl HAL Interface
...
//pre-link the graphic HAL implementation
auto helper = NSCam::IGrallocHelper::singleton();
joinRpcThreadpool();
return 0;
}
注册cameraprovider的注册模式默认是是用转移到Passthrough直通的方式
alps/system/libhidl/transport/include/hidl/LegacySupport.h
//通过getService获取CameraProvider实例对象
namespace android {
namespace hardware {
namespace details {
template <class Interface, typename Func>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
Func registerServiceCb, const std::string& name = "default") {
sp<Interface> service = Interface::getService(name, true /* getStub */);
...
status_t status = registerServiceCb(service, name); //getService获取返回后调用registerServiceCb
return status;
}
}
template <class Interface>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
const std::string& name = "default") {
return details::registerPassthroughServiceImplementation<Interface>(
[](const sp<Interface>& service, const std::string& name) {
return service->registerAsService(name); //将CameraProvider注册为一个服务,其他进程需要使用Camera 的hal层时,
}, //需通过binder得到CameraProvider代理类即可操作camera hal层,不需要每次都dlopen(HAL.so)
name);
}
alps/out/soong/.intermediates/hardware/interfaces/camera/provider/2.4/android.hardware.camera.provider@2.4_genc++/gen/android/hardware/camera/provider/2.4/CameraProviderAll.cpp
通过HIDL自动生成CameraProviderAll.cpp
::android::sp<ICameraProvider> ICameraProvider::getService(const std::string &serviceName, const bool getStub) {
return ::android::hardware::details::getServiceInternal<BpHwCameraProvider>(serviceName, true, getStub);
}
alps/system/libhidl/transport/include/hidl/HidlTransportSupport.h
namespace android{
namespace hardware{
...
namespace details {
...
template <typename BpType, typename IType = typename BpType::Pure,
typename = std::enable_if_t<std::is_same<i_tag, typename IType::_hidl_tag>::value>,
typename = std::enable_if_t<std::is_same<bphw_tag, typename BpType::_hidl_tag>::value>>
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
using ::android::hidl::base::V1_0::IBase;
sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);
if (base == nullptr) {
return nullptr;
}
...
alps/system/libhidl/transport/ServiceManagerment.cpp
namespace android{
namespace hardware{
...
struct PassthroughServiceManager : IServiceManager1_1 {
sp<IServiceManager1_0> getPassthroughServiceManager() {
return getPassthroughServiceManager1_1();
}
sp<IServiceManager1_1> getPassthroughServiceManager1_1() {//是IserviceManager1_1的子类,重写了get等方法
static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
return manager;
}
namespace details {
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
const std::string& instance,
bool retry, bool getStub) {
using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
using ::android::hidl::manager::V1_0::IServiceManager;
sp<Waiter> waiter;
sp<IServiceManager1_1> sm;
Transport transport = Transport::EMPTY;
if (kIsRecovery) {
transport = Transport::PASSTHROUGH;
} else {
sm = defaultServiceManager1_1();//获取hwservicemanager服务,用于获取service 的client端
if (sm == nullptr) {
ALOGE("getService: defaultServiceManager() is null");
return nullptr;
}
Return<Transport> transportRet = sm->getTransport(descriptor, instance);
if (!transportRet.isOk()) {
ALOGE("getService: defaultServiceManager()->getTransport returns %s",
transportRet.description().c_str());
return nullptr;
}
transport = transportRet;
}
...
if (getStub || vintfPassthru || vintfLegacy) { //getStub = true 是走此流程的,用于服务启动
const sp<IServiceManager> pm = getPassthroughServiceManager();
if (pm != nullptr) {
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);//获取ICameraProvider实例
if (!getStub || trebleTestingOverride) {
base = wrapPassthrough(base);
}
return base;
}
}
return nullptr;
}
// sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
Return<sp<IBase>> get(const hidl_string& fqName,
const hidl_string& name) override {
sp<IBase> ret = nullptr;
// open lib
openLibs(fqName, /*匿名函数作为形参*/[&](void* handle, const std::string &lib, const std::string &sym) {
// 这是一个匿名函数
// openLibs 中调用 eachLib 即调用此函数
IBase* (*generator)(const char* name);
*(void **)(&generator) = dlsym(handle, sym.c_str());
if(!generator) {
const char* error = dlerror();
LOG(ERROR) << "Passthrough lookup opened " << lib
<< " but could not find symbol " << sym << ": "
<< (error == nullptr ? "unknown error" : error);
dlclose(handle);
return true;
}
// 调用 HIDL_FETCH_ICameraProvider
// 返回CameraProvider实例
ret = (*generator)(name.c_str());
if (ret == nullptr) {
dlclose(handle);
return true; // this module doesn't provide this instance name
}
// Actual fqname might be a subclass.
// This assumption is tested in vts_treble_vintf_test
using ::android::hardware::details::getDescriptor;
std::string actualFqName = getDescriptor(ret.get());
CHECK(actualFqName.size() > 0);
registerReference(actualFqName, name);
return false;
});
// 返回CameraProvider实例
return ret;
}
static void openLibs(
const std::string& fqName,
const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */,
const std::string& /* sym */)>& eachLib) {
//fqName looks like android.hardware.foo@1.0::IFoo
// 之前有提到过
// IType::descriptor = android.hardware.camera.provider@2.4::ICameraProvider
size_t idx = fqName.find("::"); // 获取 :: 位置
if (idx == std::string::npos ||
idx + strlen("::") + 1 >= fqName.size()) {
LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
return;
}
// packageAndVersion = android.hardware.camera.provider@2.4
std::string packageAndVersion = fqName.substr(0, idx);
// ICameraProvider
std::string ifaceName = fqName.substr(idx + strlen("::"));
// 得到库名 android.hardware.camera.provider@2.4-impl
const std::string prefix = packageAndVersion + "-impl";
// 函数名HIDL_FETCH_ICameraProvider
const std::string sym = "HIDL_FETCH_" + ifaceName;
constexpr int dlMode = RTLD_LAZY;
void* handle = nullptr;
dlerror(); // clear
static std::string halLibPathVndkSp = android::base::StringPrintf(
HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION, details::getVndkVersionStr().c_str());
std::vector<std::string> paths = {HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR,
halLibPathVndkSp, HAL_LIBRARY_PATH_SYSTEM};
#ifdef LIBHIDL_TARGET_DEBUGGABLE
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
if (trebleTestingOverride) {
// Load HAL implementations that are statically linked
handle = dlopen(nullptr, dlMode);
if (handle == nullptr) {
const char* error = dlerror();
LOG(ERROR) << "Failed to dlopen self: "
<< (error == nullptr ? "unknown error" : error);
} else if (!eachLib(handle, "SELF", sym)) {
return;
}
const char* vtsRootPath = std::getenv("VTS_ROOT_PATH");
if (vtsRootPath && strlen(vtsRootPath) > 0) {
const std::string halLibraryPathVtsOverride =
std::string(vtsRootPath) + HAL_LIBRARY_PATH_SYSTEM;
paths.insert(paths.begin(), halLibraryPathVtsOverride);
}
}
#endif
for (const std::string& path : paths) {
std::vector<std::string> libs = search(path, prefix, ".so");
for (const std::string &lib : libs) {
const std::string fullPath = path + lib;
// dlopen lib
if (path == HAL_LIBRARY_PATH_SYSTEM) {
handle = dlopen(fullPath.c_str(), dlMode);
} else {
handle = android_load_sphal_library(fullPath.c_str(), dlMode);
}
if (handle == nullptr) {
const char* error = dlerror();
LOG(ERROR) << "Failed to dlopen " << lib << ": "
<< (error == nullptr ? "unknown error" : error);
continue;
}
// 调用匿名函数
if (!eachLib(handle, lib, sym)) {
return;
}
}
}
}
alps/vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/depend/instance.cpp
调用getCameraDeviceManager并对其进行初始化
ICameraProvider*
HIDL_FETCH_ICameraProvider(const char* name){
return createICameraProvider_V2_4(name, getCameraDeviceManager());
}
ICameraProvider*
createICameraProvider_V2_4(const char* providerName, NSCam::ICameraDeviceManager* manager){
auto provider = new CameraProviderImpl(providerName, manager);
provider->initialize();
return provider;
}
extern "C"
NSCam::ICameraDeviceManager* getCameraDeviceManager(){
static NSCam::CameraDeviceManagerImpl singleton(getProviderType().c_str());
static bool init = singleton.initialize();
if ( ! init ) {
MY_LOGE("CameraDeviceManagerImpl::initialize fail %p", &singleton);
return nullptr;
}
return &singleton;
}
alps/vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/CameraDeviceManagerBase.cpp
auto
CameraDeviceManagerBase::initialize() -> bool{
CAM_TRACE_NAME(LOG_TAG ":initialize");
// global vendor tags should be setup before enumerating devices...
auto pVendorTagDesc = NSCam::getVendorTagDescriptor();
if ( ! pVendorTagDesc ) {
MY_LOGE("bad pVendorTagDesc");
return false;
}
#if MTKCAM_LEGACY_HAL_API
::memset(&mVendorTagOps, 0, sizeof(mVendorTagOps));
pVendorTagDesc->getVendorTagOps(&mVendorTagOps);
#endif
// loading libraries in charge of creating devices.
auto loadDeviceFactory = [](char const* libname, char const* symbol) {
VirtEnumDeviceFactory item;
item.mLibHandle = ::dlopen(libname, RTLD_NOW);
if (item.mLibHandle == nullptr) {
char const *err_str = ::dlerror();
CAM_ULOGME("[loadDeviceFactory] dlopen: %s error=%s", libname, (err_str ? err_str : "unknown"));
return item;
}
*(void **)(&item.mCreateVirtualCameraDevice) = ::dlsym(item.mLibHandle, symbol);
if ( item.mCreateVirtualCameraDevice == nullptr ) {
char const *err_str = ::dlerror();
CAM_ULOGME("[loadDeviceFactory] dlsym: %s error=%s", symbol, (err_str ? err_str : "unknown"));
::dlclose(item.mLibHandle);
item.mLibHandle = nullptr;
return item;
}
return item;
};
#if MTKCAM_LEGACY_HAL_API
mVirtEnumDeviceFactoryMap[3] = loadDeviceFactory("libmtkcam_device3_legacy.so", "createVirtualCameraDevice");
#else
mVirtEnumDeviceFactoryMap[3] = loadDeviceFactory("libmtkcam_device3.so", "createVirtualCameraDevice");
#endif
// enumerating devices...
status_t status = OK;
MY_LOGI("+");
RWLock::AutoWLock _l(mDataRWLock);
{
status = enumerateDevicesLocked();//这个就是关键了
}
MY_LOGI("-");
return (OK==status);
}
alps/vendor/mediatek/proprietary/hardware/mtkcam/main/hal/devicemgr/depend/CameraDeviceManagerImpl.cpp
/******************************************************************************
*
* Invoked by CamDeviceManagerBase::enumerateDevicesLocked()
*
******************************************************************************/
auto
CameraDeviceManagerImpl::
onEnumerateDevicesLocked() -> ::android::status_t
{
NSMetadataProviderManager::clear();
mPhysEnumDeviceMap.clear();
//--------------------------------------------------------------------------
#if '1'==MTKCAM_HAVE_SENSOR_HAL
//IHalSensorList*const pHalSensorList = MAKE_HalSensorList();
//size_t const sensorNum = pHalSensorList->searchSensors();
///
IHalLogicalDeviceList* pHalDeviceList;
pHalDeviceList = MAKE_HalLogicalDeviceList();//IHalLogicalDeviceList::get();
size_t const deviceNum = pHalDeviceList->searchDevices();
///查找匹配的Device
CAM_LOGI("pHalDeviceList:%p logicDeviceCount:%zu physicSensorCount:%d",
pHalDeviceList,
deviceNum,
pHalDeviceList->queryNumberOfSensors());
mVirtEnumDeviceMap.setCapacity(deviceNum*2);
for (size_t instanceId = 0; instanceId < deviceNum; instanceId++)
{
//
sp<IMetadataProvider> pMetadataProvider;
pMetadataProvider = IMetadataProvider::create(instanceId);
NSMetadataProviderManager::add(instanceId, pMetadataProvider.get());
MY_LOGD("[0x%02zx] IMetadataProvider:%p sensor:%s", instanceId, pMetadataProvider.get(), pHalDeviceList->queryDriverName(instanceId));
addVirtualDevicesLocked(instanceId, pMetadataProvider);
}
size_t const sensorNum = pHalDeviceList->queryNumberOfSensors();
IHalSensorList*const pHalSensorList = MAKE_HalSensorList();
mPhysEnumDeviceMap.setCapacity(sensorNum);
for (size_t sensorId = 0; sensorId < sensorNum; sensorId++)
{
sp<PhysEnumDevice> pPhysDevice = new PhysEnumDevice;
sp<IMetadataProvider> pMetadataProvider = NSMetadataProviderManager::valueFor(sensorId);//IMetadataProvider这又是啥
pPhysDevice->mMetadataProvider = pMetadataProvider;
pPhysDevice->mSensorName = pHalSensorList->queryDriverName(sensorId);
pPhysDevice->mInstanceId = sensorId;
pPhysDevice->mFacing = pMetadataProvider->getDeviceFacing();
pPhysDevice->mWantedOrientation = pMetadataProvider->getDeviceWantedOrientation();
pPhysDevice->mSetupOrientation = pMetadataProvider->getDeviceSetupOrientation();
pPhysDevice->mHasFlashUnit = pMetadataProvider->getDeviceHasFlashLight();
mPhysEnumDeviceMap.add(sensorId, pPhysDevice);
}
#endif //#if '1'==MTKCAM_HAVE_SENSOR_HAL
//--------------------------------------------------------------------------
//
return OK;
}
alps/vendor/mediatek/proprietary/hardware/mtkcam/utils/LogicalCam/HalLogicalDeviceList.cpp
MINT32
HalLogicalDeviceList::
createDeviceMap()
{
SensorInfo_t vTempInfo;
unsigned int i = 0;
// firstly, we create a logical camera device per physical camera
IHalSensorList* const pHalSensorList = MAKE_HalSensorList();//创建sensor对象
if(CC_UNLIKELY(!pHalSensorList))
{
MY_LOGA("create pHalSensorList fail");
}
size_t const sensorNum = pHalSensorList->searchSensors();//此函数入口,主要查找匹配的硬件sensor
MY_LOGD("sensorNum : %zu", sensorNum);
for(i = 0; i < sensorNum; i++)
{
SensorStaticInfo sensorStaticInfo;
memset(&sensorStaticInfo, 0, sizeof(SensorStaticInfo));
int sendorDevIndex = pHalSensorList->querySensorDevIdx(i);
pHalSensorList->querySensorStaticInfo(sendorDevIndex, &sensorStaticInfo);
TempSensorInfo TempInfo;
TempInfo.SensorId = i;
TempInfo.RawType = sensorStaticInfo.rawFmtType;
TempInfo.Facing = sensorStaticInfo.facingDirection;
TempInfo.CaptureModeWidth = sensorStaticInfo.captureWidth;
strncpy(TempInfo.Name, pHalSensorList->queryDriverName(i), MAX_SENSOR_NAME_SIZE - 1);
uint32_t remappingSensorId;
bool isHidden;
if(getVidByDrvName(TempInfo.Name, remappingSensorId))
{
TempInfo.RemappingSensorId = (MINT32)remappingSensorId;
}
else
{
TempInfo.RemappingSensorId = i;
}
TempInfo.isHidden = getHiddenByDrvName(TempInfo.Name);
vTempInfo.add(TempInfo.Name, TempInfo);
MY_LOGD("%d : facing(%d), Name(%s), remapping(%d), isHidden(%d)"
, i, TempInfo.Facing, TempInfo.Name
, TempInfo.RemappingSensorId, TempInfo.isHidden);
sp<CamDeviceInfo> Info = new CamDeviceInfo();
Info->Sensors.push_back(i);
Info->RemappingSensorId.push_back(TempInfo.RemappingSensorId);
Info->DualFeature = 0;
Info->RawType = TempInfo.RawType;
strncpy(Info->Name, TempInfo.Name, sizeof(Info->Name));
// add physical sensor static metadata
Info->sensorStaticMetadata = MAKE_HalSensorList()->queryStaticInfo(Info->Sensors[0]);
MY_LOGD("i : %d, remapping: %d, Info Name : %s, %p", i, Info->RemappingSensorId[0], Info->Name, Info->Name);
mDeviceSensorMap.add(i, Info);
}
// then we also create logical camera device(s) from the custom file:
// camera_custom_stereo_setting.h if available
{
std::vector<struct LogicalSensorStruct> CustomDevList =
LogicalCamJSONUtil::getLogicalDevices();
MY_LOGD("manual device count = %zu", CustomDevList.size());
for (auto&& logicalDevice : CustomDevList)
{
for (int j = 0; j < logicalDevice.NumofDefinition; j++)
{
addLogicalDevice(vTempInfo, &logicalDevice, j);
}
}
}
dumpDebugInfo();
return 0;
}
函数pHalSensorList->searchSensors()将调用HalSensorList::enumeraterSensor_Locked()函数,该函数再调用
ImgSensor_drv.cpp文件中的pSensorDrv->searchSensor函数
alps/vendor/meditek/proprietary/hardware/mtkcam/include/mtkcam/utils/LogicalCam/IHalLogicalDeviceList.h
#define MAKE_HalLogicalDeviceList(...) \
MAKE_MTKCAM_MODULE(MTKCAM_MODULE_ID_UTILS_LOGICALDEV, HalLogicalDeviceList_FACTORY_T, __VA_ARGS__)
alps/vendor/meditek/proprietary/hardware/mtkcam3/main/hal/devicemgr/depend/CameraDeviceManagerImpl.cpp
auto
CameraDeviceManagerImpl::
onEnumerateDevicesLocked() -> ::android::status_t
{
#if '1'==MTKCAM_HAVE_SENSOR_HAL
IHalSensorList*const pHalSensorList = MAKE_HalSensorList();
size_t const sensorNum = pHalSensorList->searchSensors();
//IHalLogicalDeviceList* pHalDeviceList = MAKE_HalLogicalDeviceList();
alps/vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/imgsensor_drv.cpp
MINT32
ImgSensorDrv::searchSensor(IMGSENSOR_SENSOR_IDX sensorIdx)
{
MSDK_SENSOR_INIT_FUNCTION_STRUCT *pSensorInitFunc;
//! If imp sensor search process already done before,
//! only need to return the sensorDevs, not need to
//! search again.
if (m_sensorIdx[sensorIdx] != BAD_SENSOR_INDEX) {
//been processed.
LOG_MSG("[searchSensor] Already processed");
return SENSOR_ALREADY_SEARCH;
}
GetSensorInitFuncList(&pSensorInitFunc);
LOG_MSG("SENSOR search start");
//set sensor driver
MUINT32 featureParaLen = sizeof(MUINT32);
MINT32 idx = 0;
featureControl(sensorIdx, SENSOR_FEATURE_SET_DRIVER, (MUINT8 *)&idx, &featureParaLen);
LOG_MSG("set sensor driver id =%x", idx);
if((m_sensorIdx[sensorIdx] = (idx < 0) ? UNKNOWN_SENSOR_INDEX : idx) >= UNKNOWN_SENSOR_INDEX)
return SENSOR_INVALID_DRIVER;
NSFeature::SensorInfoBase* pSensorInfo = pSensorInitFunc[idx].pSensorInfo;
if (pSensorInfo)
LOG_MSG("sensorIdx %d found <%#x/%s/%s>", sensorIdx, pSensorInfo->GetID(), pSensorInfo->getDrvName(), pSensorInfo->getDrvMacroName());
else
LOG_ERR("m_pSensorInfo[%d] = NULL check if sensor list sync with kernel & user", sensorIdx);
return SENSOR_NO_ERROR;
}
alps/vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/sensorlist.cpp
MSDK_SENSOR_INIT_FUNCTION_STRUCT SensorList[] =
{
#if defined(HI1336_MIPI_RAW)
RAW_INFO(HI1336_SENSOR_ID, SENSOR_DRVNAME_HI1336_MIPI_RAW, CAM_CALGetCalData),
#endif
...
UINT32 GetSensorInitFuncList(MSDK_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList)
{
*ppSensorList = &SensorList[0];
ImgSensorDrv::featureControl(
IMGSENSOR_SENSOR_IDX sensorIdx,
ACDK_SENSOR_FEATURE_ENUM FeatureId,
MUINT8 *pFeaturePara,
MUINT32 *pFeatureParaLen
)
{
ACDK_SENSOR_FEATURECONTROL_STRUCT featureCtrl;
if (m_fdSensor == -1) {
LOG_ERR("[sendCommand]m_fdSensor fail, sendCommand must be called after init()!");
return SENSOR_UNKNOWN_ERROR;
}
if (pFeaturePara == NULL || pFeatureParaLen == NULL) {
return SENSOR_INVALID_PARA;
}
featureCtrl.InvokeCamera = sensorIdx;
featureCtrl.FeatureId = FeatureId;
featureCtrl.pFeaturePara = pFeaturePara;
featureCtrl.pFeatureParaLen = pFeatureParaLen;
if (ioctl(m_fdSensor, KDIMGSENSORIOC_X_FEATURECONCTROL , &featureCtrl) < 0) { //调用到底层
LOG_ERR("[featureControl] Err-ctrlCode (%s)", strerror(errno));
return -errno;
}
return SENSOR_NO_ERROR;
}
/*
MINT32
ImgSensorDrv::open(IMGSENSOR_SENSOR_IDX sensorIdx)
{
MUINT32 featureParaLen = sizeof(MUINT32);
MUINT32 featurePara;
return featureControl(sensorIdx, SENSOR_FEATURE_OPEN, (MUINT8 *)&featurePara, &featureParaLen);
}
*/
alps/kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor.c
static long imgsensor_ioctl(
struct file *a_pstFile,
unsigned int a_u4Command,
unsigned long a_u4Param)
{
case KDIMGSENSORIOC_X_FEATURECONCTROL:
i4RetValue = adopt_CAMERA_HW_FeatureControl(pBuff);
static inline int adopt_CAMERA_HW_FeatureControl(void *pBuf){
case SENSOR_FEATURE_SET_DRIVER:
{
MINT32 drv_idx;
psensor->inst.sensor_idx = pFeatureCtrl->InvokeCamera;
drv_idx = imgsensor_set_driver(psensor);
memcpy(pFeaturePara, &drv_idx, FeatureParaLen);
break;
}
int imgsensor_set_driver(struct IMGSENSOR_SENSOR *psensor)
{
u32 drv_idx = 0;
int ret = -EIO;
struct IMGSENSOR_SENSOR_INST *psensor_inst = &psensor->inst;
struct IMGSENSOR_INIT_FUNC_LIST *pSensorList = kdSensorList;
#define TOSTRING(value) #value
#define STRINGIZE(stringizedName) TOSTRING(stringizedName)
alps/kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_sensor_list.c
struct IMGSENSOR_INIT_FUNC_LIST kdSensorList[MAX_NUM_OF_SUPPORT_SENSOR] = {
#if defined(HI1336_MIPI_RAW)
{HI1336_SENSOR_ID,
SENSOR_DRVNAME_HI1336_MIPI_RAW,
HI1336_MIPI_RAW_SensorInit},
#endif
...
alps/kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/hi1336_mipi_raw/hi1336_mipiraw.c
UINT32 HI1336_MIPI_RAW_SensorInit(struct SENSOR_FUNCTION_STRUCT **pfFunc)
{
/* To Do : Check Sensor status here */
if (pfFunc != NULL)
*pfFunc = &sensor_func;//获取具体sensor的操作函数
return ERROR_NONE;
}