Android O
(8.0 和 8.1) 起,Google 开启了 Project Treble
计划,引入了新的系统架构模式 Treble
。
关于 Treble
架构,详情请参考:
简单来说,宏观上,Treble
之前的 Android 设备更新系统时,在更新上层系统之前必须先更新底层供应商(Vendor)的硬件支持代码,这很麻烦,新系统往往不能得到及时更新,Treble
将 Vendor
(芯片供应制造商编写的设备专属底层代码) 和 Android 系统代码分离,这样就规避之前版本的问题。
HAL (Hardware Abstract Layer - 硬件抽象层)
将硬件设备和 Android 操作系统分割开来,负责硬件设备和操作系统的通信。Android O 起,HAL 的硬件组件得到划分,比如音频,无线电频。这些底层的硬件划分通过 HIDL (HAL interface defination language - HAL接口定义语言)
和上层的操作系统中的系统服务进行通信。目前有数十个不同的 HIDL接口包 ,其中 HIDL
也是通过 Binder
实现通信的。 HIDL
和 AIDL
很相似,具体语法有区别,但核心都是通过 Binder
实现通讯
RIL (Radio interface layer - 无线接口层)
用于提供电话通信(Telephony)服务,其中也包括了 SMS
,而 RIL
是位于 HAL
层的。所以 Android O 起,RIL
的通信方式由之前的 Socket
通信变成了 Binder
通信。
关于 RIL
的底层逻辑,详情参考
源码分析 这里用 Android 8.1 (api 27)
的源码来进行分析。
RIL
借由 IRadioIndication
和 IRadioResponse
定义了 HIDL 接口,建立起 HAL
层和 framework 层的 RIL 通信交互。在 Framework 层,由 RadioIndication
和 RadioResponse
分别实现了该 HIDL 接口:
1 2 3 4 5 6 7 8 9 public class RadioIndication extends IRadioIndication .Stub { } public class RadioResponse extends IRadioResponse .Stub { }
无线通信制式有 CDMA
和 GSM
,在 Android 系统中也有对应的编码实现。
GSM 制式下的 SMS 接收过程 GSM
制式下,新短信到来,会调用 RadionIndication#newSms()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class RadionIndication extends IRadioIndication .Stub { RIL mRil; RadioIndication(RIL ril) { mRil = ril; } public void newSms (int indicationType, ArrayList<Byte> pdu) { mRil.processIndication(indicationType); byte [] pduArray = RIL.arrayListToPrimitiveArray(pdu); if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS); mRil.writeMetricsNewSms(SmsSession.Event.Tech.SMS_GSM, SmsSession.Event.Format.SMS_FORMAT_3GPP); SmsMessage sms = SmsMessage.newFromCMT(pduArray); if (mRil.mGsmSmsRegistrant != null ) { mRil.mGsmSmsRegistrant.notifyRegistrant(new AsyncResult(null , sms, null )); } } }
解析出 SmsMessage
对象后,将短信数据封装在 AsyncResult
对象并通知给相应的 GSM
注册者。
RIL
的 mGsmSmsRegistrant
是 Registrant
对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class Registrant { WeakReference refH; int what; Object userObj; public Registrant (Handler h, int what, Object obj) { refH = new WeakReference(h); this .what = what; userObj = obj; } public void notifyRegistrant (AsyncResult ar) { internalNotifyRegistrant (ar.result, ar.exception); } 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); } } public Handler getHandler () { if (refH == null ) return null ; return (Handler) refH.get(); } }
可以看出,Registrant
其实就是借由 Handler
发送消息,携带 SMS 信息的 AsyncResult
的消息则是在 Handler#handleMessage()
中被处理。而 Handler
是在 Registrant
的构造函数中被引用的,我们需要看 Handler
到底是哪个,就需要看 Ril
的 mGsmSmsRegistrant
在哪里被初始化。
RIL
继承自 BaseCommands
,通过调用 setOnNewGsmSms
实现 mGsmSmsRegistrant
的初始化。
1 2 3 4 5 6 7 8 9 10 public abstract class BaseCommands implements CommandsInterface { protected Registrant mGsmSmsRegistrant; @Override public void setOnNewGsmSms (Handler h, int what, Object obj) { mGsmSmsRegistrant = new Registrant (h, what, obj); } }
而 setOnNewGsmSms
在 GsmInboundSmsHandler
的构造函数中被调用:
1 2 3 4 5 6 7 8 9 10 11 public class GsmInboundSmsHandler extends InboundSmsHandler { private GsmInboundSmsHandler (Context context, SmsStorageMonitor storageMonitor, Phone phone) { super ("GsmInboundSmsHandler" , context, storageMonitor, phone, GsmCellBroadcastHandler.makeGsmCellBroadcastHandler(context, phone)); phone.mCi.setOnNewGsmSms(getHandler(), EVENT_NEW_SMS, null ); mDataDownloadHandler = new UsimDataDownloadHandler(phone.mCi); } }
从以上分析可以看出, GsmInboundSmsHandler
注册的 Registrant
对象只关注 EVENT_NEW_SMS
事件,并且在 RadioIndication#newSms()
中也会发送 EVENT_NEW_SMS
事件消息。
我们现在来看一下 GsmInboundSmsHandler
的继承关系,GsmInboundSmsHandler
继承自 InboundSmsHanlder
,而 InboundSmsHandler
继承自 StateMachine
, 这里的 StateMachine
就是 有限状态机
,状态机里面的不同状态(State)可以在特定条件下进行相互转换。那么,这里的 StateMachine
类是如何实现状态机的呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 public class StateMachine { private static class SmsHandler extends Handler { @Override public final void handleMessage (Message msg) { if (!mHasQuit) { if (mIsConstructionCompleted) { msgProcessedState = processMsg(msg); } performTransitions(msgProcessState, msg); } } private final State processMsg (Message msg) { while (!curStateInfo.state.processMessage(msg)) { curStateInfo = curStateInfo.parentStateInfo; if (curStateInfo == null ) { mSm.unhandledMessage(msg); break ; } } return (curStateInfo != null ) ? curStateInfo.state : null ; } private void performTransitions (State msgProcessedState, Message msg) { } private final void transitionTo (IState destState) { } private void addState (State state, State parent) { } } private SmsHandler mSmsHandler; public final Handler getHandler () { return mSmsHandler; } protected StateMachine (String name, Looper looper) { initStateMachine(name, looper); } private void initStateMachine (String name, Looper looper) { mName = name; mSmHandler = new SmHandler(looper, this ); } } public interface IState { void enter () ; void exit () ; boolean processMessage (Message msg) ; } public class State implements IState { }
通过上面的源码可以看出来,StateMachine
其实就是通过 Handler
去实现的,通过 handleMessage()
来处理当前状态,通过 transitionTo()
来进行状态迁移,通过 addState()
来进行状态机中状态的添加。而 GsmInboundSmsHandler
初始化方法中的 getHandler()
返回的就是 StateMachine
中的 SmsHandler
对象 mSmsHandler
。
接下来看一下状态机中初始时,添加了哪些状态,在 InboundSmsHandler
构造函数中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public abstract class InboundSmsHanlder extends StateMachine { protected InboundSmsHandler (String name, Context context, SmsStorageMonitor storageMonitor, Phone phone, CellBroadcastHandler cellBroadcastHandler) { super (name); addState(mDefaultState); addState(mStartupState, mDefaultState); addState(mIdleState, mDefaultState); addState(mDeliveringState, mDefaultState); addState(mWaitingState, mDeliveringState); setInitialState(mStartupState); } }
初始状态是 StartupState
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private class StartupState extends State { @Override public boolean processMessage (Message msg) { log("StartupState.processMessage:" + msg.what); switch (msg.what) { case EVENT_START_ACCEPTING_SMS: transitionTo(mIdleState); return HANDLED; } } }
而在 GsmInboundSmsHandler
初始化之后,就会发送 EVENT_START_ACCEPTING_SMS
消息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public class ImsSMSDispatcher extends SMSDispatcher { public ImsSMSDispatcher (Phone phone, SmsStorageMonitor storageMonitor, SmsUsageMonitor usageMonitor) { super (phone, usageMonitor, null ); mCdmaDispatcher = new CdmaSMSDispatcher(phone, usageMonitor, this ); mGsmInboundSmsHandler = GsmInboundSmsHandler.makeInboundSmsHandler(phone.getContext(), storageMonitor, phone); mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler(phone.getContext(), storageMonitor, phone, (CdmaSMSDispatcher) mCdmaDispatcher); mGsmDispatcher = new GsmSMSDispatcher(phone, usageMonitor, this , mGsmInboundSmsHandler); SmsBroadcastUndelivered.initialize(phone.getContext(), mGsmInboundSmsHandler, mCdmaInboundSmsHandler); InboundSmsHandler.registerNewMessageNotificationActionHandler(phone.getContext()); } } public class SmsBroadcastUndelivered { public static void initialize (Context context, GsmInboundSmsHandler gsmInboundSmsHandler, CdmaInboundSmsHandler cdmaInboundSmsHandler) { if (instance == null ) { instance = new SmsBroadcastUndelivered( context, gsmInboundSmsHandler, cdmaInboundSmsHandler); } if (gsmInboundSmsHandler != null ) { gsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_START_ACCEPTING_SMS); } if (cdmaInboundSmsHandler != null ) { cdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_START_ACCEPTING_SMS); } } }
所以在 GsmInboundSmsHandler
发送 EVENT_START_ACCEPTING_SMS
之后,状态机进入 IdleState
状态:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private class IdleState extends State { @Override public boolean processMessage (Message msg) { log("IdleState.processMessage:" + msg.what); if (DBG) log("Idle state processing message type " + msg.what); switch (msg.what) { case EVENT_NEW_SMS: case EVENT_INJECT_SMS: case EVENT_BROADCAST_SMS: deferMessage(msg); transitionTo(mDeliveringState); return HANDLED; } } }
在之前的分析中说到,RadioIndication#newSms()
发送 EVENT_NEW_SMS
事件消息,所以在接收到该消息之后,IdleState
状态会进入到 DeliveringState
状态:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 private class DeliveringState extends State { @Override public boolean processMessage (Message msg) { switch (msg.what) { case EVENT_NEW_SMS: handleNewSms((AsyncResult) msg.obj); sendMessage(EVENT_RETURN_TO_IDLE); return HANDLED; } } }
DeliveringState
状态下,接收到 EVENT_NEW_SMS
消息事件,会执行 handleNewSms()
方法,接下来看下该方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public abstract class InboundSmsHandler { private void handleNewSms (AsyncResult ar) { try { SmsMessage sms = (SmsMessage) ar.result; result = dispatchMessage(sms.mWrappedSmsMessage); } catch (RuntimeException ex) { } } private int dispatchMessage (SmsMessageBase smsb) { return dispatchMessageRadioSpecific(smsb); } protected abstract int dispatchMessageRadioSpecific (SmsMessageBase smsb) ; protected int dispatchNormalMessage (SmsMessageBase sms) { SmsHeader smsHeader = sms.getUserDataHeader(); InboundSmsTracker tracker; if ((smsHeader == null ) || (smsHeader.concatRef == null )) { tracker = TelephonyComponentFactory.getInstance().makeInboundSmsTracker(sms.getPdu(), sms.getTimestampMillis(), destPort, is3gpp2(), false , sms.getOriginatingAddress(), sms.getDisplayOriginatingAddress(), sms.getMessageBody()); } else { tracker = TelephonyComponentFactory.getInstance().makeInboundSmsTracker(sms.getPdu(), sms.getTimestampMillis(), destPort, is3gpp2(), sms.getOriginatingAddress(), sms.getDisplayOriginatingAddress(), concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount, false , sms.getMessageBody()); } return addTrackerToRawTableAndSendMessage(tracker, tracker.getDestPort() == -1 ); } } public class GsmInboundSmsHandler extends InboundSmsHandler { protected int dispatchMessageRadioSpecific (SmsMessageBase smsb) { return dispatchNormalMessage(smsb); } }
从上面的源码中可以看出,handleNewSms()
调用链为 handleNewSms()
-> dispatchMessage()
-> dispatchMessageRadioSpecific()
-> dispatchNormalMessage()
-> addTrackerToRawTableAndSendMessage()
。
接着看 addTrackerToRawTableAndSendMessage()
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 protected int addTrackerToRawTableAndSendMessage (InboundSmsTracker tracker, boolean deDup) { switch (addTrackerToRawTable(tracker, deDup)) { case Intents.RESULT_SMS_HANDLED: sendMessage(EVENT_BROADCAST_SMS, tracker); return Intents.RESULT_SMS_HANDLED; case Intents.RESULT_SMS_DUPLICATED: return Intents.RESULT_SMS_HANDLED; case Intents.RESULT_SMS_GENERIC_ERROR: default : return Intents.RESULT_SMS_GENERIC_ERROR; } } private int addTrackerToRawTable (InboundSmsTracker tracker, boolean deDup) { if (deDup) { try { if (duplicateExists(tracker)) { return Intents.RESULT_SMS_DUPLICATED; } } catch (SQLException e) { return Intents.RESULT_SMS_GENERIC_ERROR; } } String address = tracker.getAddress(); String refNumber = Integer.toString(tracker.getReferenceNumber()); String count = Integer.toString(tracker.getMessageCount()); ContentValues values = tracker.getContentValues(); Uri newUri = mResolver.insert(sRawUri, values); try { long rowId = ContentUris.parseId(newUri); if (tracker.getMessageCount() == 1 ) { tracker.setDeleteWhere(SELECT_BY_ID, new String[]{Long.toString(rowId)}); } else { String[] deleteWhereArgs = {address, refNumber, count}; tracker.setDeleteWhere(tracker.getQueryForSegments(), deleteWhereArgs); } return Intents.RESULT_SMS_HANDLED; } catch (Exception e) { loge("error parsing URI for new row: " + newUri, e); return Intents.RESULT_SMS_GENERIC_ERROR; } }
上述源码中,先执行 addTrackerToRawTable()
来试图将新短信数据插入到短信数据库,根据该方法返回的结果进而返回不同的值。插入成功后,返回 Intents.RESULT_SMS_HANDLED
,并通过 sendMessage(EVENT_BROADCAST_SMS, tracker)
发送 EVENT_BROADCAST_SMS
事件。
相同的思路,EVENT_BROADCAST_SMS
事件最终还是会在 DeliveringState
状态时被处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private class DeliveringState extends State { @Override public boolean processMessage (Message msg) { switch (msg.what) { case EVENT_BROADCAST_SMS: InboundSmsTracker inboundSmsTracker = (InboundSmsTracker) msg.obj; if (processMessagePart(inboundSmsTracker)) { sendMessage(EVENT_UPDATE_TRACKER, inboundSmsTracker); transitionTo(mWaitingState); } else { sendMessage(EVENT_RETURN_TO_IDLE); } return HANDLED; } } }
EVENT_BROADCAST_SMS
事件到来,会执行 processMessagePart()
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 private boolean processMessagePart (InboundSmsTracker tracker) { SmsBroadcastReceiver resultReceiver = new SmsBroadcastReceiver(tracker); boolean filterInvoked = filterSms(pdus, destPort, tracker, resultReceiver, true ); if (!filterInvoked) { dispatchSmsDeliveryIntent(pdus, tracker.getFormat(), destPort, resultReceiver); } } private void dispatchSmsDeliveryIntent (byte [][] pdus, String format, int destPort, SmsBroadcastReceiver resultReceiver) { Intent intent = new Intent(); intent.putExtra("pdus" , pdus); intent.putExtra("format" , format); if (destPort == -1 ) { intent.setAction(Intents.SMS_DELIVER_ACTION); ComponentName componentName = SmsApplication.getDefaultSmsApplication(mContext, true ); if (componentName != null ) { intent.setComponent(componentName); } else { intent.setComponent(null ); } } else { intent.setAction(Intents.DATA_SMS_RECEIVED_ACTION); Uri uri = Uri.parse("sms://localhost:" + destPort); intent.setData(uri); intent.setComponent(null ); intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); } Bundle options = handleSmsWhitelisting(intent.getComponent()); dispatchIntent(intent, android.Manifest.permission.RECEIVE_SMS, AppOpsManager.OP_RECEIVE_SMS, options, resultReceiver, UserHandle.SYSTEM); } public void dispatchIntent (Intent intent, String permission, int appOp, Bundle opts, BroadcastReceiver resultReceiver, UserHandle user) { mContext.sendOrderedBroadcastAsUser(intent, user, permission, appOp, opts, resultReceiver, getHandler(), Activity.RESULT_OK, null , null ); }
通过调用链:processMessagePart()
-> dispatchSmsDeliveryIntent()
-> dispatchIntent()
最终向系统发送相关短信广播。至此,Gsm
制式下的 Android 系统短信接收和广播发送过程基本分析完毕。
CDMA 制式下的 SMS 接收过程 CDMA
制式下,新短信到来,会调用 RadionIndication#cdmaNewSms()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class RadionIndication extends IRadioIndication .Stub { RIL mRil; RadioIndication(RIL ril) { mRil = ril; } public void cdmaNewSms (int indicationType, CdmaSmsMessage msg) { mRil.processIndication(indicationType); mRil.writeMetricsNewSms(SmsSession.Event.Tech.SMS_CDMA, SmsSession.Event.Format.SMS_FORMAT_3GPP2); SmsMessage sms = SmsMessageConverter.newSmsMessageFromCdmaSmsMessage(msg); if (mRil.mCdmaSmsRegistrant != null ) { mRil.mCdmaSmsRegistrant.notifyRegistrant(new AsyncResult(null , sms, null )); } } }
同样也会通过 mRil.mCdmaSmsRegistrant.notifyRegistrant
来通知给 CDMA
相关的 Registrant
对象。接下来流程和 GSM
制式下的流程基本一致,就不再详述了。
参考