服务的注册

来源:互联网 发布:乐乎 爱唐晶的小海胆 编辑:程序博客网 时间:2024/05/18 01:23

Server获得了Service Manager远程接口之后,就要把自己的Service添加到Service Manager中去,然后把自己启动起来,等待Client的请求。本文将通过分析说明Server的启动过程是怎么样的。我们通过Android Binder实列篇中的实列来说明下服务启动的整个过程。
类的继承关系图:
这里写图片描述
从上图可以明显看出BnShareBuffer实际是继承了IShareBuffer和BBinder类。IShareBuffer和BBinder类又分别继承了IInterface和IBinder类,IInterface和IBinder类又同时继承了RefBase类。
实际上,BnShareBuffer并不是直接接收到Client处发送过来的请求,而是使用了IPCThreadState接收Client处发送过来的请求,而IPCThreadState又借助了ProcessState类来与Binder驱动程序交互。IPCThreadState接收到了Client处的请求后,就会调用BBinder类的transact函数,并传入相关参数,BBinder类的transact函数最终调用BnShareBuffer类的onTransact函数,于是,就开始真正地处理Client的请求了。
源码中通过:

SharedBufferService::instantiate();//add to the systemServerstatic void instantiate()    {        defaultServiceManager()->addService(String16(SHARED_BUFFER), new SharedBufferService());    }

前面分析过defaultServiceManager()是如何获取systemServices远程代理的。本文主要分析addService这个过程是如何一步一步在系统中添加服务的。
BpServiceManger::addService的实现在framworks/native/libs/binder/IServiceManager.cpp中。

class BpServiceManager : public BpInterface<IServiceManager>{public:    BpServiceManager(const sp<IBinder>& impl)        : BpInterface<IServiceManager>(impl)    {    }   ....    virtual status_t addService(const String16& name, const sp<IBinder>& service,            bool allowIsolated)    {        Parcel data, reply;    unsigned n;        status_t err;        /*        *写入数据到parcel中,序列化数据        */        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());        data.writeString16(name);        //写入一个binder引用        data.writeStrongBinder(service);        data.writeInt32(allowIsolated ? 1 : 0);        for (n = 1; n <= 5; n++) {            err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);            if (err == -EPIPE) {                ALOGI("%s is waiting for serviceManager... (retry %d)\n",                    String8(name).string(), n);                sleep(1);            } else {                break;            }        }        return err == NO_ERROR ? reply.readExceptionCode() : err;    }   ....};

下面我们看看data.writeStrongBinder(service); 这个是服务注册的关键之所在!

status_t Parcel::writeStrongBinder(const sp<IBinder>& val)  {      return flatten_binder(ProcessState::self(), val, this);  }
status_t flatten_binder(const sp<ProcessState>& proc,      const sp<IBinder>& binder, Parcel* out)  {      flat_binder_object obj;  //内核中传输binder的结构    /*    *0x7f表示处理本Binder实体请求数据包的线程的最低优先级,FLAT_BINDER_FLAG_ACCEPTS_FDS    *表示这个Binder实体可以接受文件描述符,Binder实体在收到文件描述符时,就会在本进程中打开这个文件。    */      obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;      if (binder != NULL) {  //binder为 新建立的SharedBufferService一定不为空        IBinder *local = binder->localBinder();          if (!local) {              BpBinder *proxy = binder->remoteBinder();              if (proxy == NULL) {                  LOGE("null proxy");              }              const int32_t handle = proxy ? proxy->handle() : 0;              obj.type = BINDER_TYPE_HANDLE;              obj.handle = handle;              obj.cookie = NULL;          } else {              obj.type = BINDER_TYPE_BINDER;              obj.binder = local->getWeakRefs();              obj.cookie = local;          }      } else {          obj.type = BINDER_TYPE_BINDER;          obj.binder = NULL;          obj.cookie = NULL;      }      return finish_flatten_binder(binder, obj, out);  //将binder写入Parcel中}  
inline static status_t finish_flatten_binder(      const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out)  {      return out->writeObject(flat, false);  //最终调用writeObject写入一个对像}  

接下来status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
这里的remote成员函数来自于BpRefBase类,它返回一个BpBinder指针。

status_t BpBinder::transact(      uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  {      // Once a binder has died, it will never come back to life.      if (mAlive) {          status_t status = IPCThreadState::self()->transact(              mHandle, code, data, reply, flags);          if (status == DEAD_OBJECT) mAlive = 0;          return status;      }      return DEAD_OBJECT;  }  

最终调用IPCThreadState::transact进执行实际的操作。这里的mHandle一定为0,因为这里表示的是Service Manager远程接口,它的句柄值一定是0,code为ADD_SERVICE_TRANSACTION。

status_t IPCThreadState::transact(int32_t handle,                                    uint32_t code, const Parcel& data,                                    Parcel* reply, uint32_t flags)  {      status_t err = data.errorCheck();      flags |= TF_ACCEPT_FDS;      IF_LOG_TRANSACTIONS() {          TextOutput::Bundle _b(alog);          alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "              << handle << " / code " << TypeCode(code) << ": "              << indent << data << dedent << endl;      }      if (err == NO_ERROR) {          LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),              (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");          err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);      }      if (err != NO_ERROR) {          if (reply) reply->setError(err);          return (mLastError = err);      }      if ((flags & TF_ONE_WAY) == 0) {          #if 0          if (code == 4) { // relayout              LOGI(">>>>>> CALLING transaction 4");          } else {              LOGI(">>>>>> CALLING transaction %d", code);          }          #endif          if (reply) {              err = waitForResponse(reply);          } else {              Parcel fakeReply;              err = waitForResponse(&fakeReply);          }          #if 0          if (code == 4) { // relayout              LOGI("<<<<<< RETURNING transaction 4");          } else {              LOGI("<<<<<< RETURNING transaction %d", code);          }          #endif          IF_LOG_TRANSACTIONS() {              TextOutput::Bundle _b(alog);              alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "                  << handle << ": ";              if (reply) alog << indent << *reply << dedent << endl;              else alog << "(none requested)" << endl;          }      } else {          err = waitForResponse(NULL, NULL);      }      return err;  }  

最终通过waitForResponse ==>talkWithDriver将注册信息写入驱动。最终会唤醒在等待数据的serviceManager线程,serviceManager线程接收到数据后,会对其进行解析并添加服务到管理的服务列表中!整个过程比较复杂,在老罗的博客中有较详细的讲述!
Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析

0 0