servicemanager学习笔记(1)

看了一堆博客,源代码分析的头头是道,但是我看空谈者较多,无非是代码里面转圈圈,我就一个问题,我的Binder找不到怎么办?

当然,查,我也不另外,代码还是要理一理。

唉,吐槽太多,但是还是要老老实实尊重前人经验来。

首先看看servicemanager,区分native层和java层

首先看看native层,native层从哪儿看起了,哦,从它被启用开始,谁启用他了,哦,Init

on post-fs
312    # Load properties from
313    #     /system/build.prop,
314    #     /odm/build.prop,
315    #     /vendor/build.prop and
316    #     /factory/factory.prop
317    load_system_props
318    # start essential services
319    start logd
320    start servicemanager
321    start hwservicemanager
322    start vndservicemanager

所以跳到配置文件看看
1service servicemanager /system/bin/servicemanager
2    class core animation
3    user system
4    group system readproc
5    critical
6    onrestart restart healthd
7    onrestart restart zygote
8    onrestart restart audioserver
9    onrestart restart media
10    onrestart restart surfaceflinger
11    onrestart restart inputflinger
12    onrestart restart drm
13    onrestart restart cameraserver
14    onrestart restart keystore
15    onrestart restart gatekeeperd
16    writepid /dev/cpuset/system-background/tasks
17    shutdown critical

 所有的文章都告诉我,从main函数入口,过去main函数没有参数还好,现在main函数有参数,请问谁调用了main函数,什么时候传入的参数?我没找到,但是感觉是Init干的,我没证据,过两天找Init聊一聊。

116  int main(int argc, char** argv) {//?谁带路的,这带路的带来的两个参数分别是什么?
117      if (argc > 2) {
118          LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
119      }
120  
121      const char* driver = argc == 2 ? argv[1] : "/dev/binder";
122  
123      sp<ProcessState> ps = ProcessState::initWithDriver(driver);//确认用什么driver,Binder或者vndbinder、hwbinder
124      ps->setThreadPoolMaxThreadCount(0);//醉了,也没有注释,鬼晓得,我猜测这个估计使用默认最大值,当然不追根究底了,没啥意义。只能说这种设计很差劲
125      ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);// one way
126  
127      sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
128      if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
129          LOG(ERROR) << "Could not self register servicemanager";//自注册,我的天,真牛,还能管自己
130      }
131  
132      IPCThreadState::self()->setTheContextObject(manager);//
133      ps->becomeContextManager(nullptr, nullptr);
134  
135      sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
136  
137      BinderCallback::setupTo(looper);
138      ClientCallbackCallback::setupTo(looper, manager);
139  
140      while(true) {
141          looper->pollAll(-1);
142      }
143  
144      // should not be reached
145      return EXIT_FAILURE;
146  }
147  

 

setThreadPoolMaxThreadCount这个看看,为什么设置为0,我很好奇
330  status_t ProcessState::setThreadPoolMaxThreadCount(size_t maxThreads) {
331      status_t result = NO_ERROR;
332      if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &maxThreads) != -1) {
333          mMaxThreads = maxThreads;
334      } else {
335          result = -errno;
336          ALOGE("Binder ioctl to set max threads failed: %s", strerror(-result));
337      }
338      return result;
339  }

0也没啥特殊处理呀,真是奇怪。

 
  void ProcessState::setCallRestriction(CallRestriction restriction) {
220      LOG_ALWAYS_FATAL_IF(IPCThreadState::selfOrNull() != nullptr,
221          "Call restrictions must be set before the threadpool is started.");
222  
223      mCallRestriction = restriction;
224  }
225  

那就是构造走入了

8  ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {
89  // TODO(b/151696835): reenable performance hack when we solve bug, since with
90  //     this hack and other fixes, it is unlikely we will see even an ephemeral
91  //     failure when the manifest parse fails. The goal is that the manifest will
92  //     be read incorrectly and cause the process trying to register a HAL to
93  //     fail. If this is in fact an early boot kernel contention issue, then we
94  //     will get no failure, and by its absence, be signalled to invest more
95  //     effort in re-adding this performance hack.
96  // #ifndef VENDORSERVICEMANAGER
97  //     // can process these at any times, don't want to delay first VINTF client
98  //     std::thread([] {
99  //         vintf::VintfObject::GetDeviceHalManifest();
100  //         vintf::VintfObject::GetFrameworkHalManifest();
101  //     }).detach();
102  // #endif  // !VENDORSERVICEMANAGER
103  }

没啥意义。全注释了

到sericemanager里面看看,嘿嘿,看到了Service,所以Service到底是啥?有一个binder,类型是IBinder,通信使用的;有一些bool属性,

      struct Service {
58          sp<IBinder> binder; // not null
59          bool allowIsolated;//是否允许孤立的
60          int32_t dumpPriority;
61          bool hasClients = false; // notifications sent on true -> false.//有没有客户端
62          bool guaranteeClient = false; // forces the client check to true//是否强迫客户端检查结果
63          pid_t debugPid = 0; // the process in which this service runs//process id
64  
65          // the number of clients of the service, including servicemanager itself
66          ssize_t getNodeStrongRefCount();//这个service的客户端
67      };

有点意思,收获很大呀。

好了,接下来应该到了addService了

 //看看参数,就是service需要的几个要素,一点都不新鲜
182  Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
183      auto ctx = mAccess->getCallingContext();
184  
185      // apps cannot add services
186      if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
187          return Status::fromExceptionCode(Status::EX_SECURITY);
188      }
189  
190      if (!mAccess->canAdd(ctx, name)) {
191          return Status::fromExceptionCode(Status::EX_SECURITY);
192      }
193 //上面从用户和可访问上进行检查
//对binder进行限制,如果binder异常为空,直接返回 194 if (binder == nullptr) { 195 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT); 196 } 197 //会对service进行名字的有效性进行检查 198 if (!isValidServiceName(name)) { 199 LOG(ERROR) << "Invalid service name: " << name; 200 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT); 201 } 202 //如果没有定义vendor 的servicemanager 203 #ifndef VENDORSERVICEMANAGER
//如果没有达到满足的要求。则返回异常
204 if (!meetsDeclarationRequirements(binder, name)) { 205 // already logged 206 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT); 207 } 208 #endif // !VENDORSERVICEMANAGER 209 210 // implicitly unlinked when the binder is removed//判断binder 211 if (binder->remoteBinder() != nullptr && binder->linkToDeath(this) != OK) { 212 LOG(ERROR) << "Could not linkToDeath when adding " << name; 213 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); 214 } 215 216 // Overwrite the old service if it exists//覆盖service 217 mNameToService[name] = Service { 218 .binder = binder, 219 .allowIsolated = allowIsolated, 220 .dumpPriority = dumpPriority, 221 .debugPid = ctx.debugPid, 222 }; 223 224 auto it = mNameToRegistrationCallback.find(name); 225 if (it != mNameToRegistrationCallback.end()) { 226 for (const sp<IServiceCallback>& cb : it->second) { 227 mNameToService[name].guaranteeClient = true; 228 // permission checked in registerForNotifications 229 cb->onRegistration(name, binder); 230 } 231 } 232 233 return Status::ok(); 234 }

 扩展一下

167  bool isValidServiceName(const std::string& name) {//规范名字,没啥作用,只是强行正规而已
168      if (name.size() == 0) return false;//名字不能为空
169      if (name.size() > 127) return false;、、名字长度必须小于127
170  
171      for (char c : name) {//名字中不可以有特殊字符,如果是英文或者数字,或者特殊字符的-,_,.,/,其他都是异常,比如来个%或者$
172          if (c == '_' || c == '-' || c == '.' || c == '/') continue;
173          if (c >= 'a' && c <= 'z') continue;
174          if (c >= 'A' && c <= 'Z') continue;
175          if (c >= '0' && c <= '9') continue;
176          return false;
177      }
178  
179      return true;
180  }
181  

看看这个达标函数,一个参数,binder,一个名字

 static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) {
//靠,又跳函数了,字面解释,稳定性下的,风的定义
80 if (!Stability::requiresVintfDeclaration(binder)) { 81 return true; 82 } 83 84 return isVintfDeclared(name); 85 }

继续跟踪函数

 bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) {
44      return check(get(binder.get()), Level::VINTF);//本质是检查binder的LEVEL是不是VINTF
45  }

继续吧,有时候跳函数跳的人晕晕的,很多人觉得面向对象的好,但是我觉得面向过程的长函数更容易分析,因为现代函数封装的函数太多了,鬼晓得有 多人,但是这些许许多多封装的函数都只是各个人写的,无法成为共有API,各种不同系统各种不同项目缺少统一性。

 bool Stability::check(int32_t provided, Level required) {
106      bool stable = (provided & required) == required;//很简单,提供的且上要求的如果还是要求的那么就是true
107  
108      if (!isDeclaredStability(provided) && provided != UNDECLARED) {
109          ALOGE("Unknown stability when checking interface stability %d.", provided);
110  
111          stable = false;
112      }
113  
114      return stable;
115  }

 继续扩展

117  bool Stability::isDeclaredStability(int32_t stability) {
118      return stability == VENDOR || stability == SYSTEM || stability == VINTF;
119  }

 接下去分析吧

     ServiceCallbackMap mNameToRegistrationCallback;
using ServiceCallbackMap = std::map<std::string, std::vector<sp<IServiceCallback>>>;//本质是个map,一个是string,一个是数组的
IServiceCallback
  oneway interface IServiceCallback {
23      /**
24       * Called when a service is registered.
25       *
26       * @param name the service name that has been registered with
27       * @param binder the binder that is registered
28       */
29      void onRegistration(@utf8InCpp String name, IBinder binder);
30  }

这个使用:

262  Status ServiceManager::registerForNotifications(
263          const std::string& name, const sp<IServiceCallback>& callback) {
264      auto ctx = mAccess->getCallingContext();
265  
266      if (!mAccess->canFind(ctx, name)) {
267          return Status::fromExceptionCode(Status::EX_SECURITY);
268      }
269  
270      if (!isValidServiceName(name)) {
271          LOG(ERROR) << "Invalid service name: " << name;
272          return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
273      }
274  
275      if (callback == nullptr) {
276          return Status::fromExceptionCode(Status::EX_NULL_POINTER);
277      }
278  
279      if (OK != IInterface::asBinder(callback)->linkToDeath(this)) {
280          LOG(ERROR) << "Could not linkToDeath when adding " << name;
281          return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
282      }
283  
284      mNameToRegistrationCallback[name].push_back(callback);
285  
286      if (auto it = mNameToService.find(name); it != mNameToService.end()) {
287          const sp<IBinder>& binder = it->second.binder;
288  
289          // never null if an entry exists
290          CHECK(binder != nullptr) << name;
291          callback->onRegistration(name, binder);
292      }
293  
294      return Status::ok();
295  }

 最后发现,这个里面是经典的方法,注册,反注册,死亡监听,死亡后删除等等,我认为每一个系统开放者都能从这一段代码里面收益

 /*
2   * Copyright (C) 2019 The Android Open Source Project
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *      http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  #include "ServiceManager.h"
18  
19  #include <android-base/logging.h>
20  #include <android-base/properties.h>
21  #include <binder/BpBinder.h>
22  #include <binder/IPCThreadState.h>
23  #include <binder/ProcessState.h>
24  #include <binder/Stability.h>
25  #include <cutils/android_filesystem_config.h>
26  #include <cutils/multiuser.h>
27  #include <thread>
28  
29  #ifndef VENDORSERVICEMANAGER
30  #include <vintf/VintfObject.h>
31  #include <vintf/constants.h>
32  #endif  // !VENDORSERVICEMANAGER
33  
34  using ::android::binder::Status;
35  using ::android::internal::Stability;
36  
37  namespace android {
38  
39  #ifndef VENDORSERVICEMANAGER
40  static bool isVintfDeclared(const std::string& name) {
41      size_t firstSlash = name.find('/');
42      size_t lastDot = name.rfind('.', firstSlash);
43      if (firstSlash == std::string::npos || lastDot == std::string::npos) {
44          LOG(ERROR) << "VINTF HALs require names in the format type/instance (e.g. "
45                     << "some.package.foo.IFoo/default) but got: " << name;
46          return false;
47      }
48      const std::string package = name.substr(0, lastDot);
49      const std::string iface = name.substr(lastDot+1, firstSlash-lastDot-1);
50      const std::string instance = name.substr(firstSlash+1);
51  
52      struct ManifestWithDescription {
53          std::shared_ptr<const vintf::HalManifest> manifest;
54          const char* description;
55      };
56      for (const ManifestWithDescription& mwd : {
57              ManifestWithDescription{ vintf::VintfObject::GetDeviceHalManifest(), "device" },
58              ManifestWithDescription{ vintf::VintfObject::GetFrameworkHalManifest(), "framework" },
59          }) {
60          if (mwd.manifest == nullptr) {
61            LOG(ERROR) << "NULL VINTF MANIFEST!: " << mwd.description;
62            // note, we explicitly do not retry here, so that we can detect VINTF
63            // or other bugs (b/151696835)
64            continue;
65          }
66          if (mwd.manifest->hasAidlInstance(package, iface, instance)) {
67              LOG(INFO) << "Found " << name << " in " << mwd.description << " VINTF manifest.";
68              return true;
69          }
70      }
71  
72      // Although it is tested, explicitly rebuilding qualified name, in case it
73      // becomes something unexpected.
74      LOG(ERROR) << "Could not find " << package << "." << iface << "/" << instance
75                 << " in the VINTF manifest.";
76      return false;
77  }
78  
79  static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) {
80      if (!Stability::requiresVintfDeclaration(binder)) {
81          return true;
82      }
83  
84      return isVintfDeclared(name);
85  }
86  #endif  // !VENDORSERVICEMANAGER
87  
88  ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {
89  // TODO(b/151696835): reenable performance hack when we solve bug, since with
90  //     this hack and other fixes, it is unlikely we will see even an ephemeral
91  //     failure when the manifest parse fails. The goal is that the manifest will
92  //     be read incorrectly and cause the process trying to register a HAL to
93  //     fail. If this is in fact an early boot kernel contention issue, then we
94  //     will get no failure, and by its absence, be signalled to invest more
95  //     effort in re-adding this performance hack.
96  // #ifndef VENDORSERVICEMANAGER
97  //     // can process these at any times, don't want to delay first VINTF client
98  //     std::thread([] {
99  //         vintf::VintfObject::GetDeviceHalManifest();
100  //         vintf::VintfObject::GetFrameworkHalManifest();
101  //     }).detach();
102  // #endif  // !VENDORSERVICEMANAGER
103  }
104  ServiceManager::~ServiceManager() {
105      // this should only happen in tests
106  
107      for (const auto& [name, callbacks] : mNameToRegistrationCallback) {
108          CHECK(!callbacks.empty()) << name;
109          for (const auto& callback : callbacks) {
110              CHECK(callback != nullptr) << name;
111          }
112      }
113  
114      for (const auto& [name, service] : mNameToService) {
115          CHECK(service.binder != nullptr) << name;
116      }
117  }
118  
119  Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
120      *outBinder = tryGetService(name, true);
121      // returns ok regardless of result for legacy reasons
122      return Status::ok();
123  }
124  
125  Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
126      *outBinder = tryGetService(name, false);
127      // returns ok regardless of result for legacy reasons
128      return Status::ok();
129  }
130  
131  sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
132      auto ctx = mAccess->getCallingContext();
133  
134      sp<IBinder> out;
135      Service* service = nullptr;
136      if (auto it = mNameToService.find(name); it != mNameToService.end()) {
137          service = &(it->second);
138  
139          if (!service->allowIsolated) {
140              uid_t appid = multiuser_get_app_id(ctx.uid);
141              bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
142  
143              if (isIsolated) {
144                  return nullptr;
145              }
146          }
147          out = service->binder;
148      }
149  
150      if (!mAccess->canFind(ctx, name)) {
151          return nullptr;
152      }
153  
154      if (!out && startIfNotFound) {
155          tryStartService(name);
156      }
157  
158      if (out) {
159          // Setting this guarantee each time we hand out a binder ensures that the client-checking
160          // loop knows about the event even if the client immediately drops the service
161          service->guaranteeClient = true;
162      }
163  
164      return out;
165  }
166  
167  bool isValidServiceName(const std::string& name) {
168      if (name.size() == 0) return false;
169      if (name.size() > 127) return false;
170  
171      for (char c : name) {
172          if (c == '_' || c == '-' || c == '.' || c == '/') continue;
173          if (c >= 'a' && c <= 'z') continue;
174          if (c >= 'A' && c <= 'Z') continue;
175          if (c >= '0' && c <= '9') continue;
176          return false;
177      }
178  
179      return true;
180  }
181  
182  Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
183      auto ctx = mAccess->getCallingContext();
184  
185      // apps cannot add services
186      if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
187          return Status::fromExceptionCode(Status::EX_SECURITY);
188      }
189  
190      if (!mAccess->canAdd(ctx, name)) {
191          return Status::fromExceptionCode(Status::EX_SECURITY);
192      }
193  
194      if (binder == nullptr) {
195          return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
196      }
197  
198      if (!isValidServiceName(name)) {
199          LOG(ERROR) << "Invalid service name: " << name;
200          return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
201      }
202  
203  #ifndef VENDORSERVICEMANAGER
204      if (!meetsDeclarationRequirements(binder, name)) {
205          // already logged
206          return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
207      }
208  #endif  // !VENDORSERVICEMANAGER
209  
210      // implicitly unlinked when the binder is removed
211      if (binder->remoteBinder() != nullptr && binder->linkToDeath(this) != OK) {
212          LOG(ERROR) << "Could not linkToDeath when adding " << name;
213          return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
214      }
215  
216      // Overwrite the old service if it exists
217      mNameToService[name] = Service {
218          .binder = binder,
219          .allowIsolated = allowIsolated,
220          .dumpPriority = dumpPriority,
221          .debugPid = ctx.debugPid,
222      };
223  
224      auto it = mNameToRegistrationCallback.find(name);
225      if (it != mNameToRegistrationCallback.end()) {
226          for (const sp<IServiceCallback>& cb : it->second) {
227              mNameToService[name].guaranteeClient = true;
228              // permission checked in registerForNotifications
229              cb->onRegistration(name, binder);
230          }
231      }
232  
233      return Status::ok();
234  }
235  
236  Status ServiceManager::listServices(int32_t dumpPriority, std::vector<std::string>* outList) {
237      if (!mAccess->canList(mAccess->getCallingContext())) {
238          return Status::fromExceptionCode(Status::EX_SECURITY);
239      }
240  
241      size_t toReserve = 0;
242      for (auto const& [name, service] : mNameToService) {
243          (void) name;
244  
245          if (service.dumpPriority & dumpPriority) ++toReserve;
246      }
247  
248      CHECK(outList->empty());
249  
250      outList->reserve(toReserve);
251      for (auto const& [name, service] : mNameToService) {
252          (void) service;
253  
254          if (service.dumpPriority & dumpPriority) {
255              outList->push_back(name);
256          }
257      }
258  
259      return Status::ok();
260  }
261  
262  Status ServiceManager::registerForNotifications(
263          const std::string& name, const sp<IServiceCallback>& callback) {
264      auto ctx = mAccess->getCallingContext();
265  
266      if (!mAccess->canFind(ctx, name)) {
267          return Status::fromExceptionCode(Status::EX_SECURITY);
268      }
269  
270      if (!isValidServiceName(name)) {
271          LOG(ERROR) << "Invalid service name: " << name;
272          return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
273      }
274  
275      if (callback == nullptr) {
276          return Status::fromExceptionCode(Status::EX_NULL_POINTER);
277      }
278  
279      if (OK != IInterface::asBinder(callback)->linkToDeath(this)) {
280          LOG(ERROR) << "Could not linkToDeath when adding " << name;
281          return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
282      }
283  
284      mNameToRegistrationCallback[name].push_back(callback);
285  
286      if (auto it = mNameToService.find(name); it != mNameToService.end()) {
287          const sp<IBinder>& binder = it->second.binder;
288  
289          // never null if an entry exists
290          CHECK(binder != nullptr) << name;
291          callback->onRegistration(name, binder);
292      }
293  
294      return Status::ok();
295  }
296  Status ServiceManager::unregisterForNotifications(
297          const std::string& name, const sp<IServiceCallback>& callback) {
298      auto ctx = mAccess->getCallingContext();
299  
300      if (!mAccess->canFind(ctx, name)) {
301          return Status::fromExceptionCode(Status::EX_SECURITY);
302      }
303  
304      bool found = false;
305  
306      auto it = mNameToRegistrationCallback.find(name);
307      if (it != mNameToRegistrationCallback.end()) {
308          removeRegistrationCallback(IInterface::asBinder(callback), &it, &found);
309      }
310  
311      if (!found) {
312          LOG(ERROR) << "Trying to unregister callback, but none exists " << name;
313          return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
314      }
315  
316      return Status::ok();
317  }
318  
319  Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) {
320      auto ctx = mAccess->getCallingContext();
321  
322      if (!mAccess->canFind(ctx, name)) {
323          return Status::fromExceptionCode(Status::EX_SECURITY);
324      }
325  
326      *outReturn = false;
327  
328  #ifndef VENDORSERVICEMANAGER
329      *outReturn = isVintfDeclared(name);
330  #endif
331      return Status::ok();
332  }
333  
334  void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
335                                      ServiceCallbackMap::iterator* it,
336                                      bool* found) {
337      std::vector<sp<IServiceCallback>>& listeners = (*it)->second;
338  
339      for (auto lit = listeners.begin(); lit != listeners.end();) {
340          if (IInterface::asBinder(*lit) == who) {
341              if(found) *found = true;
342              lit = listeners.erase(lit);
343          } else {
344              ++lit;
345          }
346      }
347  
348      if (listeners.empty()) {
349          *it = mNameToRegistrationCallback.erase(*it);
350      } else {
351          (*it)++;
352      }
353  }
354  
355  void ServiceManager::binderDied(const wp<IBinder>& who) {
356      for (auto it = mNameToService.begin(); it != mNameToService.end();) {
357          if (who == it->second.binder) {
358              it = mNameToService.erase(it);
359          } else {
360              ++it;
361          }
362      }
363  
364      for (auto it = mNameToRegistrationCallback.begin(); it != mNameToRegistrationCallback.end();) {
365          removeRegistrationCallback(who, &it, nullptr /*found*/);
366      }
367  
368      for (auto it = mNameToClientCallback.begin(); it != mNameToClientCallback.end();) {
369          removeClientCallback(who, &it);
370      }
371  }
372  
373  void ServiceManager::tryStartService(const std::string& name) {
374      ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service",
375            name.c_str());
376  
377      std::thread([=] {
378          (void)base::SetProperty("ctl.interface_start", "aidl/" + name);
379      }).detach();
380  }
381  
382  Status ServiceManager::registerClientCallback(const std::string& name, const sp<IBinder>& service,
383                                                const sp<IClientCallback>& cb) {
384      if (cb == nullptr) {
385          return Status::fromExceptionCode(Status::EX_NULL_POINTER);
386      }
387  
388      auto ctx = mAccess->getCallingContext();
389      if (!mAccess->canAdd(ctx, name)) {
390          return Status::fromExceptionCode(Status::EX_SECURITY);
391      }
392  
393      auto serviceIt = mNameToService.find(name);
394      if (serviceIt == mNameToService.end()) {
395          LOG(ERROR) << "Could not add callback for nonexistent service: " << name;
396          return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
397      }
398  
399      if (serviceIt->second.debugPid != IPCThreadState::self()->getCallingPid()) {
400          LOG(WARNING) << "Only a server can register for client callbacks (for " << name << ")";
401          return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
402      }
403  
404      if (serviceIt->second.binder != service) {
405          LOG(WARNING) << "Tried to register client callback for " << name
406              << " but a different service is registered under this name.";
407          return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
408      }
409  
410      if (OK != IInterface::asBinder(cb)->linkToDeath(this)) {
411          LOG(ERROR) << "Could not linkToDeath when adding client callback for " << name;
412          return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
413      }
414  
415      mNameToClientCallback[name].push_back(cb);
416  
417      return Status::ok();
418  }
419  
420  void ServiceManager::removeClientCallback(const wp<IBinder>& who,
421                                            ClientCallbackMap::iterator* it) {
422      std::vector<sp<IClientCallback>>& listeners = (*it)->second;
423  
424      for (auto lit = listeners.begin(); lit != listeners.end();) {
425          if (IInterface::asBinder(*lit) == who) {
426              lit = listeners.erase(lit);
427          } else {
428              ++lit;
429          }
430      }
431  
432      if (listeners.empty()) {
433          *it = mNameToClientCallback.erase(*it);
434      } else {
435          (*it)++;
436      }
437  }
438  
439  ssize_t ServiceManager::Service::getNodeStrongRefCount() {
440      sp<BpBinder> bpBinder = binder->remoteBinder();
441      if (bpBinder == nullptr) return -1;
442  
443      return ProcessState::self()->getStrongRefCountForNodeByHandle(bpBinder->handle());
444  }
445  
446  void ServiceManager::handleClientCallbacks() {
447      for (const auto& [name, service] : mNameToService) {
448          handleServiceClientCallback(name, true);
449      }
450  }
451  
452  ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName,
453                                                      bool isCalledOnInterval) {
454      auto serviceIt = mNameToService.find(serviceName);
455      if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) {
456          return -1;
457      }
458  
459      Service& service = serviceIt->second;
460      ssize_t count = service.getNodeStrongRefCount();
461  
462      // binder driver doesn't support this feature
463      if (count == -1) return count;
464  
465      bool hasClients = count > 1; // this process holds a strong count
466  
467      if (service.guaranteeClient) {
468          // we have no record of this client
469          if (!service.hasClients && !hasClients) {
470              sendClientCallbackNotifications(serviceName, true);
471          }
472  
473          // guarantee is temporary
474          service.guaranteeClient = false;
475      }
476  
477      // only send notifications if this was called via the interval checking workflow
478      if (isCalledOnInterval) {
479          if (hasClients && !service.hasClients) {
480              // client was retrieved in some other way
481              sendClientCallbackNotifications(serviceName, true);
482          }
483  
484          // there are no more clients, but the callback has not been called yet
485          if (!hasClients && service.hasClients) {
486              sendClientCallbackNotifications(serviceName, false);
487          }
488      }
489  
490      return count;
491  }
492  
493  void ServiceManager::sendClientCallbackNotifications(const std::string& serviceName, bool hasClients) {
494      auto serviceIt = mNameToService.find(serviceName);
495      if (serviceIt == mNameToService.end()) {
496          LOG(WARNING) << "sendClientCallbackNotifications could not find service " << serviceName;
497          return;
498      }
499      Service& service = serviceIt->second;
500  
501      CHECK(hasClients != service.hasClients) << "Record shows: " << service.hasClients
502          << " so we can't tell clients again that we have client: " << hasClients;
503  
504      LOG(INFO) << "Notifying " << serviceName << " they have clients: " << hasClients;
505  
506      auto ccIt = mNameToClientCallback.find(serviceName);
507      CHECK(ccIt != mNameToClientCallback.end())
508          << "sendClientCallbackNotifications could not find callbacks for service ";
509  
510      for (const auto& callback : ccIt->second) {
511          callback->onClients(service.binder, hasClients);
512      }
513  
514      service.hasClients = hasClients;
515  }
516  
517  Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IBinder>& binder) {
518      if (binder == nullptr) {
519          return Status::fromExceptionCode(Status::EX_NULL_POINTER);
520      }
521  
522      auto ctx = mAccess->getCallingContext();
523      if (!mAccess->canAdd(ctx, name)) {
524          return Status::fromExceptionCode(Status::EX_SECURITY);
525      }
526  
527      auto serviceIt = mNameToService.find(name);
528      if (serviceIt == mNameToService.end()) {
529          LOG(WARNING) << "Tried to unregister " << name
530              << ", but that service wasn't registered to begin with.";
531          return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
532      }
533  
534      if (serviceIt->second.debugPid != IPCThreadState::self()->getCallingPid()) {
535          LOG(WARNING) << "Only a server can unregister itself (for " << name << ")";
536          return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
537      }
538  
539      sp<IBinder> storedBinder = serviceIt->second.binder;
540  
541      if (binder != storedBinder) {
542          LOG(WARNING) << "Tried to unregister " << name
543              << ", but a different service is registered under this name.";
544          return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
545      }
546  
547      if (serviceIt->second.guaranteeClient) {
548          LOG(INFO) << "Tried to unregister " << name << ", but there is about to be a client.";
549          return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
550      }
551  
552      int clients = handleServiceClientCallback(name, false);
553  
554      // clients < 0: feature not implemented or other error. Assume clients.
555      // Otherwise:
556      // - kernel driver will hold onto one refcount (during this transaction)
557      // - servicemanager has a refcount (guaranteed by this transaction)
558      // So, if clients > 2, then at least one other service on the system must hold a refcount.
559      if (clients < 0 || clients > 2) {
560          // client callbacks are either disabled or there are other clients
561          LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients;
562          // Set this flag to ensure the clients are acknowledged in the next callback
563          serviceIt->second.guaranteeClient = true;
564          return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
565      }
566  
567      mNameToService.erase(name);
568  
569      return Status::ok();
570  }
571  
572  }  // namespace android
573  

 

posted @ 2021-09-01 15:45  zhougong12  阅读(1226)  评论(0)    收藏  举报