android接收短信——framework处理流程(android 5.1)

时间:2023-03-09 13:40:42
android接收短信——framework处理流程(android 5.1)

modem层不懂,所以直接从RIL.java开始。以电信卡接收短信为例

modem通知RIL.java中的 RILReceiver处理接收信息

class RILReceiver implements Runnable {
byte[] buffer; RILReceiver() {
buffer = new byte[RIL_MAX_COMMAND_BYTES];
} @Override
public void
run() {
......
//建立socked连接,读取数据 processResponse(p);
......
}
}
private void
processResponse (Parcel p) {
int type; type = p.readInt(); if (type == RESPONSE_UNSOLICITED) {
processUnsolicited (p); //接收短息会进入这里
} else if (type == RESPONSE_SOLICITED) {
RILRequest rr = processSolicited (p);
if (rr != null) {
rr.release();
decrementWakeLock();
}
}
}

processUnsolicited(Parcel p)方法中,罗列了各种类型的信息,
processUnsolicited (Parcel p) {
int response;
Object ret; response = p.readInt(); try {switch(response) {
/*
cat libs/telephony/ril_unsol_commands.h \
| egrep "^ *{RIL_" \
| sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/'
*/ case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret = responseString(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret = responseInts(p); break;
case RIL_UNSOL_ON_USSD: ret = responseStrings(p); break;
case RIL_UNSOL_NITZ_TIME_RECEIVED: ret = responseString(p); break;
case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break;
case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break;
case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break;
case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break;
case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break;
case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break;
case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
case RIL_UNSOL_SIM_REFRESH: ret = responseSimRefresh(p); break;
case RIL_UNSOL_CALL_RING: ret = responseCallRing(p); break;
case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCdmaSms(p); break;
case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseRaw(p); break;
case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break;
case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: ret = responseInts(p); break;
case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break;
case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_CELL_INFO_LIST: ret = responseCellInfoList(p); break;
case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_SRVCC_STATE_NOTIFY: ret = responseInts(p); break;
case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: ret = responseHardwareConfig(p); break;
case RIL_UNSOL_RADIO_CAPABILITY:
ret = responseRadioCapability(p); break;
case RIL_UNSOL_ON_SS: ret = responseSsData(p); break;
case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: ret = responseString(p); break;
case RIL_UNSOL_LCEDATA_RECV: ret = responseLceData(p); break;

电信卡接收信息,是 RIL_UNSOL_RESPONSE_CDMA_NEW_SMS

case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
if (RILJ_LOGD) unsljLog(response); SmsMessage sms = (SmsMessage) ret; if (mCdmaSmsRegistrant != null) {
mCdmaSmsRegistrant
.notifyRegistrant(new AsyncResult(null, sms, null)); //mCdmaSmsRegistrant 在 CdmaInboundSmsHandler 初始化时创建
}
break;
public void
notifyRegistrant(AsyncResult ar)
{
internalNotifyRegistrant (ar.result, ar.exception);
} /*package*/ void
internalNotifyRegistrant (Object result, Throwable exception)
{
Handler h = getHandler(); if (h == null) {
clear();
} else {
Message msg = Message.obtain(); msg.what = what; msg.obj = new AsyncResult(userObj, result, exception); h.sendMessage(msg); //handler来处理接收信息事件
}
}
mCdmaSmsRegistrant.notifyRegistrant(..)就进入状态机(StateMachine)处理了。处理的信息接收的状态机是 InboundSmsHandler extends StateMachine
InboundSmsHandler是抽象类,对于CDMA信息是 CdmaInboundSmsHandler extends InboundSmsHandler, 对于GSM信息是 GsmInboundSmsHandler extends InboundSmsHandler

关于CdmaInboundSmsHandler 状态机是何时启动并初始化的,细节没研究。应该是在手机启动后,一系列系统服务启动时完成的。
看看CdmaInboundSmsHandler 的构造函数  
/**
* Create a new inbound SMS handler for CDMA.
*/
private CdmaInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor,
PhoneBase phone, CdmaSMSDispatcher smsDispatcher) {
super("CdmaInboundSmsHandler", context, storageMonitor, phone,
CellBroadcastHandler.makeCellBroadcastHandler(context, phone));
mSmsDispatcher = smsDispatcher;
mServiceCategoryProgramHandler = CdmaServiceCategoryProgramHandler.makeScpHandler(context,
phone.mCi);
phone.mCi.setOnNewCdmaSms(getHandler(), EVENT_NEW_SMS, null); //这里构造了RIL中需要的 mCdmaSmsRegistrant
}
 public void setOnNewCdmaSms(Handler h, int what, Object obj) {
mCdmaSmsRegistrant = new Registrant (h, what, obj);
}
/**
* Wait for state machine to enter startup state. We can't send any messages until then.
*/
public static CdmaInboundSmsHandler makeInboundSmsHandler(Context context,
SmsStorageMonitor storageMonitor, PhoneBase phone, CdmaSMSDispatcher smsDispatcher) {
CdmaInboundSmsHandler handler = new CdmaInboundSmsHandler(context, storageMonitor,
phone, smsDispatcher); //构造CdmaInboudSmsHandler状态机
handler.start(); //启动 state machine
return handler;
}

在CdmaInboudSmsHandler初始化会调用父类InboundSmsHandler的构造函数,会增加各种状态。

protected InboundSmsHandler(String name, Context context, SmsStorageMonitor storageMonitor,
PhoneBase phone, CellBroadcastHandler cellBroadcastHandler) {
super(name);
...... addState(mDefaultState);
addState(mStartupState, mDefaultState);
addState(mIdleState, mDefaultState);
addState(mDeliveringState, mDefaultState);
addState(mWaitingState, mDeliveringState); setInitialState(mStartupState);
if (DBG) log("created InboundSmsHandler");
}

综上,RILReceiver接收信息,进入状态机CdmaInboundSmsHandler处理,具体是父类StateMachine中的Hanler传递消息,并切换各状态(state)处理。

状态: mDefaultState,mStartupState,mIdleState,mDeliveringState,mWaitingState以及默认的QuitSatte, HaltState。
各状态是如何切换处理的? 没搞明白。有待研究。 接收信息最终传递处理在 mDeliveringState中 (代码实现在InboundsSmsHandler.java中)
 class DeliveringState extends State {
@Override
public void enter() {
if (DBG) log("entering Delivering state");
} @Override
public void exit() {
if (DBG) log("leaving Delivering state");
} @Override
public boolean processMessage(Message msg) {
log("DeliveringState.processMessage:" + msg.what);
switch (msg.what) {
case EVENT_NEW_SMS:
// handle new SMS from RIL
handleNewSms((AsyncResult) msg.obj); //继续处理新接收的信息
sendMessage(EVENT_RETURN_TO_IDLE);
return HANDLED;
void handleNewSms(AsyncResult ar) {
if (ar.exception != null) {
loge("Exception processing incoming SMS: " + ar.exception);
return;
} int result;
try {
SmsMessage sms = (SmsMessage) ar.result;
result = dispatchMessage(sms.mWrappedSmsMessage); //信息传递处理完成,并返回结果
} catch (RuntimeException ex) {
loge("Exception dispatching message", ex);
result = Intents.RESULT_SMS_GENERIC_ERROR;
} // RESULT_OK means that the SMS will be acknowledged by special handling,
// e.g. for SMS-PP data download. Any other result, we should ack here.
if (result != Activity.RESULT_OK) { //注意这里的返回结果,一般是 Intents.RESULT_SMS_HANDLED,才可以继续反馈 ack 到 smsc
boolean handled = (result == Intents.RESULT_SMS_HANDLED);
notifyAndAcknowledgeLastIncomingSms(handled, result, null); //这里返回ACK给短信中心(smsc),表示信息已接收。
}
}
 void notifyAndAcknowledgeLastIncomingSms(boolean success,
int result, Message response) {
if (!success) {
// broadcast SMS_REJECTED_ACTION intent
Intent intent = new Intent(Intents.SMS_REJECTED_ACTION);
intent.putExtra("result", result);
mContext.sendBroadcast(intent, android.Manifest.permission.RECEIVE_SMS);
}
acknowledgeLastIncomingSms(success, result, response);
}
protected abstract void acknowledgeLastIncomingSms(boolean success,
int result, Message response); //具体实现在 CdmaInboundsSmsHandler 或 GsmInboundSmsHandler中
CdmaInboundsSmsHandler中处理acknowledgeLastIncomingSms
@Override
protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) {
if (isInEmergencyCallMode()) {
return;
} int causeCode = resultToCause(result);
mPhone.mCi.acknowledgeLastIncomingCdmaSms(success, causeCode, response); //这里又回到RIL中处理 if (causeCode == 0) {
mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint;
}
mLastDispatchedSmsFingerprint = null;
}

RIL中用 RILSender 处理返回ACK,

 public void
acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result); rr.mParcel.writeInt(success ? 0 : 1); //RIL_CDMA_SMS_ErrorClass
// cause code according to X.S004-550E
rr.mParcel.writeInt(cause); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ " " + success + " " + cause); send(rr);
}

再看看信息传递处理dispatchMessage()

public int dispatchMessage(SmsMessageBase smsb) {
// If sms is null, there was a parsing error.
if (smsb == null) {
loge("dispatchSmsMessage: message is null");
return Intents.RESULT_SMS_GENERIC_ERROR;
} if (mSmsReceiveDisabled) {
// Device doesn't support receiving SMS,
log("Received short message on device which doesn't support "
+ "receiving SMS. Ignored.");
return Intents.RESULT_SMS_HANDLED;
} return dispatchMessageRadioSpecific(smsb);
}
protected abstract int dispatchMessageRadioSpecific(SmsMessageBase smsb);
 

InboundsSmsHandler中的dispatchMessageRadioSpecific(..)是抽象的,具体处理在CdmaInboundSmsHandler 或 GsmInboundSmsHandler中

然后会将新信息,用广播传递给MMS应用处理。