远程挂断电话流程分析
来源:互联网 发布:闲鱼淘宝介入 编辑:程序博客网 时间: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方法更新界面。
- 远程挂断电话流程分析
- 挂断电话流程分析
- Android 5.0/L 电话挂断流程分析
- Android 5.1 Phone 挂断电话流程分析
- Android 7.0 挂断电话流程分析
- Android 挂断电话流程
- Android 挂断电话流程
- Android 挂断电话流程
- Android4.4 Telephony流程分析——电话挂断
- 关于电话挂断的流程
- android电话流程(打电话,接电话,挂断电话)
- android电话流程(打电话,接电话,挂断电话)
- 挂断界面流程分析
- android电话流程(打电话,接电话,挂断电话)(二)
- android电话流程(打电话,接电话,挂断电话)(一)
- 挂断电话
- 挂断电话
- 挂断电话
- gcd小规律 [Cqoi2014]数三角形
- HDFS工作原理
- hdu6129 二进制+数学
- java笔记之java多线程的安全问题
- 【Python3.6爬虫学习记录】(七)使用Selenium+ChromeDriver爬取知乎某问题的回答
- 远程挂断电话流程分析
- HDU 6124 Euler theorem (2017 Multi-Univ Training Contest 7)
- VS2010程序打包操作(超详细的)
- 数学建模--K-近邻算法
- 频道拖拽
- Kaggle 入门介绍 https://dnc1994.com/2016/04/rank-10-percent-in-first-kaggle-competition/
- Netty(一):基础概念及消息处理流程
- Java Swing 调节图片亮度
- scala学习-scala中的元组Tuple概念