Android源码分析:ServiceManager 红狼博客

服务的添加和获取

系统中的各种service如,surfaceflingeraudioflingerCameraService等通过defaultServiceManager()获取ServiceManager的一个binder,然后再调用其AddService向系统添加一个服务,调用GetService来获取服务。

IServiceManager提供了下面这些API

GetService//通过字符串名称获取service
CheckService//
通过字符串名称检查service并返回它
AddService//
向系统注册添加一个service
ListServices//
列出所有services

管理这些服务的就在servicemanager进程中。它的代码存在于目录frameworks/base/cmds/servicemanager,主要包含两个文件service_manager.cbinder.c,它们最终生成的可执行二进制文件servicemanager,在系统启动时由启动脚本init.rc(见源码路径下的文件system/core/rootdir/init.rc)启动执行:

service servicemanager /system/bin/servicemanager
user system
Critical
onrestart restart zygote
onrestart restart media

 

servicemanager的实现

在它的main函数中,首先打开”/dev/binder”设备:

bs = binder_open(128*1024);

binder_open函数主要是将设备文件”/dev/binder”映射(mmap)出128KB大小到进程空间,这样,对映射后的内存空间的访问也就是对该设备文件的访问。然后完成binder_state结构体bs的初始化:

struct binder_state
{
int fd;// ”/dev/binder”
设备的描述符
void *mapped;//
映射后的进程空间的虚拟地址
unsigned mapsize;//
映射大小,128KB
};

具体的映射过程是:将文件中以0为开始位置、大小为128KB128*1024)的块(因为binder不是实际的磁盘文件,实际上为内核中的一块内存缓冲区)映射到进程空间中的内存地址,并返回之。这样,操作该内存地址时,就实际操作在文件对应的映射位置,此处实际为内核空间中的内存缓冲区。mmap调用如下:

bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);

其次,调用binder_become_context_manager(bs),实际执行的是ioctl操作,设置当前的当前的context manager进程:

ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);

它最终执行到内核中,亦即在binder.c文件中的binder_ioctl函数中的“BINDER_SET_CONTEXT_MGR” switch-case分支。该分支中的代码块,为该进程创建个一个node节点,并增加引用:

case BINDER_SET_CONTEXT_MGR:
if{…//
错误检查}
else
binder_context_mgr_uid = current_euid();
binder_context_mgr_node = binder_new_node(proc, NULL, NULL);//
创建节点
if (binder_context_mgr_node == NULL) {
ret = -ENOMEM;
goto err;
}
binder_context_mgr_node->local_weak_refs++;
binder_context_mgr_node->local_strong_refs++;
binder_context_mgr_node->has_strong_ref = 1;
binder_context_mgr_node->has_weak_ref = 1;

break;

最后,进入binder_loop循环:

binder_loop(bs, svcmgr_handler);

该循环不断检查对正在对/dev/binder读写的进程是否读完或写完数据(读写完数据后即表示要去调用,或提供服务结束之后让调用者可以返回),并遍历这些数据,让调用者等待、被调用者提供服务,或被调用者提供的服务结束、调用者应该返回。传递给binder_loop的实参svcmgr_handler是一个回调函数指针,用于注册添加service和查找枚举各种service

当有addServicegetService等请求时,将会调用svcmgr_handler去执行。

switch(txn->code) {
case
SVC_MGR_GET_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:
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: {
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;
}
default:
LOGE(“unknown code %dn”, txn->code);
return -1;
}

 

注意:注册C/C++编写的service时,有一定的限制,只有指定的才被允许注册,见文件service_manager.c的前面的列表:

/* TODO:
* These should come from a config file or perhaps be
* based on some namespace rules of some sort (media
* uid can register media.*, etc)
*/
static struct {
unsigned uid;
const char *name;
} allowed[] = {
{ AID_MEDIA, “media.audio_flinger” },
{ AID_MEDIA, “media.player” },
{ AID_MEDIA, “media.camera” },
{ AID_RADIO, “radio.phone” },
{ AID_RADIO, “radio.sms” },
{ AID_RADIO, “radio.phonesubinfo” },
{ AID_RADIO, “radio.simphonebook” },
/* TODO: remove after phone services are updated: */
{ AID_RADIO, “phone” },
{ AID_RADIO, “isms” },
{ AID_RADIO, “iphonesubinfo” },
{ AID_RADIO, “simphonebook” },
};

struct binder_write_read {
signed long write_size; /* bytes to write */
signed long write_consumed; /* bytes consumed by driver */
unsigned long write_buffer;
signed long read_size; /* bytes to read */
signed long read_consumed; /* bytes consumed by driver */
unsigned long read_buffer;
};

 

下图是IServiceManager的类继承关系图,BpServiceManagerBServiceManager未被系统使用。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BServiceManager的实现位于frameworks/base/cmds/runtime/ServiceManager.cpp

服务的启动

ZygoteInit类中的startSystemServer用于启动SystemServer。在system server中,是启动各种serviceAndroidService代码位于frameworks/base/services/下面:

frameworks/base/services$ ls

audioflinger camera java jni sensorservice surfaceflinger tests

Android系统的service包括C/C++实现的服务和Java实现的服务。用C/C++编写的service,如audioflingercamerasensorservicesurfaceflinger,有的则是Java编写,见java目录下面,详细见目录frameworks/base/services/java/com/android/server下面的各service

系统首先启动C/C++实现的服务,见frameworks/base/cmds/system_server/library/system_init.cpp中的system_init函数,它也是SystemServerinit1所执行的内容。下面是system_init函数部分代码:

char propBuf[PROPERTY_VALUE_MAX];
property_get(“system_init.startsurfaceflinger”, propBuf, “1″);
if (strcmp(propBuf, “1″) == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();//
首先启动surfaceflinger
}

// Start the sensor service
SensorService::instantiate();//
启动sensor service

// On the simulator, audioflinger et al don’t get started the
// same way as on the device, and we need to start them here
if (!proc->supportsProcesses()) {
// Start the AudioFlinger
AudioFlinger::instantiate();//
启动audio flinger

// Start the media playback service
MediaPlayerService::instantiate();//
启动媒体播放服务

// Start the camera service
CameraService::instantiate(); //
启动camera service

// Start the audio policy service
AudioPolicyService::instantiate(); //
启动audio策略服务
}

// And now start the Android runtime. We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes’s main(), before calling
// the init function.
LOGI(“System server: starting Android runtime.n”);
AndroidRuntime* runtime = AndroidRuntime::getRuntime();

LOGI(“System server: starting Android services.n”);
runtime->callStatic(“com/android/server/SystemServer”, “init2″);//
执行Java中的init2,启动Java编写的service

init2函数中,会在一个新的线程ServerThread里去启动众多的java服务,参见起run函数。

它们位于packagecom.android.server中,这些服务包括:

EntropyService 随机数服务

PowerManagerService 电源管理,如获取唤醒锁,让系统在不同等级上不睡眠等

TelephonyRegistry 通知电话状态变化

PackageManagerService 各种apk包管理器

ActivityManagerService 管理Activity

AccountManagerService 系统上的各种帐号密码管理

ContentService 文档内容,包括变化监控、同步等

BatteryService 监控电池电量、是否在充电等

LightsService LED指示灯的控制,如闪烁频率、色彩等

VibratorService 震动器,开关震动器及震动模式

AlarmManagerService 闹钟管理

WindowManagerService 窗口管理

BluetoothService 蓝牙服务,激活/去激活蓝牙,输入pin码等

BluetoothA2dpService 蓝牙A2DP音乐播放输出到蓝牙耳机服务

DevicePolicyManagerService 用于图案解锁

StatusBarManagerService 状态栏管理,如展开/收起、添加/去除提示图标等

ClipboardService 剪贴板,用于复制粘贴

InputMethodManagerService 输入法

NetStatService 网络流量统计,如发送和接收的字节数量

NetworkManagementService 网络接口卡管理,如pppdusb网卡,softAP、设置DNS等,也支持网卡流量计数

ConnectivityService 连接管理,有各种类型的连接,如WifiMMSSUPLDUN等。可使用ConnectivityManager去调用各API

ThrottleService 流量管控,可以通过ThrottleManager来限定时间、流量或带宽

AccessibilityManagerService 辅助功能

MountService 存储设备和USB插拔挂载与卸载

NotificationManagerService 状态栏通知管理

DeviceStorageMonitorService 监视磁盘空间, 若少于预设定的值如10%或小于2MB,就提示

LocationManagerService 管理位置信息

SearchManagerService 搜索服务

DropBoxManagerService 输出各种log,如应用程序崩溃、内核log等,DropBoxManager是其API

WallpaperManagerService 设置管理墙纸等,API接口是WallpaperManager

AudioService 调整各种音量,为异步操作。API操作接口在AudioManager

UsbService 监控usb状态,包括对usb host的支持

UiModeManagerService 控制ui模式,目前包括正常模式(UI_MODE_TYPE_NORMAL)、桌面模式(UI_MODE_TYPE_DESK)、车内模式(UI_MODE_TYPE_CAR)和夜间模式(UI_MODE_NIGHT_YES),其调用APIUiModeManager

BackupManagerService 应用程序的备份和恢复,接口APIBackupManager,可以使用命令行工具bmgr进行操作。详见官方文档“Data Backup”章节。

AppWidgetService 管理手机桌面上的widget,如更新、删除等

RecognitionManagerService 语音识别管理

DiskStatsService 报告磁盘状态信息

 

HeadsetObserver 监听有线耳机

DockObserver

本文链接地址: http://www.redwolf-blog.com/?p=891

原创文章,版权©红狼博客所有, 转载随意,但请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值