/** * This interface is used by telephony & telecom to talk to cellular radio. * All the functions have minimum one parameter: * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the * duration of a method call. If clients provide colliding serials (including passing the same * serial to different methods), multiple responses (one for each method call) must still be served. */ interface IRadio { /** * Set response functions for radio requests & radio indications. * * @param radioResponse Object containing response functions * @param radioIndication Object containing radio indications */ setResponseFunctions(IRadioResponse radioResponse, IRadioIndication radioIndication);
/** * Requests status of the ICC card * * @param serial Serial number of request. * * Response function is IRadioResponse.getIccCardStatusResponse() * */ oneway getIccCardStatus(int32_t serial); ... }
/** * Interface declaring response functions to solicited radio requests. * Response functions defined in this interface are as per following convention: * <xyz>Response is response to IRadio.<xyz> */ interface IRadioResponse { /** * @param info Response info struct containing response type, serial no. and error * @param cardStatus ICC card status as defined by CardStatus in types.hal * * Valid errors returned: * RadioError:NONE */ oneway getIccCardStatusResponse(RadioResponseInfo info, CardStatus cardStatus);
/** * @param info Response info struct containing response type, serial no. and error * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. * * Valid errors returned: * RadioError:NONE * RadioError:RADIO_NOT_AVAILABLE (radio resetting) * RadioError:PASSWORD_INCORRECT */ oneway supplyIccPinForAppResponse(RadioResponseInfo info, int32_t remainingRetries);
/** * Interface declaring unsolicited radio indications. */ interface IRadioIndication { /** * Indicates when radio state changes. * * @param type Type of radio indication * @param radioState Current radio state */ oneway radioStateChanged(RadioIndicationType type, RadioState radioState);
/** * Indicates when call state has changed. * Callee must invoke IRadio.getCurrentCalls() * Must be invoked on, for example, * "RING", "BUSY", "NO CARRIER", and also call state * transitions (DIALING->ALERTING ALERTING->ACTIVE) * * Redundent or extraneous invocations are tolerated * * @param type Type of radio indication */ oneway callStateChanged(RadioIndicationType type);
/** * Indicates when voice or data network state changed * Callee must invoke IRadio.getVoiceRegistrationState(), IRadio.getDataRegistrationState(), * and IRadio.getOperator() * * @param type Type of radio indication */ oneway networkStateChanged(RadioIndicationType type); .... }
configureRpcThreadpool(1, true/* callerWillJoin */); for (int i = 0; i < simCount; i++) { pthread_rwlock_t *radioServiceRwlockPtr = getRadioServiceRwlock(i); int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); assert(ret == 0);
radioService[i] = new RadioImpl; radioService[i]->mSlotId = i; oemHookService[i] = new OemHookImpl; oemHookService[i]->mSlotId = i; RLOGD("registerService: starting IRadio %s", serviceNames[i]); android::status_t status = radioService[i]->registerAsService(serviceNames[i]); status = oemHookService[i]->registerAsService(serviceNames[i]);
ret = pthread_rwlock_unlock(radioServiceRwlockPtr); assert(ret == 0); }
out << "#include <android/log.h>\n"; out << "#include <cutils/trace.h>\n"; out << "#include <hidl/HidlTransportSupport.h>\n\n"; if (isInterface) { // This is a no-op for IServiceManager itself. out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
// TODO(b/34274385) remove this out << "#include <hidl/LegacySupport.h>\n";
if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) { // HwBinder not available on this device or not accessible to // this process. returnnullptr; }
waitForHwServiceManager();
while (details::gDefaultServiceManager == NULL) { details::gDefaultServiceManager = fromBinder<IServiceManager, BpHwServiceManager, BnHwServiceManager>( ProcessState::self()->getContextObject(NULL)); if (details::gDefaultServiceManager == NULL) { LOG(ERROR) << "Waited for hwservicemanager, but got nullptr."; sleep(1); } } }
return details::gDefaultServiceManager; }
//等待hwservicemanager启动完成 voidwaitForHwServiceManager(){ using std::literals::chrono_literals::operator""s;
while (!WaitForProperty(kHwServicemanagerReadyProperty, "true", 1s)) { LOG(WARNING) << "Waited for hwservicemanager.ready for a second, waiting another..."; } }
if (e != NULL) { // We need to create a new BpHwBinder if there isn't currently one, OR we // are unable to acquire a weak reference on this current one. See comment // in getWeakProxyForHandle() for more info about this. IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { b = newBpHwBinder(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } else { result.force_set(b); e->refs->decWeak(this); } }
template <typename IType, typename ProxyType, typename StubType> sp<IType> fromBinder(const sp<IBinder>& binderIface){ using ::android::hidl::base::V1_0::IBase; using ::android::hidl::base::V1_0::BnHwBase;
if (binderIface.get() == nullptr) { returnnullptr; } // 代理对象,本地binder为空 if (binderIface->localBinder() == nullptr) { returnnewProxyType(binderIface); } sp<IBase> base = static_cast<BnHwBase*>(binderIface.get())->getImpl(); if (details::canCastInterface(base.get(), IType::descriptor)) { StubType* stub = static_cast<StubType*>(binderIface.get()); return stub->getImpl(); } else { returnnullptr; } }
这样HwServiceManager的在客户端的代理对象BpHwServerceManager将客户端请求发送给HAL Binder驱动;HAL Binder驱动则将请求发送给HAL服务管家的stub对象BnHwServiceManager(BnHwServiceManager在何时成为HAL服务上下文管家的,可以看看上一篇文章“Android HAL binder详解”)来完成服务的注册。
// XXX Have to look up the constructor here because otherwise that static // class initializer isn't called and gProxyOffsets.constructID is undefined :(
voidonNewCommandConnect(RIL_SOCKET_ID socket_id){ // Inform we are connected and the ril version int rilVer = s_callbacks.version; RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED, &rilVer, sizeof(rilVer), socket_id);
// implicit radio state changed RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0, socket_id);
// Send last NITZ time data, in case it was missed if (s_lastNITZTimeData != NULL) { resendLastNITZTimeData(socket_id); }
// Get version string if (s_callbacks.getVersion != NULL) { constchar *version; version = s_callbacks.getVersion(); RLOGI("RIL Daemon version: %s\n", version);