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
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.2 Introdução ao initWithDriver
3.3 Introdução ao ProcessState::init
3.4 Introdução ao construtor de ProcessState
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.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.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/binderAndroid.bp
Binder.cpp
BpBinder.cpp
IInterface.cpp
IPCThreadState.cpp
IServiceManager.cpp
Parcel.cpp
ProcessState.cppframeworks/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
{}
5.1.4 Introdução ao addService do IServiceManager, processo completo de Bp->Bn
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.htemplate<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úblicaframeworks/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;
}