ServiceManager的作用
ServiceManager 是 Binder IPC 通信的管家,本身也是一个 Binder 服务,
内部存储了 serviceName 与其 Binder Service 的对应关系 map,管理Java层和native层的 service,
支持 addService()、getService()、checkService()、listServices()等功能。
ServiceManager 在各个层之间对应关系
C++:
C++: AIDL
Java:
Java: AIDL
app 怎么拿到 SystemService
项目中使用service
(UsbManager) getSystemService(Context.USB_SERVICE);
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
(PowerManager)getSystemService(Context.POWER_SERVICE);
(LocationManager)getSystemService(Context.LOCATION_SERVICE);
(AudioManager)getSystemService(Context.AUDIO_SERVICE);
(ActivityManager) getSystemService(ACTIVITY_SERVICE);
(NsdManager)getSystemService(NsdManager::class.java);
(ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
(WindowManager)getSystemService(Context.WINDOW_SERVICE);
上下文 ContextImpl implement Context
Application 层 SystemServiceRegistry 是系统服务的注册表,用来集中管理系统服务
在 native Framework 层也有一个对应的注册表;
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
SystemServiceRegistry
//SystemServiceRegistry.java
public static Object getSystemService(ContextImpl ctx, String name) {
//根据服务名字从HashMap中取出ServiceFetcher
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
//传入上下文,借助ServiceFetcher来获取系统服务
return fetcher != null ? fetcher.getService(ctx) : null;
}
CachedServiceFetcher implement ServiceFetcher
ServiceFetcher是一个抽象接口,
抽象类 CachedServiceFetcher implement ServiceFetcher 实现了;
public final T getService(ContextImpl ctx) {
//每个上下文ctx都有一份系统服务缓存
final Object[] cache = ctx.mServiceCache;
synchronized (cache) {
//从缓存里获取系统服务
Object service = cache[mCacheIndex];
if (service == null) {
//缓存里没有,则创建
service = createService(ctx);
//存入缓存
cache[mCacheIndex] = service;
}
return (T)service;
}
}
//createService是个抽象方法
public abstract T createService(ContextImpl ctx);
createService 在 registerService 实现
//SystemServiceRegistry.java
registerService(
Context.POWER_SERVICE, PowerManager.class,
new CachedServiceFetcher<PowerManager>() {
@Override
public PowerManager createService(ContextImpl ctx){
//ServiceManager根据服务名字获取系统服务的Binder对象
IBinder b = ServiceManager.getServiceOrThrow(Context.POWER_SERVICE);
//将服务端的Binder转成客户端所需的AIDL接口类型的对象IPowerManager
IPowerManager service = IPowerManager.Stub.asInterface(b);
//再用PowerManager类包一层,方便外部使用
return new PowerManager(ctx.getOuterContext(),
service,
ctx.mMainThread.getHandler());
}});
ServieManager.getServiceOrThow()
public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
final IBinder binder = getService(name);
if (binder != null) {
return binder;
} else {
throw new ServiceNotFoundException(name);
}
}
ServiceManager.getService
//ServiceManager.java
public static IBinder getService(String name) {
//取缓存
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
//取不到就继续,这里创建完并没有存入sCache,即sCache只是预置了一些启动阶段存入的服务
//getService()获取系统服务的Binder对象,用allowBlocking包了一下,允许阻塞
return Binder.allowBlocking(getIServiceManager().getService(name));
}
return null;
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
//binder跨进程通信:
//BinderInternal.getContextObject()得到系统级别上下文的IBinder,可用来查找服务
//asInterface将IBinder转成IServiceManager(本质是BpServiceManager)
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
servicemanager/main.cpp
//framework/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
if (argc > 2) {
LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
}
const char* driver = argc == 2 ? argv[1] : "/dev/binder";
sp<ProcessState> ps = ProcessState::initWithDriver(driver);
ps->setThreadPoolMaxThreadCount(0);
ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
IPCThreadState::self()->setTheContextObject(manager);
ps->becomeContextManager(nullptr, nullptr);
sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
BinderCallback::setupTo(looper);
ClientCallbackCallback::setupTo(looper, manager);
while(true) {
looper->pollAll(-1);
}
// should not be reached
return EXIT_FAILURE;
}
servicemanager/main.cpp 序图
ProcessState 构造方法
//内存映射空间大小
#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
//最大线程池数量
#define DEFAULT_MAX_BINDER_THREADS 15
ProcessState::ProcessState(const char* driver)
: mDriverName(String8(driver)),
mDriverFD(-1),
mVMStart(MAP_FAILED),
mThreadCountLock(PTHREAD_MUTEX_INITIALIZER),
mThreadCountDecrement(PTHREAD_COND_INITIALIZER),
mExecutingThreadsCount(0),
mWaitingForThreads(0),
mMaxThreads(DEFAULT_MAX_BINDER_THREADS),
mStarvationStartTimeMs(0),
mForked(false),
mThreadPoolStarted(false),
mThreadPoolSeq(1),
mCallRestriction(CallRestriction::NONE) {
base::Result<int> opened = open_driver(driver);
if (opened.ok()) {
// mmap the binder, providing a chunk of virtual address space to receive transactions.
mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE,
opened.value(), 0);
if (mVMStart == MAP_FAILED) {
close(opened.value());
// *sigh*
opened = base::Error()
<< "Using " << driver << " failed: unable to mmap transaction memory.";
mDriverName.clear();
}
}
#ifdef __ANDROID__
LOG_ALWAYS_FATAL_IF(!opened.ok(), "Binder driver '%s' could not be opened. Terminating: %s",
driver, opened.error().message().c_str());
#endif
if (opened.ok()) {
mDriverFD = opened.value();
}
}
open_driver("/dev/binder")
static base::Result<int> open_driver(const char* driver) {
int fd = open(driver, O_RDWR | O_CLOEXEC);
if (fd < 0) {
return base::ErrnoError() << "Opening '" << driver << "' failed";
}
int vers = 0;
status_t result = ioctl(fd, BINDER_VERSION, &vers);
if (result == -1) {
close(fd);
return base::ErrnoError() << "Binder ioctl to obtain version failed";
}
if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
close(fd);
return base::Error() << "Binder driver protocol(" << vers
<< ") does not match user space protocol("
<< BINDER_CURRENT_PROTOCOL_VERSION
<< ")! ioctl() return value: " << result;
}
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
if (result == -1) {
ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
}
uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
if (result == -1) {
ALOGE_IF(ProcessState::isDriverFeatureEnabled(
ProcessState::DriverFeature::ONEWAY_SPAM_DETECTION),
"Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
}
return fd;
}
ProcessState.initWithDriver("/dev/binder")
ProcessState.initWithDriver -> ProcessState.init
sp<ProcessState> ProcessState::init(const char *driver, bool requireDefault)
{
if (driver == nullptr) {
std::lock_guard<std::mutex> l(gProcessMutex);
if (gProcess) {
verifyNotForked(gProcess->mForked);
}
return gProcess;
}
[[clang::no_destroy]] static std::once_flag gProcessOnce;
std::call_once(gProcessOnce, [&](){
if (access(driver, R_OK) == -1) {
ALOGE("Binder driver %s is unavailable. Using /dev/binder instead.", driver);
driver = "/dev/binder";
}
// we must install these before instantiating the gProcess object,
// otherwise this would race with creating it, and there could be the
// possibility of an invalid gProcess object forked by another thread
// before these are installed
int ret = pthread_atfork(ProcessState::onFork, ProcessState::parentPostFork,
ProcessState::childPostFork);
LOG_ALWAYS_FATAL_IF(ret != 0, "pthread_atfork error %s", strerror(ret));
std::lock_guard<std::mutex> l(gProcessMutex);
gProcess = sp<ProcessState>::make(driver);
});
if (requireDefault) {
// Detect if we are trying to initialize with a different driver, and
// consider that an error. ProcessState will only be initialized once above.
LOG_ALWAYS_FATAL_IF(gProcess->getDriverName() != driver,
"ProcessState was already initialized with %s,"
" can't initialize with %s.",
gProcess->getDriverName().c_str(), driver);
}
verifyNotForked(gProcess->mForked);
return gProcess;
}
open_driver 打开驱动文件
查看时序图能看到这里设置了 setContextObject
在 ProcessState 中有相对应的 getContextObject
构造方法要结合头文件一起分析