android2.3 --- Service Manager分析
Android系统Binder机制的总管是Service Manager,所有的Server(System Server)都需要向他注册,应用程序需要向其查询相应的服务。可见其作用是多么的重要,那么我们这里就要重点介绍一下这个。
这里以java层加入ServiceManager及getService为数据流分析一下。
复习一下典型的Binder模式,有利于后面的理解:
1、客户端通过某种方式得到服务器端的代理对象。从客户端角度看来代理对象和他的本地对象没有什么差别。它可以像其他本地对象一样调用其方法,访问其变量。
2、客户端通过调用服务器代理对象的方法向服务器端发送请求。
3、代理对象把用户请求通过Android内核(Linux内核)的Binder驱动发送到服务器进程。
4、服务器进程处理用户请求,并通过Android内核(Linux内核)的Binder驱动返回处理结果给客户端的服务器代理对象。
5、客户端收到服务器端的返回结果。
JAVA层代码分析:
ServiceManager.java (frameworks\base\core\java\android\os)
对于xxxManager获取服务端service基本如此用法:
利用ContextImpl.java中的
public Object getSystemService(String name)
然后再调用:
ServiceManager.getService(ServiceName);
获取相应的服务端
ex:
@Override
public Object getSystemService(String name) {
if (WIFI_SERVICE.equals(name)) {
return getWifiManager();
}
-->
private WifiManager getWifiManager()
{
synchronized (sSync) {
if (sWifiManager == null) {
IBinder b = ServiceManager.getService(WIFI_SERVICE);
IWifiManager service = IWifiManager.Stub.asInterface(b);
sWifiManager = new WifiManager(service, mMainThread.getHandler());
}
}
return sWifiManager;
}
ok,知道了客户端获取一个Service的方法之后,我们回到ServiceManager的服务端:
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
BinderInternal.getContextObject() @ BinderInternal.java 是一个native 函数:
android_os_BinderInternal_getContextObject @ android_util_Binder.cpp
返回一个 BinderProxy对象保存到类成员mRemote(ServiceManagerProxy类成员)
public abstract class ServiceManagerNative extends Binder implements IServiceManager
ServiceManagerNative 继承自 Binder 并实现了 IServiceManager 接口,利用 asInterface()则提供一个 ServiceManagerProxy 代理对象使用
class ServiceManagerProxy implements IServiceManager
定义了类ServiceManagerProxy(代理),ServiceManagerProxy继承自IServiceManager,并实现了其声明的操作函数,只会被ServiceManagerNative创建,它实现了IServiceManager的接口,IServiceManager提供了getService和addService两个成员函数来管理系统中的Service。
ok,我们沿着代码继续往前走:
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote; // 这是一个BinderProxy对象
}
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
}
上层先利用Parcel对象将数据进行序列化,然后利用transact将数据传给binder驱动,根据 mRemote 是一个 BpBinder 对象继续追踪:
JNI层代码分析:android_util_Binder.cpp
java 层通过 Binder 对象调用jni函数:
Binder.java: Binder实现的IBinder的接口,他的大部分函数都是通过JNI调用底层实现的BinderProxy是JAVA层的关键类,在JNI通过 gBinderProxyOffsets 来使用
这里只关心它的 onTransact 函数即可
BpBinder 在 BpBinder.h 实现:
class BpBinder : public IBinder
{
virtual status_t transact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
}
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) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
3、C++ native层实现 service操作实现,其实java层的直接利用jni写入到binder驱动层了:
IServiceManager.cpp (frameworks\base\libs\binder)
class BpServiceManager : public BpInterface<IServiceManager>
{
public:
// 获取Service服务端
virtual sp<IBinder> getService(const String16& name) const
{
unsigned n;
for (n = 0; n < 5; n++){
sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
LOGI("Waiting for service %s...\n", String8(name).string());
sleep(1);
}
return NULL;
}
// 添加Service到ServiceManager管理器
virtual status_t addService(const String16& name, const sp<IBinder>& service)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
}
到了这里:
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
// ----------------------------------------------------------------------
status_t BnServiceManager::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
一般都以为服务端继承BnServiceManager类实现即可:
ServiceManager.h (frameworks\base\cmds\runtime)
class BServiceManager : public BnServiceManager
其实这里不是的,这是在模拟器上的实现方法,请看其下面的Android.mk文件:
ifeq ($(TARGET_SIMULATOR),true)
...
include $(BUILD_EXECUTABLE)
endif
那么这里到底是怎么回事呢?JAVA层利用jni也是如此操作的。
这里是通过 IPCThreadState 类直接将binder请求写入到binder驱动(/dev/binder),这里简要说一下简单的流程,后续还会继续深入这个问题:
addService @ IServiceManager.cpp
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
-->
transact @ IPCThreadState
transact() --> writeTransactionData() 写入到binder驱动,这就是核心所在。。。
现在就进入到最重要的 servicemanager 大总管角色中了
源码路径:frameworks\base\cmds\servicemanager\service_manager.c
servicemanager 是一个进程,在init.rc脚本中开机就启动:
service servicemanager /system/bin/servicemanager
user system
critical
onrestart restart zygote
onrestart restart media
从其main中开始分析:
main @ service_manager.c
int main(int argc, char **argv)
{
struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER;
bs = binder_open(128*1024);
if (binder_become_context_manager(bs)) {
LOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
svcmgr_handle = svcmgr;
binder_loop(bs, svcmgr_handler);
return 0;
}
调用binder_open打开binder设备(/dev/binder),其次它调用了binder_become_context_manager函数,这个函数使他自己变为了"Server大总管"
int binder_become_context_manager(struct binder_state *bs)
{
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
即成为一个0号句柄,所有的进程都可以通过id=0来访问它。
Service Manager作为一个Server大总管,本身也是一个server。既然是一个server就要时刻准备为客户端提供服务。最好Service Manager调用binder_loop进入到循环状态,并提供了一个回调函数,等待用户的请求。注意他的Service Manager的客户端既包括应用程序(查询和获取服务),也包括Server(注册服务)。
只要server向binder设备写入请求注册Service时,Service Manager的服务处理回调函数将会被调用
这里的回调函数就是 svcmgr_handler:
int svcmgr_handler(struct binder_state *bs,
struct binder_txn *txn,
struct binder_io *msg,
struct binder_io *reply)
{
// 获取请求数据
strict_policy = bio_get_uint32(msg);
s = bio_get_string16(msg, &len);
switch(txn->code) {
case SVC_MGR_GET_SERVICE: // 获取service服务
case SVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);
ptr = do_find_service(bs, s, len);
if (!ptr)
break;
bio_put_ref(reply, ptr);
return 0;
case SVC_MGR_ADD_SERVICE: // 注册service服务
s = bio_get_string16(msg, &len);
ptr = bio_get_ref(msg);
if (do_add_service(bs, s, len, ptr, txn->sender_euid))
return -1;
break;
case SVC_MGR_LIST_SERVICES: { // 列举service服务
unsigned n = bio_get_uint32(msg);
si = svclist;
while ((n-- > 0) && si)
si = si->next;
if (si) {
bio_put_string16(reply, si->name);
return 0;
}
return -1;
}
}
这里也是对请求的服务回写到binder驱动,别忘记了客户端同步处理:
transact @ IPCThreadState.cpp
if ((flags & TF_ONE_WAY) == 0) {
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
} else {
err = waitForResponse(NULL, NULL);
}
--> 这里利用talkWithDriver()利用:
ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) 请求与回应数据。
IPCThreadState 是一个非常关键的类,由其直接于binder驱动打交道,后文将会重点分析。
模块层次基本如下:
相关推荐
根据提供的信息,“HP Service Manager history”这一主题主要围绕着HP Service Manager(HP SM)的发展历程进行探讨。HP Service Manager是一款由惠普公司开发的企业级IT服务管理软件,它旨在帮助企业组织管理和...
### Microsoft System Center 2012 Service Manager Cookbook #### 知识点概览 - **基础知识**:了解Microsoft System Center 2012 Service Manager的基本概念、架构和组件。 - **配置与管理**:掌握如何配置和管理...
EMC存储系统是企业级数据中心的关键组成部分,而Unisphere Service Manager (USM) 是EMC VNX系列存储设备的重要维护工具。USM是一款基于Java的桌面应用,它取代了之前的Navisphere Service Taskbar (NST),专门用于...
SQL2005 Service Manager是一款专为SQL Server 2005设计的系统托盘工具,它类似于SQL Server 2000中的服务管理器,提供了直观且便捷的方式来管理和监控SQL Server实例的状态。这款工具的主要功能集中在对SQL Server ...
NSSM (Non-Sucking Service Manager) 是一个开源工具,用于将任何Windows程序打包成服务,并在启动时自动运行。NSSM是一款轻量级且易于使用的应用程序,适用于系统管理员和开发人员。 NSSM的主要功能包括: 1.将任何...
UnisphereServiceManagerLauncher-Win-32-x86-en_US-1.3.9.1.0236 EMC的管理工具。USM可以注册机器、添加更换硬件、升级软件、收集诊断日志
Service Manager 2012.pptx
Unisphere Service Manager(USM)是一个基于Java的桌面应用程序,是EMC VNX中端产品系列维护的重要工具之一,主要用途是:升级、安装和维护存储系统的硬件和软件,以前的软件叫做 Navisphere Service Taskbar,简称...
### Cisco Content Services Gateway Service Manager 4.1 产品概述与功能详解 #### 一、产品背景及概述 Cisco Content Services Gateway (CSG) Service Manager 4.1 是 CISCO 系统公司推出的一款网络管理工具,它...
SQL2005 Service Manager 桌面任务栏显示
PowerManagerService.java
5 Service Manager Generic Installer.exe
Android2.3 ActivityManagerService流程分析
IBM Tivoli Business Service Manager, 版本4.1是一款专为解决现代复杂业务服务管理问题而设计的软件。在当今的IT环境中,业务服务往往跨越多个操作孤岛,涉及不断演变的遗留技术和新兴技术。当出现服务问题时,传统...
简单的android Service组件apk可供参考学习,实现设备管理器的激活。
Unisphere Service Manager(USM)是一个基于Java的桌面应用程序,它能帮助我们升级、安装和维护存储系统的硬件和软件。支持「EMC VNX、CX4、CX3、CX」系列硬件存儲。
### Cisco Home Agent Service Manager 4.1 产品概述与关键知识点 #### 一、产品背景与定位 **Cisco Home Agent Service Manager** 是由Cisco Systems公司推出的一款专门针对移动无线网络管理的专业工具。作为...
4 Service Manager App LOB Owner Installer.exe
用于管理PHP进程(比如一些消费者...基于SWOOLE。...?... ... //this will autoload php-service-manager while(true) { file_put_contents("/tmp/logger.log", rand(1, 9) . ',', FILE_APPEND); sleep(1); }