android Telephony学习 --- 第六篇 android7.0 MO InCallActivity启动流程

标签: android Telephony InCallActivity 源码
12人阅读 评论(1) 收藏 举报
分类:

我们先看下7.0启动InCallActivity时序图:
android Telephony学习 --- 第六篇 android7.0 MO InCallActivity启动流程

还记得上篇讲的*号标记的地方么,对CallIntentProcessor里调用CallsManager的startOutgoingCall方法,我们从这里开始分析:

// Send to CallsManager to ensure the InCallUI gets kicked off before the broadcast returns
Call call = callsManager.startOutgoingCall(handle, phoneAccountHandle, clientExtras, initiatingUser);
  • packages/services/Telecomm – CallsManager
if (!mCalls.contains(call) && mPendingMOEmerCall == null) {
   // We check if mCalls already contains the call because we could potentially be reusing
   // a call which was previously added (See {@link #reuseOutgoingCall}).
   addCall(call);
        }

去寻找监听CallsManagerListener的onCallAdded方法:

    private void addCall(Call call) {
        for (CallsManagerListener listener : mListeners) {
            listener.onCallAdded(call);
        }    
    }        
  • packages/services/Telecomm – InCallController
   @Override
    public void onCallAdded(Call call) {
        if (!isBoundToServices()) {
            bindToServices(call);
        }
    }

来看关键代码,绑定InCallService:

            Intent intent = new Intent(InCallService.SERVICE_INTERFACE);
            intent.setComponent(mInCallServiceInfo.getComponentName());
            if (call != null && !call.isIncoming() && !call.isExternalCall()){
                intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS,
                        call.getIntentExtras());
                intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
                        call.getTargetPhoneAccount());
            }

            Log.i(this, "Attempting to bind to InCall %s, with %s", mInCallServiceInfo, intent);
            mIsConnected = true;
            if (!mContext.bindServiceAsUser(intent, mServiceConnection,
                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE |
                        Context.BIND_ABOVE_CLIENT,
                        UserHandle.CURRENT)) {
                Log.w(this, "Failed to connect.");
                mIsConnected = false;
            }

查看mServiceConnection的onServiceConnected方法:

private class InCallServiceBindingConnection extends InCallServiceConnection {

        private final ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                synchronized (mLock) {
                    try {
                        mIsBound = true;
                        if (mIsConnected) {
                            // Only proceed if we are supposed to be connected.
                            onConnected(service);
                        }
                    } 
                }
            }

onConnected方法:

        protected void onConnected(IBinder service) {
            boolean shouldRemainConnected =
                    InCallController.this.onConnected(mInCallServiceInfo, service);
        }

先找到aidl IInCallService对应的接收端,并找到方法addCall:

  private boolean onConnected(InCallServiceInfo info, IBinder service) {
        IInCallService inCallService = IInCallService.Stub.asInterface(service);
        mInCallServices.put(info, inCallService);
        try {
            inCallService.setInCallAdapter(
                    new InCallAdapter(
                            mCallsManager,
                            mCallIdMapper,
                            mLock,
                            info.getComponentName().getPackageName()));
        } 

        for (Call call : calls) {
            try {
                // Track the call if we don't already know about it.
                addCall(call);
                numCallsSent += 1;
                inCallService.addCall(ParcelableCallUtils.toParcelableCall(
                        call,
                        true /* includeVideoProvider */,
                        mCallsManager.getPhoneAccountRegistrar(),
                        info.isExternalCallsSupported()));
            } catch (RemoteException ignored) {
            }
        }
  • packages/services/Telecomm – InCallService
    private final class InCallServiceBinder extends IInCallService.Stub {
        @Override
        public void addCall(ParcelableCall call) {
            mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget();
        }
  • frameworks/base/telecomm – Phone
    去找监听的代码,找到onCallAdded方法:
    private void fireCallAdded(Call call) {
        for (Listener listener : mListeners) {
            listener.onCallAdded(this, call);
        }
    }
  • packages/services/Telecomm – InCallService
    绕了一下,又回到了InCallService,并去寻找InCallService的子类:
 private Phone.Listener mPhoneListener = new Phone.Listener() {
        /** ${inheritDoc} */
        @Override
        public void onCallAdded(Phone phone, Call call) {
            InCallService.this.onCallAdded(call);
        }
  • packages/app/Dialer – InCallServiceImpl

InCallServiceImpl extends InCallService

    @Override
    public void onCallAdded(Call call) {
        InCallPresenter.getInstance().onCallAdded(call);
    }
  • packages/app/Dialer – InCallPresenter
    public void onCallAdded(final android.telecom.Call call) {
        if (shouldAttemptBlocking(call)) {
            maybeBlockCall(call);
        } else {
                mCallList.onCallAdded(call);
        }
    }
  • packages/app/Dialer – CallList
    需要找到实现监听implements CallList.Listener,实现方法onCallListChange的地方:
    private void notifyGenericListeners() {
        for (Listener listener : mListeners) {
            listener.onCallListChange(this);
        }
    }
  • packages/app/Dialer – InCallPresenter

startOrFinishUi

    public void onCallListChange(CallList callList) {
        InCallState newState = getPotentialStateFromCallList(callList);
        InCallState oldState = mInCallState;
        newState = startOrFinishUi(newState);

启动InCallActivity:

    public void showInCall(final boolean showDialpad, final boolean newOutgoingCall) {
        Log.i(this, "Showing InCallActivity");
        mContext.startActivity(getInCallIntent(showDialpad, newOutgoingCall));
    }

到这为止,呼出InCallActivity启动的流程基本结束了。

查看评论

Android N 通话界面_InCallActivity

本流程图基于MTK平台 Android 7.0,普通来电,本流程只作为沟通学习使用本篇博客主要来看看整个 IncallUI 界面的容器 InCallActivityInCallActivity启动流程...
  • michael_yt
  • michael_yt
  • 2017-02-06 20:36:59
  • 2672

android N 拨打电话流程(MO)

本流程图基于MTK平台 Android N,拨打的普通电话,本流程只作为沟通学习使用整体流程图流程中部分重点知识packages-apps目录 dialer应用的DialpadFragment.onC...
  • michael_yt
  • michael_yt
  • 2016-12-24 11:43:32
  • 3905

Android 6.0 Phone MO(去电)流程分析(应用层)

写在前面的话本文主要分析MO(去电)的流程,研究的代码是Android 6.0的,目前只关注应用层,以GSM为例。(如果图片看不清的话,可以右键选择在新标签中打开图片,或者把图片另存到自己电脑再查看。...
  • linyongan
  • linyongan
  • 2015-08-11 16:01:22
  • 7850

MO CALL流程

Call文件目录从上层InCallUI一直到Telephony Framework层,总共包含下面五个部分。 InCallUI : packages/apps/InCallUI (sy...
  • amd123456789
  • amd123456789
  • 2017-07-12 19:18:49
  • 815

Android 5.1 Lollipop Phone工作流程浅析(十三)__InCallActivity启动Performance浅析

Google在2015年3月9日低调发布了Android 5.1,从官方博客的描述来看只是进行了小幅更新,如增加多SIM卡支持,HD Voice支持等。虽然Google对外声称只是稳定性和性能上的微调...
  • yihongyuelan
  • yihongyuelan
  • 2015-12-30 13:34:55
  • 8647

Android 4.4 Kitkat Phone工作流程浅析(十二)__4.4小结与5.0概览

在Android 4.4 中,Google 对Telephony_Phone进行了重构,前面也通过一些列文章分析了Android 4.4 中Telephony Phone的工作流程。但在2014年10...
  • yihongyuelan
  • yihongyuelan
  • 2015-05-04 11:15:10
  • 14821

Android Telephony启动过程源码分析

2 TelePhony启动代码分析: 2.1 Telephony关键类初始化 2.1.1 Phone进程启动 Phone就象个后台进程一样,开机即运行并一直存在(如果...
  • xiashaohua
  • xiashaohua
  • 2014-10-27 20:20:05
  • 3961

Android的RIL驱动模块telephony启动流程

#include stdio.h> #include fcntl.h> #include errno.h> int main() {     int ret;     int f...
  • lhf_tiger
  • lhf_tiger
  • 2013-08-08 20:35:24
  • 1710

Telephony MO CALL/IMS CALL

本篇文章介绍Telephony的MO(Mobile Original) call 的流程。 1.拨号App中输入号码并拨号,Android的源生的拨号App为Dialer(packages/apps/...
  • djialin0418
  • djialin0418
  • 2016-04-06 07:40:32
  • 1517

Android 7.0 telephony主要变化

  • 2016年09月26日 14:49
  • 3.33MB
  • 下载
    个人资料
    等级:
    访问量: 1895
    积分: 187
    排名: 99万+
    最新评论