作者:GentlemanTsao
https://blog.csdn.net/GentelmanTsao
每篇一格言:
当好农民种好地,把头条留给别人。
——郁亮(万科集团董事会主席)
目录
接framework篇,没有看过framework的tx请先从framework开始:
接下来我们开始RIL部分的分析。
RSSI 上报的整体层次关系
首先回顾下RSSI 上报的整体层次关系,认识RIL所处的位置:
RSSI RIL部分的类关系
下面我们先看一下RIL部分的类关系,先建立整体认识。
图示中,
蓝色箭头:request call flow
绿色箭头:response call flow
analysis 1:RIL
在framework篇已经知道,ServiceStateTracker调用RIL的getSignalStrength方法获取signal。
下面回顾一下RIL的getSignalStrength:
public void getSignalStrength(Message result) {
//1 得到radio实例
IRadio radioProxy = getRadioProxy(result);
。。。
//2.得到RILRequest
RILRequest rr = obtainRequest(RIL_REQUEST_SIGNAL_STRENGTH, result,
mRILDefaultWorkSource);
。。。
//3. call radio的getSignalStrength
radioProxy.getSignalStrength(rr.mSerial);
。。。
}
2.得到RILRequest的实现逻辑是
取一个RILRequest对象;
并将该对象加到列表mRequestList;
private RILRequest obtainRequest(int request, Message result, WorkSource workSource) {
//2.1 取一个RILRequest对象
RILRequest rr = RILRequest.obtain(request, result, workSource);
//2.2 并将该对象加到列表
addRequest(rr);
return rr;
}
private void addRequest(RILRequest rr) {
acquireWakeLock(rr, FOR_WAKELOCK);
synchronized (mRequestList) {
rr.mStartTimeMs = SystemClock.elapsedRealtime();
//将RILRequest对象加入到 mRequestList
mRequestList.append(rr.mSerial, rr);
}
}
mRequestList是以RILRequest 为元素的SparseArray:
SparseArray<RILRequest> mRequestList = new SparseArray<RILRequest>();
mRequestList有什么用呢?试想,从RIL的角度看,经手了这么多request,必然涉及到后续的管理以及response callback的响应,所以RIL保留了request的临时档案,即mRequestList。
analysis 2:RILRequest
如下是RILRequest的类关系图
三个重要属性:
mSerial :序号
mRequest :消息请求ID
mResult :消息返回
一个重要方法:
obtain:
传入request,result,workspace,返回RILRequest对象。
RILRequest对象优先从pool中取,取不到则新建一个。
private static RILRequest obtain(int request, Message result) {
RILRequest rr = null;
synchronized (sPoolSync) {
if (sPool != null) {
rr = sPool;
sPool = rr.mNext;
rr.mNext = null;
sPoolSize--;
}
}
if (rr == null) {
rr = new RILRequest();
}
rr.mSerial = sNextSerial.getAndUpdate(n -> ((n + 1) % Integer.MAX_VALUE));
rr.mRequest = request;
rr.mResult = result;
。。。
return rr;
}
analysis 3:IRadio
回到RIL的getSignalStrength,最后执行到:
//3. call radio的getSignalStrength
radioProxy.getSignalStrength(rr.mSerial);
这里的radioProxy是IRadio的实例,IRadio是一个接口类,声明了telephony与cellular radio的通讯方法。其中包括getSignalStrength:
oneway getSignalStrength(int32_t serial);
它是一个request方法,有对应的response方法是IRadioResponse.getSignalStrengthResponse()
注:oneway修饰词
后面会讲到,IRadio的实现在ril_service中,因而getSignalStrength是远程调用。为了避免远程调用阻塞,用oneway修饰。
analysis 4:RadioImpl
即IRadio的实现类,在ril_service中定义
struct RadioImpl : public V1_1::IRadio, public hidl_death_recipient {
}
它的具体实现依赖平台。下面以QUALCOMM平台为例,看getSignalStrength的具体实现:
Return<void> RadioImpl::getSignalStrength(int32_t serial) {
std::shared_ptr<RadioContext> ctx = getContext(serial);
//Step1:得到message实例
auto msg = std::make_shared<RilRequestGetSignalStrengthMessage>(ctx);
。。。
//Step2:定义了callback方法
GenericCallback<QcRilRequestMessageCallbackPayload> cb(
[this, serial](std::shared_ptr<Message> msg, Message::Callback::Status status,
std::shared_ptr<QcRilRequestMessageCallbackPayload> resp) -> void {
if (resp != nullptr) {
RadioResponseInfo respInfo = {};
SignalStrength signalStrength = {};
populateResponseInfo(respInfo, serial, RESPONSE_SOLICITED, resp->errorCode);
auto rilSigResult = std::static_pointer_cast<qcril::interfaces::RilGetSignalStrengthResult_t>(resp->data);
。。。
convertRilSignalStrengthToHal(rilSigResult->respData, signalStrength);
RADIO_HIDL_SEND_RESPONSE(mSlotId, mRadioResponse,
getSignalStrengthResponse, respInfo, signalStrength);
}
});
//Step3:把step2的方法设为message的callback,然后分发message给NAS
msg->setCallback(&cb);
msg->dispatch();
。。。
}
message的callback方法是对返回数据的处理。下面详细分析step2:callback的实现(如下)
GenericCallback<QcRilRequestMessageCallbackPayload> cb(
[this, serial](std::shared_ptr<Message> msg, Message::Callback::Status status,
std::shared_ptr<QcRilRequestMessageCallbackPayload> resp) -> void {
if (resp != nullptr) {
//mark1:RadioResponseInfo
RadioResponseInfo respInfo = {};
//mark2:这是HAL中的SignalStrength
SignalStrength signalStrength = {};
populateResponseInfo(respInfo, serial, RESPONSE_SOLICITED, resp->errorCode);
auto rilSigResult = std::static_pointer_cast<qcril::interfaces::RilGetSignalStrengthResult_t>(resp->data);
。。。
//signal从ril转换到hal
convertRilSignalStrengthToHal(rilSigResult->respData, signalStrength);
//call HAL的getSignalStrengthResponse
RADIO_HIDL_SEND_RESPONSE(mSlotId, mRadioResponse,
getSignalStrengthResponse, respInfo, signalStrength);
}
});
mark1:RadioResponseInfo
该类封装了radio 消息返回的相关讯息,如下
mark2:HAL中的SignalStrength
该类封装了HAL中的signal讯息(注意区别于framework中的SignalStrength )
其中timingAdvance记录的是蜂窝到设备的传递时间,以ms为单位。
OK,数据已完备,接下来要返回给请求者。
analysis 5:IRadioResponse
和IRadio同样是接口类,上面已提到,它有一个response方法对应IRadio中的 getSignalStrength方法,即getSignalStrengthResponse(如下):
oneway getSignalStrengthResponse(RadioResponseInfo info, SignalStrength sigStrength);
它传递的参数即是RadioResponseInfo 和SignalStrength (HAL)。
我们还需看它的实现。
analysis 6:RadioResponse
RadioResponse是IRadioResponse 接口的实现类。
它实现了getSignalStrengthResponse方法,如下:
public void getSignalStrengthResponse(RadioResponseInfo responseInfo,
android.hardware.radio.V1_0.SignalStrength sigStrength) {
responseSignalStrength(responseInfo, sigStrength);
}
private void responseSignalStrength(
RadioResponseInfo responseInfo,
android.hardware.radio.V1_0.SignalStrength signalStrength) {
// 回调1:mRil即RIL.java
//根据responseInfo得到RILRequest
//还记得RILRequest的三个重要属性吗,回顾下analysis 2:RILRequest
RILRequest rr = mRil.processResponse(responseInfo);
if (rr != null) {
SignalStrength ret = new SignalStrength(signalStrength);
if (responseInfo.error == RadioError.NONE) {
// 发送RILRequest中保留的返回消息
sendMessageResponse(rr.mResult, ret);
}
// 回调2:回调RIL的processResponseDone
//处理error,记录log,处理wakelock,释放RILRequest
mRil.processResponseDone(rr, responseInfo, ret);
}
}
发送的返回消息便是EVENT_GET_SIGNAL_STRENGTH。
为什么?回顾下analysis 2:RILRequest以及framework篇:
全面&详细解析RSSI 其一,framework篇
analysis 7:ServiceStateTracker
最后,又回到ServiceStateTracker了,它接收EVENT_GET_SIGNAL_STRENGTH消息并更新signal数据,接着又安排了下一次signal poll。
case EVENT_GET_SIGNAL_STRENGTH:
。。。
ar = (AsyncResult) msg.obj;
onSignalStrengthResult(ar);
queueNextSignalStrengthPoll();
break;
这样framework的signal便不断刷新。
下面继续QCRIL的部分解析:
全面&详细解析RSSI 其三,QCRIL篇
养成好习惯,看完点赞,每天进步一点点