android 系统上做GC双模的---数据业务的处理分析

来源:互联网 发布:图片分类展示网站源码 编辑:程序博客网 时间:2024/05/13 13:43

一:modem相关的各种状态的监听和通知机制/通话相关的图标变换的工作原理。

网络状态,evdo,图标的处理
a、注册监听部分
==>SystemServer.java
  init2()
    Thread thr = new ServerThread();
    thr.setName("android.server.ServerThread");
    thr.start();
      ServerThread.run()
        com.android.server.status.StatusBarPolicy.installIcons(context, statusBar);
          sInstance = new StatusBarPolicy(context, service);
            // phone_signal
            mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
            mPhoneData = IconData.makeIcon("phone_signal",
               null, com.android.internal.R.drawable.stat_sys_signal_null, 0, 0);
            mPhoneIcon = service.addIcon(mPhoneData, null);
             // register for phone state notifications.
            ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))
                .listen(mPhoneStateListener,
                          PhoneStateListener.LISTEN_SERVICE_STATE
                        | PhoneStateListener.LISTEN_SIGNAL_STRENGTH
                        | PhoneStateListener.LISTEN_CALL_STATE
                        | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
                        | PhoneStateListener.LISTEN_DATA_ACTIVITY);
             //实际是调用的是TelephonyRegistry.listen,此listen函数会将Iphonestatelistener添加到对应的的handler数组中,到时来了事件会轮询回调。

            // data_connection
            mDataData = IconData.makeIcon("data_connection",
                null, com.android.internal.R.drawable.stat_sys_data_connected_g, 0, 0);
            mDataIcon = service.addIcon(mDataData, null);
            service.setIconVisibility(mDataIcon, false);

b、事件通知部分
==>PhoneFactory.java
makeDefaultPhones()
  sPhoneNotifier = new DefaultPhoneNotifier();
  useNewRIL(context);
    phone = new GSMPhone(context, new RIL(context), sPhoneNotifier);

for example
==>DataConnectionTracker.java
notifyDefaultData(String reason)
  phone.notifyDataConnection(reason);
    mNotifier.notifyDataConnection(this, reason);
    ==>DefaultPhoneNotifier.java
      mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
                    "telephony.registry"));
      mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()),
                    sender.isDataConnectivityPossible(), reason, sender.getActiveApn(),
                    sender.getInterfaceName(null));

 

二 CDMA EVDO拨号上网的通路原理。

上层java程序调用gprs流程:
=>PhoneApp.java
  onCreate()
    PhoneFactory.makeDefaultPhones(this);
      phone = new GSMPhone(context, new SimulatedCommands(), sPhoneNotifier);
        mDataConnection = new DataConnectionTracker (this);
          createAllPdpList();//建立缺省pdpconnection
             pdp = new PdpConnection(phone);
               dataLink = new PppLink(phone.mDataConnection);
               dataLink.setOnLinkChange(this, EVENT_LINK_STATE_CHANGED, null);
       
          //某个条件触发执行
          trySetupData(String reason)
           setupData(reason);
             pdp = findFreePdp();
             Message msg = obtainMessage();
             msg.what = EVENT_DATA_SETUP_COMPLETE;
             msg.obj = reason;
             pdp.connect(apn, msg);
                         phone.mCM.setupDefaultPDP(apn.apn, apn.user, apn.password,
                            obtainMessage(EVENT_SETUP_PDP_DONE));
        
           //收到EVENT_SETUP_PDP_DONE消息
           =>pdpconnection.java
           handleMessage()
             case EVENT_SETUP_PDP_DONE:
               dataLink.connect();//dataLink是pppLink.java
                  SystemService.start(SERVICE_PPPD_GPRS);//启动pppd_grps服务
                  poll.what = EVENT_POLL_DATA_CONNECTION;
                  sendMessageDelayed(poll, POLL_SYSFS_MILLIS);//启动轮询,看是否成功连接gprs
                    checkPPP()//每隔5秒轮询,看是否连接成功,或断开
                      //如果已经连接
                      mLinkChangeRegistrant.notifyResult(LinkState.LINK_UP);

                  //执行到pdpconnection.handleMessage()
                  case EVENT_LINK_STATE_CHANGED
                    onLinkStateChanged(ls);
                      case LINK_UP:
                        notifySuccess(onConnectCompleted);
                          onCompleted.sendToTarget();
              
                  //执行dataConnectionTracker.java的handleMessage()
                  case EVENT_DATA_SETUP_COMPLETE
                    notifyDefaultData(reason);
                      setupDnsProperties();
                      setState(State.CONNECTED);
                      phone.notifyDataConnection(reason);
                      startNetStatPoll();
                        resetPollStats();
                        1、读取发送出去的包数和接受到的包数
                        2、如果发送的数据包且没有收到应答包数n大于等于看门狗追踪的限定包数。
                        2.1、开始轮询pdp context list,尝试恢复网络连接
                        2.2、如果轮询24次后还没有联通网络则停止网络状态轮询,进行一次ping实验。
                        2.2.1、如果ping成功则,重新进行网络状态轮询,否则发送EVENT_START_RECOVERY事件。

                      // reset reconnect timer
                      nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;

着重c++部分代码的角度分析

=>DataConnectionTracker.java
trySetupData(String reason)
  setupData(reason);
    =>PdpConnection.java
    pdp.connect(apn, msg);
      =>RIL.JAVA
      phone.mCM.setupDefaultPDP(apn.apn, apn.user, apn.password,
                obtainMessage(EVENT_SETUP_PDP_DONE));
        send(rr);
        //send socket to RIL
      
        //enter c++ layer
        =>ril.cpp
        processCommandsCallback (int fd, short flags, void *param)
          processCommandBuffer(p_record, recordlen);
            status = p.readInt32(&request);
            pRI->pCI = &(s_commands[request]);
            pRI->pCI->dispatchFunction(p, pRI);
             dispatchStrings();
               s_callbacks.onRequest(pRI->pCI->requestNumber, pStrings, datalen, pRI);
               =>reference-ril.c
                 onRequest();
                   requestSetupDefaultPDP(data, datalen, t);
                     err = write_at_to_data_channel("ATD*99***1#",1);
                   
                     //after a while.get "connect" from data channel,so need to send socket message to java layer.
                     p.writeInt32 (RESPONSE_SOLICITED);
                     p.writeInt32 (pRI->token);//the serial No  in the request list.
                     errorOffset = p.dataPosition();
                     p.writeInt32 (e);
                     if (e == RIL_E_SUCCESS) {
                        /* process response on success */
                        ret = pRI->pCI->responseFunction(p, response, responselen);

                        /* if an error occurred, rewind and mark it */
                        if (ret != 0) {
                          p.setDataPosition(errorOffset);
                          p.writeInt32 (ret);
                        }
                     }
                     sendResponse(p);
                     sendResponseRaw(p.data(), p.dataSize());
                       ret = blockingWrite(fd, (void *)&header, sizeof(header));
                       blockingWrite(fd, data, dataSize);
                     
                       =>RIL.JAVA
                       RILReceiver.run();
                         length = readRilMessage(is, buffer);
                         p = Parcel.obtain();
                         p.unmarshall(buffer, 0, length);
                         p.setDataPosition(0);
                         processResponse(p);
                           processSolicited (p);
                             serial = p.readInt();
                             error = p.readInt();
                             rr = findAndRemoveRequestFromList(serial);
                             ret =  responseStrings(p);
                             if (rr.mResult != null) {
                               AsyncResult.forMessage(rr.mResult, ret, null);
                               rr.mResult.sendToTarget();
                             }
        
       =>pdpConnection.java
       handleMessage()
         case EVENT_SETUP_PDP_DONE:
            ...
            dataLink.connect();
            =>pppLink.java
              SystemProperties.set(PROPERTY_PPPD_EXIT_CODE, "");
              SystemService.start(SERVICE_PPPD_GPRS);//启动pppd_grps服务

              poll.what = EVENT_POLL_DATA_CONNECTION;
              sendMessageDelayed(poll, POLL_SYSFS_MILLIS);
              dataConnection.state = State.CONNECTING;
              handleMessage()
                case EVENT_POLL_DATA_CONNECTION
                  checkPPP();
                    if (ArrayUtils.equals(mCheckPPPBuffer, UP_ASCII_STRING, UP_ASCII_STRING.length)
                    || ArrayUtils.equals(mCheckPPPBuffer, UNKNOWN_ASCII_STRING,
                            UNKNOWN_ASCII_STRING.length)
                            && dataConnection.state == State.CONNECTING)
                    if (mLinkChangeRegistrant != null) {
                      mLinkChangeRegistrant.notifyResult(LinkState.LINK_UP);
                  =>pdpConnection.java
                  handleMessage()
                    case EVENT_LINK_STATE_CHANGED:
                      DataLink.LinkState ls  = (DataLink.LinkState) ar.result;
                      onLinkStateChanged(ls);
                        case LINK_UP:
                           notifySuccess(onConnectCompleted);
                             AsyncResult.forMessage(onCompleted);
                             onCompleted.sendToTarget();
                           
                             =>DataConnectionTracker.java
                             handleMessage()
                               case EVENT_DATA_SETUP_COMPLETE:
                               ...
                                 SystemProperties.set("gsm.defaultpdpcontext.active", "true");
                                 notifyDefaultData(reason);
                                   setupDnsProperties();//设置dns,gw,我们的实现方式是在pppd中设置的,不用pppd拨号的适用。
                                   setState(State.CONNECTED);
                                   phone.notifyDataConnection(reason);
                                       mNotifier.notifyDataConnection(this, reason);
                                       =>DefaultPhoneNotifier.java
                                          //mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
                    "telephony.registry"));构造函数中初始化了mRegistry
                                          mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()),
                                              sender.isDataConnectivityPossible(), reason, sender.getActiveApn(),
                                              sender.getInterfaceName(null));
                                  startNetStatPoll();   

                }

原创粉丝点击