先抛出一张类图关系,纯手工制作,比较乱,不过看完文章后再来看这张图会很清晰:
1.cameraservice在mediaservice中启动:
CameraService::instantiate();
先分析一下CameraService的继承类:
class CameraService :
public BinderService<CameraService>,
public BnCameraService,
public IBinder::DeathRecipient,
public camera_module_callbacks_t
{
1,第一个是BinderService,
会发现cameraservice其实并没有实现父类BinderService的方法instantiate();所以会调用父类的方法:
static void instantiate() { publish(); }
都是静态方法:
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}
static char const* getServiceName() { return "media.camera"; }
初始化得到一个sm实例,这里得到的也就是全局中唯一的servicemanager,向sm实例中添加cameraservice服务实例,到这里cameraservice成功注册到sm中,后续需要与cameraservice建立沟通只要向sm传入service name就能获取到这个cameraservice服务。这边传入的service name是:media.camera。
2.第二个继承的类 public BnCameraService,
BnCameraService/BpCameraService/ICameraService 三个类是第一个跟camera相关的binder框架之一,里面主要是上层快要启动camera 相关实际操作之前的跟camera一些交互包括获取camera id和连接到cameraservce这两个重要操作。
virtual int32_t getNumberOfCameras() = 0;
virtual status_t getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo) = 0;
virtual status_t getCameraCharacteristics(int cameraId,
CameraMetadata* cameraInfo) = 0;
// Returns 'OK' if operation succeeded
// - Errors: ALREADY_EXISTS if the listener was already added
virtual status_t addListener(const sp<ICameraServiceListener>& listener)
= 0;
// Returns 'OK' if operation succeeded
// - Errors: BAD_VALUE if specified listener was not in the listener list
virtual status_t removeListener(const sp<ICameraServiceListener>& listener)
= 0;
/**
* clientPackageName and clientUid are used for permissions checking. if
* clientUid == USE_CALLING_UID, then the calling UID is used instead. Only
* trusted callers can set a clientUid other than USE_CALLING_UID.
*/
virtual status_t connect(const sp<ICameraClient>& cameraClient,
int cameraId,
const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICamera>& device) = 0;
virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb,
int cameraId,
const String16& clientPackageName,
int clientUid,
/*out*/
sp<IProCameraUser>& device) = 0;
virtual status_t connectDevice(
const sp<ICameraDeviceCallbacks>& cameraCb,
int cameraId,
const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICameraDeviceUser>& device) = 0;
cameraservice继承它,也就成为了这些接口的实现者。
这边看一下当上层准备启动camera应用来连接cameraservice的过程:
在camera.java中的open接口中:
public static Camera open() {
int numberOfCameras = getNumberOfCameras();
CameraInfo cameraInfo = new CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
return new Camera(i);
}
}
return null;
}
最先调用的jni函数是getNumberOfCameras(),获取camera的index,为后面打开camera设备做准备:
对应下面的JNI层接口在android_hardware_camera.cpp中,目录在base/core/jni文件夹下:
static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz)
{
return Camera::getNumberOfCameras();
}
可以看到是通过静态调用方式,camera类并没有实现这个方法,而是父类CameraBase实现了:
int CameraBase<TCam, TCamTraits>::getNumberOfCameras() {
const sp<ICameraService> cs = getCameraService();
if (!cs.get()) {
// as required by the public Java APIs
return 0;
}
return cs->getNumberOfCameras();
}
代码虽简洁,但都是干货:
const sp cs = getCameraService();这个操作获取目前的cameraservice在客户端这边的binder实例,获取这个实例也就是为了能够在客户端这边跨进程调用cameraservice的接口:
// establish binder interface to camera service
template <typename TCam, typename TCamTraits>
const sp<ICameraService>& CameraBase<TCam, TCamTraits>::getCameraService()
{
Mutex::Autolock _l(gLock);
if (gCameraService.get() == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
binder = sm->getService(String16(kCameraServiceName));
if (binder != 0) {
break;
}
ALOGW("CameraService not published, waiting...");
usleep(kCameraServicePollDelay);
} while(true);
if (gDeathNotifier == NULL) {
gDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(gDeathNotifier);
gCameraService = interface_cast<ICameraService>(binder);
}
ALOGE_IF(gCameraService == 0, "no CameraService!?");
return gCameraService;
}
看这个获取cameraservice的过程,先是通过defaultServiceManager()得到全局的sm service,然后通过servicename 去获取cameraservice,可以看到这里传入的name 变量:kCameraServiceName。这个在camerabase.h中声明:
const char* kCameraServiceName = "media.camera";
获取上来的是一个binder实例,通过binder->linkToDeath(gDeathNotifier);应该是向binder激活注册的意思。也就是第一套bidner框架就此激活。
接着把这个binder类型通过C++的强制转化成cameraservice的实例,就这样获取到了远程调用cameraservice接口的binder实例,