简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

1.前言
本篇目的:理解ServiceManager成员函数addService是如何添加服务的。
2.ServiceManager::addService如何添加服务实现
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
    auto ctx = mAccess->getCallingContext();
    // apps cannot add services
    if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
        return Status::fromExceptionCode(Status::EX_SECURITY);
    }
    if (!mAccess->canAdd(ctx, name)) {
        return Status::fromExceptionCode(Status::EX_SECURITY);
    }
    if (binder == nullptr) {
        return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
    }
    if (!isValidServiceName(name)) {
        LOG(ERROR) << "Invalid service name: " << name;
        return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
    }
#ifndef VENDORSERVICEMANAGER
    if (!meetsDeclarationRequirements(binder, name)) {
        // already logged
        return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
    }
#endif  // !VENDORSERVICEMANAGER
    // implicitly unlinked when the binder is removed
    if (binder->remoteBinder() != nullptr &&
        binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
        LOG(ERROR) << "Could not linkToDeath when adding " << name;
        return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
    }
    // Overwrite the old service if it exists
    mNameToService[name] = Service {
        .binder = binder,
        .allowIsolated = allowIsolated,
        .dumpPriority = dumpPriority,
        .debugPid = ctx.debugPid,
    };
    auto it = mNameToRegistrationCallback.find(name);
    if (it != mNameToRegistrationCallback.end()) {
        for (const sp<IServiceCallback>& cb : it->second) {
            mNameToService[name].guaranteeClient = true;
            // permission checked in registerForNotifications
            cb->onRegistration(name, binder);
        }
    }
    return Status::ok();
}
<1>.关键点
mNameToService[name] = Service {
.binder = binder,
.allowIsolated = allowIsolated,
.dumpPriority = dumpPriority,
.debugPid = ctx.debugPid,
};
<2>.注释
其中name表示服务名,binder表示每个服务的实例对象,将他们存放在mNameToService里面,那么mNameToService是什么类型呢?接着往下看
<3>.mNameToService定义
# ServiceManager.h
struct Service {
        sp<IBinder> binder; // not null
        bool allowIsolated;
        int32_t dumpPriority;
        bool hasClients = false; // notifications sent on true -> false.
        bool guaranteeClient = false; // forces the client check to true
        pid_t debugPid = 0; // the process in which this service runs
        // the number of clients of the service, including servicemanager itself
        ssize_t getNodeStrongRefCount();
    };
using ServiceMap = std::map<std::string, Service>;
ServiceMap mNameToService;
  由以上代码可以看到mNameToService的类型是ServiceMap,ServiceMap又是std::map<std::string, Service>的别名,它是一个C++的STL的map容器,第一个参数是key,第二个是value。
  第一个参数的类型是string,第二个是Service类。
<4>.再看mNameToService[name]
mNameToService[name] = Service {
        .binder = binder,
        .allowIsolated = allowIsolated,
        .dumpPriority = dumpPriority,
        .debugPid = ctx.debugPid,
    };
我们再看上边表达式初始化,将类Service的所有成员变量插入到map容器,对应的key就是name,Service的成员变量包括.binder(表示服务类对象),dumpPriority(表示优先级)。
3.addService应用实例
#include <cstdio>
#include <iostream>
#include <typeinfo>
#include <map>
using namespace std;
class Binder{
};
//struct Service {
class Service {
public:
  Binder *binder;
  bool allowIsolated;
  int32_t dumpPriority;
  bool hasClients = false;
  bool guaranteeClient = false;
  pid_t pid = 0;
  ssize_t getNodeStrongRefCount();
};
//using设置别名:ServiceMap;容器map第一个参数是key,第二个是value;value为Service,Service又是一个类,包含变量和函数.
using ServiceMap = map<string, Service>;
ServiceMap mNameToService;
int main(){
  Binder *binder1 = new Binder;
  string name = "manager";
  mNameToService[name] = Service {
    .binder = binder1,
    .allowIsolated = false,
    .dumpPriority = 20,
    .guaranteeClient = true,
    .pid = 10,
  };
  string name_01 = "camera";
  Binder *binder2 = new Binder;
  mNameToService[name_01] = Service {
    .binder = binder2,
    .allowIsolated = false,
    .dumpPriority = 24,
    .guaranteeClient = false,
    .pid = 11,
  };
  //first:表示key的值;second:表示value的值,即Service.
  for(const auto& pair : mNameToService) {
    printf("xxx-------->line = %d, first_name = %s, priority = %d, pid = %d\n",__LINE__,pair.first.c_str(), pair.second.dumpPriority,pair.second.pid);
  }
}
打印:
xxx-------->line = 51, first_name = camera, priority = 24, pid = 11
xxx-------->line = 51, first_name = manager, priority = 20, pid = 10
4.总结
ServiceManager调用addService注册服务类,本质是将服务名+服务的对象插入到C++的map容器中,Client使用的时候,可以从map容器中获取就可以了。



















