对Tele这一块的MO流程在源码环境下做一个跟进,通过观察每一个方法的跳转加深对MO流程的印象,如有错误,欢迎在评论区指出,篇幅较长,请耐心阅读。
-
packages/apps/Dialer/java/com/android/dialer/dialpadview/DialpadFragment.java
-
handleDialButtonPressed();
-
private void handleDialButtonPressed() { ... PreCall.start(getContext(), new CallIntentBuilder(number, CallInitiationType.Type.DIALPAD)); ... }
-
-
packages/apps/Dialer/java/com/android/dialer/callintent/CallIntentBuilder.java
-
new CallIntentBuilder构造方法
-
CallIntentBuilder.java中的build方法,返回intent请求对象,Action为ACTION_CALL,还有些附加信息
public Intent build() { Intent intent = new Intent(Intent.ACTION_CALL, uri); 206 intent.putExtra( 207 TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, 208 isVideoCall ? VideoProfile.STATE_BIDIRECTIONAL : VideoProfile.STATE_AUDIO_ONLY);
-
-
vendor/codeaurora/commonsys/packages/apps/Dialer/java/com/android/dialer/precall/PreCall.java
-
接着调用外层的PreCall.start();
static void start(Context context, CallIntentBuilder builder) { 43 DialerUtils.startActivityWithErrorToast(context, getIntent(context, builder)); 44 }
-
-
packages/apps/Dialer/java/com/android/dialer/util/DialerUtils.java
-
转到 DialerUtils.startActivityWithErrorToast();
public static void startActivityWithErrorToast( ...//首先判断是不是CallIntentBuilder.build里面的Intent,再对intent的附加信息做出一些处理,执行placeCallOrMakeToast() if ((Intent.ACTION_CALL.equals(intent.getAction()))) { ... placeCallOrMakeToast(context , intent); }else { context.startActivity(intent); }
-
转到 placeCallOrMakeToast(context , intent);
118 private static void placeCallOrMakeToast(Context context, Intent intent) { final boolean hasCallPermission = TelecomUtil.placeCall(context, intent); //接着再判断是否有拨打电话的权限
-
-
packages/apps/Dialer/java/com/android/dialer/telecom/TelecomUtil.java
-
转到TelecomUtil.placeCall(context, intent);
258 public static boolean placeCall(Context context, Intent intent) { 259 if (hasCallPhonePermission(context)) {//再次判断是否有拨打权限 260 getTelecomManager(context).placeCall(intent.getData(), intent.getExtras());//去创建TelecomManager对象 261 return true; 262 } 263 return false; 264 }
-
转到getTelecomManager(context);
301 private static TelecomManager getTelecomManager(Context context) { 302 return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); 303 }//返回一个TelecomManager对象,调用其placeCall方法,服务名是TELECOM_SERVICE
-
-
frameworks/base/telecomm/java/android/telecom/TelecomManager.java
-
转到TelecomManager.placeCall(Uri address, Bundle extras);
1857 public void placeCall(Uri address, Bundle extras) {//携带了intent的地址(应该是电话)以及其上的附加信息 1858 ITelecomService service = getTelecomService();//获取ITelecomService服务 //如果服务开启,地址不为空就会执行,此处还对附加信息进行判空处理,如果为空就new Bundle(),如果不为空就用传进来的extras 1864 service.placeCall(address, extras == null ? new Bundle() : extras,//第一次跨进程的服务调用 1865 mContext.getOpPackageName());
-
转到getTelecomService();
2092 private ITelecomService getTelecomService() { 2093 if (mTelecomServiceOverride != null) {//判断是否已经存在服务 2094 return mTelecomServiceOverride; 2095 } 2096 return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE)); 2097 }//由此可知ITelecomService这个服务的服务名为TELECOM_SERVICE
-
-
frameworks/base/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
- 转到void placeCall(in Uri handle, in Bundle extras, String callingPackage); 但毕竟这是接口,还是得去它的实现中去看这个方法的实现,ITelecomService的实现在TelecomServiceImpl这个类中
-
packages/services/Telecomm/src/com/android/server/telecom/TelecomServiceImpl.java
-
转到private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub()
108 private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() { ...//继续调用placeCall() 1230 public void placeCall()(Uri handle, Bundle extras, String callingPackage) { ... synchronized (mLock) { 1277 try {//创建一个新的intent,并根据传过来的intent的信息做出更新 1288 final Intent intent = new Intent(hasCallPrivilegedPermission ? 1289 Intent.ACTION_CALL_PRIVILEGED : Intent.ACTION_CALL, handle); ...//接着又处理了附加信息,创建用户CallIntent的处理器 1294 mUserCallIntentProcessorFactory.create(mContext, userHandle) 1295 .processIntent( 1296 intent, callingPackage, isSelfManaged || 1297 (hasCallAppOp && hasCallPermission), 1298 true /* isLocalInvocation */);
-
-
packages/services/Telecomm/src/com/android/server/telecom/components/UserCallIntentProcessor.java
-
转到UserCallIntentProcessor.processIntent
82 public void processIntent(Intent intent, String callingPackageName, 83 boolean canCallNonEmergency, boolean isLocalInvocation) { 85 if (!isVoiceCapable()) { 86 return; 87 } 88 89 String action = intent.getAction(); 90 //对三种拨号请求的类型做了或运算,表示都能进入到下面的processOutgoingCallIntent方法 91 if (Intent.ACTION_CALL.equals(action) || 92 Intent.ACTION_CALL_PRIVILEGED.equals(action) || 93 Intent.ACTION_CALL_EMERGENCY.equals(action)) { 94 processOutgoingCallIntent(intent, callingPackageName, canCallNonEmergency, 95 isLocalInvocation); 96 }
-
转到processOutgoingCallIntent()
99 private void processOutgoingCallIntent(Intent intent, String callingPackageName, 100 boolean canCallNonEmergency, boolean isLocalInvocation) { ... sendIntentToDestination(intent, isLocalInvocation, callingPackageName);
-
转到sendIntentToDestination();
196 private boolean sendIntentToDestination(Intent intent, boolean isLocalInvocation, 197 String callingPackage) { ... 200 if (isLocalInvocation) {//从TelecomServiceImpl中调用的就执行如下方法 201 // We are invoking this from TelecomServiceImpl中调用的就执行如下方法, so TelecomSystem is available. Don't 202 // bother trampolining the intent, just sent it directly to the call intent processor. 203 // TODO: We should not be using an intent here; this whole flows needs cleanup. 204 Log.i(this, "sendIntentToDestination: send intent to Telecom directly."); 205 synchronized (TelecomSystem.getInstance().getLock()) { 206 TelecomSystem.getInstance().getCallIntentProcessor().processIntent(intent, 207 callingPackage);//最终会调用到CallIntentProcessor的processIntent方法 208 }
-
-
packages/services/Telecomm/src/com/android/server/telecom/CallIntentProcessor.java
-
调用到CallIntentProcessor.processIntent();
84 public void processIntent(Intent intent, String callingPackage) {//判断是不是未知来电 85 final boolean isUnknownCall = intent.getBooleanExtra(KEY_IS_UNKNOWN_CALL, false);//如果不是未知来电 else { //执行processOutgoingCallIntent 92 processOutgoingCallIntent(mContext, mCallsManager, intent, callingPackage); 93 }
-
调用到processOutgoingCallIntent()方法
104 static void processOutgoingCallIntent( ... 201 // Send to CallsManager to ensure the InCallUI gets kicked off before the broadcast returns // 发送到CallsManager以确保在广播返回之前启动Incallui // 1.调用callsManager.startOutgoingCall()方法 202 CompletableFuture<Call> callFuture = callsManager 203 .startOutgoingCall(handle, phoneAccountHandle, clientExtras, initiatingUser, 204 intent, callingPackage); ...// 2.调用sendNewOutgoingCallIntent() 211 sendNewOutgoingCallIntent(context, call, callsManager, intent); ...
-
调用到sendNewOutgoingCallIntent()方法
219 static void sendNewOutgoingCallIntent(Context context, Call call, CallsManager callsManager, 220 Intent intent) { ...//调用到 broadcaster.processCall() 发起主动呼叫通知的广播 NewOutgoingCallIntentBroadcaster broadcaster; 240 broadcaster.processCall(disposition);
-
调用到broadcaster.processCall()方法 在packages/services/Telecomm/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
public void processCall(CallDisposition disposition) { ...//调用placeOutgoingCallImmediately() 354 placeOutgoingCallImmediately(mCall, disposition.callingAddress, null, 355 speakerphoneOn, videoState);
-
调用到placeOutgoingCallImmediately()方法
504 private void placeOutgoingCallImmediately(Call call, Uri handle, GatewayInfo gatewayInfo, 505 boolean speakerphoneOn, int videoState) { ...//调用callsManager.placeOutgoingCall()方法 511 mCallsManager.placeOutgoingCall(call, handle, gatewayInfo, speakerphoneOn, videoState);
综上:调用CallIntentProcessor.processOutgoingCallIntent()方法时,最终会一起调用如下两个方法
- callsManager.startOutgoingCall(); 开始拨号前的准备工作,创建Call对象,将其添加到通话列表,发出新增Call的通知
- callsManager.placeOutgoingCall(); 继续传递拨号请求
-
-
-
packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java
-
调用到callsManager.startOutgoingCall();
1304 CompletableFuture<Call> startOutgoingCall(Uri handle, 1305 PhoneAccountHandle requestedAccountHandle, 1306 Bundle extras, UserHandle initiatingUser, Intent originalIntent, 1307 String callingPackage) { ...//依靠传进来的Uri创建Call对象,当Call对象连接上服务时,Uri可能会产生变化,但大多数情况下它是不变的 1317 if (call == null) { 1318 call = new Call(getNextCallId(), mContext, 1319 this, 1320 mLock, 1321 mConnectionServiceRepository, 1322 mPhoneNumberUtilsAdapter, 1323 handle, ... } ...//处理其它类型的Call对象 1634 if (isPotentialMMICode(handle) && !isSelfManaged) { 1635 // 如果是Potential MMI Code就不添加Call对象 1636 callToUse.addListener(this); 1637 } else if (!mCalls.contains(callToUse) && mPendingMOEmerCall == null) { 1638 // 有可能会重复使用以前保存在mCalls里的Call对象,所以要先判断列表里是否包含了新增的Call对象 //(See {@link #reuseOutgoingCall}). 1641 addCall(callToUse);//保存并触发新增Call的通知 1642 }
-
调用到callsManager.addCall();
3072 public void addCall(Call call) { 3073 Trace.beginSection("addCall"); 3074 Log.v(this, "addCall(%s)", call); 3075 call.addListener(this);// 将Call对象的Listener设置为CallsManager 3076 mCalls.add(call); ...//更新Call对象的mInentExtras属性,此属性在telecom包下的Call对象中,如下所示 566 private final Bundle mIntentExtras; 3084 updateCanAddCall();//更新addCall的状态 //遍历已经注册的CallsManagerListener,调用其onCallAdded方法,目的是为了快速设置Call对象为第一路通话 3086 for (CallsManagerListener listener : mListeners) { // 回调,通知增加了Call对象 3090 listener.onCallAdded(call);
- Call对象设置监听为CallsManager,CallsManager对象将Call对象添加到mCalls中,通过mListeners进行回调,他们之间相互引用
-
探究mListeners
// mListeners是一个类型为CallsManagerListener的Set集合,初始大小为16,在CallsManager的构造方法中添加了13个监听器 303 private final Set<CallsManagerListener> mListeners是一个类型为 = Collections.newSetFromMap( 304 new ConcurrentHashMap<CallsManagerListener, Boolean>(16, 0.9f, 1)); public CallsManager { 527 mListeners.add(mInCallWakeLockController); 528 mListeners.add(statusBarNotifier); 529 mListeners.add(mCallLogManager); 530 mListeners.add(mPhoneStateBroadcaster); 531 mListeners.add(mInCallController);//拨号流程主要关注此监听器 532 mListeners.add(mCallAudioManager); 533 mListeners.add(mCallRecordingTonePlayer); 534 mListeners.add(missedCallNotifier); 535 mListeners.add(mHeadsetMediaButton); 536 mListeners.add(mProximitySensorManager); }
-
-
packages/services/Telecomm/src/com/android/server/telecom/InCallController.java
-
调用到InCallController.onCallAdded()
763 public void onCallAdded(Call call) { 764 if (!isBoundAndConnectedToServices()) { 765 Log.i(this, "onCallAdded: %s; not bound or connected.", call); 766 // 如果没有绑定或连接服务就执行bindToServices,此处是第一次绑定,Dialer和Telecom的绑定 767 bindToServices(call); } else { 769 ...// 如果有绑定或连接服务
-
调用到InCallController.bindToServices();
1103 public void bindToServices(Call call) { ...//重点关注InCallServiceBindingConnection创建的对象,即carModeInCall 1125 carModeInCall = new InCallServiceBindingConnection(carModeComponentInfo); 1128 mInCallServiceConnection = //用carModeInCall作为构造方法的参数,创建mInCallServiceConnection 1129 new CarSwappingInCallServiceConnection(systemInCall, carModeInCall); //判断是不是显示的car的UI 1132 mInCallServiceConnection.setCarMode(shouldUseCarModeUI()); //真正的开始和InCallServie连接 1135 if (mInCallServiceConnection.connect(call) == 1136 InCallServiceConnection.CONNECTION_SUCCEEDED) { 1137 // 只有成功连接到通话界面的服务,才能执行连接无界面InCallService服务 1139 connectToNonUiInCallServices(call);
-
InCallServiceConnection是InCallController的内部共有类,InCallServiceBindingConnection、EmergencyInCallServiceConnection和CarSwappingInCallServiceConnection是InCallController的内部私有类,全部继承于InCallServiceConnection
-
调用到mInCallServiceConnection.connect(call); 此时是CarSwappingInCallServiceConnection的connect方法
471 public int connect(Call call) { 472 if (mIsConnected) { 473 // 当前未连接 474 return CONNECTION_SUCCEEDED; 475 } else { 476 int result = mCurrentConnection.connect(call);
-
调用到mCurrentConnection.connect(call);
private InCallServiceConnection mCurrentConnection; //在CarSwappingInCallServiceConnection构造方法中 446 public CarSwappingInCallServiceConnection( ... 451 mCurrentConnection = getCurrentConnection();
-
调用到getCurrentConnection();
531 private InCallServiceConnection getCurrentConnection() { 532 if (mIsCarMode && mCarModeConnection != null) { //不走这一步 533 return mCarModeConnection; 534 } else { //走这一步,所以是mDialerConnection.connect(Call); 535 return mDialerConnection; 536 } 537 }
-
调用到InCallServiceBindingConnection的connect()方法
210 public int connect(Call call) { 211 if (mIsConnected) {//先判断是不是已经连接成功了,连接成功就忽略本次请求,很明显这里没成功,往下走 212 Log.addEvent(call, LogUtils.Events.INFO, "Already connected, ignoring request."); 213 return CONNECTION_SUCCEEDED; 214 } ...// 新new一个intent,指明绑定的service为InCallService.SERVICE_INTERFACE 224 Intent intent = new Intent(InCallService.SERVICE_INTERFACE); 225 intent.setComponent(mInCallServiceInfo.getComponentName());// 设置intent的action为InCallService服务的包名 //如果Call对象不为空、确认是拨号操作、不是外部的Call对象 226 if (call != null && !call.isIncoming() && !call.isExternalCall()){ ...//添加一系列的附加信息TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS,TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE 231 } //真正的开始连接了 233 Log.i(this, "Attempting to bind to InCall %s, with %s", mInCallServiceInfo, intent); 234 mIsConnected = true; 235 if (!mContext.bindServiceAsUser(intent, mServiceConnection,//同步创建mServiceConnection匿名对象 236 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE | 237 Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS | 238 Context.BIND_ABOVE_CLIENT, 239 UserHandle.CURRENT)) { //注:创建InCallServiceBindingConnection对象的时候会同步创建ServiceConnection的匿名对象mServiceConnection 166 private class InCallServiceBindingConnection extends InCallServiceConnection { 167 168 private final ServiceConnection mServiceConnection = new ServiceConnection() {
-
调用到mServiceConnection的匿名内部类ServiceConnection重写的方法
170 public void onServiceConnected(ComponentName name, IBinder service) { 177 // Only proceed if we are supposed to be connected. 178 onConnected(service); 184 } 185 186 @Override 187 public void onServiceDisconnected(ComponentName name) { ... 199 };
-
调用到InCallServiceBindingConnection的onConnected()方法
280 protected void onConnected(IBinder service) { 281 boolean shouldRemainConnected = 282 InCallController.this.onConnected(mInCallServiceInfo, service); 283 if (!shouldRemainConnected) { 288 disconnect(); 289 } 290 }
-
调用到InCallController的onConnected()方法
1358 private boolean onConnected(InCallServiceInfo info, IBinder service) { ...//获取IInCallService服务并保存 1362 IInCallService inCallService = IInCallService.Stub.asInterface(service); 1363 mInCallServices.put(info, inCallService); // 添加Adapter 1365 try { 1366 inCallService.setInCallAdapter( 1367 new InCallAdapter( 1368 mCallsManager, 1369 mCallIdMapper, 1370 mLock, 1371 info.getComponentName().getPackageName())); } ...//把之前添加进来的Call对象,通过IInCallService发送出去,通过addCall方法 1383 for (Call call : calls) { //第二次跨进程服务调用 ...//有Call对象的转换,将com.android.server.telecom.Call转换成可跨进程传递的对象android.telecom.ParcelabelCall 1396 inCallService.addCall(ParcelableCallUtils.toParcelableCall( 1397 call, 1398 true /* includeVideoProvider */, 1399 mCallsManager.getPhoneAccountRegistrar(), 1400 info.isExternalCallsSupported(), 1401 includeRttCall, 1402 info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI)); ...//通过inCallService传递Call的更新状态 1406 try { 1407 inCallService.onCallAudioStateChanged(mCallsManager.getAudioState()); 1408 inCallService.onCanAddCallChanged(mCallsManager.canAddCall());
- 由于绑定了IncallService服务,所以下一步应该走到IncallService的方法,由于IncallService是一个位于frameworks/base/telecomm/java/android/telecom/InCallService.java的抽象类,所以需要转到其实现类InCallServiceImpl.java中
-
-
packages/apps/Dialer/java/com/android/incallui/InCallServiceImpl.java
-
调用到InCallServiceImpl的onBind()去响应绑定服务这个过程
95 public IBinder onBind(Intent intent) { ...//启动指定的IncallActivity 113 InCallPresenter.getInstance().maybeStartRevealAnimation(intent); ...//调用到父类的onBind方法 120 IBinder iBinder = super.onBind(intent);
-
调用到InCallService的onBind()方法
421 public IBinder onBind(Intent intent) { 422 return new InCallServiceBinder(); 423 }
-
调用到内部类InCallServiceBinder
private final class InCallServiceBinder extends IInCallService.Stub { 293 @Override//最终在这里调用到setInCallAdapter以及addCall 294 public void setInCallAdapter(IInCallAdapter inCallAdapter) { 295 mHandler.obtainMessage(MSG_SET_IN_CALL_ADAPTER, inCallAdapter).sendToTarget(); 296 } 297 298 @Override 299 public void addCall(ParcelableCall call) { 300 mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget(); 301 } 302 303 @Override 304 public void updateCall(ParcelableCall call) { 305 mHandler.obtainMessage(MSG_UPDATE_CALL, call).sendToTarget(); 306 } // mHandler发送Handler消息将IInCallService的同步调用转换为异步处理 //--------------------------------------------------------------------------------------------------------------------- //同步调用在匿名内部类 ServiceConnection (InCallController的私有内部类InCallServiceBindingConnection) 中 166 private class InCallServiceBindingConnection extends InCallServiceConnection { 167 168 private final ServiceConnection mServiceConnection = new ServiceConnection() { 169 @Override 170 public void onServiceConnected(ComponentName name, IBinder service) { 171 Log.startSession("ICSBC.oSC"); 172 synchronized (mLock) { ... 178 onConnected(service);
- onBind()只是获取到了intent对象,对于Call对象的信息一无所知,相当于对InCallActivity的预加载过程,具体的Call对象信息状态的更新在addCall和updateCall中完成
-
调用到setInCallAdapter
294 public void setInCallAdapter(IInCallAdapter inCallAdapter) { // 发初异步处理消息 MSG_SET_IN_CALL_ADAPTER 295 mHandler.obtainMessage(MSG_SET_IN_CALL_ADAPTER, inCallAdapter).sendToTarget(); 296 }
-
调用到handleMessage();
206 private final Handler mHandler = new Handler(Looper.getMainLooper()) { 207 @Override 208 public void handleMessage(Message msg) { 209 if (mPhone == null && msg.what != MSG_SET_IN_CALL_ADAPTER) { 210 return; 211 } 212 213 switch (msg.what) { 214 case MSG_SET_IN_CALL_ADAPTER: 215 String callingPackage = getApplicationContext().getOpPackageName(); // 创建Phone对象,给Phone对象的Listener属性赋值,这个Phone对象和InCallService在同一个包下面 // 此处还new InCallAdapter,可以跨进程调用Telecom应用 216 mPhone = new Phone(new InCallAdapter((IInCallAdapter) msg.obj), callingPackage, 217 getApplicationContext().getApplicationInfo().targetSdkVersion); // 此处是拨号流程Dialer应用中第一个Listener 218 mPhone.addListener(mPhoneListener); 219 onPhoneCreated(mPhone); 220 break;
-
此时setInCallAdapter()已调用完毕,回过头来调用addCall();
221 case MSG_ADD_CALL: 222 mPhone.internalAddCall((ParcelableCall) msg.obj); 223 break;
-
-
frameworks/base/telecomm/java/android/telecom/Phone.java
-
调用到Phone.internalAddCall();
145 final void internalAddCall(ParcelableCall parcelableCall) {//根据parcelableCall的信息创建Call对象 146 Call call = new Call(this, parcelableCall.getId(), mInCallAdapter, 147 parcelableCall.getState(), mCallingPackage, mTargetSdkVersion); 148 mCallByTelecomCallId.put(parcelableCall.getId(), call); 149 mCalls.add(call); 150 checkCallTree(parcelableCall); 151 call.internalUpdate(parcelableCall, mCallByTelecomCallId);通过parcelableCall更新当前的Call对象 152 fireCallAdded(call);//发出新增Call的通知 153 }
- 这里就很疑惑了,好像在CallsManager.addCall方法中有同样的创建Call对象和发出新增Call对象通知的操作,那么这两个Call对象是否是同一个?
- 答案是否定的,CallsManager中创建的Call对象是在packages/services/Telecomm/src/com/android/server/telecom中的定义,而Phone.internalAddCall中的Call对象是在frameworks/base/telecomm/java/android/telecom/中的定义,前者是在Telecom应用中,后者是在Dialer应用中。Telecom应用中创建Call对象后,会通过此Call对象创建跨进程传递的parcelableCall对象,在Dialer应用中通过parcelableCall的信息继续创建Dialer中的Call对象
-
调用到Phone.fireCallAdded();
380 private void fireCallAdded(Call call) { // private final List<Listener> mListeners = new CopyOnWriteArrayList<>(); 线程安全 // 这里的mListeners通过赋值已经是mPhoneListener 381 for (Listener listener : mListeners) { 382 listener.onCallAdded(this, call);//传递Call对象, 383 } 384 }
-
响应到frameworks/base/telecomm/java/android/telecom/InCallService.java——InCallService.mPhoneListener.onCallAdded();
372 private Phone.Listener mPhoneListener = new Phone.Listener() { ... 391 public void onCallAdded(Phone phone, Call call) { 392 InCallService.this.onCallAdded(call); 393 }
-
调用到InCallService.onCallAdded();
606 public void onCallAdded(Call call) { 607 } //是一个空方法,说明子类重写了此方法
-
-
packages/apps/Dialer/java/com/android/incallui/InCallServiceImpl.java
-
调用到[InCallServiceImpl.onCallAdded();
66 public void onCallAdded(Call call) { 67 Trace.beginSection("InCallServiceImpl.onCallAdded"); 68 InCallPresenter.getInstance().onCallAdded(call); 69 Trace.endSection(); 70 } //接着会进入类InCallPresenter调用其onCallAdded()方法,最终的调用结果是 628 callList.onCallAdded(context, call, latencyReport);
-
-
packages/apps/Dialer/java/com/android/incallui/call/CallList.java
-
调用到CallList.onCallAdded();
122 public void onCallAdded( 123 final Context context, final android.telecom.Call telecomCall, LatencyReport latencyReport) { ... 148 call.addListener(new DialerCallListenerImpl(call));//添加监听跟踪信息 ... 798 private class DialerCallListenerImpl implements DialerCallListener { 816 public void onDialerCallUpdate() { 817 Trace.beginSection("CallList.onDialerCallUpdate"); 818 onUpdateCall(call); 819 notifyGenericListeners(); 820 Trace.endSection(); 821 } //拨号流程Dialer应用中第二个Listener 615 private void notifyGenericListeners() { 616 Trace.beginSection("CallList.notifyGenericListeners"); 617 for (Listener listener : listeners) { 618 listener.onCallListChange(this); 619 } 620 Trace.endSection(); 621 } //接着会进入类InCallPresenter调用onCallListChange,拨号流程Dialer应用中第三个Listener 882 for (InCallStateListener listener : listeners) { 883 LogUtil.d( 884 "InCallPresenter.onCallListChange", 885 "Notify " + listener + " of state " + inCallState.toString()); 886 listener.onStateChange(oldState, inCallState, callList); 887 }
至此,通过调用onStateChange方法后结束了一开始在CallsManager中调用startOutgoingCall的调用,之后会显示出通话界面InCallActivity
下面开始跟进CallsManager.placeOutgoingCall
-
-
packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java
-
调用到CallsManager.placeOutgoingCall();
1947 public void placeOutgoingCall(Call call, Uri handle, GatewayInfo gatewayInfo, 1948 boolean speakerphoneOn, int videoState) { ...//如果获取到目标用户或者是紧急电话 1996 if (call.getTargetPhoneAccount() != null || call.isEmergencyCall()) { 1999 if (call.isSelfManaged() && !isOutgoingCallPermitted) { 2000 notifyCreateConnectionFailed(call.getTargetPhoneAccount(), call); 2001 } else { 2002 if (call.isEmergencyCall()) {//如果是紧急电话 2004 disconnectSelfManagedCalls("place emerg call" /* reason */); 2005 } 2007 if (mPendingMOEmerCall == null) {//开始创建Connection对象 2011 call.startCreateConnection(mPhoneAccountRegistrar); 2012 } ...
-
-
packages/services/Telecomm/src/com/android/server/telecom/Call.java
-
调用到Call.startCreateConnection();
1720 void startCreateConnection(PhoneAccountRegistrar phoneAccountRegistrar) { ...//先判断是否已经拥有createProssesor处理器,如果有则返回 1728 mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this, 1729 phoneAccountRegistrar, mContext); 1730 mCreateConnectionProcessor.process();//通过mCreateConnectionProcessor来创建Connection对象
-
-
packages/services/Telecomm/src/com/android/server/telecom/CreateConnectionProcessor.java
-
调用到CreateConnectionProcessor.process();
158 public void process() { ... 171 attemptNextPhoneAccount(); }
-
调用到CreateConnectionProcessor.attemptNextPhoneAccount();
205 private void attemptNextPhoneAccount() { ... 233 if (mCallResponse != null && attempt != null) {// 又创建了一个新的服务 236 mService = mRepository.getService(phoneAccount.getComponentName(), 237 phoneAccount.getUserHandle()); 238 if (mService == null) {// 如果这个服务没有连接,则递归调用attemptNextPhoneAccount 239 Log.i(this, "Found no connection service for attempt %s", attempt); 240 attemptNextPhoneAccount(); 241 } else { 242 mConnectionAttempt++; 243 mCall.setConnectionManagerPhoneAccount(attempt.connectionManagerPhoneAccount); 244 mCall.setTargetPhoneAccount(attempt.targetPhoneAccount); 245 mCall.setConnectionService(mService); 246 setTimeoutIfNeeded(mService, attempt); if { ... 249 } else {// 服务连接好后,通过服务创建Connection对象 258 mService.createConnection(mCall,CreateConnectionProcessor.this); ----------------------------------------------------------------------------------------------------------------------- //在本类中,mService的定义如下,说明它是ConnectionServiceWrapper类型的服务 124 private ConnectionServiceWrapper mService;
-
-
packages/services/Telecomm/src/com/android/server/telecom/ConnectionServiceWrapper.java
-
调用到ConnectionServiceWrapper.createConnection();
1107 public void createConnection(final Call call, final CreateConnectionResponse response) { 1111 public void onSuccess() { ... 1178 } 1181 public void onFailure() { ... 1184 } 1187 mBinder.bind(callback, call); ----------------------------------------------------------------------------------------------------------------------- 68public class ConnectionServiceWrapper extends ServiceBinder implements 69 ConnectionServiceFocusManager.ConnectionServiceFocus { 1043 private Binder2 mBinder = new Binder2(); } 42public abstract class ServiceBinder { 62 final class Binder2 { ... } } // 所以,从上面可以看出mBinder是ConnectionServiceWrapper的父类
-
-
packages/services/Telecomm/src/com/android/server/telecom/ServiceBinder.java
-
调用到Binder2.bind();
70 void bind(BindCallback callback, Call call) { ... 85 if (mServiceConnection == null) {// 通过mServiceAction指定将要绑定什么服务 86 Intent serviceIntent = new Intent(mServiceAction).setComponent(mComponentName); 87 ServiceConnection connection = new ServiceBinderConnection(call); ... 96 } else {///开始绑定服务,第二次绑定Telecom和Telephony的绑定 97 isBound = mContext.bindService(serviceIntent, connection, bindingFlags); ----------------------------------------------------------------------------------------------------------------------- //在ConnectionServiceWrapper的构造方法中调用了父类的构造方法,即 1062 ConnectionServiceWrapper( 1063 ComponentName componentName, 1064 ConnectionServiceRepository connectionServiceRepository, 1065 PhoneAccountRegistrar phoneAccountRegistrar, 1066 CallsManager callsManager, 1067 Context context, 1068 TelecomSystem.SyncRoot lock, 1069 UserHandle userHandle) { 1070 super(ConnectionService.SERVICE_INTERFACE, componentName, context, lock, userHandle); ...// 将父类中构造方法的第一个参数serviceAction赋值为ConnectionService.SERVICE_INTERFACE }
255 protected ServiceBinder(String serviceAction, ComponentName componentName, Context context, 256 TelecomSystem.SyncRoot lock, UserHandle userHandle) { ...// 即bind方法里面intent要绑定的服务为ConnectionService.SERVICE_INTERFACE 262 mServiceAction = serviceAction; ... 265 }
-
研究ServiceConnection connection = new ServiceBinderConnection(call),调用到ServiceConnection.onServiceConnected();
//bindService中传入了ServiceConnection的对象,响应到ServiceConnection的onServiceConnected(); 145 public void onServiceConnected(ComponentName componentName, IBinder binder) { ... 162 if (binder != null) { 163 mServiceDeathRecipient = new ServiceDeathRecipient(componentName); 164 try { 165 binder.linkToDeath(mServiceDeathRecipient, 0); 166 mServiceConnection = this; 167 setBinder(binder); //保存绑定服务成功后的Binder对象 168 handleSuccessfulConnection();//bindService成功之后的处理逻辑
-
调用到ServiceBinder.setBinder();
418 private void setBinder(IBinder binder) { 419 if (mBinder != binder) { 420 if (binder == null) { ...//binder != null 走下面 425 } 426 } else { 427 mBinder = binder; 428 setServiceInterface(binder); 429 } 430 } 431 }
-
调用到ServiceBinder.setServiceInterface();
438 protected abstract void setServiceInterface(IBinder binder);// 抽象方法,在子类ConnectionServiceWrapper中实现
-
调用到ConnectionServiceWrapper的setServiceInterface方法
1622 protected void setServiceInterface(IBinder binder) { 1623 mServiceInterface = IConnectionService.Stub.asInterface(binder);//保存BInder对象 1624 Log.v(this, "Adding Connection Service Adapter."); 1625 addConnectionServiceAdapter(mAdapter);// 增加Adapter对象 1626 }
-
调用到ConnectionServiceWrapper.addConnectionServiceAdapter();
1082 private void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) { ...// 最终是通过ConnectionService服务增加Adapter对象 1086 mServiceInterface.addConnectionServiceAdapter(adapter, Log.getExternalSession()); ... 1090 } // 此处添加的是IConnectionServiceAdapter,进入其aidl文件查看
-
frameworks/base/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
47 void setActive(String callId, in Session.Info sessionInfo); 48 49 void setRinging(String callId, in Session.Info sessionInfo); 50 51 void setDialing(String callId, in Session.Info sessionInfo); 52 53 void setPulling(String callId, in Session.Info sessionInfo); ... // 全是和通话状态相关的接口方法,当前绑定的服务为ConnectionService,通过调用Adapter中的方法来更新Telec om通话状态
-
回过头来看handleSuccessfulConnection(); 这个方法在ServiceBinder类里面
356 private void handleSuccessfulConnection() { 357 // Make a copy so that we don't have a deadlock inside one of the callbacks. 防止死锁 358 Set<BindCallback> callbacksCopy = new ArraySet<>(); 359 synchronized (mCallbacks) {// 进来后每回处理的都是新的数组 360 callbacksCopy.addAll(mCallbacks); 361 mCallbacks.clear(); 362 } 363 364 for (BindCallback callback : callbacksCopy) { 365 callback.onSuccess(); 366 } 367 }
-
callback.onSuccess()在子类ConnectionServiceWrapper.createConnection中实现
1107 public void createConnection(final Call call, final CreateConnectionResponse response) { 1108 Log.d(this, "createConnection(%s) via %s.", call, getComponentName()); 1109 BindCallback callback = new BindCallback() { 1110 @Override 1111 public void onSuccess() { ...// 根据通话的相关信息创建connectionRequest 1149 ConnectionRequest connectionRequest = new ConnectionRequest.Builder() 1150 .setAccountHandle(call.getTargetPhoneAccount()) 1151 .setAddress(call.getHandle()) 1152 .setExtras(extras) 1153 .setVideoState(call.getVideoState()) 1154 .setTelecomCallId(callId)// 1155 // For self-managed incoming calls, if there is another ongoing call Telecom 1156 // is responsible for showing a UI to ask the user if they'd like to answer 1157 // this new incoming call. 1158 .setShouldShowIncomingCallUi( 1159 !mCallsManager.shouldShowSystemIncomingCallUi(call)) 1160 .setRttPipeFromInCall(call.getInCallToCsRttPipeForCs()) 1161 .setRttPipeToInCall(call.getCsToInCallRttPipeForCs()) 1162 .build(); 1164 try { 1165 mServiceInterface.createConnection( // 第二次跨进程访问,绑定的对象依然为ConnectionService 1166 call.getConnectionManagerPhoneAccount(), 1167 callId, 1168 connectionRequest, 1169 call.shouldAttachToExistingConnection(), 1170 call.isUnknown(), 1171 Log.getExternalSession());
- 拨号流程中,telecom应用第二次跨进程访问,将call对象传给了Dialer应用,使通话界面得到更新,第三次跨进程访问,将Call拨号请求的相关信息封装成ConnectionRequest对象并传给了TeleService应用
-
根据AndroidManifest.xml中的定义,android.telecom.ConnectionService服务所服务的Java类为TelephonyConnectionService,TelephonyConnectionService继承自ConnectionService抽象类,分别从onBind,addConnectionServiceAdapter和createConnection加以分析
-
调用到ConnectionService.onBinder()
1542 public final IBinder onBind(Intent intent) { 1543 return mBinder;// 返回IConnectionService.Stub的对象 1544 }
-
调用到ConnectionService.mBinder.addConnectionServiceAdapter()
207 public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter, 208 Session.Info sessionInfo) { ... 214 mHandler.obtainMessage(MSG_ADD_CONNECTION_SERVICE_ADAPTER, args).sendToTarget(); ... } 680 private final Handler mHandler = new Handler(Looper.getMainLooper()) { 681 @Override 682 public void handleMessage(Message msg) { 683 switch (msg.what) { 684 case MSG_ADD_CONNECTION_SERVICE_ADAPTER: { 685 SomeArgs args = (SomeArgs) msg.obj; 686 try { 687 IConnectionServiceAdapter adapter = (IConnectionServiceAdapter) args.arg1; 688 Log.continueSession((Session) args.arg2, 689 SESSION_HANDLER + SESSION_ADD_CS_ADAPTER); 690 mAdapter.addAdapter(adapter); 691 onAdapterAttached(); 692 } finally { 693 args.recycle(); 694 Log.endSession(); 695 } 696 break;
-
调用到ConnectionService.createConnection() 继续发送拨号请求
1558 private void createConnection( 1559 final PhoneAccountHandle callManagerAccount, 1560 final String callId, 1561 final ConnectionRequest request, 1562 boolean isIncoming, 1563 boolean isUnknown) { ...// 分别去创建不同的connection对象 1583 } else { 1584 connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request) 1585 : isIncoming ? onCreateIncomingConnection(callManagerAccount, request) 1586 : onCreateOutgoingConnection(callManagerAccount, request); ... 1617 mAdapter.handleCreateConnectionComplete( ...//通过mAdapter传过来的binder对象进行接口回调
-
首先看onCreateOutgoingConnection,子类TelephonyService重写了此方法
-
-
packages/services/Telephony/src/com/android/services/telephony/TelephonyConnectionService.java
-
调用到[TelephonyConnectionService.onCreateOutgoingConnection
497 public Connection onCreateOutgoingConnection( 498 PhoneAccountHandle connectionManagerPhoneAccount, 499 final ConnectionRequest request) { ...//首先判断是不时紧急电话 674 final Phone phone = getPhoneForAccount(request.getAccountHandle(), isEmergencyNumber, 675 /* Note: when not an emergency, handle can be null for unknown callers */ 676 handle == null ? null : handle.getSchemeSpecificPart()); ... 691 placeOutgoingConnection(request, resultConnection, phone);
-
调用到placeOutgoingConnection();
1399 private void placeOutgoingConnection( ... 1410 if (phone != null) {// 这里的Phone对象为GsmCdmaPhone 1411 if (isAddParticipant) { 1412 phone.addParticipant(number); 1413 return; 1414 } else { 1415 originalConnection = phone.dial(number, new ImsPhone.ImsDialArgs.Builder() 1416 .setVideoState(videoState) 1417 .setIntentExtras(extras) 1418 .setRttTextStream(connection.getRttTextStream()) 1419 .build()); 1420 } 1421 }
-
如果是普通呼叫,则此处的Phone对象为GsmCdmaPhone,调用到GsmCdmaPhone.dial()
1158 public Connection dial(String dialString, @NonNull DialArgs dialArgs) 1159 throws CallStateException { ... 1267 if (isPhoneTypeGsm()) { 1268 return dialInternal(dialString, new DialArgs.Builder<>() 1269 .setIntentExtras(dialArgs.intentExtras) 1270 .build()); 1271 } else { 1272 return dialInternal(dialString, dialArgs);
-
调用到GsmCdmaPhone.dialInternal(),两个参数的
1318 protected Connection dialInternal(String dialString, DialArgs dialArgs, 1319 ResultReceiver wrappedCallback) 1320 throws CallStateException { ... 1348 } else { 1349 return mCT.dial(newDialString, dialArgs.intentExtras);
-
mCT即GsmCdmaCallTracker
-
-
frameworks/opt/telephony/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
-
调用到[GsmCdmaCallTracker.dialGsm
282 public synchronized Connection dialGsm(String dialString, int clirMode, UUSInfo uusInfo, 283 Bundle intentExtras) 284 throws CallStateException { ... 326 mPendingMO = new GsmCdmaConnection(mPhone, checkForTestEmergencyNumber(dialString), 327 this, mForegroundCall, isEmergencyCall);kan ... 338 if ( mPendingMO.getAddress() == null || mPendingMO.getAddress().length() == 0 339 || mPendingMO.getAddress().indexOf(PhoneNumberUtils.WILD) >= 0) {//如果号码非法 ... 346 } else { 347 // Always unmute when initiating a new call 348 setMute(false); 349 boolean isPhoneInEcmMode = EcbmHandler.getInstance().isInEcm(); 350 // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit. 351 if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {// 调用到mCi.dial() 352 mCi.dial(mPendingMO.getAddress(), mPendingMO.isEmergencyCall(), 353 mPendingMO.getEmergencyNumberInfo(), 354 mPendingMO.hasKnownUserIntentEmergency(), clirMode, uusInfo, 355 obtainCompleteMessage());
-
调用到mCi.dial时,将通话请求转交到Modem中
-
-
packages/services/Telecomm/src/com/android/server/telecom/ConnectionServiceWrapper.java
-
回过头来看mAdapter.handleCreateConnectionComplete()接口回调
1689 private void handleCreateConnectionComplete( 1690 String callId, 1691 ConnectionRequest request, 1692 ParcelableConnection connection) { ... 1708 } else { 1709 // Successful connection 1710 if (mPendingResponses.containsKey(callId)) { 1711 mPendingResponses.remove(callId) 1712 .handleCreateConnectionSuccess(mCallIdMapper, connection);
-
最终调用到Call.handleCreateConnectionSuccess();
1734 public void handleCreateConnectionSuccess( 1735 CallIdMapper idMapper, 1736 ParcelableConnection connection) { ... 1758 switch (mCallDirection) { 1759 case CALL_DIRECTION_INCOMING: 1760 // Listeners (just CallsManager for now) will be responsible for checking whether 1761 // the call should be blocked. 1762 for (Listener l : mListeners) { 1763 l.onSuccessfulIncomingCall(this); 1764 } 1765 break; 1766 case CALL_DIRECTION_OUTGOING: 1767 for (Listener l : mListeners) { 1768 l.onSuccessfulOutgoingCall(this, 1769 getStateFromConnectionState(connection.getState())); 1770 } 1771 break; //Call类中有ListenerBase抽象类,它实现了Listener接口,实现了Listener所有方法,并且都是空方法,在ListenerBase的三个子类CallsManager,InCallController的匿名内部类对象mCallListener,InComingCallNotifier的匿名内部类对象mCallListener,在这三个类中只有CallsManger重写了onSuccessfulOutgoingCall方法,继续跟进
-
调用到CallsManager.onSuccessfulOutgoingCall()
581 public void onSuccessfulOutgoingCall(Call call, int callState) { ... 584 setCallState(call, callState, "successful outgoing call");// 改变Call的状态 ... 596 markCallAsDialing(call);
-
调用到CallsManager.markCallAsDialing();
2528 void markCallAsDialing(Call call) { 2529 setCallState(call, CallState.DIALING, "dialing set explicitly");
-
调用到CallsManager.setCallState();
3137 private void setCallState(Call call, int newState, String tag) { 3168 for (CallsManagerListener listener : mListeners) { 3169 if (LogUtils.SYSTRACE_DEBUG) { ...// 这里的Listener为InCallController 3173 listener.onCallStateChanged(call, oldState, newState);
-
调用到InCallController.onCallStateChanged();
912 public void onCallStateChanged(Call call, int oldState, int newState) { 913 updateCall(call); 914 }
-
调用到InCallController.updateCall();
1446 private void updateCall(Call call, boolean videoProviderChanged, boolean rttInfoChanged) { ...// 通过已经修改状态的Call对象构造跨进程传递的ParcelableCall对象 1460 ParcelableCall parcelableCall = ParcelableCallUtils.toParcelableCall( 1461 call, 1462 videoProviderChanged /* includeVideoProvider */, 1463 mCallsManager.getPhoneAccountRegistrar(), 1464 info.isExternalCallsSupported(), 1465 rttInfoChanged && info.equals(mInCallServiceConnection.getInfo()), 1466 info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI); ... 1471 try {// 通过inCallService调用updateCall来更新当前通话界面的通话状态为Dialing 1472 inCallService.updateCall(parcelableCall);
-
至此,打电话流程完毕
-
-
共有条评论 网友评论