远程挂断电话流程分析

来源:互联网 发布:闲鱼淘宝介入 编辑:程序博客网 时间:2024/06/05 05:16

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方法更新界面。



原创粉丝点击