Android Camera Framework Stream(二)
2010-12-05 22:30
204 查看
接下来,我们通过对流程的步步分析来将
camera
整体串接起来
:
1.
首先则看看
camera.java
的
onCreate
函数入口,针对
android
的所有应用,
onCreate
函数入口作为跟踪和了解应用架构的首选。
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
devlatch = new CountDownLatch(1);
CountDownLatch()
关于这个类,可以简单的理解为它是用来线程之间的等待处理,当然这里采用的计数为
1
,则可以简单理解为一个计数开关来控制调用了
tlatch.await()
函数的进程,方式就是将
devlatch
的计数减为
0(countDown()
)
。
这里启动了一个线程用来打开
camera
服务,而打开过程则比较费时
(
一般在
2s
左右
)
,故单独启用一个线程避免应用线程阻塞。
Thread startPreviewThread = new Thread(new Runnable() {
CountDownLatch tlatch = devlatch;
public void run() {
try {
mStartPreviewFail = false;
ensureCameraDevice();
// Wait for framework initialization to be complete before
// starting preview
try {
tlatch.await();
} catch (InterruptedException ie) {
mStartPreviewFail = true;
}
startPreview();
} 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(e);
}
mStartPreviewFail = true;
}
}
});
startPreviewThread.start();
在这里,需要跟进
ensureCameraDevice();
该函数,可以看到其实现为:
private void ensureCameraDevice() throws CameraHardwareException {
if (mCameraDevice == null) {
mCameraDevice = CameraHolder.instance().open();
mInitialParams = mCameraDevice.getParameters();
}
}
当前
mCameraDevice()
实例为
null,
则会调用
CameraHolder.instance().open()
函数来创建
mCameraDevice
对象实例。
private android.hardware.Camera mCameraDevice;
跟进
CameraHolder.instance().open()
,进入到了
CameraHolder
类中:
public synchronized android.hardware.Camera open()
throws CameraHardwareException {
Assert(mUsers == 0);
if (mCameraDevice == null) {
try {
mCameraDevice = android.hardware.Camera.open();
} catch (RuntimeException e) {
Log.e(TAG, "fail to connect Camera", e);
throw new CameraHardwareException(e);
}
mParameters = mCameraDevice.getParameters();
} else {
……
下面大概介绍下我对
CameraHolder
的理解:
1
、
CameraHolder
对
mCameraDevice
实例进行短暂的保留
(keep()
函数中可以设定这个保留时长
,
一般默认为
3000ms)
,避免用户在短暂退出
camera
又重新进入时,缩短
camera
启动时长
(
正如之前所说,打开
CameraDevice
时间较长
)
2
、
CameraHolder
并有一个关键的计数
mUsers
用来保证
open()
和
release()
的配套调用,避免多次重复释放或者打开
(
上层应用的保护措施之一
)
。
2.
第一步的完成,进而跳转到了
android.hardware.Camera
类中的
open()
函数接口调用。
public static Camera open() {
return new Camera();
}
静态函数,也就可以通过类名直接调用,
open()
函数中去创建一个
Camera
的实例。
Camera() {
mShutterCallback = null;
mRawImageCallback = null;
mJpegCallback = null;
mPreviewCallback = null;
mPostviewCallback = null;
mZoomListener = null;
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else {
mEventHandler = null;
}
native_setup(new WeakReference<Camera>(this));
}
在
Camera
构造函数中有这个关键的一步
,
最开始的一些
callback
可以认为它们最终被底层调用到
(
至于具体流程后面会讲到
)
。
EventHandler
和
Looper
我们暂时跳过,知道它是消息处理就行了。最后也就是最为关键的函数接口调用:
native_setup
private native final void native_setup(Object camera_this);
典型的
native
函数接口声明,说明并非
camera
类的本地函数实现,也就意味着会通过
JNI(Java Native Interface)
调用对用
C++
文件中的函数接口。
3.
通过代码搜索,或者如果你清楚
JNI
文件路径也可以去该路径下找。
其实这边有个小技巧,虽然不一定都通用,但可以试试看:
java
类的
package
名往往可以作为寻找相应
JNI
文件的途径:
package android.hardware;
则就可以通过
android.hardware.
camera.cpp
来寻找
(
其实还是归咎于
android
的规范命名规则
)
。
跳转到
android_hardware_Camera.cpp
中寻找
native_setup()
所对应的
JNI
函数接口:
static JNINativeMethod camMethods[] = {
{ "native_setup",
"(Ljava/lang/Object;)V",
(void*)android_hardware_Camera_native_setup },
{ "native_release",
"()V",
(void*)android_hardware_Camera_release },
{ "setPreviewDisplay",
"(Landroid/view/Surface;)V",
(void *)android_hardware_Camera_setPreviewDisplay },
……
而
camMethods[]
在什么时候映射的那?继续看:
int register_android_hardware_Camera(JNIEnv *env)
{
…..
// Register native functions
return AndroidRuntime::registerNativeMethods(env, "android/hardware/Camera",
camMethods,NELEM(camMethods));
}
最终在
AndroidRuntime.cpp
中被调用:
REG_JNI(register_android_hardware_Camera),
说明如果我们自己要添加
JNI
接口实现的话,这些地方也需要添加相应的代码
(
具体在
AndroidRuntime.cpp
的细节我没深看,也不做介绍
)
。
简单介绍:
JNINativeMethod
的第一个成员是一个字符
串,表示了
JAVA
本地调用方法的名称,这个名称是在
JAVA
程序中调用的名称;第二个成员也是一个字符串,表示
JAVA
本地调用方法的参数和返回值;第三个成员是
JAVA
本地调用方法对应的
C
语言函数
。
跟进观察
android_hardware_Camera_native_setup()
函数的实现:
// connect to camera service
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
sp<Camera> camera =
Camera::connect();
if (camera == NULL) {
jniThrowException(env, "java/lang/RuntimeException",
"Fail to connect to camera service");
return;
}
….
}
初步可以认为
Camera::connect()
的函数调用时返回了一个
Camera
的实例对象。
4.
通过上述的跟进流程来到了针对上层应用而言最为直接的类:
camera.cpp
:
对
Camera::connect
函数的调用如下:
sp<Camera> Camera::connect()
{
LOGV("connect");
sp<Camera> c =
new Camera();
const sp<ICameraService>& cs =
getCameraService();
if (cs != 0) {
c->mCamera =
cs->connect(c);
}
if (c->mCamera != 0) {
c->mCamera->asBinder()->linkToDeath(c);
c->mStatus = NO_ERROR;
} else {
c.clear();
}
return c;
}
首先是创建一个
camera
对象实例,然后通过调用
getCameraService()
去取得
ICameraService
的服务实例:
// establish binder interface to camera service
const sp<ICameraService>& Camera::getCameraService()
{
Mutex::Autolock _l(mLock);
if (mCameraService.get() == 0) {
sp<IServiceManager> sm =
defaultServiceManager()
;
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.camera"));
if (binder != 0)
break;
LOGW("CameraService not published, waiting...");
usleep(500000); // 0.5 s
} while(true);
if (mDeathNotifier == NULL) {
mDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(mDeathNotifier);
mCameraService = interface_cast<ICameraService>(binder);
}
LOGE_IF(mCameraService==0, "no CameraService!?");
return mCameraService;
}
这边就涉及到了
ServiceManager()
对服务的管理,在这之前
Camera
的服务已经注册到了
ServiceManager
中,我们可以通过服务字串
(media.camera)
来获得
camera service(
其本质得到的是
CameraService
的实例对象,虽然通过类型上溯转换成父类
ICameraService
,对
ICameraService
对象的函数调用本质是调用到了
CameraService
的函数实现
)
。
在得到
camera service
后,返回之前的步骤:当得到的
cs
即
cameraservice
实例存在时,通过调用
cs->connect(c)
去得到
ICamera
实例,并赋值给了
camera
实例的一个类成员
ICamera
mCamera
:
if (cs != 0) {
c->mCamera = cs->connect(c);
5.
接下来则涉及到ICamraService
的相关调用关系,其实这个地方需要去弄清楚一些函数接口的实现在具体哪些文件中,因为存在较多的虚函数。
继续流程,上一步走到了
cs->connect()
,也就是
ICameraService
的
connect()
函数接口。
class ICameraService : public IInterface
{
public:
enum {
CONNECT = IBinder::FIRST_CALL_TRANSACTION,
};
public:
DECLARE_META_INTERFACE(CameraService);
virtual sp<ICamera>
connect(const sp<ICameraClient>& cameraClient) = 0;
};
可以发现该connect()
接口为一个纯虚函数,需要
ICameraService
的子类对该接口进行实现,从而对connect()
的调用则会映射到
ICameraService
子类的具体实现。
关于
ICameraService
的实例问题,目前暂时跳过
(
后面马上就会讲到
)
,简单认为这个时候会调用到其一个子类的实现:
class BpCameraService: public BpInterface<ICameraService>
{
public:
BpCameraService(const sp<IBinder>& impl)
:
BpInterface<ICameraService>(impl)
{
}
// connect to camera service
virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient)
{
Parcel data, reply;
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
data.writeStrongBinder(cameraClient->asBinder());
remote()->transact(BnCameraService::CONNECT, data, &reply);
return interface_cast<ICamera>(reply.readStrongBinder());
}
};
BpCameraService
为代理类,其主要用途为
Binder
通讯机制即进程间的通讯
(Client/Service)
,最终还是会调用
BnCameraService
的具体实现,即:
status_t
BnCameraService::onTransact
(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CONNECT: {
CHECK_INTERFACE(ICameraService, data, reply);
sp<ICameraClient> cameraClient
= interface_cast<ICameraClient>(data.readStrongBinder());
sp<ICamera> camera = connect(cameraClient);
reply->writeStrongBinder(camera->asBinder());
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
而BnCameraService
(
为实现类
)
类继承于ICameraService
,并且也并没有对connect()
纯虚函数进行了实现,同样意味着其实该调用的实质是
BnCameraService
的子类实现。
毕竟虚函数的调用没有实例肯定是没有意义的,说明我们需要找到对
connect()
纯虚函数的实现子类即继承于
BnCameraService
。
6.
结合上面所述,可以寻找到了继承于BnCameraService
的子类CameraService.cpp
:
这时虽然找到了CameraService
该类,但是你肯定会问到该类实例的创建在什么地方哪?再后头看
CameraService
启动注册的地方:
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
这个
main
函数位于
main_mediaserver.cpp
中,而
mediaserver
是在系统开始的时候就启动起来的
server
端(MediaServer
,在系统启动时由
init
所启动,具可参考
init.rc
文件
),进而将相关的服务也创建了实例。
跟进
CameraService::instantiate()
函数实现,可以发现:
void CameraService::instantiate() {
defaultServiceManager()->addService(
String16("
media.camera
"),
new CameraService()
);
}
创建了一个
CameraService
实例
,并给定了
CameraService
的服务字串为
”media.camera”
,而之前在通过
ServiceManager
获取
CameraService
的时候,所调用的接口为binder = sm->getService(String16("media.camera"));
,两者保持了一样的字符串。
if (mCameraService.get() == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.camera"));
if (binder != 0)
break;
LOGW("CameraService not published, waiting...");
usleep(500000); // 0.5 s
} while(true);
if (mDeathNotifier == NULL) {
mDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(mDeathNotifier);
mCameraService = interface_cast<ICameraService>(binder);
}
结合上述分析,此处的binder
对象其实为CameraService
类实例
(
多态类型转换
)
。
interface_cast<ICameraService>(binder)
宏映射,需要展开:
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
INTERFACE::asInterface(obj);
宏映射,继续展开可得:
sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)
/
{
/
sp<I##INTERFACE> intr;
/
if (obj != NULL) {
/
intr = static_cast<I##INTERFACE*>(
/
obj->queryLocalInterface(
/
I##INTERFACE::descriptor).get());
/
if (intr == NULL) {
/
intr = new Bp##INTERFACE(obj);
/
}
/
}
/
return intr;
/
}
(
其上的宏展开都是在
IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
中实现的
)
此处又创建了一个BpCameraService
(new Bp##INTERFACE)
对象并将binder
对象
(obj)
传入到
BpCameraService
的构造函数中。
虽然获取的时候通过多态将
CameraService
实例转换成了
BnCameraService
也进一步解释了为什么
ICameraService
子类
BnCameraservice
中的
connect
函数实质会调用到
CameraService
中函数实现了。
于是就调用到了
CameraService
的
connect
函数接口:
sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient) {
…..
// create a new Client object
client = new Client(this, cameraClient, callingPid);
mClient = client;
if (client->mHardware == NULL) {
client = NULL;
mClient = NULL;
return client;
}
…..
}
创建了一个
Client
实例对象,并将该实例对象赋值给
CameraSevice
的类成员
mClient,
方便其实函数接口对
Client
的调用。
在这之前需要提及它的一个内部类
Client
,该类才是最为关键的函数实现
,CameraService
的一些接口都会调用到其
Client
实例的具体函数。
camera
整体串接起来
:
1.
首先则看看
camera.java
的
onCreate
函数入口,针对
android
的所有应用,
onCreate
函数入口作为跟踪和了解应用架构的首选。
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
devlatch = new CountDownLatch(1);
CountDownLatch()
关于这个类,可以简单的理解为它是用来线程之间的等待处理,当然这里采用的计数为
1
,则可以简单理解为一个计数开关来控制调用了
tlatch.await()
函数的进程,方式就是将
devlatch
的计数减为
0(countDown()
)
。
这里启动了一个线程用来打开
camera
服务,而打开过程则比较费时
(
一般在
2s
左右
)
,故单独启用一个线程避免应用线程阻塞。
Thread startPreviewThread = new Thread(new Runnable() {
CountDownLatch tlatch = devlatch;
public void run() {
try {
mStartPreviewFail = false;
ensureCameraDevice();
// Wait for framework initialization to be complete before
// starting preview
try {
tlatch.await();
} catch (InterruptedException ie) {
mStartPreviewFail = true;
}
startPreview();
} 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(e);
}
mStartPreviewFail = true;
}
}
});
startPreviewThread.start();
在这里,需要跟进
ensureCameraDevice();
该函数,可以看到其实现为:
private void ensureCameraDevice() throws CameraHardwareException {
if (mCameraDevice == null) {
mCameraDevice = CameraHolder.instance().open();
mInitialParams = mCameraDevice.getParameters();
}
}
当前
mCameraDevice()
实例为
null,
则会调用
CameraHolder.instance().open()
函数来创建
mCameraDevice
对象实例。
private android.hardware.Camera mCameraDevice;
跟进
CameraHolder.instance().open()
,进入到了
CameraHolder
类中:
public synchronized android.hardware.Camera open()
throws CameraHardwareException {
Assert(mUsers == 0);
if (mCameraDevice == null) {
try {
mCameraDevice = android.hardware.Camera.open();
} catch (RuntimeException e) {
Log.e(TAG, "fail to connect Camera", e);
throw new CameraHardwareException(e);
}
mParameters = mCameraDevice.getParameters();
} else {
……
下面大概介绍下我对
CameraHolder
的理解:
1
、
CameraHolder
对
mCameraDevice
实例进行短暂的保留
(keep()
函数中可以设定这个保留时长
,
一般默认为
3000ms)
,避免用户在短暂退出
camera
又重新进入时,缩短
camera
启动时长
(
正如之前所说,打开
CameraDevice
时间较长
)
2
、
CameraHolder
并有一个关键的计数
mUsers
用来保证
open()
和
release()
的配套调用,避免多次重复释放或者打开
(
上层应用的保护措施之一
)
。
2.
第一步的完成,进而跳转到了
android.hardware.Camera
类中的
open()
函数接口调用。
public static Camera open() {
return new Camera();
}
静态函数,也就可以通过类名直接调用,
open()
函数中去创建一个
Camera
的实例。
Camera() {
mShutterCallback = null;
mRawImageCallback = null;
mJpegCallback = null;
mPreviewCallback = null;
mPostviewCallback = null;
mZoomListener = null;
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else {
mEventHandler = null;
}
native_setup(new WeakReference<Camera>(this));
}
在
Camera
构造函数中有这个关键的一步
,
最开始的一些
callback
可以认为它们最终被底层调用到
(
至于具体流程后面会讲到
)
。
EventHandler
和
Looper
我们暂时跳过,知道它是消息处理就行了。最后也就是最为关键的函数接口调用:
native_setup
private native final void native_setup(Object camera_this);
典型的
native
函数接口声明,说明并非
camera
类的本地函数实现,也就意味着会通过
JNI(Java Native Interface)
调用对用
C++
文件中的函数接口。
3.
通过代码搜索,或者如果你清楚
JNI
文件路径也可以去该路径下找。
其实这边有个小技巧,虽然不一定都通用,但可以试试看:
java
类的
package
名往往可以作为寻找相应
JNI
文件的途径:
package android.hardware;
则就可以通过
android.hardware.
camera.cpp
来寻找
(
其实还是归咎于
android
的规范命名规则
)
。
跳转到
android_hardware_Camera.cpp
中寻找
native_setup()
所对应的
JNI
函数接口:
static JNINativeMethod camMethods[] = {
{ "native_setup",
"(Ljava/lang/Object;)V",
(void*)android_hardware_Camera_native_setup },
{ "native_release",
"()V",
(void*)android_hardware_Camera_release },
{ "setPreviewDisplay",
"(Landroid/view/Surface;)V",
(void *)android_hardware_Camera_setPreviewDisplay },
……
而
camMethods[]
在什么时候映射的那?继续看:
int register_android_hardware_Camera(JNIEnv *env)
{
…..
// Register native functions
return AndroidRuntime::registerNativeMethods(env, "android/hardware/Camera",
camMethods,NELEM(camMethods));
}
最终在
AndroidRuntime.cpp
中被调用:
REG_JNI(register_android_hardware_Camera),
说明如果我们自己要添加
JNI
接口实现的话,这些地方也需要添加相应的代码
(
具体在
AndroidRuntime.cpp
的细节我没深看,也不做介绍
)
。
简单介绍:
JNINativeMethod
的第一个成员是一个字符
串,表示了
JAVA
本地调用方法的名称,这个名称是在
JAVA
程序中调用的名称;第二个成员也是一个字符串,表示
JAVA
本地调用方法的参数和返回值;第三个成员是
JAVA
本地调用方法对应的
C
语言函数
。
跟进观察
android_hardware_Camera_native_setup()
函数的实现:
// connect to camera service
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
sp<Camera> camera =
Camera::connect();
if (camera == NULL) {
jniThrowException(env, "java/lang/RuntimeException",
"Fail to connect to camera service");
return;
}
….
}
初步可以认为
Camera::connect()
的函数调用时返回了一个
Camera
的实例对象。
4.
通过上述的跟进流程来到了针对上层应用而言最为直接的类:
camera.cpp
:
对
Camera::connect
函数的调用如下:
sp<Camera> Camera::connect()
{
LOGV("connect");
sp<Camera> c =
new Camera();
const sp<ICameraService>& cs =
getCameraService();
if (cs != 0) {
c->mCamera =
cs->connect(c);
}
if (c->mCamera != 0) {
c->mCamera->asBinder()->linkToDeath(c);
c->mStatus = NO_ERROR;
} else {
c.clear();
}
return c;
}
首先是创建一个
camera
对象实例,然后通过调用
getCameraService()
去取得
ICameraService
的服务实例:
// establish binder interface to camera service
const sp<ICameraService>& Camera::getCameraService()
{
Mutex::Autolock _l(mLock);
if (mCameraService.get() == 0) {
sp<IServiceManager> sm =
defaultServiceManager()
;
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.camera"));
if (binder != 0)
break;
LOGW("CameraService not published, waiting...");
usleep(500000); // 0.5 s
} while(true);
if (mDeathNotifier == NULL) {
mDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(mDeathNotifier);
mCameraService = interface_cast<ICameraService>(binder);
}
LOGE_IF(mCameraService==0, "no CameraService!?");
return mCameraService;
}
这边就涉及到了
ServiceManager()
对服务的管理,在这之前
Camera
的服务已经注册到了
ServiceManager
中,我们可以通过服务字串
(media.camera)
来获得
camera service(
其本质得到的是
CameraService
的实例对象,虽然通过类型上溯转换成父类
ICameraService
,对
ICameraService
对象的函数调用本质是调用到了
CameraService
的函数实现
)
。
在得到
camera service
后,返回之前的步骤:当得到的
cs
即
cameraservice
实例存在时,通过调用
cs->connect(c)
去得到
ICamera
实例,并赋值给了
camera
实例的一个类成员
ICamera
mCamera
:
if (cs != 0) {
c->mCamera = cs->connect(c);
5.
接下来则涉及到ICamraService
的相关调用关系,其实这个地方需要去弄清楚一些函数接口的实现在具体哪些文件中,因为存在较多的虚函数。
继续流程,上一步走到了
cs->connect()
,也就是
ICameraService
的
connect()
函数接口。
class ICameraService : public IInterface
{
public:
enum {
CONNECT = IBinder::FIRST_CALL_TRANSACTION,
};
public:
DECLARE_META_INTERFACE(CameraService);
virtual sp<ICamera>
connect(const sp<ICameraClient>& cameraClient) = 0;
};
可以发现该connect()
接口为一个纯虚函数,需要
ICameraService
的子类对该接口进行实现,从而对connect()
的调用则会映射到
ICameraService
子类的具体实现。
关于
ICameraService
的实例问题,目前暂时跳过
(
后面马上就会讲到
)
,简单认为这个时候会调用到其一个子类的实现:
class BpCameraService: public BpInterface<ICameraService>
{
public:
BpCameraService(const sp<IBinder>& impl)
:
BpInterface<ICameraService>(impl)
{
}
// connect to camera service
virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient)
{
Parcel data, reply;
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
data.writeStrongBinder(cameraClient->asBinder());
remote()->transact(BnCameraService::CONNECT, data, &reply);
return interface_cast<ICamera>(reply.readStrongBinder());
}
};
BpCameraService
为代理类,其主要用途为
Binder
通讯机制即进程间的通讯
(Client/Service)
,最终还是会调用
BnCameraService
的具体实现,即:
status_t
BnCameraService::onTransact
(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CONNECT: {
CHECK_INTERFACE(ICameraService, data, reply);
sp<ICameraClient> cameraClient
= interface_cast<ICameraClient>(data.readStrongBinder());
sp<ICamera> camera = connect(cameraClient);
reply->writeStrongBinder(camera->asBinder());
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
而BnCameraService
(
为实现类
)
类继承于ICameraService
,并且也并没有对connect()
纯虚函数进行了实现,同样意味着其实该调用的实质是
BnCameraService
的子类实现。
毕竟虚函数的调用没有实例肯定是没有意义的,说明我们需要找到对
connect()
纯虚函数的实现子类即继承于
BnCameraService
。
6.
结合上面所述,可以寻找到了继承于BnCameraService
的子类CameraService.cpp
:
这时虽然找到了CameraService
该类,但是你肯定会问到该类实例的创建在什么地方哪?再后头看
CameraService
启动注册的地方:
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
这个
main
函数位于
main_mediaserver.cpp
中,而
mediaserver
是在系统开始的时候就启动起来的
server
端(MediaServer
,在系统启动时由
init
所启动,具可参考
init.rc
文件
),进而将相关的服务也创建了实例。
跟进
CameraService::instantiate()
函数实现,可以发现:
void CameraService::instantiate() {
defaultServiceManager()->addService(
String16("
media.camera
"),
new CameraService()
);
}
创建了一个
CameraService
实例
,并给定了
CameraService
的服务字串为
”media.camera”
,而之前在通过
ServiceManager
获取
CameraService
的时候,所调用的接口为binder = sm->getService(String16("media.camera"));
,两者保持了一样的字符串。
if (mCameraService.get() == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.camera"));
if (binder != 0)
break;
LOGW("CameraService not published, waiting...");
usleep(500000); // 0.5 s
} while(true);
if (mDeathNotifier == NULL) {
mDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(mDeathNotifier);
mCameraService = interface_cast<ICameraService>(binder);
}
结合上述分析,此处的binder
对象其实为CameraService
类实例
(
多态类型转换
)
。
interface_cast<ICameraService>(binder)
宏映射,需要展开:
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
INTERFACE::asInterface(obj);
宏映射,继续展开可得:
sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)
/
{
/
sp<I##INTERFACE> intr;
/
if (obj != NULL) {
/
intr = static_cast<I##INTERFACE*>(
/
obj->queryLocalInterface(
/
I##INTERFACE::descriptor).get());
/
if (intr == NULL) {
/
intr = new Bp##INTERFACE(obj);
/
}
/
}
/
return intr;
/
}
(
其上的宏展开都是在
IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
中实现的
)
此处又创建了一个BpCameraService
(new Bp##INTERFACE)
对象并将binder
对象
(obj)
传入到
BpCameraService
的构造函数中。
虽然获取的时候通过多态将
CameraService
实例转换成了
BnCameraService
也进一步解释了为什么
ICameraService
子类
BnCameraservice
中的
connect
函数实质会调用到
CameraService
中函数实现了。
于是就调用到了
CameraService
的
connect
函数接口:
sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient) {
…..
// create a new Client object
client = new Client(this, cameraClient, callingPid);
mClient = client;
if (client->mHardware == NULL) {
client = NULL;
mClient = NULL;
return client;
}
…..
}
创建了一个
Client
实例对象,并将该实例对象赋值给
CameraSevice
的类成员
mClient,
方便其实函数接口对
Client
的调用。
在这之前需要提及它的一个内部类
Client
,该类才是最为关键的函数实现
,CameraService
的一些接口都会调用到其
Client
实例的具体函数。
相关文章推荐
- Android Camera Framework Stream
- Android Camera Framework Stream(三)
- Android Camera Framework Stream(二)
- Android Camera Framework Stream(一)
- Android Camera Framework Stream(三)
- Android Camera Framework Stream(一)
- Android Camera Framework Stream(三)
- Android Camera Framework Stream(二)
- Android Camera Framework Stream(三)
- Android Camera Framework Stream(一)
- Android Camera Framework Stream(一)
- Android Camera Framework Stream
- Android Camera Framework Stream(一)
- Android Camera Framework Stream
- Android Camera Framework Stream(一)
- Android Camera Framework Stream(一)
- Android Camera Framework Stream
- Android Camera Framework Stream
- Android Camera Framework Stream(一)
- Android Camera Framework Stream