Android Binder-ServiceManager

317 阅读4分钟

ServiceManager的作用

ServiceManager 是 Binder IPC 通信的管家,本身也是一个 Binder 服务,

内部存储了 serviceName 与其 Binder Service 的对应关系 map,管理Java层和native层的 service,

支持 addService()、getService()、checkService()、listServices()等功能。

ServiceManager 在各个层之间对应关系

C++:

aospxref.com/android-12.…

C++: AIDL

aospxref.com/android-12.…

Java:

aospxref.com/android-12.…

Java: AIDL

aospxref.com/android-12.…

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

aosp.app/android-11.…

//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

servicemanager目录

aosp.app/android-13.…

//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 序图

image.png

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 打开驱动文件

aosp.app/android-13.…

查看时序图能看到这里设置了 setContextObject

在 ProcessState 中有相对应的 getContextObject

构造方法要结合头文件一起分析

aosp.app/android-13.…

最后 servicemanager.rc 在 init 启动时的规则

aosp.app/android-13.…