挂断界面流程分析

来源:互联网 发布:股票行情软件下载 编辑:程序博客网 时间:2024/06/05 09:07

3,挂断界面分析

无论数本地主动挂断还是远程挂断,最后都会finish通话界面。

在远程挂点电话流程分析已论述, CallsManager的setCallState方法会更新界面,在此就是finish通话界面。

同样的,消息流也会从services telecom走到InCallUI。

3.1 services telecom

CallsManager的setCallState方法调用流程图如下,


CallsManager的setCallState方法中有关电话挂断的代码如下,

listener.onCallStateChanged(call, oldState, newState);

在InCallController方法中,比较多的方法会调用updateCall方法,该方法如下,

for (Map.Entry<ComponentName, IInCallService> entry : mInCallServices.entrySet()) {    ComponentName componentName = entry.getKey();    IInCallService inCallService = entry.getValue();    componentsUpdated.add(componentName);    try {       inCallService.updateCall(parcelableCall);    } catch (RemoteException ignored) {    }}

IinCallService指向的是dialer进程中的是InCallService的内部类InCallServiceBinder。

3.2 InCallUI

InCallService的内部类InCallServiceBinder的updateCall方法如下,

public void updateCall(ParcelableCall call) {     mHandler.obtainMessage(MSG_UPDATE_CALL, call).sendToTarget();}

mHandler变量的handleMessage方法对MSG_UPDATE_CALL消息处理如下,

case MSG_UPDATE_CALL:    mPhone.internalUpdateCall((ParcelableCall) msg.obj);    break;

Phone的internalUpdateCall方法调用流程图如下,


Phone的internalUpdateCall方法如下,

final void internalUpdateCall(ParcelableCall parcelableCall) {    Call call = mCallByTelecomCallId.get(parcelableCall.getId());    if (call != null) {         checkCallTree(parcelableCall);         call.internalUpdate(parcelableCall, mCallByTelecomCallId);    }}

Call的fireStateChanged方法如下,

private void fireStateChanged(final int newState) {    for (CallbackRecord<Callback> record : mCallbackRecords) {          final Call call = this;          final Callback callback = record.getCallback();          record.getHandler().post(new Runnable() {              @Override              public void run() {                  callback.onStateChanged(call, newState);              }         });    }}

mCallbackRecordslist中保存了回调的CallbackRecord对象,

是在registerCallback方法中注册的,

public void registerCallback(Callback callback, Handler handler) {      unregisterCallback(callback);      // Don't allow new callback registration if the call is already being destroyed.      if (callback != null && handler != null && mState != STATE_DISCONNECTED) {          mCallbackRecords.add(new CallbackRecord<Callback>(callback, handler));      }}

在InCallUI的Call.java中的构造方法中,会调用Telecom Call的registerCallback进行注册,

public Call(android.telecom.Call telecommCall) {     mTelecommCall = telecommCall;     mId = ID_PREFIX + Integer.toString(sIdCounter++);     updateFromTelecommCall();     mTelecommCall.registerCallback(mTelecomCallCallback);}

注意, Telecom Call是services telecom对外提供的接口,phone系统中有好几个名为Call的类,当然,还有一些其他的同名类,

看代码时千万不要混淆。

mTelecomCallCallback变量的onStateChanged方法如下,

private android.telecom.Call.Callback mTelecomCallCallback =    new android.telecom.Call.Callback() {        @Override        public void onStateChanged(android.telecom.Call call, int newState) {            Log.d(this, "TelecommCallCallback onStateChanged call=" + call + " newState="                           + newState);            update();        }•••

mTelecomCallCallback变量的大部分方法都会调用update方法,

update方法如下,

private void update() {     Trace.beginSection("Update");     int oldState = getState();     updateFromTelecommCall();     if (oldState != getState() && getState() == Call.State.DISCONNECTED) {         CallList.getInstance().onDisconnect(this);         /* Disconnect the QTI IMS service */         mQtiImsInterfaceImpl.stopQtiImsInterface();     } else {         CallList.getInstance().onUpdate(this);     }     Trace.endSection();}

在很多情况下会更新call,

如果当前的状态是断开(DISCONNECTED),那就调用CallList的onDisconnect方法;

其他情况下,例如远程接听,会调用CallList的onUpdate方法。

在此,接听的更新就不论述了,和onDisconnect方法调用流程几乎相同。

CallList的onDisconnect方法如下,

public void onDisconnect(Call call) {     if (updateCallInMap(call)) {         Log.i(this, "onDisconnect: " + call);         // notify those listening for changes on this specific change         notifyCallUpdateListeners(call);         // notify those listening for all disconnects         notifyListenersOfDisconnect(call);    }}

notifyListenersOfDisconnect方法如下,

private void notifyListenersOfDisconnect(Call call) {     for (Listener listener : mListeners) {         listener.onDisconnect(call);     }}

InCallPresenter的onDisconnect方法如下,

public void onDisconnect(Call call) {     maybeShowErrorDialogOnDisconnect(call);     // We need to do the run the same code as onCallListChange.     onCallListChange(mCallList);// finish activity     if (isActivityStarted()) {         mInCallActivity.dismissKeyguard(false);     }     wakeUpScreen();//屏幕唤醒}

InCallPresenter的attemptFinishActivity方法如下,

if (doFinish) {   mInCallActivity.setExcludeFromRecents(true);   mInCallActivity.finish();

直接调用InCallActivity的finish方法。

这样,通话界面就finish了。整个通话过程也结束了。

另外,在InCallPresenter 的onCallListChange方法中,调用startOrFinishUi方法之后,

for (InCallStateListener listener : mListeners) {     Log.d(this, "Notify " + listener + " of state " + mInCallState.toString());     listener.onStateChange(oldState, mInCallState, callList);}

会调用监听器的onStateChange方法,和来电时的onIncomingCall 监听方法类似,

VideoCallPresenter/CallCardPresenter/CallButtonPresenter等会实现onStateChange方法,更新界面。

原创粉丝点击