服务的添加和获取
系统中的各种service如,surfaceflinger、audioflinger和CameraService等通过defaultServiceManager()获取ServiceManager的一个binder,然后再调用其AddService向系统添加一个服务,调用GetService来获取服务。
IServiceManager提供了下面这些API:
GetService//通过字符串名称获取service
CheckService//通过字符串名称检查service并返回它
AddService//向系统注册添加一个service
ListServices//列出所有services
管理这些服务的就在servicemanager进程中。它的代码存在于目录frameworks/base/cmds/servicemanager下,主要包含两个文件service_manager.c和binder.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为开始位置、大小为128KB(128*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。
当有addService和getService等请求时,将会调用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的类继承关系图,BpServiceManager和BServiceManager未被系统使用。
BServiceManager的实现位于frameworks/base/cmds/runtime/ServiceManager.cpp
服务的启动
ZygoteInit类中的startSystemServer用于启动SystemServer。在system server中,是启动各种service。Android的Service代码位于frameworks/base/services/下面:
frameworks/base/services$ ls
audioflinger camera java jni sensorservice surfaceflinger tests
Android系统的service包括C/C++实现的服务和Java实现的服务。用C/C++编写的service,如audioflinger、camera、sensorservice和surfaceflinger,有的则是Java编写,见java目录下面,详细见目录frameworks/base/services/java/com/android/server下面的各service。
系统首先启动C/C++实现的服务,见frameworks/base/cmds/system_server/library/system_init.cpp中的system_init函数,它也是SystemServer中init1所执行的内容。下面是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函数。
它们位于package:com.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 网络接口卡管理,如pppd,usb网卡,softAP、设置DNS等,也支持网卡流量计数
ConnectivityService 连接管理,有各种类型的连接,如Wifi,MMS,SUPL,DUN等。可使用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),其调用API是UiModeManager。
BackupManagerService 应用程序的备份和恢复,接口API是BackupManager,可以使用命令行工具bmgr进行操作。详见官方文档“Data Backup”章节。
AppWidgetService 管理手机桌面上的widget,如更新、删除等
RecognitionManagerService 语音识别管理
DiskStatsService 报告磁盘状态信息
HeadsetObserver 监听有线耳机
DockObserver
本文链接地址: http://www.redwolf-blog.com/?p=891
原创文章,版权©红狼博客所有, 转载随意,但请注明出处。