Camera (api1)的打开过程
setModuleFromIndex()@CameraActivity.javaà
{
mPhotoModule = new PhotoModule();
mPhotoModule.init(this,mCameraPhotoModuleRootView);
mCurrentModule= mPhotoModule;
}
init ()@PhotoModule.java à
{
mOpenCameraThread= new OpenCameraThread();
mOpenCameraThread.start();
}
private class OpenCameraThread extendsThread {
//先打开camera设备,然后启动预览
openCamera();
startPreview();
}
openCamera()@PhotoModule.javaà
{
//这里的mCameraDevice实际对应了AndroidCameraProxyImpl的实例,而AndroidCameraProxyImpl类中有一个android.hardware.Camera.java对象,这个对象通过jni对应了cameraService.Client这个内部类的实例,根据不同api,cameraService.Client又对应了CameraClient或者Camera2Client。
mCameraDevice= CameraUtil.openCamera(
mActivity,mCameraId, mHandler,
mActivity.getCameraOpenErrorCallback());
}
openCamera()@CameraUtil.javaà
CameraProxy open()@CameraHolder.javaà
{
CameraProxymCameraDevice;
mCameraDevice= CameraManagerFactory
.getAndroidCameraManager().cameraOpen(handler,cameraId, cb);
}
CameraManager.CameraProxy cameraOpen()@AndroidCameraManagerImpl.javaà
{
// 发出OPEN_CAMERA消息执行打开camera的操作,如果正常打开了camera设备,就返回一个AndroidCameraProxyImpl实例。
mCameraHandler.obtainMessage(OPEN_CAMERA,cameraId, 0,
CameraOpenErrorCallbackForward.getNewInstance(
handler,callback)).sendToTarget();
if(mCamera != null)
returnnew AndroidCameraProxyImpl();
}
对OPEN_CAMERA消息的处理是调用android.hardware.Camera.java中的open方法:
mCamera = android.hardware.Camera.open(msg.arg1)@AndroidCameraManagerImpl.javaà
Camera open(int cameraId) @frameworks/base/core/java/android/hardware/Camera.javaà
Camera(int cameraId) @frameworks/base/core/java/android/hardware/Camera.javaà
cameraInitNormal ()@frameworks/base/core/java/android/hardware/Camera.javaà
cameraInitVersion()@frameworks/base/core/java/android/hardware/Camera.javaà
{
//核心操作,通过jni调用到c++层。
return native_setup(newWeakReference<Camera>(this), cameraId, halVersion, packageName);
}
Step1、从app侧调用到framework侧的android.hardware.Camera.java,调用它的open函数,通过JNI调用到本地层,android_hardware_Camera.cpp中的android_hardware_Camera_native_setup(),调用到framework/av侧的Camera.cpp中connect,通过它完成camera实例的创建,让client与service建立联系,
同时创建一个监听类JNICameraContext,监听camera底层回传的数据和消息,notifycallback,datacallback,datacallbacktimestamp。
android_hardware_Camera_native_setup()@frameworks/base/core/jni/android_hardware_Camera.cppà
{
//这里调用到Camera.cpp中,这里主要做了2件事情,一个是通过Camera.cpp间接加载camera设备,一个是创建了JNICameraContext实例,这个实例对象中会保存camera.cpp间接打开的camera设备,所以后面通过context.getCamera()返回的就是Camera.cpp间接打开的设备,同时camera->setListener(context)设置了监听,这样camera设备中的回调就可以通过这个listener传到Framework层,比如下面的dataCallback(),其中的listener就是这个context。
camera= Camera::connect(cameraId, clientName,
Camera::USE_CALLING_UID,Camera::USE_CALLING_PID);
sp<JNICameraContext>context = newJNICameraContext(env, weak_this,clazz, camera);
camera->setListener(context);
}
void Camera::dataCallback(int32_t msgType,const sp<IMemory>& dataPtr,
camera_frame_metadata_t*metadata)
{
sp<CameraListener> listener;
{
Mutex::Autolock _l(mLock);
listener = mListener;
}
if (listener != NULL) {
listener->postData(msgType, dataPtr, metadata);
}
}
Step2、camera.cpp中的connect函数,client会向service发起连接请求,获取cameraservice实例,connect的返回值会关联到client,也就是camera.cpp这个实例,这样客户端服务端就建立了连接,上层对camera功能的调用,通过camera.cpp这个实例,传到cameraservice中client,实现对hal层的控制。在connect过程中,创建CameraClient时,创建了另一个实例:camerahardwareinterface它负责cameraservice跟hal层的交互,通过CameraHardwareInterface这个实例,注册了notifycallback,datacallback,datacallbacktimestamp这三个回调,这个hardware实例会打开camera驱动,初始化预览窗口,cameraservice在第一次被引用时,会通过hw_get_module加载camera的hal模块,这样cameraservice就可以通过这个module对象对camera hal模块的控制。
Camera::connect()@Frameworks/av/camera/camera.cppà
CameraBaseT::connect()@Frameworks/av/camera/camera.cppà
typedef CameraBase<TCam> CameraBaseT@CameraBase.h
sp<TCam> CameraBase<TCam,TCamTraits>::connect()@CameraBase.cppà
{
//这里会先获取cameraService的句柄,然后调用cameraService中的connect方法。我们这里看下c->mCamera这个出参是什么类型?CameraBase是一个模板类,它的connect是一个模板方法,那么对应的TCam实际是Camera.cpp的这个Camera类型,这个可以从:
class Camera :publicCameraBase<Camera>……看出。
所以c->mCamera中mCamera就是就是CameraBase中成员变量sp<TCamUser> mCamera;
这个出参在CameraService中被赋值为CameraService.Client。
sp<TCam>c = new TCam(cameraId);
sp<TCamCallbacks>cl = c;
constsp<::android::hardware::ICameraService> cs = getCameraService();
ret= (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
clientPid,/*out*/ &c->mCamera);
}
//因为CameraService继承了RefBase,所以被实例化时会执行onFirstRef方法,这个调用是在CameraService启动时执行的。
CameraService::onFirstRef()@frameworks/av/services/camera/libcameraservice/cameraservice.cpp
{
//这里是加载camera模块,打开camera设备,打开的设备句柄handle保存在:
camera_module_t-> hw_module_t-> (void*dso);
然后创建CameraModule实例,后续Cameraservice就可以通过CameraModule实例来访问camera设备,
camera_module_t*rawModule;
interr = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(const hw_module_t **)&rawModule);
mModule= new CameraModule(rawModule);
}
//接着看CameraService的connect方法。
CameraService::connect()@frameworks/av/services/camera/libcameraservice/cameraservice.cpp
{
//这个client实例赋值给了上面提到的 connect()@CameraBase.cpp中的&c->mCamera。
sp<Client>client = nullptr;
ret= connectHelper<ICameraClient,Client>(cameraClient, id,
CAMERA_HAL_API_VERSION_UNSPECIFIED,clientPackageName, clientUid, clientPid, API_1,
/*legacyMode*/false, /*shimUpdateOnly*/ false, /*out*/client);
*device= client;
}
//这个函数的主要作用就是调用makeClient生成CameraClient,调用它的初始化方法,同时把这个CameraClient实例赋值给上面的sp<Client> client。
CameraService::connectHelper()@CameraService.h{
ret= makeClient(this, cameraCb, clientPackageName, id, facing, clientPid,
clientUid,getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
/*out*/&tmp);
err= client->initialize(mModule)
}
CameraService::makeClient( )@cameraservice.cpp
{
//根据不同的api生成不同的实例。
caseCAMERA_DEVICE_API_VERSION_1_0:
*client= new CameraClient(cameraService, tmp, packageName, cameraId, facing,
clientPid,clientUid, getpid(), legacyMode);
caseCAMERA_DEVICE_API_VERSION_3_0:
*client= new Camera2Client(cameraService, tmp, packageName, cameraId, facing,
clientPid,clientUid, servicePid, legacyMode);
*client= new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
facing,clientPid, clientUid, servicePid);
}
//以CameraClient为例,
CameraClient::initialize()@CameraClient.cpp
{
//创建一个CameraHardwareInterface,其中initialize的参数module就是CameraService中创建的CameraModule实例,CameraClient可以通过mHardware对象跟camera设备通信。
mHardware= new CameraHardwareInterface(camera_device_name);
//这里打开camera设备,初始化Hal层的预览窗口
res= mHardware->initialize(module);
//设置回调函数。
mHardware->setCallbacks(notifyCallback,
dataCallback,dataCallbackTimestamp,
(void*)(uintptr_t)mCameraId);
}
Step3、camera hal层的实现
Hal层的创建过程中,会生成一个camerahardwarecomip实例,会创建三个比较重要的线程,previewThread,capturethread,autofocusthread,hal层处理完数据会有回调,有三种,notifycallback,datacallback,datacallbacktimestamp,这些回调会报给jni层的JNIcameracontext,
底层cameahardwarecomip这个实例创建后,做很多的初始化,如isp数据加载,底层支持的照片大小,对焦模式,感光度,把底层的图片格式设置为jpeg,这些camera底层参数的默认设置,然后等待上层的回调。
Step4、预览功能
Hal层的预览是又previewthread线程实现的,在打开camera驱动,创建cameahardwarecomip实例时,同时创建了previewthread,focusethread,capturethread,hardware创建以后,previewthread就启动了,但是因为预览窗口没有设置,app层也没法预览命令,实际这个线程时处于阻塞状态的。
接下来,app发startpreview命令,当前是拍照模式,就是photomodule发起这个命令,cameraservice处理这个请求,并传入到hal层,调用hardware的setpreviewwindow,startpreview设置预览窗口,开启预览,会根据用户的设置重新设置camera底层的参数,激活前面堵塞的previewthread,完成预览功能的开启。
Step5、拍照功能
App层发送拍照命令,就是shutterbutton的触发,调用onshutterbuttonfocus,onshutterbuttonclick,进行存储空间的检查,底层进行拍照,触发capturethread线程的运行,申请snapshot需要的buffer,从预览获取图片帧进行编码,在对图形数据编码前,对图片做缩放,生成thumbnail,设置图片的exif信息,编码生成图片文件,上层shutterbutton抬起,底层的数据处理还在进行,底层编码图片结束,会有jpegcallback,camerastorage开始进行图片存储,开始写exif信息,写文件流,写图片结束后,把数据记录插入数据库
大致关系:
一,Camera.cpp 实现了ICameraClient的回调接口如:notifyCallback,dataCallback等,
BpCameraClient通过ipc调用这些callback到BnCameraClient,然后BnCameraClient把请求转到Camera.cpp,从Camera.cpp继承了BnCameraClient可以得出这个结论,
class Camera : public::android::hardware::BnCameraClient。
二,Camera.cpp对应了CameraClient,在api2中实际是CameraDeviceClient,这个CameraDeviceClient对应了CameraService中的client,即CameraService::Client,在connectHelper中生成一个client后即makeClient后,会调用finishConnectLocked把这个client保存到mActiveClientManager中,这里保存了当前活动的应用层的client,以便cameraservice可以跟这些client通信。