概述MMS 的收发操作借助于手机的短信机制,实际收发过程需要网络的 APN 支持,使用特定的 APN 接入点实现 MMS 数据的真实发送和接收; 源码流程1) Telephpony.java getOrCreateThreadId() 函数: 目录: \frameworks\base\core\java\android\provider\ 说明:这个函数根据接收者列表和未保存的消息返回一个线程 ID ,如果这个消息开始一个新的线程,那么函数分配一个线程 ID ,否则返回一个适当的已经存在的线程 ID ; 2) MmsMessageSender.java sendMessage() 函数: 目录: \packages\apps\mms\src\com\android\mms\transaction\ 说明:对 Mms 进行封包 3) 再一次调用第一步函数 4) ConnectivityService.java startUsingNetworkFeature() 函数: 目录: \framework\base\services\java\com\android\server\ 说明:该函数为实现 Mms 网络连接的关键函数,下面我们详细分析: A、 enforceChangePermission() :判断调用的进程是否具有操作权限,如果不具有,抛出一个 SecurityException 异常,并强制准许权限 B、 ConnectivityManager.isNetworkTypeValid(networkType) 来判断 networkType 是否合法,如果不合法返回一个 APN_REQUEST_FAILED , 在这里用到了最重要的 ConnectivityManager 类: public class ConnectivityManager 定义在 \frameworks\base\core\java\android\net 的 ConnectivityManager.java 里,其主要作用为: 1 、监视网络连接,如 WIFI 、 GPRS 、 UMTS 等 2 、当网路连接出现变化的时候,发送广播 intents 3 、当一个网络连接丢失之后,尝试连接另一个网络 4 、为 App 提供粗粒度、细粒度的有效网络状态查询 C、 FeatureUser f = new FeatureUser(networkType, feature, binder); 新建一个 FeatureUser 类变量,该类实现:当调用进程 died 时发送一个 Notice ,这样就可以自我老化 D 、 int usedNetworkType = networkType; if(networkType == ConnectivityManager.TYPE_MOBILE) { if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) { usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS; } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) { usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL; } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN)) { usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN; } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) { usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI; } } 这段代码获取使用的网络类型; E 、 NetworkStateTracker network = mNetTrackers[usedNetworkType]; NetworkStateTracker 类在 NetworkStateTracker.java 里:每个子类保持跟踪一个网络接口的连接状态,一个网络的状态信息由一个 Tracker 类保持,基类管理 network-type-independent 网络状态 F 、 mFeatureUsers.add(f); 列表操作,将 f 添加到列表的 end G 、 if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) { // this gets used for per-pid dns when connected mNetRequestersPids[usedNetworkType].add(currentPid); } 判断网络操作需要的 Pid 是否包含当前 Pid ,如果不包含就添加进去 H 、 mHandler.sendMessageDelayed(mHandler.obtainMessage( NetworkStateTracker.EVENT_RESTORE_DEFAULT_NETWORK, f), getRestoreDefaultNetworkDelay()); 消息发送,问题:消息的 Handle 函数也在该文件本地,? I 、 if ((ni.isConnectedOrConnecting() == true) && !network.isTeardownRequested()) { if (ni.isConnected() == true) { // add the pid-specific dns Log.d(TAG, "fanyl test ++++ before handleDnsConfigurationChange"); handleDnsConfigurationChange();
if (DBG) Log.d(TAG, "special network already active"); return Phone.APN_ALREADY_ACTIVE; } if (DBG) Log.d(TAG, "special network already connecting"); return Phone.APN_REQUEST_STARTED; } 这里判断网络是正在连接还是已经连接完成,如果是已经连接完成,就去设置 Dns ,并返回 already 状态 J 、 network.reconnect() 如果网络不是已经连接完成的状态的话,这里触发一个重新连接,直到网络状态变成 isConnected ;
5) 接下来的操作存在于 DataConnectionTracker.java 里: public synchronized int enableApnType(String type) : 该函数确保用指定的类型连接 APN ,成功返回 APN_ALREADY_ACTIVE 或者 APN_REQUEST_STARTED private void setEnabled(int id, boolean enable) : 发送 EVENT_ENABLE_NEW_APN 事件 protected synchronized void onEnableApn(int apnId, int enabled) 该实例主要功能是判断目前是 enable 还是 disable APN ,如果是 enable 的话,调用 onEnableNewApn(); 实现 enable APN ,如果是 disable 的话,根据 enabledCount , onCleanUpConnection 关闭 APN 或者改为默认连接 6) public void handleMessage(Message msg) , ConnectivityService.java 里 进入到对事件 EVENT_STATE_CHANGED 的处理, state= CONNECTED, old= CONNECTING, reason= apnChanged, apnTypeList= mms ,应该是最后调用了 handleConnect(info); 发送一个广播事件 7) MobileDataStateTracker.java : MobileDataStateReceiver 类的 public void onReceive(Context context, Intent intent) 函数里处理 case CONNECTED 处理;调用 setDetailedState ( NetworkStateTracker 类实例)发送了 EVENT_STATE_CHANGED 事件 8) 然后又跳回 ConnectivityService.java 里的 handleMessage 函数 EVENT_STATE_CHANGED 事件的 CONNECTED 状态处理 9) handleConnect 里最后调用 updateNetworkSettings (实现在 NetworkStateTracker 类里),并发送 sendConnectedBroadcast(info); 广播事件 10) ConnectivityService.java handleDnsConfigurationChange 配置 DNS 信息,并在 handleConnect 函数调用 addPrivateDnsRoutes 添加路由信息 11) 接下来调用了 GpsLocationProvider.java 里的 updateNetworkState 和 runLocked ,原因不明? 12) 接下来返回去调用 startUsingNetworkFeature ( ConnectivityService.java ),又一次 add dns ?,然后返回 APN_ALREADY_ACTIVE 状态 13) ensureRouteToHost()(/packages/apps/Mms/src/com/android/mms/transaction/Transaction.java) 调用了 ConnectivityManager 类里的 requestRouteToHost 至此关于 Mms 的 Apn 网络连接就建立起来了, 下面的步骤是在 RILJ 层以及 RILD 层实现数据和 AT 命令与 modem 的数据通信,省去 下面分析 disable APN 的流程,基本上就是 Start 的反过程: 1) 数据通信完毕, SendTransaction.java 里的 run 函数给出数据通信完成之后的状态 2) stopUsingNetworkFeature ()( ConnectivityService 实例);这个就是 startUsingNetworkFeature 的反过程 3) disableApnType ( mms ), DataConnectionTracker 类 4) setEnabled , DataConnectionTracker 类 5) |
|