二次拨号计时, 就是在拨打电话给对方,对方电话接通后, 发送个line control 消息给自己, phone 接收到消息, 对电话拨通时间重置的一个动作。
二次拨号计时,在phoneApp 最主要的一个实现就是监听 lineControl 消息。 需要用到的函数在
PhoneProxy.java (frameworks\base\telephony\java\com\android\internal\telephony)中有个函数:
public void registerForLineControlInfo(Handler h, int what, Object obj) {
mActivePhone.registerForLineControlInfo( h, what, obj);
}
所以我的做法是在Phone中IncallScreen.java 中注册一个监听
// only for cdma ElapsedTime reset
mCM.getPhoneInCall().registerForLineControlInfo(mHandler, PHONE_LINE_CONTROL_INFO, null);
在handle 中处理这个事件 。
case PHONE_LINE_CONTROL_INFO:
log("................PHONE_LINE_CONTROL_INFO");
resetLineControlInfo((AsyncResult) msg.obj);
break;
函数的具体实现为:
/**
* Displays a notification when the phone receives a LineControl record.
*/
private void resetLineControlInfo(AsyncResult r) {
// Extract the LineControl String from the message
CdmaLineControlInfoRec lineControlInfoRec = (CdmaLineControlInfoRec)(r.result);
if (lineControlInfoRec != null) {
byte polarityIncluded = lineControlInfoRec.lineCtrlPolarityIncluded;
if (DBG) log("resetLineControlInfo: polarityIncluded=" + polarityIncluded);
if (polarityIncluded ==1){
mCallCard.resetElapsedTime();
}
}
}
其中, mCallCard.resetElapsedTime() , 就是在callcard.java 中实现对计时的reset 。 从而实现二次计时。
附:
二次拨号跟踪流程(高通7627A平台):
1,Qcril_cm.c (vendor\qcom\proprietary\qcril\qcril_fusion) 中的
void qcril_cm_process_cdma_info_recs
(
qcril_instance_id_e_type instance_id,
qcril_modem_id_e_type modem_id
)
函数。 把所有infoRecs 消息都归类成 RIL_UNSOL_CDMA_INFO_REC 。 并上传报告给Ril侧。
2, 在RIL.java (frameworks\base\telephony\java\com\android\internal\telephony) 中, 函数processUnsolicited处理 RIL_UNSOL_CDMA_INFO_REC 消息。
case RIL_UNSOL_CDMA_INFO_REC:
ArrayList<CdmaInformationRecords> listInfoRecs;
try {
listInfoRecs = (ArrayList<CdmaInformationRecords>)ret;
} catch (ClassCastException e) {
Log.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
break;
}
for (CdmaInformationRecords rec : listInfoRecs) {
if (RILJ_LOGD) unsljLogRet(response, rec);
notifyRegistrantsCdmaInfoRec(rec);
}
break;
其中 notifyRegistrantsCdmaInfoRec 函数中, 有判断是否是 linecontrol消息。
private void
notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
int response = RIL_UNSOL_CDMA_INFO_REC;
。。。。。。。。。。。。。。。。。。。。。。。。。。
} else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) {
Log.e(LOG_TAG, ".................................infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec");
if (mLineControlInfoRegistrants != null) {
if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
mLineControlInfoRegistrants.notifyRegistrants(
new AsyncResult (null, infoRec.record, null));
}
} else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) {
。。。。。。。。。。。。。。。。。。。。。。。。。。。
}
如果是 linecontrol 消息, 那就会对所有注册 linecontrol 监听消息的对象发送一个通知。比如上面的phoneApp。