当前位置: 首页 > news >正文

Android12 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 servicesif (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 VENDORSERVICEMANAGERif (!meetsDeclarationRequirements(binder, name)) {// already loggedreturn Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);}
#endif  // !VENDORSERVICEMANAGER// implicitly unlinked when the binder is removedif (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 existsmNameToService[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 registerForNotificationscb->onRegistration(name, binder);}}return Status::ok();
}

解读

一、函数入口与权限校验​

​​调用方身份验证​​

auto ctx = mAccess->getCallingContext();
if (multiuser_get_app_id(ctx.uid) >= AID_APP) {return Status::fromExceptionCode(Status::EX_SECURITY);
}

​​作用​​:禁止普通应用进程(UID >= AID_APP)注册系统服务。
​​底层逻辑​​:multiuser_get_app_id 提取调用方 UID 的类别,若属于应用范畴则直接拒绝,防止权限越界。
​​服务添加权限校验​​

if (!mAccess->canAdd(ctx, name)) {return Status::fromExceptionCode(Status::EX_SECURITY);
}

​​SELinux 策略​​:mAccess->canAdd 检查调用方是否拥有 add_service SELinux 权限标签(如 servicemanager.te 中定义)。
​​动态权限控制​​:例如,ActivityManagerService 需声明 MANAGE_SERVICES 权限方可注册服务。

二、参数合法性校验​​

​​服务名有效性检查​​

if (!isValidServiceName(name)) {LOG(ERROR) << "Invalid service name: " << name;return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
}

​​规则​​:服务名需满足以下条件:
非空且长度 ≤ 127 字符;
符合命名规范(如不允许特殊字符);
非系统保留名称(如 android.* 前缀可能仅限系统进程使用)。
​​服务接口声明验证​​

#ifndef VENDORSERVICEMANAGER
if (!meetsDeclarationRequirements(binder, name)) {return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
}
#endif

​​目的​​:确保服务实现了声明的 AIDL 接口(如通过 BnInterface 或 BpInterface 继承链验证)。
​​厂商定制​​:VENDORSERVICEMANAGER 宏用于区分标准 ServiceManager 与厂商定制版本,后者可能放宽接口限制。

三、服务生命周期管理​​

​​Binder 死亡回调绑定​​

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);
}

​​作用​​:当服务进程崩溃时,通过 linkToDeath 触发 ServiceManager 清理失效服务。
​​实现细节​​:remoteBinder 判断服务是否为远程对象(跨进程),仅远程服务需要绑定死亡通知。

四、服务注册与存储​​

​​服务存储结构​​

mNameToService[name] = Service {.binder = binder,.allowIsolated = allowIsolated,.dumpPriority = dumpPriority,.debugPid = ctx.debugPid,
};

​​数据结构​​:mNameToService 是 std::map<std::string, Service>,键为服务名,值为 Service 结构体。
​​字段含义​​:
allowIsolated:是否允许隔离环境(如沙盒应用)访问该服务;
dumpPriority:服务在 dumpsys 命令中的输出优先级;
debugPid:服务所属进程的 PID,用于调试。
​​覆盖式更新策略​​
直接覆盖同名服务的旧条目,无需显式删除,避免服务重启时的状态不一致问题。

五、回调通知机制​​

auto it = mNameToRegistrationCallback.find(name);
if (it != mNameToRegistrationCallback.end()) {for (const sp<IServiceCallback>& cb : it->second) {mNameToService[name].guaranteeClient = true;cb->onRegistration(name, binder);}
}

​​功能​​:触发注册回调,通知监听该服务名的组件(如 IServiceCallback 实现类)服务已可用。
​​应用场景​​:系统监控工具可借此实现服务状态实时追踪。

相关文章:

  • Django 结合 Vue 实现简单管理系统的详解
  • JDBC 与 MyBatis 详解:从基础到实践
  • 7、生命周期:魔法的呼吸节奏——React 19 新版钩子
  • Qt 入门 5 之其他窗口部件
  • webgl入门实例-11WebGL 视图矩阵 (View Matrix)基本概念
  • 6.6 “3步调用ChatGPT打造高可靠Python调度器,零依赖实现定时任务自动化“
  • [Unity]-[UI]-[Prefab] 关于UGUI UI Prefab的制作技巧
  • 数据结构——顺序表(C语言实现)
  • 论文阅读:2024 arxiv AI Safety in Generative AI Large Language Models: A Survey
  • Odoo:免费开源的轧制品行业管理软件
  • Python 项目文档编写全攻略:从入门到自动化维护
  • PLM系统如何支持利益相关者分析?沟通矩阵设计
  • .NET Core 服务实现监控可观测性最佳实践
  • C#/.NET/.NET Core拾遗补漏合集(25年4月更新)
  • 在国产麒麟Kylin Linux Advanced Server V10中使用QT5开发环境并支持中文输入
  • HarmonyOs学习 环境配置后 实验1:创建项目Hello World
  • 第八篇:系统分析师第三遍——3、4章
  • UE5编辑器静止状态下(非 Play 模式)睫毛和眼睛的渲染是正常的,而在 Play 模式下出现模糊
  • 回顾与动机 - 为什么我们需要 Transformer
  • Attention 机制核心 - Transformer 的基石
  • 世遗X时尚,七匹狼这场大秀秀出中国文化独特魅力
  • 西安旅游:2024年营业收入约5.82亿元,同比增长5.88%
  • 轻流科技薄智元:AI时代,打造“工业智造”需要“共生式进化”
  • “不可见社会”:一周城市生活
  • 左眼失明左耳失聪,办理残疾人证被拒?县残联:双眼残疾才能办
  • 习近平结束对越南、马来西亚和柬埔寨国事访问回到北京