Princípio do ServiceManager – combinação de código do Android 12 S

​ServiceManager é a parte central da comunicação do Binder, fornecendo registro de serviço e funções de consulta. Nas versões anteriores ao Android 11, ele usa diretamente APIs como open, mmap e ioctl para interagir com o driver do binder. A partir do Android 11, o ServiceManager abandona o uso dessas interfaces de nível inferior e recorre à biblioteca libbinder e ao AIDL.

Índice

Índice

1. análise de arquivo rc

2. Diagrama de classes do ServiceManager

2.1 Introdução ao diretório ServiceManager

2.2 Introdução ao diagrama de classes do ServiceManager

2.3 Bn, Bp introdução do caminho do arquivo de implementação específico final

3. Processo de inicialização do ServiceManager

3.1 Iniciar entrada

3.2 Introdução ao initWithDriver

3.3 Introdução ao ProcessState::init

3.4 Introdução ao construtor de ProcessState

3.5 introdução ao open_driver

3.6 Fluxograma geral de inicialização do ServiceManager

4. Introdução ao IServicManager

4.1 Introdução ao diretório do IServiceManager

4.2 Introdução ao bp do IServiceManager

4.3 Introdução ao defaultServiceManager

4.4 Introdução à implementação de interface_cast e asInterface

4.5 Introdução a outras interfaces do IServiceManager

5. Outros serviços registram/obtêm serviços através do IServicManager

5.1: Serviços de Registro

5.1.1 Exemplo de adição de outros serviços ao ServiceManager

5.1.2 Introdução ao addService no Cliente

5.1.3 Processo de atribuição do mTheRealServiceManager

5.1.4 Introdução ao addService do IServiceManager, processo completo de Bp->Bn

5.1.5 Introdução ao remote() em remote()->transact do BpServiceManager no lado do cliente

5.1.6 Introdução de transações do BpBinder no lado do cliente

5.1.6 Introdução ao talkWithDriver do cliente

5.1.7 Como o servidor sabe que há uma alteração de dados em /dev/binder e os lê

5.1.8 Introdução ao LooperCallback herdado por BinderCallback no ServiceManager

5.1.9 Introdução ao BinderCallback no ServiceManager

5.1.10 Processo subsequente de handleEvent em BinderCallback no ServiceManager

5.1.11 Introdução ao onTransact do BnServiceManager no lado do servidor

5.1.12 Introdução ao addService no lado do servidor

5.1.13 Introdução para adicionar mapa de lista de serviços no lado do servidor

5.2 Obtenção de serviços

5.2.1 Obtenha exemplo de serviço através do IServiceManager

5.2.2 Introdução à interface getService do lado do cliente

5.2.3 processo getServerice Bp->Bn em IServiceManager 

5.2.4 Introdução ao getService do lado do servidor


1. análise de arquivo rc

O ServiceManager é iniciado pelo init por meio do arquivo rc, e o conteúdo do rc é o seguinte: frameworks/native/cmds/servicemanager/servicemanager.rc

service servicemanager /system/bin/servicemanager
    class core animation
    user system
    group system readproc
    critical//表明这个Service对设备至关重要,如果Service在四分钟内退出超过4次,则设备将重启进入recovery模式
    //onrestart在重启时执行一条命令。
    onrestart restart apexd
    onrestart restart audioserver
    onrestart restart gatekeeperd
    onrestart class_restart main
    onrestart class_restart hal
    onrestart class_restart early_hal
    writepid /dev/cpuset/system-background/tasks
    shutdown critical//设置Service进程的关闭行为

2. Diagrama de classes do ServiceManager

2.1 Introdução ao diretório ServiceManager

ServiceManager está localizado no seguinte diretório
frameworks/native/cmds/servicemanager/
 Access.cpp  
 Access.h  
 Android.bp  
 main.cpp  
 ServiceManager.cpp  
 ServiceManager.h  
 servicemanager.rc  
 TEST_MAPPING  
 test_sm.cpp  
 vndservicemanager.rc

2.2 Introdução ao diagrama de classes do ServiceManager

O diagrama de classes do ServiceManager é o seguinte:

2.3 Bn, Bp introdução do caminho do arquivo de implementação específico final

A implementação do BpServiceManager está no diretório a seguir, e outros arquivos relacionados out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm64_armv8XXX/gen/aidl/android/os são gerados automaticamente neste diretório aidl

BnClientCallback.h   
BnServiceDebugInfo.h  
BpClientCallback.h   
BpServiceDebugInfo.h  
IClientCallback.cpp  
IServiceCallback.cpp  
IServiceManager.cpp  
ServiceDebugInfo.cpp
BnServiceCallback.h  
BnServiceManager.h    
BpServiceCallback.h  
BpServiceManager.h    
IClientCallback.h    
IServiceCallback.h    
IServiceManager.h    
ServiceDebugInfo.h


Entre eles, BnServiceManager é o lado do servidor, e sua classe de implementação é denominada ServiceManager.cpp

3. Processo de inicialização do ServiceManager

3.1 Iniciar entrada

ServiceManager é o servidor. Depois de iniciado, ele chama primeiro a função principal. O diretório é o seguinte

frameworks/native/cmds/servicemanager/main.cpp

int main(int argc, char** argv) {
    if (argc > 2) {
        LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
    }
    //从servicemanager.rc中可看到,启动servicemanager时没有多余的参数,所以次数arvc=1,则driver为"/dev/binder"。
    const char* driver = argc == 2 ? argv[1] : "/dev/binder";

    //打开并映射binder驱动, open mmap 和以前的binder不同的地方
    sp<ProcessState> ps = ProcessState::initWithDriver(driver);
    //设置thread poll的最大线程数量
    ps->setThreadPoolMaxThreadCount(0);
    //设置调用限制,FATAL_IF_NOT_ONEWA意思是:在阻塞调用时中止进程
    //oneway 限制,ServiceManager发起的 Binder 调用必须是单向,否则打印堆栈日志提示
    ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
    //实例化ServiceManager, Access为鉴权
    sp<ServiceManager> manager = sp<ServiceManager>::make(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
    IPCThreadState::self()->setTheContextObject(manager);
    //将自己设置为管理员,handle是0
    ps->becomeContextManager();
    //准备looper
    sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
    //以前是 binder_loop死 循环接收驱动的消息,现在是 通知驱动BC_ENTER_LOOPER,监听驱动fd,有消息时回调到handleEvent处理binder调用
    BinderCallback::setupTo(looper);
    //服务的注册监听相关
    ClientCallbackCallback::setupTo(looper, manager);
    //无限循环等待消息
    while(true) {
        looper->pollAll(-1);
    }

    // should not be reached
    return EXIT_FAILURE;
}

3.2 Introdução ao initWithDriver

frameworks/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::initWithDriver(const char* driver)
{     //retorna um objeto ProcessState sp     return init(driver, true /*requireDefault*/);}


3.3 Introdução ao ProcessState::init

frameworks/native/libs/binder/ProcessState.cpp

sp<ProcessState> ProcessState::init(const char *driver, bool requireDefault)
{     [[clang::no_destroy]] static sp<ProcessState> gProcess;     [[clang::no_destroy]] static std::mutex gProcessMutex;

    if (driver == nullptr) {         std::lock_guard<std::mutex> l(gProcessMutex);         retornar gProcess;     }


    [[clang::no_destroy]] static std::once_flag gProcessOnce;
    //call_once garante que a função ou fragmento de código só precisa ser executado uma vez em um ambiente multithread
    std::call_once(gProcessOnce, [&](){   //julgamento/ Se dev/binder é legível, 0 para sucesso, -1 para falha.         if (access(driver, R_OK) == -1) {             ALOGE("O driver Binder %s não está disponível. Usando /dev/binder em vez disso .", driver);             driver = "/dev/binder";         }
     



        std::lock_guard<std::mutex> l(gProcessMutex);
       //实例化ProcessState
        gProcess = sp<ProcessState>::make(driver);

    });

    if (requireDefault) {         // Detecta se estamos tentando inicializar com um driver diferente e         // considera isso um erro. ProcessState só será inicializado uma vez acima.         LOG_ALWAYS_FATAL_IF(gProcess->getDriverName() != driver,                             "ProcessState já foi inicializado com %s,"                             "não é possível inicializar com %s.",                             gProcess->getDriverName().c_str(), driver);     }






    retornar gProcess;
}

3.4 Introdução ao construtor de ProcessState

frameworks/native/libs/binder/ProcessState.cpp

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    //abrir driver
    , mDriverFD(open_driver(driver))
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsC quantidade(0)
    , mWaitingForThreads(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
    , mCallRestriction(CallRestriction::NONE)
{     if (mDriverFD >= 0) {         // mapeia o fichário, fornecendo um pedaço de espaço de endereço virtual para receber transações.


        //Mapeamento de memória virtual, finalmente chame a função binder_mmap()
        //O tamanho da memória mapeada:

       //#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
        //1M-2 páginas tão grandes quanto o tamanho normal do aplicativo
        mVMStart = mmap(nullptr, BINDER_VM_SIZE , PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0 );
        if (mVMStart == MAP_FAILED) {             // *suspiro*             ALOGE("Falha no uso de %s: não foi possível mapear a memória de transação.\n", mDriverName.c_str());             close(mDriverFD);             mDriverFD = -1;             mDriverName.clear();         }     }






#ifdef __ANDROID__
    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "O driver do Binder '%s' não pôde ser aberto. Terminando.", driver);
#endif
}

3.5 introdução ao open_driver

frameworks/native/libs/binder/ProcessState.cpp

static int open_driver(const char *driver)
{   //Abra /dev/binder, leia e grave e habilite o sinalizador close-on-exec (close-on-exec) para o descritor de arquivo recém-criado para evitar tempo de descritor de arquivo não intencional vaza para o processo filho criado por fork     int fd = open(driver, O_RDWR | O_CLOEXEC);     if (fd >= 0) {         int vers = 0;         //Obtém a versão do Binder e finalmente chama a função binder_ioctl()         status_t result = ioctl (fd, BINDER_VERSION, &vers);         if (resultado == -1) {             ALOGE("Binder ioctl para obter versão falhou: %s", strerror(errno));             close(fd);             fd = -1;         }         if (resultado! = 0 || versões! = BINDER_CURRENT_PROTOCOL_VERSION) {
 











          ALOGE("O protocolo do driver Binder (%d) não corresponde ao protocolo de espaço do usuário (%d)! Valor de retorno de ioctl(): %d",
                vers, BINDER_CURRENT_PROTOCOL_VERSION, resultado);
            fechar(fd);
            fd = -1;
        }
        tamanho_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        //设置最大threads数量
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
        if (resultado == -1) {             ALOGE("Binder ioctl para definir o máximo de threads falhou: %s", strerror(errno));         }         uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;         //设置oneway         result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);





        if (resultado == -1) {             ALOGD("Binder ioctl para ativar a detecção de spam unilateral falhou: %s", strerror(errno));         }     } else {         ALOGW("Falha na abertura de '%s': %s\n", driver, strerror(errno));     }     retornar fd; }






3.6 Fluxograma geral de inicialização do ServiceManager

O processo acima está organizado em um fluxograma da seguinte forma: pode-se observar que as operações open, ioctl e mmap são executadas em initWithDriver.

4. Introdução ao IServicManager

4.1 Introdução ao diretório do IServiceManager

O código do IServiceManager está localizado no seguinte diretório
frameworks/native/libs/binder

Android.bp
Binder.cpp
BpBinder.cpp
IInterface.cpp
IPCThreadState.cpp
IServiceManager.cpp
Parcel.cpp
ProcessState.cpp

frameworks/native/libs/binder/aidl/android/os/
IClientCallback.aidl  
IServiceCallback.aidl  
IServiceManager.aidl  
ServiceDebugInfo.aidl

4.2 Introdução ao bp do IServiceManager

IServiceManager é compilado em libbinder.so, que se refere a libbinder_aidl, e o arquivo aidl usado no serviço ServiceManager superior também se refere a este libbinder_aidl.

frameworks/native/libs/binder/Android.bp

cc_library { 
name: "libbinder",

// for vndbinder

vendor_available: true, vndk: { enabled: true, },
...
    srcs: [
        "Binder.cpp",
        "BpBinder.cpp",
        "IInterface.cpp",
        "IPCThreadState.cpp",
        "IServiceManager.cpp",
...

        ":libbinder_aidl",//引用aidl文件
],
    aidl: {//输出aidl头文件

        export_aidl_headers: true,

    },
},
// AIDL interface between libbinder and framework.jar
filegroup {
    name: "libbinder_aidl",
    srcs: [//aidl文件
        "aidl/android/os/IClientCallback.aidl",
        "aidl/android/os/IServiceCallback.aidl",
        "aidl/android/os/IServiceManager.aidl",
        "aidl/android/os/ServiceDebugInfo.aidl",
    ],
    path: "aidl",
}

 IServiceManager é baseado em AIDL e libbinder, e a classe ServiceManagerShim herda IServiceManager.As solicitações do cliente são encaminhadas por ServiceManagerShim. Porque o cliente obtém o objeto IServiceManager através do método defaultServiceManager().

4.3 Introdução ao defaultServiceManager

A implementação do defaultServiceManager é a seguinte: Você pode ver que o ponteiro do objeto ServiceManagerShim é retornado no final, então todas as solicitações do lado do cliente são encaminhadas pelo ServiceManagerShim.

frameworks/native/libs/binder/IServiceManager.cpp

sp<IServiceManager> defaultServiceManager()
{
    std::call_once(gSmOnce, []() {
        sp<AidlServiceManager> sm = nullptr;
        while (sm == nullptr) {
            //拿到客户端BpServiceManager(new BpBinder(0))的实例
            sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
            if (sm == nullptr) {
                ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str());
                sleep(1);
            }
        }
        //new ServiceManagerShim,拿到BpServiceManager
        gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
    });

    return gDefaultServiceManager;
}

Em seguida, fale sobre como obter o objeto fichário do lado bp em defaultServiceManager, obter BpBinder(0) por meio de ProcessState::self()->getContextObject(nullptr) e, em seguida, obter BpServiceManager por meio de interface_cast.

frameworks/native/libs/binder/ProcessState.cpp

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
//获取handler为0的IBinder
    sp<IBinder> context = getStrongProxyForHandle(0);
...
    return context;
}

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    //加锁
    AutoMutex _l(mLock);
    handle_entry* e = lookupHandleLocked(handle);
    if (e != nullptr) {
        IBinder* b = e->binder;
        if (b == nullptr || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                IPCThreadState* ipc = IPCThreadState::self();
                CallRestriction originalCallRestriction = ipc->getCallRestriction();
                //设置调用限制
                ipc->setCallRestriction(CallRestriction::NONE);

                Parcel data;
                //PING_TRANSACTION
                status_t status = ipc->transact(
                        0, IBinder::PING_TRANSACTION, data, nullptr, 0);

                ipc->setCallRestriction(originalCallRestriction);
                //如果object死亡,就返回空
                if (status == DEAD_OBJECT)
                   return nullptr;
            }
            //new BpBinder(0)
            sp<BpBinder> b = BpBinder::create(handle);
            e->binder = b.get();
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
...
        }
    }
    //返回客户端BpBinder
    return result;
}

4.4 Introdução à implementação de interface_cast e asInterface

Como o interface_cast é implementado? Vamos ver como é o código-fonte. O asInterface é retornado na função interface_cast, ou seja, um novo objeto proxy Bp é retornado. Quando o serviço é definido, ele deve conter a seguinte instrução.

DECLARE_META_INTERFACE(CustomizeManagerService); 
IMPLEMENT_META_INTERFACE(CustomizeManagerService, NATIVESERVICE_NAME);

frameworks/native/libs/binder/include/binder/IInterface.h

template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)                                                                                                                              
{
    return INTERFACE::asInterface(obj);
}
//在服务中声明
#define DECLARE_META_INTERFACE(INTERFACE)
    static ::android::sp<I##INTERFACE> asInterface(                     \                                                                                                                
            const ::android::sp<::android::IBinder>& obj);   
//在服务中声明
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) 
   ::android::sp<I##INTERFACE> I##INTERFACE::asInterface(              \
            const ::android::sp<::android::IBinder>& obj)               \
    {                                                                   \
        ::android::sp<I##INTERFACE> intr;                               \
        if (obj != nullptr) {                                           \
            intr = ::android::sp<I##INTERFACE>::cast(                   \
                obj->queryLocalInterface(I##INTERFACE::descriptor));    \
            if (intr == nullptr) {                                      \
                //new Bp的代理对象并返回
                intr = ::android::sp<Bp##INTERFACE>::make(obj);         \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    } 

4.5 Introdução a outras interfaces do IServiceManager

Algumas interfaces são definidas no IServiceManager, que herda o IInterface, portanto, as interfaces de função no lado do cliente e no lado do servidor devem ser consistentes com essas interfaces e deve haver implementações específicas no lado do servidor.

frameworks/native/libs/binder/IServiceManager.cpp

#include <binder/IServiceManager.h>
#include <android/os/BnServiceCallback.h>
#include <android/os/IServiceManager.h>
//ServiceManagerShim继承IServiceManager
class ServiceManagerShim : public IServiceManager
{
public:
    explicit ServiceManagerShim (const sp<AidlServiceManager>& impl);

    sp<IBinder> getService(const String16& name) const override;
    sp<IBinder> checkService(const String16& name) const override;
    status_t addService(const String16& name, const sp<IBinder>& service,
                        bool allowIsolated, int dumpsysPriority) override;
    Vector<String16> listServices(int dumpsysPriority) override;
    sp<IBinder> waitForService(const String16& name16) override;
    bool isDeclared(const String16& name) override;
    Vector<String16> getDeclaredInstances(const String16& interface) override;
    std::optional<String16> updatableViaApex(const String16& name) override;
    IBinder* onAsBinder() override {
        return IInterface::asBinder(mTheRealServiceManager).get();
    }
};

frameworks/native/libs/binder/include/binder/IServiceManager.h

classe IServiceManager: IInterface pública

...

5. Outros serviços registram/obtêm serviços através do IServicManager

5.1: Serviços de Registro

5.1.1 Exemplo de adição de outros serviços ao ServiceManager

Primeiro observe um exemplo de serviço de registro, conforme mostrado na figura abaixo, você pode ver que o serviço de registro é feito através da interface addService do IServiceManager.

sp<ProcessState> proc(ProcessState::self());
//获取BpServiceManager指针
sp<IServiceManager> sm = defaultServiceManager();

sp<CustomizeManagerService> mService = new CustomizeManagerService();
//通过IServiceManager注册服务
sm->addService(String16(NATIVESERVICE_NAME), mService, false);

ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();

5.1.2 Introdução ao addService no Cliente

Neste exemplo, quando o serviço CustomizeManagerService registra o serviço por meio de IServiceManager, ele obtém o ponteiro do objeto do BpServiceManager por meio da interface defaultServiceManager() e, em seguida, adiciona o serviço por meio da interface addService. O código addService é o seguinte:

frameworks/native/libs/binder/IServiceManager.cpp
status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
                                        bool allowIsolated, int dumpsysPriority)
{
    //mTheRealServiceManager为BpServiceManager
    Status status = mTheRealServiceManager->addService(
        String8(name).c_str(), service, allowIsolated, dumpsysPriority);
    return status.exceptionCode();
}

5.1.3 Processo de atribuição do mTheRealServiceManager

Como surgiu o mTheRealServiceManager? Vamos dar uma olhada no processo de atribuição de mTheRealServiceManager

frameworks/native/libs/binder/IServiceManager.cpp
//两者等价
using AidlServiceManager = android::os::IServiceManager;

// From the old libbinder IServiceManager interface to IServiceManager.
class ServiceManagerShim : public IServiceManager
{
...
//变量声明
    sp<AidlServiceManager> mTheRealServiceManager;
};

sp<IServiceManager> defaultServiceManager()
{
...
        sp<AidlServiceManager> sm = nullptr;
        while (sm == nullptr) {
            sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
...
        }
        //此处将sm传入了,即也就赋值给了mTheRealServiceManager
        gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
...
}

ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl)
 : mTheRealServiceManager(impl)//impl赋给mTheRealServiceManager
{}
Pode-se observar pelo exposto que mTheRealServiceManager é equivalente a impl, que é o objeto ServiceManager do Bp.

5.1.4  Introdução ao addService do IServiceManager, processo completo de Bp->Bn

Em seguida, fale sobre o processo addService e vá para IServiceManager.cpp e execute-os de acordo com os seguintes rótulos 1, 2, 3, 4 e 5.

 out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm64_armv8-a_shared/gen/aidl/android/os/IServiceManager.cpp

#include <android/os/IServiceManager.h>
#include <android/os/BpServiceManager.h>
namespace android {
namespace os {
DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager")
}  // namespace os
}  // namespace android
#include <android/os/BpServiceManager.h>
#include <android/os/BnServiceManager.h>
#include <binder/Parcel.h>
#include <android-base/macros.h>
BpServiceManager::BpServiceManager(const ::android::sp<::android::IBinder>& _aidl_impl)
    : BpInterface<IServiceManager>(_aidl_impl){
}
1. 先走Bp的addService方法
::android::binder::Status BpServiceManager::addService(const ::std::string& name, const ::android::sp<::android::IBinder>& service, bool allowIsolated, int32_t dumpPriority) {
  ::android::Parcel _aidl_data;
  _aidl_data.markForBinder(remoteStrong());
  ::android::Parcel _aidl_reply;
  ::android::status_t _aidl_ret_status = ::android::OK;
  ::android::binder::Status _aidl_status;
  //标注远程服务名称,getInterfaceDescriptor为远程服务端接口描述
  _aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_ret_status = _aidl_data.writeUtf8AsUtf16(name);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_ret_status = _aidl_data.writeStrongBinder(service);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_ret_status = _aidl_data.writeBool(allowIsolated);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_ret_status = _aidl_data.writeInt32(dumpPriority);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  2. 调用transact方法,与服务端进行通信,此处remote()后面会解释
  _aidl_ret_status = remote()->transact(BnServiceManager::TRANSACTION_addService, _aidl_data, &_aidl_reply, 0);
  if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IServiceManager::getDefaultImpl())) {
     return IServiceManager::getDefaultImpl()->addService(name, service, allowIsolated, dumpPriority);
  }
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  if (!_aidl_status.isOk()) {
    return _aidl_status;
  }
  _aidl_error:
  _aidl_status.setFromStatusT(_aidl_ret_status);
  return _aidl_status;
}
}  // namespace os
}  // namespace android

namespace android {
namespace os {
BnServiceManager::BnServiceManager()
{
  ::android::internal::Stability::markCompilationUnit(this);
}
3. 走Bn端的onTransact
::android::status_t BnServiceManager::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
  ::android::status_t _aidl_ret_status = ::android::OK;
  switch (_aidl_code) {
4. 根据Bp端的transact中关键字走进此处case
  case BnServiceManager::TRANSACTION_addService:
  {
    ::std::string in_name;
    ::android::sp<::android::IBinder> in_service;
    bool in_allowIsolated;
    int32_t in_dumpPriority;
    if (!(_aidl_data.checkInterface(this))) {
      _aidl_ret_status = ::android::BAD_TYPE;
      break;
    }
    _aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_name);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
    _aidl_ret_status = _aidl_data.readStrongBinder(&in_service);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
    _aidl_ret_status = _aidl_data.readBool(&in_allowIsolated);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
    _aidl_ret_status = _aidl_data.readInt32(&in_dumpPriority);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
    5. 调用Bn端的getService方法
    ::android::binder::Status _aidl_status(addService(in_name, in_service, in_allowIsolated, in_dumpPriority));
    _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
    if (!_aidl_status.isOk()) {
      break;
    }
  }
...
}  // namespace os
}  // namespace android

5.1.5 Introdução ao remote() em remote()->transact do BpServiceManager no lado do cliente

Pode-se observar na etapa 2 que a próxima comunicação é realizada chamando remote()->transact(BnServiceManager::TRANSACTION_getService, _aidl_data, &_aidl_reply, 0).

O que é remoto()? Pela sua implementação pode-se perceber que é mRemote.

frameworks/native/libs/binder/include/binder/Binder.h

 class BpRefBase : public virtual RefBase
{
    inline IBinder* remote() const { return mRemote; }
    IBinder* const          mRemote;
};

mRemote é atribuído no método a seguir, você pode ver que o.get() é atribuído a mRemote.

frameworks/native/libs/binder/include/binder/IInterface.h

BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(nullptr), mState(0)                                                                                                                                        
{... }

Onde está a instanciação do BpRefBase? A seguir, podemos ver que o parâmetro de entrada remoto é atribuído a BpRefBase no construtor de BpInterface.
frameworks/native/libs/binder/include/binder/IInterface.h

template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)                                                                                                                                                                  
{}

Como pode ser visto no arquivo a seguir, BpServiceManager herda BpInterface, então onde o BpServiceManager é instanciado?Na explicação acima de defaultServiceManager, pode-se ver claramente que o parâmetro de entrada é BpBinder.

/out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm64_armv8-a_shared/gen/aidl/android/os/BpServiceManager.h

#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <utils/Errors.h>
#include <android/os/IServiceManager.h>
namespace android {
namespace os {
class BpServiceManager : public ::android::BpInterface<IServiceManager> {
...
};  // class BpServiceManager
}  // namespace os
}  // namespace android

Pode-se ver acima que remote() é BpBinder. Isso também entrou no método transact do BpBinder.

5.1.6 Introdução de transações do BpBinder no lado do cliente

frameworks/native/libs/binder/BpBinder.cpp

status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
...
        status_t status;
...
            status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags);
...
    return DEAD_OBJECT;
}

frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
... //cmd为BC_TRANSACTION
    err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);
...
        if (reply) {
            err = waitForResponse(reply);
        } else {
            Parcel fakeReply;
            err = waitForResponse(&fakeReply);
        }
...
}

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
    binder_transaction_data tr;

    tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
    tr.target.handle = handle;
    tr.code = code;
    tr.flags = binderFlags;
    tr.cookie = 0;
    tr.sender_pid = 0;
    tr.sender_euid = 0;

    const status_t err = data.errorCheck();
    if (err == NO_ERROR) {
        tr.data_size = data.ipcDataSize();
        tr.data.ptr.buffer = data.ipcData();
        tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
        tr.data.ptr.offsets = data.ipcObjects();
    } else if (statusBuffer) {
        tr.flags |= TF_STATUS_CODE;
        *statusBuffer = err;
        tr.data_size = sizeof(status_t);
        tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
        tr.offsets_size = 0;
        tr.data.ptr.offsets = 0;
    } else {
        return (mLastError = err);
    }
//cmd为BC_TRANSACTION
    mOut.writeInt32(cmd);
    mOut.write(&tr, sizeof(tr));

    return NO_ERROR;
}

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
...     //和Driver通信
        if ((err=talkWithDriver()) < NO_ERROR) break;
...
}

5.1.6 Introdução ao talkWithDriver do cliente

status_t IPCThreadState::talkWithDriver(bool doReceive)
{ ...

//Comunique-se com /dev/binder, fd é mProcess->mDriverFD
        if (ioctl( mProcess->mDriverFD , BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
...
}


Até agora, o fluxo de dados do lado do cliente terminou, então como o lado do servidor sabe que há uma alteração de dados em /dev/binder e os lê?

5.1.7 Como o servidor sabe que há uma alteração de dados em /dev/binder e os lê

3: No processo de inicialização do ServiceManager  , pode-se observar que quando o lado do servidor é iniciado, dois retornos de chamada são registrados, um dos quais é BinderCallback, e o lado do servidor conhece as alterações de dados em /dev/binder por meio do BinderCallback e notifica o ServerManager para Leia-o.

5.1.8 Introdução ao LooperCallback herdado por BinderCallback no ServiceManager

     BinderCallback herda LooperCallback, e LooperCallback pode ver a implementação principal do Handler na camada C++, e você conhecerá a função de LooperCallback. Existem duas funções importantes no Handler, nomeadamente addFd e handleEvent.

system/core/libutils/include/utils/Looper.h
class LooperCallback : public virtual RefBase {
...
    virtual int handleEvent(int fd, int events, void* data) = 0;
};

class Looper : public RefBase {

public:

    int addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data);
    int addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data);

...

addFd函数在调用时, 传入一个需要添加的fd到对应Looper的epoll事件监听池中,对fd中感兴趣的事件进行监听,监听的结果会返回到传入的监听器中。

handleEvent函数是用于处理指定的文件描述符poll事件,就是在looper中epoll_wait之后,当我们增加的fd有数据就会调用这个函数。

5.1.9 ServiceManager中的BinderCallback介绍

下面看一下Server端的BinderCallback是怎么做的。

frameworks/native/cmds/servicemanager/main.cpp

class BinderCallback : public LooperCallback {
public:
    static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
        sp<BinderCallback> cb = sp<BinderCallback>::make();

        int binder_fd = -1;
        //这个binder_fd是哪个fd呢
        IPCThreadState::self()->setupPolling(&binder_fd);
        LOG_ALWAYS_FATAL_IF(binder_fd < 0, "Failed to setupPolling: %d", binder_fd);
        //向looper中添加binder_fd,并传入callback监听器
        int ret = looper->addFd(binder_fd,
                                Looper::POLL_CALLBACK,
                                Looper::EVENT_INPUT,
                                cb,
                                nullptr /*data*/);
        LOG_ALWAYS_FATAL_IF(ret != 1, "Failed to add binder FD to Looper");

        return cb;
    }
    //当binder_fd有变化时,会回调该函数
    int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
        //收到变化时,调用此函数
        IPCThreadState::self()->handlePolledCommands();
        return 1;  // Continue receiving callbacks.
    }
};

frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::setupPolling(int* fd)
{
...
    //此处对fd进行了赋值
    *fd = mProcess->mDriverFD;
    return 0;
}

Pode ser visto no código acima que no método setupTo de BinderCallback, o método addFd é chamado e mProcess-> mDriverFD é atribuído a binder_fd e passado para o looper, de modo que seja exatamente igual ao fd acima talkWithDriver , ou seja, quando mProcess->mDriverFD Quando o conteúdo em mDriverFD for alterado, o método handleEvent será chamado para notificar o ServiceManager do lado do servidor.

Qual fd do nó é mDriverFD?mDriverFD é atribuído quando o método open_driver(driver) é executado quando ProcessState executa o construtor.

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))

Conforme explicado acima, open_driver é chamado quando ProcessState é instanciado após a execução do método ProcessState::initWithDriver(driver) em main.cpp, e o driver de entrada é "/dev/binder". Até agora, você entendeu melhor o princípio Binder?

frameworks/native/cmds/servicemanager/main.cpp
    const char* driver = argc == 2 ? argv[1]: "/dev/fichário" ;
    sp<ProcessState> ps = ProcessState::initWithDriver( driver );

frameworks/native/libs/binder/ProcessState.cpp
static int open_driver(const char *driver)
{     // driver就是"/dev/binder"     int fd = open( driver , O_RDWR | O_CLOEXEC); ...     retornar fd; }




Há cada vez mais coisas para falar, se você não entende, leia várias vezes.

Neste ponto, o ServiceManager do lado do servidor já sabe que o conteúdo da memória compartilhada em /dev/binder foi alterado e então a operação de leitura real será iniciada.

5.1.10 Processo subsequente de handleEvent em BinderCallback no ServiceManager

IPCThreadState::self()->handlePolledCommands() é chamado em handleEvent em BinderCallback.

frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::handlePolledCommands()
{     status_t resultado;

    faça {         resultado= getAndExecuteCommand ();     } while (mIn.dataPosition() <mIn.dataSize());

    processPendingDerefs();
    flushCommands();
    resultado de retorno;
}

frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::getAndExecuteCommand()
{     status_t resultado;     int32_t cmd;

    resultado = talkWithDriver();
    if (resultado >= NO_ERROR) { ...         cmd = mIn.readInt32();//cmd é BR_TRANSACTION, há uma explicação na frente ...


        resultado = executeCommand(cmd);

...
}

sp< BBinder > the_context_object;
status_t IPCThreadState:: executeCommand (int32_t cmd)
{ ...     switch ((uint32_t)cmd) { case BR_TRANSACTION:         { ...


   

            } else {                 //sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());                 //IPCThreadState::self()->setTheContextObject(manager);//将manager设置给了the_context_object,所以the_context_object就是Server端ServerManager对象//                调用BBinder的transact                 error = the_context_object->transact(tr.code, buffer, &resposta, tr.flags);             } ... } frameworks/native/libs/binder/Binder.cpp status_t BBinder::transact (     código uint32_t, const Parcel& dados, resposta Parcel*, sinalizadores uint32_t) {     status_t err = NO_ERROR;     mudar (código) { ...














            err = onTransact (código, dados, resposta, sinalizadores);
            quebrar;
    }

5.1.11 Introdução ao onTransact do BnServiceManager no lado do servidor

Finalmente, o método onTransact do BnServiceManager é chamado , que é a terceira etapa acima.

out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm64_armv8-a_shared/gen/aidl/android/os/BnServiceManager.h #include <
binder/IInterface.h>
#include <android/os/IServiceManager. h>
namespace android { namespace os { class BnServiceManager : public ::android:: BnInterface <IServiceManager> { ...     ::android::status_t onTransact (uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android:: Parcela* _aidl_reply, uint32_t _aidl_flags) substituição;



...

frameworks/native/libs/binder/include/binder/IInterface.h
classe BnInterface : INTERFACE pública, BBinder pública

frameworks/native/libs/binder/include/binder/Binder.h

classe BBinder : public IBinder
{

...
    virtual status_t     onTransact (código uint32_t,
                                    const Parcel& data,
                                    Parcel* resposta,
                                    uint32_t flags = 0);

...

5.1.12 Introdução ao addService no lado do servidor

Quando a etapa 5 for executada, ele entrará em frameworks/native/cmds/servicemanager/ServiceManager.cpp no ​​lado Bn, ou seja, na implementação de código do servidor Bn.

frameworks/native/cmds/servicemanager/ServiceManager.cpp

 Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool permitIsolated, int32_t dumpPriority) { auto     ctx = mAccess->getCallingContext(); ...     //Adiciona o nome do serviço ao Na estrutura     // Sobrescrever o serviço antigo se existir



    mNameToService[nome] = Serviço {         .binder = fichário,         .allowIsolated = permitirIsolado,         .dumpPriority = dumpPriority,         .debugPid = ctx.debugPid,     }; ...     retornar Status::ok(); }







5.1.13 Introdução para adicionar mapa de lista de serviços no lado do servidor

A declaração de mNameToService é a seguinte, ou seja, o serviço final é adicionado ao mapa

frameworks/native/cmds/servicemanager/ServiceManager.h

usando ServiceMap = std:: map <std::string, Service>;
ServiceMap mNameToService;

    struct Service {         sp<IBinder> fichário; // não é nulo         bool permitirIsolado;         int32_t dumpPrioridade;         bool hasClients = falso; // notificações enviadas em true -> false.         bool garantiaCliente = falso; // força a verificação do cliente para true         pid_t debugPid = 0; // o processo no qual este serviço é executado





        // o número de clientes do serviço, incluindo o próprio servicemanager
        ssize_t getNodeStrongRefCount();
    };

5.2 Obtenção de serviços

5.2.1 Obtenha exemplo de serviço através do IServiceManager

O exemplo de obtenção do serviço é o seguinte, e o objeto de serviço correspondente também é obtido por meio do IServiceManager.

sp<IServiceManager> sm = defaultServiceManager();
//获取服务
sp<ICustomizeManagerService> mService = ICustomizeManagerService::asInterface(sm->getService(String16("customizeManagerservice")));
if(mService != NULL)
{
    //获取到服务的binder对象,然后调用服务的接口
    mService.customize();
}

Como o asInterface é implementado? Foi explicado acima, você pode pesquisar.

5.2.2 Introdução à interface getService do lado do cliente

Na interface getService, se o serviço não for iniciado, ele iniciará o serviço, mas aguardará até 5s.

frameworks/native/libs/binder/IServiceManager.cpp
sp<IBinder> ServiceManagerShim::getService(const String16& name) const
{
    sp<IBinder> svc = checkService(name)
......
    //有5s超时机制
    constexpr int64_t timeout = 5000;
    int64_t startTime = uptimeMillis();
    ......
    int n = 0;
    while (uptimeMillis() - startTime < timeout) {
        n++;
        usleep(1000*sleepTime);

        sp<IBinder> svc = checkService(name);
        if (svc != nullptr) {
            ALOGI("Waiting for service '%s' on '%s' successful after waiting %" PRIi64 "ms",
                  String8(name).string(), ProcessState::self()->getDriverName().c_str(),
                  uptimeMillis() - startTime);
...
}

sp<IBinder> ServiceManagerShim::checkService(const String16& name) const
{
    sp<IBinder> ret;
    //checkService
    if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
        return nullptr;
    }
    return ret;
}

5.2.3 processo getServerice Bp->Bn em IServiceManager 

#include <android/os/BpServiceManager.h>
#include <android/os/BnServiceManager.h>
#include <binder/Parcel.h>
#include <android-base/macros.h>
namespace android {
namespace os {
BpServiceManager::BpServiceManager(const ::android::sp<::android::IBinder>& _aidl_impl)
    : BpInterface<IServiceManager>(_aidl_impl){
}
1. Bp端getService
::android::binder::Status BpServiceManager::getService(const ::std::string& name, ::android::sp<::android::IBinder>* _aidl_return) {
  ::android::Parcel _aidl_data;
  _aidl_data.markForBinder(remoteStrong());
  ::android::Parcel _aidl_reply;
  ::android::status_t _aidl_ret_status = ::android::OK;
  ::android::binder::Status _aidl_status;
  _aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
2. write name
  _aidl_ret_status = _aidl_data.writeUtf8AsUtf16(name);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
3. BpBinder->transact
  _aidl_ret_status = remote()->transact(BnServiceManager::TRANSACTION_getService, _aidl_data, &_aidl_reply, 0);
  if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IServiceManager::getDefaultImpl())) {
     return IServiceManager::getDefaultImpl()->getService(name, _aidl_return);
  }
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  if (!_aidl_status.isOk()) {
    return _aidl_status;
  }
  _aidl_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_error:
  _aidl_status.setFromStatusT(_aidl_ret_status);
  return _aidl_status;
}
}  // namespace os
}  // namespace android

#include <android/os/BnServiceManager.h>
#include <binder/Parcel.h>
#include <binder/Stability.h>
namespace android {
namespace os {
BnServiceManager::BnServiceManager()
{
  ::android::internal::Stability::markCompilationUnit(this);
}
4.Bn->onTransact
::android::status_t BnServiceManager::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
  ::android::status_t _aidl_ret_status = ::android::OK;
  switch (_aidl_code) {
  case BnServiceManager::TRANSACTION_getService:
  {
    ::std::string in_name;
    ::android::sp<::android::IBinder> _aidl_return;
    if (!(_aidl_data.checkInterface(this))) {
      _aidl_ret_status = ::android::BAD_TYPE;
      break;
    }
5. read name
    _aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_name);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
6.调用Bn端实现类getService
    ::android::binder::Status _aidl_status(getService(in_name, &_aidl_return));
    _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
    if (!_aidl_status.isOk()) {
      break;
    }
7.将reply write进去
    _aidl_ret_status = _aidl_reply->writeStrongBinder(_aidl_return);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
  }
  break;
...


5.2.4 Introdução ao getService do lado do servidor

Eventualmente será chamado para o lado Bn.

Bn服务端
frameworks/native/cmds/servicemanager/ServiceManager.cpp
Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
    *outBinder = tryGetService(name, false);
    return Status::ok();
}


sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
    auto ctx = mAccess->getCallingContext();

    sp<IBinder> out;
    Service* service = nullptr;
//去mNameToService查找name名字的service
    if (auto it = mNameToService.find(name); it != mNameToService.end()) {
        service = &(it->second);

        if (!service->allowIsolated) {
            uid_t appid = multiuser_get_app_id(ctx.uid);
            bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;

            if (isIsolated) {
                return nullptr;
            }
        }
        out = service->binder;
    }

    if (!mAccess->canFind(ctx, name)) {
        return nullptr;
    }

    if (!out && startIfNotFound) {
//启动服务
        tryStartService(name);
    }

    if (out) {
        // Setting this guarantee each time we hand out a binder ensures that the client-checking
        // loop knows about the event even if the client immediately drops the service
        service->guaranteeClient = true;
    }

    return out;
}

Acho que você gosta

Origin blog.csdn.net/weixin_41028555/article/details/130316582
Recomendado
Clasificación