目录
一 代码分析
第一步
-
1 定义 class IMcuService : public IInterface 接口
- 0 DECLARE_META_INTERFACE(McuService); 声明 IMcuService 类的元接口
- 1 为 McuService 类定义了一个静态成员变量 descriptor,用来描述接口名称,可以通过成员函数getInterfaceDescriptor()来获取。
- 2 同时定义了一个静态成员函数 asInterface(),用来讲一个 IBinder对象装换为一个IMcuService接口。
- 3 最后定义了其他接口操作函数
-
2 定义 Binder 本地对象类 class BnMcuService: public BnInterface
-
3 实现 class BnMcuServic :: onTransact() 方法
-
4 使用宏 IMPLEMENT_META_INTERFACE 来实现 IMcuService 类的元接口
- 0 使用宏 MPLEMENT_META_INTERFACE 来实现 IMcuService 类的元接口
- 1 将 McuService 类的静态成员变量 descriptor 设置为 " android.hardware.IMcuService "
- 2 实现了 IMcuService 类的构造函数和析构函数,是空函数
- 3 实现了成员函数 getInterfaceDescriptor() ,用来获取一个IMcuService类的描述符,即 descriptor
- 4 实现了 asInterface(),用来将一个 IBinder 对象装换为一个 IMcuService 接口。
-
5 定义BInder 代理对象类 BpMcuService BpMcuService,他继承了模块类 BpInterface
class BpMcuService: public BpInterface
实现如下功能:- 1 向服务进程发出 ATTACH 请求
- 2 向服务进程发出 GET_VERSION 请求
- 3 向服务进程发出 GET_TIME 请求
- 4 向服务进程发出 SET_POWER_STATE 请求
- 5 向服务进程发出 START_UPDATE 请求
- 6 向服务进程发出 STOP_UPDATE 请求
第二步
- 1 构建 class McuService : public BinderService, public BnMcuService
- 定义class McuService 服务,继承于本地对象 public BnMcuService,此服务用于操作 mcu专用串口底层
- 2 实现 McuService::onFirstRef()方法,用于打开 mcu专用串口。当该服务被引用的时候,自动调用该方法。
- 3 实现 McuService::instantiate()方法,将该服务注册进 Service Manager中,并将服务命名为 “media.mcu”
- 4 实现 McuService::ModuleClient::ModuleClient()构造函数,用于获取申请该服务的客户进程。
- 5 实现 McuService::attach() 方法,所有申请该服务的进程对于该服务本身来说,它们都是客户进程,所以 McuService::attach() 方法 用于将申请该服务的进程绑定到自身内部的客户进程类,用于绑定和记录与自己通信的客户进程信息。
- 6 操纵 mcu专用串口 的方法
第三步
- 0 调用 McuService::instantiate();//注册 McuService 服务
- 1 创建一个线程池,接着调用 进程中的 ProcessState对象的成员函数 startThreadPool来启动一个Binder线程池。
- 2 加入线程池,调用主线程的 IPCThreadstate对象的成员函数 joinThreadPool将主线程添加到进程的Binder线程中,用来处理来自Client的进程的通信请求
第四步
- 0 定义 class Mcu : public BnMcuClient, public IBinder::DeathRecipient
- 1 该类用于获取 服务 “media.mcu”
- 1 实现 Mcu::getMcuService() 获取 上述注册到 Service Manage的服务 “media.mcu”
- 2 实现 Mcu::Mcu() 初始化 mHandle、mCallback
- 3 实现 Mcu::attach() 获取该服务接口
第五步 实现JNI,打通Android上层服务接口通道
- 0 JNI实现本地方法 android_server_Mcu_setup() 对应 native_setup()
- 0 该方法内部调用 Mcu::attach() 获取 服务 “media.mcu”
- 1 实现JNI 本地方法
- 1 JNI实现本地方法 对应 native_finalize()
- 2 JNI实现本地方法 对应 native_get_mcu_Version()
- 3 JNI实现本地方法 对应 native_get_mcu_Time()
- 4 JNI实现本地方法 对应 native_setPowerState()
- 5 JNI实现本地方法 对应 native_startUpdate()
- 6 JNI实现本地方法 对应 native_stopUpdate()
- 2 注册JNI
第六步 实现Android上层硬件访服务
第七步 启动服务Android上层硬件访服务
二 服务打开过程梳理
- 1 打开 mcu串口服务McuManagerService.java
- 2 开mcu串口服务JNI
- 3 调用 Mcu::attach()
- 4 调用 McuService::attach()
三 总结
四 头文件笔记
一 代码分析
第一步 :
1 定义 class IMcuService : public IInterface 接口
0. DECLARE_META_INTERFACE(McuService); 声明 IMcuService 类的元接口
1. 为 McuService 类定义了一个静态成员变量 descriptor,用来描述接口名称,可以通过成员函数getInterfaceDescriptor()来获取。
2. 同时定义了一个静态成员函数 asInterface(),用来讲一个 IBinder对象装换为一个IMcuService接口。
3. 最后定义了其他接口操作函数
2 定义 Binder 本地对象类 class BnMcuService: public BnInterface<IMcuService>
3 实现 class BnMcuServic :: onTransact() 方法
4 使用宏 IMPLEMENT_META_INTERFACE 来实现 IMcuService 类的元接口
0. 使用宏 MPLEMENT_META_INTERFACE 来实现 IMcuService 类的元接口
1. 将 McuService 类的静态成员变量 descriptor 设置为 " android.hardware.IMcuService "
2. 实现了 IMcuService 类的构造函数和析构函数,是空函数
3. 实现了成员函数 getInterfaceDescriptor() ,用来获取一个IMcuService类的描述符,即 descriptor
4. 实现了 asInterface(),用来将一个 IBinder 对象装换为一个 IMcuService 接口。
5 定义BInder 代理对象类 BpMcuService BpMcuService,他继承了模块类 BpInterface
class BpMcuService: public BpInterface<IMcuService>
实现如下功能:
向服务进程发出 ATTACH 请求
向服务进程发出 GET_VERSION 请求
向服务进程发出 GET_TIME 请求
向服务进程发出 SET_POWER_STATE 请求
向服务进程发出 START_UPDATE 请求
向服务进程发出 STOP_UPDATE 请求
framework/av/include/mcu/IMcuService.h
class IMcu;
class IMcuClient;
/* 定义硬件服务接口 IMcuService */
class IMcuService : public IInterface
{
public:
mcu_metadata_t *test;
/* DECLARE_META_INTERFACE(McuService); 声明 IMcuService 类的元接口
1. 为 McuService 类定义了一个静态成员变量 descriptor,用来描述接口名称,可以通过成员函数getInterfaceDescriptor()来获取。
2. 同时定义了一个静态成员函数 asInterface(),用来讲一个 IBinder对象装换为一个IMcuService接口。
3. 最后定义了其他接口操作函数
*/
DECLARE_META_INTERFACE(McuService);
virtual status_t attach(mcu_handle_t handle,const sp<IMcuClient>& client,sp<IMcu>& mcu) = 0;
virtual String8 getVersion(int type) = 0;
virtual String8 getTime(int type) = 0;
virtual int setPowerState(int state)= 0;
virtual int startUpdate(int state)= 0;
virtual int stopUpdate(int state)= 0;
};
/*
* 定义了一个 Binder 本地对象类 BnMcuService,它实现了模板类 BnInterface的成员函数 onTransact。
*/
class BnMcuService: public BnInterface<IMcuService>
{
public:
/*
* 成员函数 onTransact 是虚函数,它是由 BBinder 的子类,即 Binder本地对象类来实现的,他负责分发与业务相关的进程间通
* 信请求。事实上,与业务相关的进程间通信请求是由Binder本地对象类的子类,即Service组件来负责处理的。
*/
virtual status_t onTransact( uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags = 0);
};
framework/av/mcu/IMcuService.cpp
/*
实现本地对象 onTransact()方法:对应代理对象的各个请求
*/
status_t BnMcuService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case ATTACH: {
CHECK_INTERFACE(IMcuService, data, reply);
mcu_handle_t handle = data.readInt32();
sp<IMcuClient> client = interface_cast<IMcuClient>(data.readStrongBinder());
ALOGV("ATTACH handle %d ", handle);
sp<IMcu> mcu;
status_t status = attach(handle, client,mcu);
reply->writeInt32(status);
if (mcu != 0) {
reply->writeInt32(1);
reply->writeStrongBinder(IInterface::asBinder(mcu));
//reply->writeStrongBinder(mcu->asBinder());
} else {
reply->writeInt32(0);
}
return NO_ERROR;
} break;
case GET_VERSION:{
CHECK_INTERFACE(IMcuService, data, reply);
int type = data.readInt32();
String8 version = getVersion(type);
reply->writeString8(version);
return NO_ERROR;
}break;
case GET_TIME:{
CHECK_INTERFACE(IMcuService, data, reply);
int type = data.readInt32();
String8 time = getTime(type);
reply->writeString8(time);
return NO_ERROR;
}break;
case SET_POWER_STATE:{
CHECK_INTERFACE(IMcuService,data,reply);
int type = data.readInt32();
int state = setPowerState(type);
reply->writeInt32(state);
return NO_ERROR;
}
break;
case START_UPDATE:{
CHECK_INTERFACE(IMcuService,data,reply);
int type = data.readInt32();
int state = startUpdate(type);
reply->writeInt32(state);
return NO_ERROR;
}
break;
case STOP_UPDATE:{
CHECK_INTERFACE(IMcuService,data,reply);
int type = data.readInt32();
int state = stopUpdate(type);
reply->writeInt32(state);
return NO_ERROR;
}
break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
/*
0. 使用宏 IMPLEMENT_META_INTERFACE 来实现 IMcuService 类的元接口
1. 将 IMcuService 类的静态成员变量 descriptor 设置为 " android.hardware.IMcuService "
2. 实现了 IMcuService 类的构造函数和析构函数,是空函数
3. 实现了成员函数 getInterfaceDescriptor() ,用来获取一个IMcuService类的描述符,即 descriptor
4. 实现了 asInterface(),用来将一个 IBinder 对象装换为一个 IMcuService 接口。
*/
IMPLEMENT_META_INTERFACE(McuService, "android.hardware.IMcuService");
/*
定义BInder 代理对象类 BpMcuService BpMcuService,他继承了模块类 BpInterface
实现如下功能:
向服务进程发出 ATTACH 请求
向服务进程发出 GET_VERSION 请求
向服务进程发出 GET_TIME 请求
向服务进程发出 SET_POWER_STATE 请求
向服务进程发出 START_UPDATE 请求
向服务进程发出 STOP_UPDATE 请求
*/
class BpMcuService: public BpInterface<IMcuService>
{
public:
BpMcuService(const sp<IBinder>& impl): BpInterface<IMcuService>(impl)
{
}
/*
获取目标服务的接口,并向该服务发出 ATTACH 请求
*/
virtual status_t attach(mcu_handle_t handle,const sp<IMcuClient>& client,sp<IMcu>& mcu)
{
Parcel data, reply;
data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
data.writeInt32(handle);
data.writeStrongBinder(IInterface::asBinder(client));
ALOGV("attach() handle %d", handle);
status_t status = remote()->transact(ATTACH, data, &reply);
if (status != NO_ERROR) {
return status;
}
status = reply.readInt32();
if (reply.readInt32() != 0) {
mcu = interface_cast<IMcu>(reply.readStrongBinder());
}
return status;
}
/*
获取目标服务的接口,并向该服务发出 GET_VERSION 请求
*/
virtual String8 getVersion(int type)
{
Parcel data,reply;
data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
data.writeInt32(type);
remote()->transact(GET_VERSION,data,&reply);
return reply.readString8();
}
/*
获取目标服务的接口,并向该服务发出 GET_TIME 请求
*/
virtual String8 getTime(int type)
{
Parcel data,reply;
data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
data.writeInt32(type);
remote()->transact(GET_TIME,data,&reply);
return reply.readString8();
}
/*
获取目标服务的接口,并向该服务发出 SET_POWER_STATE 请求
*/
virtual int setPowerState(int state)
{
Parcel data,reply;
data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
data.writeInt32(state);
remote()->transact(SET_POWER_STATE,data,&reply);
return reply.readInt32();
}
/*
获取目标服务的接口,并向该服务发出 START_UPDATE 请求
*/
virtual int startUpdate(int state)
{
Parcel data,reply;
data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
data.writeInt32(state);
remote()->transact(START_UPDATE,data,&reply);
return reply.readInt32();
}
/*
获取目标服务的接口,并向该服务发出 STOP_UPDATE 请求
*/
virtual int stopUpdate(int state)
{
Parcel data,reply;
data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
data.writeInt32(state);
remote()->transact(STOP_UPDATE,data,&reply);
return reply.readInt32();
}
};
第二步
0 定义 class McuService : public BinderService<McuService>, public BnMcuService
定义class McuService 服务,继承于本地对象 public BnMcuService,此服务用于操作 mcu专用串口底层
1 实现 McuService::onFirstRef()方法,用于打开 mcu专用串口。当该服务被引用的时候,自动调用该方法。
2 实现 McuService::instantiate()方法,将该服务注册进 Service Manager中,并将服务命名为 "media.mcu"
3 实现 McuService::ModuleClient::ModuleClient()构造函数,用于获取申请该服务的客户进程。
4 实现 McuService::attach() 方法,所有申请该服务的进程对于该服务本身来说,它们都是客户进程,所以 McuService::attach() 方法 用于将申请该服务的进程绑定到自身内部的客户进程类,用于绑定和记录与自己通信的客户进程信息。
5 操纵 mcu专用串口 的方法
virtual String8 getVersion(int type);
virtual String8 getTime(int type);
virtual int setPowerState(int state );
virtual int startUpdate(int status);
virtual int stopUpdate(int status);
6 其他
frameworks/av/services/mcuservice/McuService.h
// 继承 BnMcuService ,实现BnMcuService没有实现的方法
class McuService : public BinderService<McuService>, public BnMcuService
{
friend class BinderService<McuService>;
public:
class ModuleClient;
static char const* getServiceName() { return "media.mcu"; }
static void instantiate(); //注册McuService服务到 Service Manage 中,并将服务名称命名为"media.mcu"。
McuService();
virtual ~McuService();
// IMcuService
virtual status_t attach(mcu_handle_t handle, const sp<IMcuClient>& client,sp<IMcu>& mcu);
virtual String8 getVersion(int type);
virtual String8 getTime(int type);
virtual int setPowerState(int state );
virtual int startUpdate(int status);
virtual int stopUpdate(int status);
virtual status_t dump(int fd, const Vector<String16>& args);
void onCallbackEvent(const sp<IMemory>& event);
void removeClient(sp<ModuleClient> client);
int isFileExist(const char *pathFile);
void heartBeat();
......
/* 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息 */
class ModuleClient : public BnMcu, public IBinder::DeathRecipient {
public:
ModuleClient(const sp<McuService>& mcuService,const sp<IMcuClient>& client,mcu_handle_t handle);
virtual ~ModuleClient();
// IMcu
virtual void detach();
virtual status_t dump(int fd, const Vector<String16>& args);
sp<IMcuClient> client() const { return mClient; }//返回 mClient
void onCallbackEvent(const sp<IMemory>& event);
virtual void onFirstRef();//该类第一次被引用是调用
// IBinder::DeathRecipient implementation
virtual void binderDied(const wp<IBinder> &who);
private:
mutable Mutex mLock; // protects mClient, mConfig and mTuner
sp<McuService> mMcuService;
/*
IMcuClient 类 : 硬件服务接口 class IMcuClient : public IInterface
event callback binder interface
*/
sp<IMcuClient> mClient;
mcu_handle_t mHandle;
};
sp<CallbackThread> getCallbackThread() const { return mCallbackThread; }
int handleFrameData(FrameData *frame);
static void callback(mcu_event_t *halEvent, void *cookie);
private:
virtual void onFirstRef();
int sendCallbackEvent(FrameData *frame);
int mcuEventMonitor(int fd,const Vector<String16> &args);
void sendCMD(int cmd);
void sendCMD(int cmd,int length,unsigned char *data);
FrameData sendCMDWait(int cmd,int length,unsigned char *data,int second);
FrameData sendCMDWait(int cmd);
int setBackLightValue(int value);
int openBackLight(void);
int closeBackLight(void);
int setNextFuncState(int state,int cmd);
Mutex mServiceLock; // protects mModules
Vector< sp<ModuleClient> > mModuleClients;//动态数组,声明一个动态数组 ModuleClient mModuleClients[]
sp<CallbackThread> mCallbackThread; // event callback thread
sp<ReadThread> mReadThread; // read data thread
sp<HeartbeatThread> mHearbeatThread;
sp<UpdateThread>mUpdateThread;
sp<CommunicationInterface> mCommInterface;
pthread_mutex_t mDataMutex;
pthread_cond_t mDataCond;
int mFuncState;
FrameData mFrameData;
};
frameworks/av/services/mcuservice/McuService.cpp
McuService::McuService() : mFuncState(FUNC_CMD_NONE)
{
ALOGI("%s", __FUNCTION__);
}
void McuService::onFirstRef()
{
ALOGD("McuService::onFirstRef");
...
memset(&mFrameData,0x0,sizeof(FrameData));
mCommInterface = new UartComm2("/dev/ttyS3");//构造函数 传递取目标字符串:"/dev/ttyS3"
mCommInterface->openInterface();//打开目标串口"/dev/ttyS3" ,并且设置波特率
...
}
void McuService::instantiate()
{
ALOGV("McuService::instantiate");
/*
首先通过defaultServiceManager()获取一个 ServiceManager类对象,利用该类的addService()方法,将 McuService服务 注册到 Service Manager中,并且命名为 "media.mcu"
这样Client进程就可以通过名称 "media.mcu" 来获取这个McuService服务的一个代理对象了
*/
defaultServiceManager()->addService(String16("media.mcu"), new McuService());
}
/*工作 :绑定 service进程(本地对象)与client进程(代理对象),初始化 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息。
1 初始化 class McuService :: class ModuleClient ::mcu_handle_t mHandle = handle
2 初始化 class McuService :: class ModuleClient :: sp<IMcuClient> mClient = class IMcuClient client
3 初始化 mcu = class McuService :: class ModuleClient moduleClient
4 初始化 class McuService :: class ModuleClient::sp<McuService> mMcuService = this
5 向动态数组 ModuleClient mModuleClients[] 中添加 moduleClient 对象
6 初始化传递进来的 IMcu类 mcu对象 为 class McuService :: class ModuleClient moduleClient
*/
status_t McuService::attach(mcu_handle_t handle,const sp<IMcuClient>& client,sp<IMcu>& mcu)
{
ALOGV("%s handle: %d", __FUNCTION__,handle);
size_t i;
sp<ModuleClient> moduleClient;//ModuleClient类对象
...
//ModuleClient类构造函数 : McuService::ModuleClient::ModuleClient() ,创建 对象 moduleClient
/*
初始化 McuService类 mMcuService对象为 mcuService
class McuService :: class ModuleClient::sp<McuService> mMcuService;
初始化 IMcuClient类接口 mClient 对象为 client
class McuService :: class ModuleClient :: sp<IMcuClient> mClient;
初始化 mcu_handle_t mHandle = handle
class McuService :: class ModuleClient ::mcu_handle_t mHandle;
*/
moduleClient = new ModuleClient(this, client,handle);
if(moduleClient != 0)
{
//向动态数组 ModuleClient mModuleClients[] 中添加 moduleClient 对象?
mModuleClients.add(moduleClient);
//初始化传递进来的 IMcu类 mcu对象 为 moduleClient
mcu = moduleClient;
}
else
{
return NO_INIT;
}
return NO_ERROR;
}
/* //ModuleClient类构造函数 :
初始化 McuService类 mMcuService对象为 mcuService
class McuService :: class ModuleClient::sp<McuService> mMcuService;
初始化 IMcuClient类接口 mClient 对象为 client
class McuService :: class ModuleClient :: sp<IMcuClient> mClient;
初始化 mcu_handle_t mHandle = handle
class McuService :: class ModuleClient ::mcu_handle_t mHandle;
*/
McuService::ModuleClient::ModuleClient(const sp<McuService>& mcuService,const sp<IMcuClient>& client,mcu_handle_t handle)
: mMcuService(mcuService), mClient(client), mHandle(handle)
{
}
第三步
0 调用 McuService::instantiate();//注册 McuService 服务
1 创建一个线程池,接着调用 进程中的 ProcessState对象的成员函数 startThreadPool来启动一个Binder线程池。
2 加入线程池,调用主线程的 IPCThreadstate对象的成员函数 joinThreadPool将主线程添加到进程的Binder线程中,用来处理来自Client的进程的通信请求
frameworks/av/services/mcuservice/main_mcuservice.cpp
int main(int argc, char** argv){
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
/*
首先通过 defaultServiceManager()获取一个 ServiceManager类对象,利用该类的addService()方法,将 McuService 服务 注册到 Service Manager中,并且命名为 "media.mcu"
这样Client进程就可以通过名称 "media.mcu" 来获取这个McuService服务的一个代理对象了
*/
McuService::instantiate();
/* 创建一个线程池
* 接着调用 进程中的 ProcessState对象的成员函数 startThreadPool来启动一个Binder线程池。
*/
ProcessState::self()->startThreadPool();
/* 加入线程池
调用主线程的 IPCThreadstate对象的成员函数 joinThreadPool将主线程添加到进程的Binder线程中,用来处理来自Client的进程的通信请求。
*/
IPCThreadState::self()->joinThreadPool();
}
第四步
0 定义 class Mcu : public BnMcuClient, public IBinder::DeathRecipient
该类用于获取 服务 "media.mcu"
1 实现 Mcu::getMcuService() 获取 上述注册到 Service Manage的服务 "media.mcu"
2 实现 Mcu::Mcu() 初始化 mHandle、mCallback
3 实现 Mcu::attach() 获取该服务接口
frameworks/av/include/mcu/Mcu.h
class Mcu : public BnMcuClient, public IBinder::DeathRecipient
{
public:
virtual ~Mcu();
static sp<Mcu> attach(mcu_handle_t handle,const sp<McuCallback>& callback);
static const sp<IMcuService>& getMcuService(); //用于获取 "media.mcu" 的服务
void detach()
virtual void onEvent(const sp<IMemory>& eventMemory); // BpMcuClient
virtual void binderDied(const wp<IBinder>& who); //IBinder::DeathRecipient
private:
Mcu(mcu_handle_t handle,const sp<McuCallback>&);
Mutex mLock;
sp<IMcu> mIMcu;
const mcu_handle_t mHandle;
sp<McuCallback> mCallback;
};
frameworks/av/mcu/Mcu.cpp
namespace {
sp<IMcuService> gMcuService;
const int kMcuServicePollDelay = 500000; // 0.5s
const char* kMcuServiceName = "media.mcu";
Mutex gLock;
//死亡通知子类
class DeathNotifier : public IBinder::DeathRecipient
{
public:
DeathNotifier() {
}
virtual void binderDied(const wp<IBinder>& who __unused) {
ALOGV("binderDied");
Mutex::Autolock _l(gLock);
gMcuService.clear();
ALOGW("Mcu service died!");
}
};
sp<DeathNotifier> gDeathNotifier;
};
/* 用于获取 "media.mcu" 的服务 */
const sp<IMcuService>& Mcu::getMcuService()
{
Mutex::Autolock _l(gLock);
if (gMcuService.get() == 0) {
//IServiceManager对象,即获取ServiceManager的代理对象
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
//获取名为kMcuServiceName = "media.mcu" 的服务
binder = sm->getService(String16(kMcuServiceName));
if (binder != 0) {
break;
}
ALOGW("McuService not published, waiting...");
usleep(kMcuServicePollDelay);
} while(true);
if (gDeathNotifier == NULL) {
//创建死亡通知对象 gDeathNotifier
gDeathNotifier = new DeathNotifier();
}
//将死亡通知连接到binder
binder->linkToDeath(gDeathNotifier);
gMcuService = interface_cast<IMcuService>(binder);
}
ALOGE_IF(gMcuService == 0, "no McuService!?");
return gMcuService;
}
/*用于请求服务接口,并且发送 ATTACH 请求
0 获取 "media.mcu" 的服务
1 传递参数 mcu_handle_t handle => class Mcu :: mcu_handle_t mHandle
2 传递参数 McuCallback callback => class Mcu :: sp<McuCallback> mCallback
3 获取目标服务的接口,并调用该接口的attach()功能。即获取 McuService.cpp中注册的"media.mcu"服务(McuService),并且调用McuService::attach()函数
工作 :绑定 service进程(本地对象)与client进程(代理对象),初始化 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息。
1 初始化 class McuService :: class ModuleClient ::mcu_handle_t mHandle = handle
2 初始化 class McuService :: class ModuleClient :: sp<IMcuClient> mClient = mcu
3 初始化 mcu->mIMcu = class McuService :: class ModuleClient moduleClient
*/
sp<Mcu> Mcu::attach(mcu_handle_t handle,const sp<McuCallback>& callback)
{
ALOGV("attach()");
sp<Mcu> mcu;
const sp<IMcuService>& service = getMcuService();//获取 "media.mcu" 的服务
if (service == 0) {
return mcu;
}
mcu = new Mcu(handle,callback);//初始化 mHandle、mCallback 成员变量
status_t status = service->attach(handle,mcu, mcu->mIMcu);//获取目标服务的接口,并向该服务发出 ATTACH 请求
if (status == NO_ERROR && mcu->mIMcu != 0) {
IInterface::asBinder(mcu->mIMcu)->linkToDeath(mcu);
} else {
ALOGW("Error %d connecting to mcu service", status);
mcu.clear();
}
return mcu;
}
/* // Mcu 带参构造函数 目前工作只是初始化 mHandle、mCallback 成员变量
初始化 const mcu_handle_t mHandle = handle
初始化 sp<McuCallback> mCallback = callback
*/
Mcu::Mcu(mcu_handle_t handle, const sp<McuCallback>& callback)
: mHandle(handle), mCallback(callback)
{
}
第五步 实现JNI,打通Android上层服务接口通道
0 JNI实现本地方法 android_server_Mcu_setup() 对应 native_setup()
0 该方法内部调用 Mcu::attach() 获取 服务 "media.mcu"
1 实现JNI 本地方法
1 JNI实现本地方法 对应 native_finalize()
2 JNI实现本地方法 对应 native_get_mcu_Version()
3 JNI实现本地方法 对应 native_get_mcu_Time()
4 JNI实现本地方法 对应 native_setPowerState()
5 JNI实现本地方法 对应 native_startUpdate()
6 JNI实现本地方法 对应 native_stopUpdate()
2 注册JNI
frameworks/base/services/core/jni/com_android_server_mcu_McuManagerService.cpp
…
…
// JNI实现本地方法 对应 native_setup()
static void android_server_Mcu_setup(JNIEnv *env, jobject thiz,jobject serviceObj)
{
......
/*
调用 Mcu::attach()
*/
sp<Mcu> mcu = Mcu::attach(handle,callback);
}
/*
1 JNI实现本地方法 对应 native_finalize()
2 JNI实现本地方法 对应 native_get_mcu_Version()
3 JNI实现本地方法 对应 native_get_mcu_Time()
4 JNI实现本地方法 对应 native_setPowerState()
5 JNI实现本地方法 对应 native_startUpdate()
6 JNI实现本地方法 对应 native_stopUpdate()
*/
//Java 本地接口方法表
static JNINativeMethod gMethods[] = {
{"native_setup", "(Ljava/lang/Object;)V", (void *)android_server_Mcu_setup},
{"native_finalize", "()V", (void *)android_server_Mcu_finalize},
{"native_get_mcu_Version", "(I)Ljava/lang/String;", (void *)android_server_Mcu_getVersion},
{"native_get_mcu_Time","(I)Ljava/lang/String;", (void *)android_server_Mcu_getTime},
{"native_setPowerState","(I)I", (void *)android_server_Mcu_setPowerState},
{"native_startUpdate","(I)I",(void *)android_server_Mcu_startUpdate},
{"native_stopUpdate","(I)I",(void *)android_server_Mcu_stopUpdate},
};
//注册java本地接口方法
int register_android_server_mcu(JNIEnv *env)
{
......
}
第六步 Android上层硬件访服务
frameworks/base/services/core/java/com/android/server/mcu/McuManagerService.java
public final class McuManagerService extends SystemService {
/*构造*/
public McuManagerService(Context context) {
......
/*
对应于 JNI: android_server_Mcu_setup(),获取服务 "media.mcu"
*/
native_setup(this);
......
}
......
private native void native_setup(Object manager_this);
private native void native_finalize();
private native String native_get_mcu_Version(int type);
private native String native_get_mcu_Time(int type);
private native int native_setPowerState(int type);
private native int native_startUpdate(int type);
private native int native_stopUpdate(int type);
}
第七步 : 启动服务 McuManagerService
SystemServer.java
import com.android.server.mcu.McuManagerService;
boolean isMcuServer = SystemProperties.get("ro.mcu.server").equals("1");
if(isMcuServer)
{
mSystemServiceManager.startService(McuManagerService.class);
}
二 服务打开过程梳理
1 打开 mcu串口服务McuManagerService.java
mcu串口服务
frameworks/base/services/core/java/com/android/server/mcu/McuManagerService.java
public final class McuManagerService extends SystemService {
private static final String TAG = "McuManagerService";
...
/*构造*/
public McuManagerService(Context context) {
...
native_setup(this);
...
}
......
private native void native_setup(Object manager_this);
private native void native_finalize();
private native String native_get_mcu_Version(int type);
private native String native_get_mcu_Time(int type);
private native int native_setPowerState(int type);
private native int native_startUpdate(int type);
private native int native_stopUpdate(int type);
}
2 开mcu串口服务JNI
......
......
// JNI实现本地方法 对应 native_setup()
static void android_server_Mcu_setup(JNIEnv *env, jobject thiz,jobject serviceObj)
{
......
/*
调用 Mcu::attach()
*/
sp<Mcu> mcu = Mcu::attach(handle,callback);
}
/*
1 JNI实现本地方法 对应 native_finalize()
2 JNI实现本地方法 对应 native_get_mcu_Version()
3 JNI实现本地方法 对应 native_get_mcu_Time()
4 JNI实现本地方法 对应 native_setPowerState()
5 JNI实现本地方法 对应 native_startUpdate()
6 JNI实现本地方法 对应 native_stopUpdate()
*/
//Java 本地接口方法表
static JNINativeMethod gMethods[] = {
{"native_setup", "(Ljava/lang/Object;)V", (void *)android_server_Mcu_setup},
{"native_finalize", "()V", (void *)android_server_Mcu_finalize},
{"native_get_mcu_Version", "(I)Ljava/lang/String;", (void *)android_server_Mcu_getVersion},
{"native_get_mcu_Time","(I)Ljava/lang/String;", (void *)android_server_Mcu_getTime},
{"native_setPowerState","(I)I", (void *)android_server_Mcu_setPowerState},
{"native_startUpdate","(I)I",(void *)android_server_Mcu_startUpdate},
{"native_stopUpdate","(I)I",(void *)android_server_Mcu_stopUpdate},
};
//注册java本地接口方法
int register_android_server_mcu(JNIEnv *env)
{
......
}
3 调用 Mcu::attach()
frameworks/av/mcu/Mcu.cpp
调用 Mcu::attach(),看代码可以知道,Mcu::attach()其实就是连接到 本地服务 McuService
......
/* 用于获取 "media.mcu" 的服务 */
const sp<IMcuService>& Mcu::getMcuService()
{
Mutex::Autolock _l(gLock);
if (gMcuService.get() == 0) {
//IServiceManager对象,即获取ServiceManager的代理对象
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
//获取名为kMcuServiceName = "media.mcu" 的服务
binder = sm->getService(String16(kMcuServiceName));
if (binder != 0) {
break;
}
ALOGW("McuService not published, waiting...");
usleep(kMcuServicePollDelay);
} while(true);
if (gDeathNotifier == NULL) {
//创建死亡通知对象 gDeathNotifier
gDeathNotifier = new DeathNotifier();
}
//将死亡通知连接到binder
binder->linkToDeath(gDeathNotifier);
gMcuService = interface_cast<IMcuService>(binder);
}
ALOGE_IF(gMcuService == 0, "no McuService!?");
return gMcuService;
}
/*用于请求服务接口,并且发送 ATTACH 请求
0 获取 "media.mcu" 的服务
1 传递参数 mcu_handle_t handle => class Mcu :: mcu_handle_t mHandle
2 传递参数 McuCallback callback => class Mcu :: sp<McuCallback> mCallback
3 获取目标服务的接口,并调用该接口的attach()功能。即获取 McuService.cpp中注册的"media.mcu"服务(McuService),并且调用McuService::attach()函数
工作 :绑定 service进程(本地对象)与client进程(代理对象),初始化 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息。
1 初始化 class McuService :: class ModuleClient ::mcu_handle_t mHandle = handle
2 初始化 class McuService :: class ModuleClient :: sp<IMcuClient> mClient = mcu
3 初始化 mcu->mIMcu = class McuService :: class ModuleClient moduleClient
*/
sp<Mcu> Mcu::attach(mcu_handle_t handle,const sp<McuCallback>& callback)
{
ALOGV("attach()");
sp<Mcu> mcu;
const sp<IMcuService>& service = getMcuService();//获取 "media.mcu" 的服务
if (service == 0) {
return mcu;
}
mcu = new Mcu(handle,callback);//初始化 mHandle、mCallback 成员变量
status_t status = service->attach(handle,mcu, mcu->mIMcu);//获取目标服务的接口,并向该服务发出 ATTACH 请求
if (status == NO_ERROR && mcu->mIMcu != 0) {
IInterface::asBinder(mcu->mIMcu)->linkToDeath(mcu);
} else {
ALOGW("Error %d connecting to mcu service", status);
mcu.clear();
}
return mcu;
}
// Mcu 带参构造函数 目前工作只是初始化 mHandle、mCallback 成员变量
/*
初始化 const mcu_handle_t mHandle = handle
初始化 sp<McuCallback> mCallback = callback
*/
Mcu::Mcu(mcu_handle_t handle, const sp<McuCallback>& callback)
: mHandle(handle), mCallback(callback)
{
}
4 调用 McuService::attach()
mcu专用串口本地服务
frameworks/av/services/mcuservice/McuService.cpp
调用 McuService::attach(),看代码可以知道就是 绑定 service进程(本地对象)与client进程(代理对象),初始化 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息。
/*
当McuService类被引用的时候 就会调用McuService::onFirstRef() 打开串口,具体操作在 av/services/mcuservice/UartComm2.cpp 中实现
*/
void McuService::onFirstRef()
{
ALOGD("McuService::onFirstRef");
......
mCommInterface = new UartComm2("/dev/ttyS3");//构造函数 传递取目标字符串:"/dev/ttyS3"
mCommInterface->openInterface();//打开目标串口"/dev/ttyS3" ,并且设置波特率
......
mUpdateThread = NULL;
}
void McuService::instantiate()
{
ALOGV("McuService::instantiate");
/*
首先通过 defaultServiceManager()获取一个 ServiceManager类对象,利用该类的addService()方法,将 McuService服务 注册到 Service Manager中,并且命名为 "media.mcu"
这样Client进程就可以通过名称 "media.mcu" 来获取这个McuService服务的一个代理对象了
*/
defaultServiceManager()->addService(String16("media.mcu"), new McuService());
}
/*工作 :绑定 service进程(本地对象)与client进程(代理对象),初始化 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息。
1 初始化 class McuService :: class ModuleClient ::mcu_handle_t mHandle = handle
2 初始化 class McuService :: class ModuleClient :: sp<IMcuClient> mClient = class IMcuClient client
3 初始化 mcu = class McuService :: class ModuleClient moduleClient
4 初始化 class McuService :: class ModuleClient::sp<McuService> mMcuService = this
5 向动态数组 ModuleClient mModuleClients[] 中添加 moduleClient 对象
6 初始化传递进来的 IMcu类 mcu对象 为 class McuService :: class ModuleClient moduleClient
*/
status_t McuService::attach(mcu_handle_t handle,const sp<IMcuClient>& client,sp<IMcu>& mcu)
{
ALOGV("%s handle: %d", __FUNCTION__,handle);
size_t i;
sp<ModuleClient> moduleClient;//ModuleClient类对象
AutoMutex lock(mServiceLock);
mcu.clear();
if (client == 0) {
return BAD_VALUE;
}
for (i = 0; i < mModuleClients.size(); i++) {
/* ModuleClient类对象 mModuleClients,client()方法返回 IMcuClient接口 mClient对象 */
if (mModuleClients[i]->client() == client) {
// client already connected: reject
mcu = NULL;
return ALREADY_EXISTS;
}
}
//ModuleClient类构造函数 : McuService::ModuleClient::ModuleClient() ,创建 对象 moduleClient
/*
初始化 McuService类 mMcuService对象为 mcuService
class McuService :: class ModuleClient::sp<McuService> mMcuService;
初始化 IMcuClient类接口 mClient 对象为 client
class McuService :: class ModuleClient :: sp<IMcuClient> mClient;
初始化 mcu_handle_t mHandle = handle
class McuService :: class ModuleClient ::mcu_handle_t mHandle;
*/
moduleClient = new ModuleClient(this, client,handle);
if(moduleClient != 0)
{
//向动态数组 ModuleClient mModuleClients[] 中添加 moduleClient 对象?
mModuleClients.add(moduleClient);
//初始化传递进来的 IMcu类 mcu对象 为 moduleClient
mcu = moduleClient;
}
else
{
return NO_INIT;
}
return NO_ERROR;
}
......
//ModuleClient类构造函数 :
/*
初始化 McuService类 mMcuService对象为 mcuService
class McuService :: class ModuleClient::sp<McuService> mMcuService;
初始化 IMcuClient类接口 mClient 对象为 client
class McuService :: class ModuleClient :: sp<IMcuClient> mClient;
初始化 mcu_handle_t mHandle = handle
class McuService :: class ModuleClient ::mcu_handle_t mHandle;
*/
McuService::ModuleClient::ModuleClient(const sp<McuService>& mcuService,const sp<IMcuClient>& client,mcu_handle_t handle)
: mMcuService(mcuService), mClient(client), mHandle(handle)
{
}
......
这样就弄清了 上层服务到frameworks本地服务的流数据。那么是什么时候注册frameworks本地服务到 service manager的呢?
frameworks/av/services/mcuservice/main_mcuservice.cpp
int main(int argc, char** argv){
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
McuService::instantiate();//注册 McuService 服务
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
三 总结
四 头文件笔记
class IMcuService : public IInterface
class IMcuClient : public IInterface
class IMcu : public IInterface
本地服务
class BnMcuService: public BnInterface<IMcuService>
onTransact()
class BnMcuClient : public BnInterface<IMcuClient>
onTransact()
class BnMcu: public BnInterface<IMcu>
onTransact()
服务类
class McuService : public BnMcuService
//记录与当前服务(本地对象)连接的 客户进程(代理对象)信息
class ModuleClient : public BnMcu
class Mcu : public BnMcuClient
sp<IMcu> mIMcu;
const mcu_handle_t mHandle;
sp<McuCallback> mCallback;
**********************************************************************************************************
framework/av/include/mcu/IMcuService.h
class IMcu;
class IMcuClient;
/* 定义硬件服务接口 IMcuService */
class IMcuService : public IInterface
{
public:
mcu_metadata_t *test;
/* DECLARE_META_INTERFACE(McuService); 声明 IMcuService 类的元接口
1. 为 IMcuService 类定义了一个静态成员变量 descriptor,用来描述接口名称,可以通过成员函数getInterfaceDescriptor()来获取。
2. 同时定义了一个静态成员函数 asInterface(),用来讲一个 IBinder对象装换为一个IMcuService接口。
3. 最后定义了其他接口操作函数
*/
DECLARE_META_INTERFACE(McuService);
virtual status_t attach(mcu_handle_t handle,const sp<IMcuClient>& client,sp<IMcu>& mcu) = 0;
virtual String8 getVersion(int type) = 0;
virtual String8 getTime(int type) = 0;
virtual int setPowerState(int state)= 0;
virtual int startUpdate(int state)= 0;
virtual int stopUpdate(int state)= 0;
};
/*
* 定义了一个 Binder 本地对象类 BnMcuService,它实现了模板类 BnInterface的成员函数 onTransact。
*/
class BnMcuService: public BnInterface<IMcuService>
{
public:
/*
* 成员函数 onTransact 是虚函数,它是由 BBinder 的子类,即 Binder本地对象类来实现的,他负责分发与业务相关的进程间通
* 信请求。事实上,与业务相关的进程间通信请求是由Binder本地对象类的子类,即Service组件来负责处理的。
*/
virtual status_t onTransact( uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags = 0);
};
---------------------------------------------------------------------------------------------------------
framework/av/include/mcu/IMcuClient.h
/* 定义硬件服务接口 IMcuClient */
class IMcuClient : public IInterface
{
public:
/* DECLARE_META_INTERFACE(McuClient); 声明 IMcuClient类的元接口
1. 为 IMcuClient 类定义了一个静态成员变量 descriptor,用来描述接口名称,可以通过成员函数getInterfaceDescriptor()来获取。
2. 同时定义了一个静态成员函数 asInterface(),用来讲一个 IBinder对象装换为一个IMcuClient接口。
3. 最后定义了其他接口操作函数
*/
DECLARE_META_INTERFACE(McuClient);
virtual void onEvent(const sp<IMemory>& eventMemory) = 0;
};
/*定义一个Binder 本地对象 BnMcuClient */
class BnMcuClient : public BnInterface<IMcuClient>
{
public:
virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
};
--------------------------------------------------------------------------------------------------------------------
frameworks/av/include/mcu/Mcu.h
class Mcu : public BnMcuClient, public IBinder::DeathRecipient
{
public:
virtual ~Mcu();
static sp<Mcu> attach(mcu_handle_t handle,const sp<McuCallback>& callback);
static const sp<IMcuService>& getMcuService(); //用于获取 "media.mcu" 的服务
void detach()
virtual void onEvent(const sp<IMemory>& eventMemory); // BpMcuClient
virtual void binderDied(const wp<IBinder>& who); //IBinder::DeathRecipient
private:
Mcu(mcu_handle_t handle,const sp<McuCallback>&);
Mutex mLock;
sp<IMcu> mIMcu;
const mcu_handle_t mHandle;
sp<McuCallback> mCallback;
};
---------------------------------------------------------------------------------------------------------------------
frameworks/av/include/mcu/McuCallback.h
class McuCallback : public RefBase
{
public:
McuCallback() {}
virtual ~McuCallback() {}
virtual void onEvent(struct mcu_event *event) = 0;
};
------------------------------------------------------------------------------------------------------------------------
frameworks/av/include/mcu/IMcu.h
//接口
class IMcu : public IInterface
{
public:
DECLARE_META_INTERFACE(Mcu);//声明 IMcu 接口
virtual void detach() = 0;
};
//本地对象 BnMcu 负责分发与业务相关的进程间通
class BnMcu: public BnInterface<IMcu>
{
public:
virtual status_t onTransact( uint32_t code,const Parcel& data,Parcel* reply, uint32_t flags = 0);
};
------------------------------------------------------------------------------------------------------------------------
frameworks/av/services/mcuservice/UartComm2.h
public:
UartComm2(char *name);//构造函数 获取目标字符串:"/dev/ttyS3"
virtual ~UartComm2();
void setName(char *name);
virtual void init();
virtual int writeData(unsigned int length,unsigned char *buffer);
virtual int readData(unsigned int length,unsigned char *buffer);
virtual int openInterface();//打开目标串口,并且设置波特率
virtual int closeInterface();
virtual int enableDebug(int enable);
bool setParameter(unsigned int speed, int size, int parity, int stop);
bool getParameter(unsigned int *speed, int *size, int *parity, int *stop);
private:
int mEnableDebug;
int mCommFd;
char mName[NAME_LEN];//存放目标字符串:"/dev/ttyS3"
};
------------------------------------------------------------------------------------------------------------------------
frameworks/av/services/mcuservice/McuService.h
// 继承 BnMcuService ,实现BnMcuService没有实现的方法
class McuService : public BinderService<McuService>, public BnMcuService
{
friend class BinderService<McuService>;
public:
class ModuleClient;
static char const* getServiceName() { return "media.mcu"; }
static void instantiate(); //注册McuService服务到 Service Manage 中,并将服务名称命名为"media.mcu"。
McuService();
virtual ~McuService();
// IMcuService
virtual status_t attach(mcu_handle_t handle, const sp<IMcuClient>& client,sp<IMcu>& mcu);
virtual String8 getVersion(int type);
virtual String8 getTime(int type);
virtual int setPowerState(int state );
virtual int startUpdate(int status);
virtual int stopUpdate(int status);
virtual status_t dump(int fd, const Vector<String16>& args);
void onCallbackEvent(const sp<IMemory>& event);
void removeClient(sp<ModuleClient> client);
int isFileExist(const char *pathFile);
void heartBeat();
......
/* 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息 */
class ModuleClient : public BnMcu, public IBinder::DeathRecipient {
public:
ModuleClient(const sp<McuService>& mcuService,const sp<IMcuClient>& client,mcu_handle_t handle);
virtual ~ModuleClient();
// IMcu
virtual void detach();
virtual status_t dump(int fd, const Vector<String16>& args);
sp<IMcuClient> client() const { return mClient; }//返回 mClient
void onCallbackEvent(const sp<IMemory>& event);
virtual void onFirstRef();//该类第一次被引用是调用
// IBinder::DeathRecipient implementation
virtual void binderDied(const wp<IBinder> &who);
private:
mutable Mutex mLock; // protects mClient, mConfig and mTuner
sp<McuService> mMcuService;
/*
IMcuClient 类 : 硬件服务接口 class IMcuClient : public IInterface
event callback binder interface
*/
sp<IMcuClient> mClient;
mcu_handle_t mHandle;
};
sp<CallbackThread> getCallbackThread() const { return mCallbackThread; }
int handleFrameData(FrameData *frame);
static void callback(mcu_event_t *halEvent, void *cookie);
private:
virtual void onFirstRef();
int sendCallbackEvent(FrameData *frame);
int mcuEventMonitor(int fd,const Vector<String16> &args);
void sendCMD(int cmd);
void sendCMD(int cmd,int length,unsigned char *data);
FrameData sendCMDWait(int cmd,int length,unsigned char *data,int second);
FrameData sendCMDWait(int cmd);
int setBackLightValue(int value);
int openBackLight(void);
int closeBackLight(void);
int setNextFuncState(int state,int cmd);
Mutex mServiceLock; // protects mModules
Vector< sp<ModuleClient> > mModuleClients;//动态数组,声明一个动态数组 ModuleClient mModuleClients[]
sp<CallbackThread> mCallbackThread; // event callback thread
sp<ReadThread> mReadThread; // read data thread
sp<HeartbeatThread> mHearbeatThread;
sp<UpdateThread>mUpdateThread;
sp<CommunicationInterface> mCommInterface;
pthread_mutex_t mDataMutex;
pthread_cond_t mDataCond;
int mFuncState;
FrameData mFrameData;
};
------------------------------------------------------------------------------------------------------------------------