QuarkXPress 设计模式 远程桌面登陆 多线程 ssm 百度seo关键词优化 vue实例 sql server 视频教程 jquery拼接字符串 ubuntu更改文件夹权限 python模块 python输入输出 python的range python3教程 python字典get python中str函数 简单python脚本实例 java中继承 java环境变量配置 java时间类 java中的数据结构 java字符串替换 java时间类型 java基础框架 java网页 sql实例 tmac修改器 内存修改器 allowoverride 刺激战场脚本 emit 黑市商人 蓝牙测试软件 iar下载 php正则匹配 小米9截图 vs2008中文版下载 ftp客户端软件 调试js 优酷app播放器下载
当前位置: 首页 > 学习教程  > 编程语言

源码环境下跟进MO通话流程(涉及到其中每一个方法的跳转)

2020/8/31 15:33:06 文章标签:

对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);
        
      • 至此,打电话流程完毕


本文链接: http://www.dtmao.cc/news_show_150355.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?