去电界面启动分析---之二

2019-04-14 08:25发布

1.3启动去电界面

在InCallController的onCallAdded方法中有关去电界面的代码如下, inCallService.addCall(parcelableCall); 通过binder跨进程调用Incall 的InCallService内部类InCallServiceBinder的addCall方法, public void addCall(ParcelableCall call) { mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget(); } mHandler的handleMessage对MSG_ADD_CALL消息处理如下, case MSG_ADD_CALL: mPhone.internalAddCall((ParcelableCall) msg.obj); break; 此时实际上运行于dailer进程中, Phone的internalAddCall方法调用流程图如下,
Phone的internalAddCall方法如下, final void internalAddCall(ParcelableCall parcelableCall) { Call call = new Call(this, parcelableCall.getId(), mInCallAdapter, parcelableCall.getState(), parcelableCall.isActive()); mCallByTelecomCallId.put(parcelableCall.getId(), call); mCalls.add(call); checkCallTree(parcelableCall); call.internalUpdate(parcelableCall, mCallByTelecomCallId); fireCallAdded(call); } fireCallAdded方法如下, private void fireCallAdded(Call call) { for (Listener listener : mListeners) { listener.onCallAdded(this, call); } } Listener监听器是Phone的内部接口, 变量mListeners list中保存着所有注册的监听器, private final List mListeners = new CopyOnWriteArrayList<>(); 调用addListener方法添加监听器, public final void addListener(Listener listener) { mListeners.add(listener); } 在此,会回调InCallService的匿名Phone.Listener的onCallAdded方法, 是在设置InCallAdapter过程中处理MSG_SET_IN_CALL_ADAPTER消息时注册监听器的, case MSG_SET_IN_CALL_ADAPTER: mPhone = new Phone(new InCallAdapter((IInCallAdapter) msg.obj)); mPhone.addListener(mPhoneListener);//注册监听器 onPhoneCreated(mPhone); break; Phone.Listener的onCallAdded方法如下, public void onCallAdded(Phone phone, Call call) { InCallService.this.onCallAdded(call); } onCallAdded在子类InCallServiceImpl中实现,如下, public void onCallAdded(Call call) { CallList.getInstance().onCallAdded(call); InCallPresenter.getInstance().onCallAdded(call); } CallList的onCallAdded方法如下, public void onCallAdded(android.telecom.Call telecommCall) { Trace.beginSection("onCallAdded"); Call call = new Call(telecommCall);//构造call对象 Log.d(this, "onCallAdded: callState=" + call.getState()); if (call.getState() == Call.State.INCOMING || call.getState() == Call.State.CALL_WAITING) { onIncoming(call, call.getCannedSmsResponses());//如果是来电 } else { onUpdate(call);//更新call } Trace.endSection(); } notifyGenericListeners方法如下, private void notifyGenericListeners() { for (Listener listener : mListeners) { listener.onCallListChange(this); } } Listener 监听器也是CallList的接口,也是在addListener方法中注册, public void addListener(Listener listener) { Preconditions.checkNotNull(listener); mListeners.add(listener); // Let the listener know about the active calls immediately. listener.onCallListChange(this); } InCallPresenter实现了CallList.Listener接口, public class InCallPresenter implements CallList.Listener, 并且在setUp方法中调用CallList的addListener方法注册监听器, mCallList.addListener(this); 在InCallPresenter的startOrFinishUi方法中,会进行各种判断,其中,来电的有关代码如下, if (showCallUi || showAccountPicker || isAutoAnswer) { Log.i(this, "Start in call UI"); showInCall(false /* showDialpad */, !showAccountPicker /* newOutgoingCall */); showInCall方法如下, public void showInCall(final boolean showDialpad, final boolean newOutgoingCall) { Log.i(this, "Showing InCallActivity"); mContext.startActivity(getInCallIntent(showDialpad, newOutgoingCall)); } getInCallIntent方法如下, public Intent getInCallIntent(boolean showDialpad, boolean newOutgoingCall) { final Intent intent = new Intent(Intent.ACTION_MAIN, null); intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK); intent.setClass(mContext, InCallActivity.class); if (showDialpad) { intent.putExtra(InCallActivity.SHOW_DIALPAD_EXTRA, true); } intent.putExtra(InCallActivity.NEW_OUTGOING_CALL_EXTRA, newOutgoingCall); return intent; } 因此,启动的是InCallActivity来显示来电界面,这样,转了这么久,来电界面终于显示出来了。至于去电界面的具体view在此就不论述了。 Dialer的AndroidManifest.xml有关InCallActivity如下,