远程挂断电话流程分析

3,远程挂断电话流程分析

3.1 services Telephony

当远程挂断/拒接电话时,GsmCallTracker的handlePollCalls 方法有关代码如下,

if (mDroppedDuringPoll.size() > 0) {
   mCi.getLastCallFailCause(
       obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
}

由于不是主动发起的挂断流程,因此会向RIL发送消息获取通话断开的cause,

RIL的getLastCallFailCause方法如下,

public void  getLastCallFailCause (Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
send(rr);
}

注意,此时封装了EVENT_GET_LAST_CALL_FAIL_CAUSE消息。

向ril库发送RIL_REQUEST_LAST_CALL_FAIL_CAUSE消息,ril处理查询完成之后,返回上报结果, processSolicited方法中

对该消息处理如下,

1,读取消息处理结果,

case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret =  responseFailCause(p); break;

responseFailCause方法如下,

private Object responseFailCause(Parcel p) {
    LastCallFailCause failCause = new LastCallFailCause();
    failCause.causeCode = p.readInt();
    if (p.dataAvail() > 0) {
       failCause.vendorCause = p.readString();
    }
    return failCause;
}

返回的是LastCallFailCause对象。

2,分发消息给对应的注册类处理,

if (rr.mResult != null) {
     AsyncResult.forMessage(rr.mResult, ret, null);
     rr.mResult.sendToTarget();
}

GsmCallTracker的handleMessage方法中对EVENT_GET_LAST_CALL_FAIL_CAUSE消息处理如下,

1,首先获取结果,也就是断开的原因,

LastCallFailCause failCause = (LastCallFailCause)ar.result;
causeCode = failCause.causeCode;
vendorCause = failCause.vendorCause;

2,调用GsmConnection的onRemoteDisconnect继续处理,

for (int i = 0, s =  mDroppedDuringPoll.size(); i < s ; i++ ) {
    GsmConnection conn = mDroppedDuringPoll.get(i);
     conn.onRemoteDisconnect(causeCode, vendorCause);
}

updatePhoneState();//更新phone状态
mPhone.notifyPreciseCallStateChanged();
mDroppedDuringPoll.clear();

GsmConnection的onRemoteDisconnect方法调用流程图如下,


onRemoteDisconnect方法如下,

void onRemoteDisconnect(int causeCode, String vendorCause) {
    this.mPreciseCause = causeCode;
    this.mVendorCause = vendorCause;
    onDisconnect(disconnectCauseFromCode(causeCode));
}

在onDisconnect方法中,又会调用GSMPhone的notifyDisconnect方法,该方法如下,

void notifyDisconnect(Connection cn) {
    mDisconnectRegistrants.notifyResult(cn);
    mNotifier.notifyDisconnectCause(cn.getDisconnectCause(), cn.getPreciseDisconnectCause());
}
在父类PhoneBase中注册mDisconnectRegistrants的方法为registerForDisconnect,
public void registerForDisconnect(Handler h, int what, Object obj) {
   checkCorrectThread(h);
   mDisconnectRegistrants.addUnique(h, what, obj);
}

同样的, TelephonyConnection的setOriginalConnection方法中调用了PhoneBase的registerForDisconnect方法,

getPhone().registerForDisconnect(mHandler, MSG_DISCONNECT, null);

TelephonyConnection的内部变量mHandler的handleMessage方法对该消息处理如下,

case MSG_DISCONNECT:
    updateState();
    break;

调用带参数的updateState方法,

void updateState() {
    updateState(false);
}

updateState方法如下,

1,获取当前的Call状态,

Call.State newState = mOriginalConnection.getState();

2,根据状态分别进行处理,

switch (newState) {
    case IDLE:
        break;
case ACTIVE:
•••

如果是断开状态,调用setDisconnected方法进一步处理,

setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
     mOriginalConnection.getDisconnectCause(),
      mOriginalConnection.getVendorDisconnectCause()));

3,更新信息已经相关状态,

updateStatusHints();
updateConnectionCapabilities();
updateAddress();
updateMultiparty();

setDisconnected方法在父类Connection中实现,如下,

public final void setDisconnected(DisconnectCause disconnectCause) {
      checkImmutable();
      mDisconnectCause = disconnectCause;
      setState(STATE_DISCONNECTED);
      Log.d(this, "Disconnected with cause %s", disconnectCause);
      for (Listener l : mListeners) {
          l.onDisconnected(this, disconnectCause);
     }
}

mListeners变量中保存了所有注册的监听器,

private final Set<Listener> mListeners = Collections.newSetFromMap(
            new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));

并且是在addConnectionListener方法中添加监听器的,

public final Connection addConnectionListener(Listener l) {
     mListeners.add(l);
     return this;
}

再看ConnectionService的addConnection方法,

private void addConnection(String callId, Connection connection) {
     mConnectionById.put(callId, connection);
     mIdByConnection.put(connection, callId);
     connection.addConnectionListener(mConnectionListener);
     connection.setConnectionService(this);
}

调用了Connection的addConnectionListener方法注册mConnectionListener变量,

因此当Connection中的setDisconnected调用监听器的onDisconnected方法时,会调用ConnectionService的

mConnectionListener的onDisconnected方法。

在此注意的是, ConnectionService只是一个抽象类,其实运行的是子类TelephonyConnectionService。还是在

services Telephony进程中,并没有跨进程调用。

ConnectionService的mConnectionListener变量是一个匿名内部类,

private final Connection.Listener mConnectionListener = new Connection.Listener() {

其onDisconnected方法如下,

public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
    String id = mIdByConnection.get(c);
    Log.d(this, "Adapter set disconnected %s", disconnectCause);
    mAdapter.setDisconnected(id, disconnectCause);
}

ConnectionServiceAdapter的setDisconnected方法如下,

void setDisconnected(String callId, DisconnectCause disconnectCause) {
    for (IConnectionServiceAdapter adapter : mAdapters) {
         try {
            adapter.setDisconnected(callId, disconnectCause);
         } catch (RemoteException e) {
         }
    }
}

Adapter其实是一个跨进程调用, adapter 指services telecom进程中的ConnectionServiceWrapper的内部类Adapter。

3.2 services telecom

ConnectionServiceWrapper的内部类Adapter定义如下,

private final class Adapter extends IConnectionServiceAdapter.Stub {

调用流程图如下,


Adapter的setDisconnected方法如下,

if (call != null) {
     mCallsManager.markCallAsDisconnected(call, disconnectCause);
}

CallsManager的setCallState方法如下,

if (mCalls.contains(call)) {
    for (CallsManagerListener listener : mListeners) {
         if (Log.SYSTRACE_DEBUG) {
              Trace.beginSection(listener.getClass().toString() + " onCallStateChanged");
         }
         listener.onCallStateChanged(call, oldState, newState);
         if (Log.SYSTRACE_DEBUG) {
               Trace.endSection();
         }
        }
       updateCallsManagerState();
}

调用监听器的onCallStateChanged方法更新界面。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值