Android 7.0 Camera架构源码分析1 - CameraService启动
2017-12-13 21:12
621 查看
本系列教程主要讲解Camera从APP层到HAL层的整个流程,第一篇先讲解CameraService的启动,后面会讲解open、preview、takepicture的流程。
Android 7.0之前CameraService是在mediaserver进程中注册的,看下Android 6.0的代码:
接着看下Android 7.0中main_mediaserver.cpp的代码,发现没有了CameraService::instantiate(); 也就是说Android 7.0之后就不在main_mediaserver.cpp中注册了。
我们看下FrameWork层Camera的代码(frameworks\av\camera ),发现多了个cameraserver文件夹 ,看下里面的main_cameraserver.cpp,原来CameraServe::instantiaicte()在这里。
从这里可以猜测cameraserver应该是作为独立的进程运行的,我们看下 cameraserver文件夹下面的另一个文件cameraserver.rc
cameraserver.rc由Android.mk文件来打包到指定位置:
那cameraserver.rc文件什么时候执行呢?这里我们需要理解下Android系统启动过程,Android系统启动包括两大块:Linux内核启动,Android框架启动。
1,Linux内核启动:
BootLoader启动
内核启动首先装载BootLoader引导程序,执行完进入kthreadd内核进程,这是所有内核进程的父进程。
加载Linux内核
初始化驱动、安装根文件系统等,最后启动第一个用户进程init进程,它是所有用户进程的父进程。这样就进入了Android框架的启动阶段。
2,Android框架启动
init进程启动后会加载init.rc(system\core\rootdir\init.rc)脚本,当它执行mount_all指令挂载分区时,会加载/{system,vendor,odm}/etc/init目录下的所有rc脚本,这样就会启动cameraserver进程,同时也会启动zygote进程(第一个Java层进程,也是Java层所有进程的父进程)、ServiceManager、mediaserver(多媒体服务进程)、surfaceflinger(屏幕渲染相关的进程)等。之后zygote会孵化出启动system_server进程,Android framework里面的所有service(ActivityManagerService、WindowManagerService等)都是由system_server启动,这里就不细讲了。
那为什么Android 7.0之前cameraservice是运行在mediaserver进程中的,而从Android 7.0开始将cameraservice分离出来成一个单独的cameraserver进程?这是为了安全性,因为mediaserver 进程中有很多其它的Service,如AudioFlinger、MediaPlayerService等,如果这其中有一个Service挂掉就会导致mediaserver进程重启,如果相机正在执行,这样就会挂掉,用户体验很差。
现在知道了cameraserver进程是怎么启动的了,下面分析下它的启动过程,cameraserver进程的入口是frameworks\av\camera\cameraserver\main_cameraserver.cpp的main函数,看下代码:
我们主要关注CameraService::instantiate(),别的几行属于Binder机制,我这里假设你已经熟悉了,不熟悉的话先补下Binder知识,不然后面很难理解的。
CameraService继承了BinderService和BnCameraService类。CameraService::instantiate()函数是调用其父类BinderService类的方法。
BinderService使用了模板类,使用CameraService::instantiate()初始化时,SERVICE就是CameraService。替换模板后CameraService::instantiate()函数如下:
我们知道defaultServiceManager返回的是BpServiceManager,看下它的addService函数:
注意addService第二个参数service是sp类型,而sp初始化时,会调用其包装的对象的onFirstRef()函数,不懂的可以参考Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析
这里的service就是CameraService,看下它的onFirstRef()函数:
camera_module_t(hardware\libhardware\include\hardware\camera_common.h)的声明如下:
hw_get_module()函数定义在hardware\libhardware\hardware.c文件中
根据上述代码,dlsym就是找HMI的地址,而HMI就是HAL_MODULE_INFO_SYM的宏定义,所以最终就是找HAL_MODULE_INFO_SYM的地址。
通过查找Android 7.0 代码,发现HAL_MODULE_INFO_SYM是在hardware/qcom/camera/QCamera2/QCamera2Hal.cpp文件中实现的(如果你的7.0源码没有HAL层的代码,可以参考在线源代码http://androidxref.com/)。
所以最终rawModule就是指向HAL_MODULE_INFO_SYM,这样CameraService就跟Camera HAL层联系起来了。
回到CameraService::onFirstRef()函数中:
onFirstRef函数主要是根据ID查找并加载HAL模块的动态链接库,然后创建CameraModule对象并初始化以及获取摄像头数量,之后给HAL层设置一个监听接口。
回到addService函数中,接着看其里面的具体内容:
到这里只是将数据封装了一下,但是还没发送,接着看waitForResponse函数:
下面就进入到了Linux内核中了,AOSP中没有这部分代码,我们可以使用这两个Linux内核在线阅读网站:https://lxr.missinglinkelectronics.com/linux 或者 http://elixir.free-electrons.com/
首先binder_init函数会创建 /dev/binder节点:
回到IPCThreadState::talkWithDriver:
看下binder_thread_write写操作:
对比这张Binder架构图,Client就是cameraserver进程,Service就是servicemanager进程,整个注册服务的过程就是cameraserver进程发送BC_TRANSACTION命令到Binder驱动中,然后Binder驱动发送BR_TRANSACTION命令到servermanager进程中注册,这里会生成一个handle,用来标识”media.camera”服务,然后将此服务添加到svclist全局链表中。然后通过BC_REPLY命令将返回结果发送到Binder驱动中,Binder驱动再通过BR_REPLY命令将结果发送给cameraserver进程。
至此,CameraService的servicename和实例就在ServiceManager中注册了,之后别的进程即可通过ServiceManager跨进程获取CameraService服务。并且CameraService通过onFirstRef()函数跟Camera HAL层联系起来了。
作者:lb377463323
出处:http://blog.csdn.net/lb377463323
原文链接:http://blog.csdn.net/lb377463323/article/details/78796915
转载请注明出处!
Android 7.0之前CameraService是在mediaserver进程中注册的,看下Android 6.0的代码:
//path: frameworks\av\media\mediaserver\main_mediaserver.cpp int main() { sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); ALOGI("ServiceManager: %p", sm.get()); AudioFlinger::instantiate(); MediaPlayerService::instantiate(); ResourceManagerService::instantiate(); //初始化相机服务 CameraService::instantiate(); AudioPolicyService::instantiate(); SoundTriggerHwService::instantiate(); RadioService::instantiate(); registerExtensions(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }
接着看下Android 7.0中main_mediaserver.cpp的代码,发现没有了CameraService::instantiate(); 也就是说Android 7.0之后就不在main_mediaserver.cpp中注册了。
//没有CameraService::instantiate(),也少了几个别的服务,这里只关注CameraService int main(int argc __unused, char **argv __unused) { signal(SIGPIPE, SIG_IGN); sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm(defaultServiceManager()); ALOGI("ServiceManager: %p", sm.get()); InitializeIcuOrDie(); MediaPlayerService::instantiate(); ResourceManagerService::instantiate(); registerExtensions(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }
我们看下FrameWork层Camera的代码(frameworks\av\camera ),发现多了个cameraserver文件夹 ,看下里面的main_cameraserver.cpp,原来CameraServe::instantiaicte()在这里。
int main(int argc __unused, char** argv __unused) { signal(SIGPIPE, SIG_IGN); sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); ALOGI("ServiceManager: %p", sm.get()); //初始化CameraService服务 CameraServe::instantiaicte(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }
从这里可以猜测cameraserver应该是作为独立的进程运行的,我们看下 cameraserver文件夹下面的另一个文件cameraserver.rc
//这表示由init进程启动名字为cameraserver的进程,果然是独立进程,路径为/system/bin/cameraserver service cameraserver /system/bin/cameraserver //class表示类别,同一类别(这里是main类别)的进程同时启动,同时停止 class main //用户名及分组 user cameraserver group audio camera input drmrpc ioprio rt 4 writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
cameraserver.rc由Android.mk文件来打包到指定位置:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) //源文件 LOCAL_SRC_FILES:= \ main_cameraserver.cpp LOCAL_SHARED_LIBRARIES := \ libcameraservice \ libcutils \ libutils \ libbinder \ libcamera_client //模块的名称 LOCAL_MODULE:= cameraserver LOCAL_32_BIT_ONLY := true LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter //LOCAL_INIT_RC会将cameraserver.rc放在/system/etc/init/目录中,这个目录下的脚本会由init进程来启动。 LOCAL_INIT_RC := cameraserver.rc include $(BUILD_EXECUTABLE)
那cameraserver.rc文件什么时候执行呢?这里我们需要理解下Android系统启动过程,Android系统启动包括两大块:Linux内核启动,Android框架启动。
1,Linux内核启动:
BootLoader启动
内核启动首先装载BootLoader引导程序,执行完进入kthreadd内核进程,这是所有内核进程的父进程。
加载Linux内核
初始化驱动、安装根文件系统等,最后启动第一个用户进程init进程,它是所有用户进程的父进程。这样就进入了Android框架的启动阶段。
2,Android框架启动
init进程启动后会加载init.rc(system\core\rootdir\init.rc)脚本,当它执行mount_all指令挂载分区时,会加载/{system,vendor,odm}/etc/init目录下的所有rc脚本,这样就会启动cameraserver进程,同时也会启动zygote进程(第一个Java层进程,也是Java层所有进程的父进程)、ServiceManager、mediaserver(多媒体服务进程)、surfaceflinger(屏幕渲染相关的进程)等。之后zygote会孵化出启动system_server进程,Android framework里面的所有service(ActivityManagerService、WindowManagerService等)都是由system_server启动,这里就不细讲了。
那为什么Android 7.0之前cameraservice是运行在mediaserver进程中的,而从Android 7.0开始将cameraservice分离出来成一个单独的cameraserver进程?这是为了安全性,因为mediaserver 进程中有很多其它的Service,如AudioFlinger、MediaPlayerService等,如果这其中有一个Service挂掉就会导致mediaserver进程重启,如果相机正在执行,这样就会挂掉,用户体验很差。
现在知道了cameraserver进程是怎么启动的了,下面分析下它的启动过程,cameraserver进程的入口是frameworks\av\camera\cameraserver\main_cameraserver.cpp的main函数,看下代码:
int main(int argc __unused, char** argv __unused) { signal(SIGPIPE, SIG_IGN); //获取一个ProcessState跟Binder驱动打交道 sp<ProcessState> proc(ProcessState::self()); //获取ServiceManager用以注册该服务 sp<IServiceManager> sm = defaultServiceManager(); ALOGI("ServiceManager: %p", sm.get()); CameraService::instantiate(); //线程池管理 ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }
我们主要关注CameraService::instantiate(),别的几行属于Binder机制,我这里假设你已经熟悉了,不熟悉的话先补下Binder知识,不然后面很难理解的。
CameraService继承了BinderService和BnCameraService类。CameraService::instantiate()函数是调用其父类BinderService类的方法。
class CameraService : public BinderService<CameraService>, public ::android::hardware::BnCameraService, public IBinder::DeathRecipient, public camera_module_callbacks_t { ...... } //模板类 template<typename SERVICE> class BinderService { public: static status_t publish(bool allowIsolated = false) { sp<IServiceManager> sm(defaultServiceManager()); return sm->addService( String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); } static void publishAndJoinThreadPool(bool allowIsolated = false) { publish(allowIsolated); joinThreadPool(); } static void instantiate() { publish(); } ...... }
BinderService使用了模板类,使用CameraService::instantiate()初始化时,SERVICE就是CameraService。替换模板后CameraService::instantiate()函数如下:
static void instantiate() { publish(); } static status_t publish() { sp<IServiceManager> sm(defaultServiceManager()); /getServiceName()返回"media.camera"字符串 return sm->addService( String16(CameraService ::getServiceName()), new CameraService (), false); }
我们知道defaultServiceManager返回的是BpServiceManager,看下它的addService函数:
virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated) { Parcel data, reply; //写入Interface name,这里是"android.os.IServiceManager" data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); //写入Service name data.writeString16(name); //写入Service实例 data.writeStrongBinder(service); data.writeInt32(allowIsolated ? 1 : 0); //remote()实际上是指BpBinder(0) status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readExceptionCode() : err; }
注意addService第二个参数service是sp类型,而sp初始化时,会调用其包装的对象的onFirstRef()函数,不懂的可以参考Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析
这里的service就是CameraService,看下它的onFirstRef()函数:
//原始代码有点长,这里只保留了比较重要的代码 void CameraService::onFirstRef() { BnCameraService::onFirstRef(); //camera_module_t和CAMERA_HARDWARE_MODULE_ID定义在hardware\libhardware\include\hardware\camera_common.h中, camera_module_t *rawModule; //注意这里把rawModule强转成camera_module_t,至于为什么能强转,下面会讲的 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t **)&rawModule); //创建CameraModule对象并初始化 mModule = new CameraModule(rawModule); err = mModule->init(); //获取摄像头数量 mNumberOfCameras = mModule->getNumberOfCameras(); mNumberOfNormalCameras = mNumberOfCameras; int latestStrangeCameraId = INT_MAX; for (int i = 0; i < mNumberOfCameras; i++) { String8 cameraId = String8::format("%d", i); //获取每个camera的信息以及初始化状态 } //因为CameraService继承了camera_module_callbacks_t,定义在camera_common.h中,所以这里的Callback主要监听camera_device_status_change和torch_mode_status_change if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) { mModule->setCallbacks(this); } //连接CameraServiceProxy服务,也就是"media.camera.proxy"服务,此服务由SystemServer注册到ServiceManager中 CameraService::pingCameraServiceProxy(); }
camera_module_t(hardware\libhardware\include\hardware\camera_common.h)的声明如下:
typedef struct camera_module { //注意common必须是camera_module的第一个成员,这样就可以根据camera_module_t的地址强转成hw_module_t hw_module_t common; int (*get_number_of_cameras)(void); ...... } camera_module_t;
hw_get_module()函数定义在hardware\libhardware\hardware.c文件中
int hw_get_module(const char *id, const struct hw_module_t **module) { return hw_get_module_by_class(id, NULL, module); } int hw_get_module_by_class(const char *class_id, const char *inst, const struct hw_module_t **module) { ...... //首先根据ro.hardware.class_id.inst查找动态链接库路径,如果可以找到,直接跳到found位置 snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name); if (property_get(prop_name, prop, NULL) > 0) { if (hw_module_exists(path, sizeof(path), name, prop) == 0) { goto found; } } //在所有的配置变量中查找所需模块的动态链接库路径 for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) { if (property_get(variant_keys[i], prop, NULL) == 0) { continue; } if (hw_module_exists(path, sizeof(path), name, prop) == 0) { goto found; } } return -ENOENT; found: //根据路径加载动态链接库,并将硬件模块的结构体地址赋给module return load(class_id, path, module); }
static int load(const char *id, const char *path, const struct hw_module_t **pHmi) { int status = -EINVAL; void *handle = NULL; struct hw_module_t *hmi = NULL; //打开.so文件 handle = dlopen(path, RTLD_NOW); //获取hal_module_info结构体的地址 const char *sym = HAL_MODULE_INFO_SYM_AS_STR; hmi = (struct hw_module_t *)dlsym(handle, sym); } //hardware.h /** * Name of the hal_module_info */ #define HAL_MODULE_INFO_SYM HMI /** * Name of the hal_module_info as a string */ #define HAL_MODULE_INFO_SYM_AS_STR "HMI"
根据上述代码,dlsym就是找HMI的地址,而HMI就是HAL_MODULE_INFO_SYM的宏定义,所以最终就是找HAL_MODULE_INFO_SYM的地址。
通过查找Android 7.0 代码,发现HAL_MODULE_INFO_SYM是在hardware/qcom/camera/QCamera2/QCamera2Hal.cpp文件中实现的(如果你的7.0源码没有HAL层的代码,可以参考在线源代码http://androidxref.com/)。
static hw_module_t camera_common = { .tag = HARDWARE_MODULE_TAG, .module_api_version = CAMERA_MODULE_API_VERSION_2_4, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = CAMERA_HARDWARE_MODULE_ID, .name = "QCamera Module", .author = "Qualcomm Innovation Center Inc", .methods = &qcamera::QCamera2Factory::mModuleMethods, .dso = NULL, .reserved = {0} }; camera_module_t HAL_MODULE_INFO_SYM = { .common = camera_common, .get_number_of_cameras = qcamera::QCamera2Factory::get_number_of_cameras, .get_camera_info = qcamera::QCamera2Factory::get_camera_info, .set_callbacks = qcamera::QCamera2Factory::set_callbacks, .get_vendor_tag_ops = qcamera::QCamera3VendorTags::get_vendor_tag_ops, .open_legacy = qcamera::QCamera2Factory::open_legacy, .set_torch_mode = qcamera::QCamera2Factory::set_torch_mode, .init = NULL, .reserved = {0} };
所以最终rawModule就是指向HAL_MODULE_INFO_SYM,这样CameraService就跟Camera HAL层联系起来了。
回到CameraService::onFirstRef()函数中:
//创建CameraModule对象并初始化 mModule = new CameraModule(rawModule); err = mModule->init(); //获取摄像头数量 mNumberOfCameras = mModule->getNumberOfCameras(); mNumberOfNormalCameras = mNumberOfCameras;
CameraModule::CameraModule(camera_module_t *module) { //对mModule进行初始化 mModule = module; } int CameraModule::init() { //mModule->init就是指向HAL_MODULE_INFO_SYM的init,为NULL if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 && mModule->init != NULL) { ATRACE_BEGIN("camera_module->init"); res = mModule->init(); ATRACE_END(); } //调用getNumberOfCameras() mCameraInfoMap.setCapacity(getNumberOfCameras()); } int CameraModule::getNumberOfCameras() { int numCameras; //调用HAL_MODULE_INFO_SYM的get_number_of_cameras()函数 numCameras = mModule->get_number_of_cameras(); return numCameras; } //查看HAL层代码 int QCamera2Factory::get_number_of_cameras() { int numCameras = 0; //gQCamera2Factory为空的话,创建一个对象 if (!gQCamera2Factory) { gQCamera2Factory = new QCamera2Factory(); if (!gQCamera2Factory) { LOGE("Failed to allocate Camera2Factory object"); return 0; } } if(gQCameraMuxer) numCameras = gQCameraMuxer->get_number_of_cameras(); else //获取Camera摄像头数量 numCameras = gQCamera2Factory->getNumberOfCameras(); return numCameras; } QCamera2Factory::QCamera2Factory() { mHalDescriptors = NULL; mCallbacks = NULL; //get_num_of_cameras()在mm_camera_interface.c中,之后就会进入到Linux内核,往下就不讲了 mNumOfCameras = get_num_of_cameras(); mNumOfCameras_expose = get_num_of_cameras_to_expose(); ...... }
onFirstRef函数主要是根据ID查找并加载HAL模块的动态链接库,然后创建CameraModule对象并初始化以及获取摄像头数量,之后给HAL层设置一个监听接口。
回到addService函数中,接着看其里面的具体内容:
virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated) { Parcel data, reply; //写入Interface name,这里是"android.os.IServiceManager" data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); //写入Service name data.writeString16(name); //写入Service实例 data.writeStrongBinder(service); data.writeInt32(allowIsolated ? 1 : 0); //remote()实际上是指BpBinder(0),它是指Binder驱动中的0号引用,也就是指ServiceManager的代理对象 status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readExceptionCode() : err; } status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { // Once a binder has died, it will never come back to life. if (mAlive) { //通过IPCThreadState对象来向Binder驱动发送添加服务的请求,注意mHandle值为0 status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; } return DEAD_OBJECT; } status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t err = data.errorCheck(); if (err == NO_ERROR) { //将数据封装成binder_transaction_data结构,并写到mOut变量中 err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); } if ((flags & TF_ONE_WAY) == 0) { if (reply) { err = waitForResponse(reply); } else { Parcel fakeReply; err = waitForResponse(&fakeReply); } } return err; } status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer) { binder_transaction_data tr; //封装数据 tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */ tr.target.handle = handle; tr.code = code; tr.flags = binderFlags; tr.cookie = 0; tr.sender_pid = 0; tr.sender_euid = 0; const status_t err = data.errorCheck(); if (err == NO_ERROR) { tr.data_size = data.ipcDataSize(); tr.data.ptr.buffer = data.ipcData(); tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t); tr.data.ptr.offsets = data.ipcObjects(); } ...... //写到mOut变量中 mOut.writeInt32(cmd); mOut.write(&tr, sizeof(tr)); return NO_ERROR; }
到这里只是将数据封装了一下,但是还没发送,接着看waitForResponse函数:
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) { uint32_t cmd; int32_t err; while (1) { //跟Binder驱动交互,这个是核心,在下面讲解 if ((err=talkWithDriver()) < NO_ERROR) break; //读取Binder驱动返回的命令 cmd = (uint32_t)mIn.readInt32(); IF_LOG_COMMANDS() { alog << "Processing waitForResponse Command: " << getReturnString(cmd) << endl; } switch (cmd) { case BR_TRANSACTION_COMPLETE: if (!reply && !acquireResult) goto finish; break; case BR_DEAD_REPLY: err = DEAD_OBJECT; goto finish; case BR_FAILED_REPLY: err = FAILED_TRANSACTION; goto finish; case BR_ACQUIRE_RESULT: { ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT"); const int32_t result = mIn.readInt32(); if (!acquireResult) continue; *acquireResult = result ? NO_ERROR : INVALID_OPERATION; } goto finish; case BR_REPLY: { binder_transaction_data tr; err = mIn.read(&tr, sizeof(tr)); ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY"); if (err != NO_ERROR) goto finish; if (reply) { if ((tr.flags & TF_STATUS_CODE) == 0) { reply->ipcSetDataReference( reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(binder_size_t), freeBuffer, this); } else { err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer); freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(binder_size_t), this); } } else { freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(binder_size_t), this); continue; } } goto finish; default: err = executeCommand(cmd); if (err != NO_ERROR) goto finish; break; } } finish: if (err != NO_ERROR) { if (acquireResult) *acquireResult = err; if (reply) reply->setError(err); mLastError = err; } return err; } //不穿参数时doReceive为true status_t IPCThreadState::talkWithDriver(bool doReceive) { //mProcess是IPCThreadState初始化时所包含的ProcessState对象,它的mDriverFD对应Binder驱动的文件描述符 if (mProcess->mDriverFD <= 0) { return -EBADF; } //将mOut的数据封装到binder_write_read结构体中 binder_write_read bwr; // Is the read buffer empty? const bool needRead = mIn.dataPosition() >= mIn.dataSize(); // We don't want to write anything if we are still reading // from data left in the input buffer and the caller // has requested to read the next data. const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0; bwr.write_size = outAvail; bwr.write_buffer = (uintptr_t)mOut.data(); // This is what we'll read. if (doReceive && needRead) { bwr.read_size = mIn.dataCapacity(); bwr.read_buffer = (uintptr_t)mIn.data(); } else { bwr.read_size = 0; bwr.read_buffer = 0; } bwr.write_consumed = 0; bwr.read_consumed = 0; status_t err; do { #if defined(__ANDROID__) //这里就是向Binder驱动写入命令和数据 if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0) err = NO_ERROR; #else err = INVALID_OPERATION; #endif } while (err == -EINTR); ...... return err; }
下面就进入到了Linux内核中了,AOSP中没有这部分代码,我们可以使用这两个Linux内核在线阅读网站:https://lxr.missinglinkelectronics.com/linux 或者 http://elixir.free-electrons.com/
//路径 linux/drivers/android/binder.c linux/include/uapi/linux/android/binder.h
首先binder_init函数会创建 /dev/binder节点:
static int __init binder_init(void) { ...... while ((device_name = strsep(&device_names, ","))) { //初始化Binder设备 ret = init_binder_device(device_name); } return ret; } static int __init init_binder_device(const char *name) { int ret; struct binder_device *binder_device; binder_device = kzalloc(sizeof(*binder_device), GFP_KERNEL); if (!binder_device) return -ENOMEM; //操作函数结构体 binder_device->miscdev.fops = &binder_fops; binder_device->miscdev.minor = MISC_DYNAMIC_MINOR; //设备名称,这里就是"binder",这样用户空间可以通过/dev/binder节点进行操作 binder_device->miscdev.name = name; binder_device->context.binder_context_mgr_uid = INVALID_UID; binder_device->context.name = name; //向内核中注册misc设备 ret = misc_register(&binder_device->miscdev); if (ret < 0) { kfree(binder_device); return ret; } hlist_add_head(&binder_device->hlist, &binder_devices); return ret; } //这里指定了文件操作的函数 static const struct file_operations binder_fops = { .owner = THIS_MODULE, .poll = binder_poll, //从Linux kernel 2.6.36版本开始,删除了ioctl函数指针,用unlocked_ioctl取代 .unlocked_ioctl = binder_ioctl, .compat_ioctl = binder_ioctl, .mmap = binder_mmap, .open = binder_open, .flush = binder_flush, .release = binder_release, };
回到IPCThreadState::talkWithDriver:
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0) err = NO_ERROR; //ioctl就对应内核中的binder_ioctl函数, static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int ret; struct binder_proc *proc = filp->private_data; struct binder_thread *thread; ...... //从binder_proc中查找binder_thread,如果当前线程已经加入到proc的线程队列则直接返回,如果不存在则创建binder_thread,并将当前线程添加到当前的proc thread = binder_get_thread(proc); switch (cmd) { case BINDER_WRITE_READ: ret = binder_ioctl_write_read(filp, cmd, arg, thread); if (ret) goto err; break; } static int binder_ioctl_write_read(struct file *filp, unsigned int cmd, unsigned long arg, struct binder_thread *thread) { int ret = 0; struct binder_proc *proc = filp->private_data; unsigned int size = _IOC_SIZE(cmd); void __user *ubuf = (void __user *)arg; struct binder_write_read bwr; if (size != sizeof(struct binder_write_read)) { ret = -EINVAL; goto out; } //把用户空间的binder_write_read数据拷贝到内核空间bwr if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { ret = -EFAULT; goto out; } if (bwr.write_size > 0) { //当写缓存中有数据时,执行Binder写操作 ret = binder_thread_write(proc, thread, bwr.write_buffer, bwr.write_size, &bwr.write_consumed); trace_binder_write_done(ret); //如果Binder写操作失败,则将bwr数据拷回到内核空间,并返回 if (ret < 0) { bwr.read_consumed = 0; if (copy_to_user(ubuf, &bwr, sizeof(bwr))) ret = -EFAULT; goto out; } } if (bwr.read_size > 0) { //当读缓存中有数据时,执行Binder读操作 ret = binder_thread_read(proc, thread, bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK); trace_binder_read_done(ret); if (!list_empty(&proc->todo)) wake_up_interruptible(&proc->wait); //如果Binder读操作失败,则将bwr数据拷回到内核空间,并返回 if (ret < 0) { if (copy_to_user(ubuf, &bwr, sizeof(bwr))) ret = -EFAULT; goto out; } } //将bwr数据拷回到内核空间,并返回 if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { ret = -EFAULT; goto out; } out: return ret; }
看下binder_thread_write写操作:
static int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, binder_uintptr_t binder_buffer, size_t size, binder_size_t *consumed) { uint32_t cmd; struct binder_context *context = proc->context; void __user *buffer = (void __user *)(uintptr_t)binder_buffer; void __user *ptr = buffer + *consumed; void __user *end = buffer + size; while (ptr < end && thread->return_error == BR_OK) { if (get_user(cmd, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); trace_binder_command(cmd); if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) { binder_stats.bc[_IOC_NR(cmd)]++; proc->stats.bc[_IOC_NR(cmd)]++; thread->stats.bc[_IOC_NR(cmd)]++; } switch (cmd) { ...... //我们前面发送的命令就是BC_TRANSACTION case BC_TRANSACTION: case BC_REPLY: { struct binder_transaction_data tr; //拷贝用户空间数据到内核空间tr if (copy_from_user(&tr, ptr, sizeof(tr))) return -EFAULT; ptr += sizeof(tr); binder_transaction(proc, thread, &tr, cmd == BC_REPLY, 0); break; } } return 0; } static void binder_transaction(struct binder_proc *proc, struct binder_thread *thread, struct binder_transaction_data *tr, int reply, binder_size_t extra_buffers_size) { ...... if (reply) { ...... } else { //因为我们传的tr->target.handle为0,也就是ServiceManager进程 if (tr->target.handle) { ...... } else { //直接获取ServiceManager的在Binder驱动中的binder_node目标节点 target_node = context->binder_context_mgr_node; } //获取ServiceManager的进程 target_proc = target_node->proc; } ...... if (target_thread) { e->to_thread = target_thread->pid; //获取ServiceManager的TODO队列和等待队列 target_list = &target_thread->todo; target_wait = &target_thread->wait; } //分配两个结构体内存 t = kzalloc(sizeof(*t), GFP_KERNEL); binder_stats_created(BINDER_STAT_TRANSACTION); tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL); binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE); ...... //为target_proc分配一块Buffer t->buffer = binder_alloc_buf(target_proc, tr->data_size, tr->offsets_size, extra_buffers_size, !reply && (t->flags & TF_ONE_WAY)); ...... //向target_list,也就是ServiceManager的TODO队列,添加BINDER_WORK_TRANSACTION事务 t->work.type = BINDER_WORK_TRANSACTION; list_add_tail(&t->work.entry, target_list); //向当前线程的TODO队列添加BINDER_WORK_TRANSACTION_COMPLETE事务 tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; list_add_tail(&tcomplete->entry, &thread->todo); //如果ServiceManager进程正在等待,则唤醒 if (target_wait) { if (reply || !(t->flags & TF_ONE_WAY)) wake_up_interruptible_sync(target_wait); else wake_up_interruptible(target_wait); } return; }
对比这张Binder架构图,Client就是cameraserver进程,Service就是servicemanager进程,整个注册服务的过程就是cameraserver进程发送BC_TRANSACTION命令到Binder驱动中,然后Binder驱动发送BR_TRANSACTION命令到servermanager进程中注册,这里会生成一个handle,用来标识”media.camera”服务,然后将此服务添加到svclist全局链表中。然后通过BC_REPLY命令将返回结果发送到Binder驱动中,Binder驱动再通过BR_REPLY命令将结果发送给cameraserver进程。
至此,CameraService的servicename和实例就在ServiceManager中注册了,之后别的进程即可通过ServiceManager跨进程获取CameraService服务。并且CameraService通过onFirstRef()函数跟Camera HAL层联系起来了。
作者:lb377463323
出处:http://blog.csdn.net/lb377463323
原文链接:http://blog.csdn.net/lb377463323/article/details/78796915
转载请注明出处!
相关文章推荐
- Android 7.0 Camera架构源码分析
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- Android5.1.1Camera 系统架构源码分析(2)---->Camera的startPreview和setPreviewCallback
- Android四大组件Service启动源码分析
- Android Camera 系统架构源码分析(5)---->Camera数据Buf的传递方式及相关类
- Android 7.0 Gallery图库源码分析2 - 分析启动流程
- Android7.0 Messaging源码分析(0) - 启动篇
- Android Camera 系统架构源码分析(1)---->Camera的初始化
- Android服务之PackageManagerService启动源码分析
- Android源码解析四大组件系列(一)---Service的启动过程分析
- Android Camera 系统架构源码分析(5)---->Camera数据Buf的传递方式及相关类
- Android服务启动之StartService源码分析
- Android服务启动之StartService源码分析
- Android笔记-service启动过程分析:startService源码分析
- Android笔记-service启动过程分析:bindService源码分析、startService和bindService区别
- Android Service的启动流程源码分析(8.0)