IMS

开机初始化流程图请见如下附件,流程图较大,文档中显示不清晰。

IMS开机初始化流程图

1.1 监控IMS Service

PhoneApp进程是在系统开机时启动的,Phone进程初始化的时候(步骤1~6),在创建GSMPhone或者CDMAPhone之后,会执行监控IMS Service的流程,也就是流程图上的步骤7,在PhoneFactory.Java的makeDefaultPhone()方法中:

/**

* FIXME replace this with

some other way of making these

* instances

*/

public static void

makeDefaultPhone(Context context) {

......

//先根据phoneType创建GSMPhone或者CDMAPhone

for (int i = 0; i <

numPhones; i++) {

PhoneBase phone =

null;

int phoneType =

TelephonyManager.getPhoneType(Modes[i]);

if (phoneType ==

PhoneConstants.PHONE_TYPE_GSM) {

phone =

TelephonyPluginDelegate.getInstance().makeGSMPhone(context,

sss[i], sPhoneNotifier, i);

} else if

(phoneType == PhoneConstants.PHONE_TYPE_CDMA) {

phone =

TelephonyPluginDelegate.getInstance().makeCDMALTEPhone(context,

sCommandsInterfaces[i], sPhoneNotifier, i);

}

Rlog.i(LOG_TAG,

"Creating Phone with type = " + phoneType + " sub = " + i);

sProxyPhones[i] =

TelephonyPluginDelegate.getInstance().makePhoneProxy(phone);

}

......

//在makeDefaultPhone()方法的最后,等所有要初始化的操作

//(如创建RIL,Default Phone等)都执行完之后。

for (int i = 0; i <

numPhones; i++) {

//开始执行监控IMS Service的流程

sProxyPhones[i].startMonitoringImsService();

}

}

接着来到PhoneProxy.java的startMonitoringImsService()方法中,可以看到在监控IMS service之前必须先创建Default Phone。

public void

startMonitoringImsService() {

//必须先创建Default Phone

if (mActivePhone !=

null) {

mActivePhone.startMonitoringImsService();

}

}

接着来到PhoneBase.java的startMonitoringImsService()方法中,来到这里,主要是为了注册上监听IMS SERVICE UP或者DOWN的广播。等到ImsService onCreate()的时候,会发出ACTION_IMS_SERVICE_UP的广播,然后PhoneBase接收到广播之后就可以执行创建IMSPhone对象(1.3小节会详细讲)和通知modem turn on IMS的流程(1.4小节会详细讲)。

@Override

public void

startMonitoringImsService() {

if (getPhoneType() ==

PhoneConstants.PHONE_TYPE_SIP) {

return;

}

synchronized(PhoneProxy.lockForRadioTechnologyChange) {

IntentFilter

filter = new IntentFilter();

filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);

filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);

//注册监听IMS SERVICE UP或者DOWN的广播

mContext.registerReceiver(mImsIntentReceiver, filter);

mImsIntentReceiverRegistered = true;

// Monitor IMS

service - but first poll to see if already up (could miss

//

intent)

//初始化ImsManager对象

ImsManager imsManager =

ImsManager.getInstance(mContext, getPhoneId());

//IMS

service目前还不可用

if (imsManager !=

null && imsManager.isServiceAvailable()) {

mImsServiceReady = true;

ImsPhone();

ImsManager.updateImsServiceConfig(mContext, mPhoneId, false);

}

}

}

1.2 IMS Service的启动

备注:这部分内容是Qualcomm的实现。

步骤11:ImsServiceAutoboot.java监听了ACTION_BOOT_COMPLETED和ACTION_SIM_STATE_CHANGED广播,在开机的时候,ImsServiceAutoboot会先收到ACTION_SIM_STATE_CHANGED广播。

//ClassName是ImsService,所以下面启动的Service就是Ims Service

private final static

String mClassName = ImsService.class.getName();

public void

onReceive(Context context, Intent intent) {

String intentAction =

intent.getAction();

//在开机的时候,会先收到ACTION_SIM_STATE_CHANGED广播

if

((Intent.ACTION_BOOT_COMPLETED.equals(intentAction))  ||

(ACTION_SIM_STATE_CHANGED.equals(intentAction))) {

//如果这时候Service还没有启动

if

(!isServiceRunning(context)) {

Log.d(TAG,

"Starting " + mClassName + " : " + intentAction + " received. ");

//启动Service

startService(context);

} else

{

Log.d(TAG,

mClassName + " is already running. " +

intentAction + " ignored. ");

}

} else {

Log.e(TAG,

"Received Intent: " + intent.toString());

}

}

private void

startService(Context context) {

ComponentName comp =

new ComponentName(context.getName(), mClassName);

//启动Ims Service

ComponentName service

= context.startService(new Intent().setComponent(comp));

if (service == null)

{

Log.e(TAG, "Could

Not Start Service " + comp.toString());

} else {

Log.e(TAG,

mClassName + " service Started Successfully");

}

}

在ImsService.java的onCreate()方法中

public void onCreate() {

super.onCreate();

Log.d (LOG_TAG,

"ImsService created!");

mServiceSub = new

ImsServiceSub[getNumSubscriptions()];

for (int i = 0; i <

getNumSubscriptions(); i++) {

//在这里初始化ImsServiceSub对象,在ImsServiceSub的

//构造方法中进而会初始化ImsSenderRxr、ImsServiceSubHandler

//等对象并且监听IMS、Call等的状态变化;

//(ImsSenderRxr跟RILJ作用类似,可以跟Qcril交互,

// IMS的流程会走ImsSenderRxr而不会走RIL.java)

mServiceSub[i] = new ImsServiceSub(i +

1, this);

}

ServiceManager.addService("ims", mBinder);

//配置mImsPhoneId为DEFAULT_PHONE_ID,发送ACTION_IMS_SERVICE_UP广播

switchImsPhoneByPhoneId(DEFAULT_PHONE_ID);

final int defaultSub =

1;

ImsVideoGlobals.init(mServiceSub[defaultSub-1], this);

/* Check if any change

in socket communication is required */

initSubscriptionStatus();

/* Initialize Call

Deflect support to not supported */

initCallDeflectStatus();

}

/* Method to re-initialize

the Ims Phone instances */

private void

switchImsPhoneByPhoneId(int phoneId) {

if (mImsPhoneId ==

phoneId) {

Log.d(LOG_TAG,

"switchImsPhone: ImsPhoneId: " + mImsPhoneId + " UNchanged");

return;

}

Log.d(LOG_TAG,

"switchImsPhone: ImsPhoneId:" + mImsPhoneId + " changed to " +

phoneId);

mImsPhoneId =

phoneId;

/* Change the socket

communication */

final int defaultSub =

1;

mServiceSub[defaultSub-1].registerForPhoneId(mImsPhoneId);

/* Shut-down the

existing ims phone */

int mNumPhones =

TelephonyManager.getDefault().getPhoneCount();

for (int i = 0; i <

mNumPhones; i++) {

if(mImsPhoneId !=

i) {

Intent intent

= new Intent(ImsManager.ACTION_IMS_SERVICE_DOWN);

intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);

intent.putExtra(ImsManager.EXTRA_PHONE_ID, i);

this.sendStickyBroadcast(new Intent(intent));

}

}

/* Create the new IMS

phone */

Intent intent = new

Intent(ImsManager.ACTION_IMS_SERVICE_UP);

intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);

//添加ImsPhoneId,发送广播,通知PhoneBase

intent.putExtra(ImsManager.EXTRA_PHONE_ID, mImsPhoneId);

this.sendStickyBroadcast(new Intent(intent));

}

在IMS Service启动之后,回到PhoneBase.java的mImsIntentReceiver广播接收器中

private BroadcastReceiver

mImsIntentReceiver = new BroadcastReceiver() {

@Override

public void

onReceive(Context context, Intent intent) {

Rlog.d(LOG_TAG,

"mImsIntentReceiver: action " + intent.getAction());

//先判断intent中是否包含Phone Id

if

(intent.hasExtra(ImsManager.EXTRA_PHONE_ID)) {

int

extraPhoneId = intent.getIntExtra(ImsManager.EXTRA_PHONE_ID,

SubscriptionManager.INVALID_PHONE_INDEX);

Rlog.d(LOG_TAG, "mImsIntentReceiver: extraPhoneId = " +

extraPhoneId);

//如果获取到的Phone Id等于-1或者Phone Id跟当前get到的

//phone

Id不一样,说明有误,所以直接return

if

(extraPhoneId == SubscriptionManager.INVALID_PHONE_INDEX ||

extraPhoneId != getPhoneId()) {

return;

}

}

synchronized

(PhoneProxy.lockForRadioTechnologyChange) {

//如果ACTION是IMS_SERVICE_UP,说明IMS Service已启动

if

(intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) {

//将标志设置成true,在更新ImsPhone时会用到

mImsServiceReady = true;

//创建或者更新ImsPhone(1.3小节会详细讲)

updateImsPhone();

//更新配置信息,通知Modem turn On/Off IMS(1.4小节会详细讲)

ImsManager.updateImsServiceConfig(mContext, mPhoneId, false);

} else if

(intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)){

mImsServiceReady = false;

updateImsPhone();

}

}

}

};

1.3 创建ImsPhone

protected void

updateImsPhone() {

Rlog.d(LOG_TAG,

"updateImsPhone"

+ "

mImsServiceReady=" + mImsServiceReady);

//如果ImsService已启动并且ImsPhone还没有被创建

if (mImsServiceReady

&& (mImsPhone == null)) {

//通过PhoneFactory创建ImsPhone,这里的this就是default Phone

mImsPhone =

PhoneFactory.makeImsPhone(mNotifier, this);

//registerPhone的作用是把新创建的ImsPhone对象添加到CallManager

//的Phone list中,并且为ImsPhone注册监听各种Phone States

CallManager.getInstance().registerPhone(mImsPhone);

mImsPhone.registerForSilentRedial(

this,

EVENT_INITIATE_SILENT_REDIAL, null);

} else if

(!mImsServiceReady && (mImsPhone != null)) {

CallManager.getInstance().unregisterPhone(mImsPhone);

mImsPhone.unregisterForSilentRedial(this);

mImsPhone.dispose();

// Potential GC

issue if someone keeps a reference to ImsPhone.

// However: this

change will make sure that such a reference does

// not access

functions through NULL pointer.

//mImsPhone.removeReferences();

mImsPhone =

null;

}

}

接着PhoneFactory还是调了ImsPhoneFactory的makePhone()方法

/**

* Makes a {@link

ImsPhone} object.

* @return the {@code

ImsPhone} object or null if the exception occured

*/

public static ImsPhone

makeImsPhone(PhoneNotifier phoneNotifier, Phone defaultPhone) {

return

ImsPhoneFactory.makePhone(sContext, phoneNotifier, defaultPhone);

}

而ImsPhoneFactory中只有一个方法,也就是

public static ImsPhone

makePhone(Context context,

PhoneNotifier

phoneNotifier, Phone defaultPhone) {

try {

//直接new ImsPhone,在ImsPhone的构造方法中又

//会new ImsPhoneCallTracker,在ImsPhoneCallTracker的

//构造方法中,会执行获取IMS注册状态的流程(第二节会详细讲)

return new

ImsPhone(context, phoneNotifier, defaultPhone);

} catch (Exception e)

{

Rlog.e("VoltePhoneFactory", "makePhone", e);

return

null;

}

}

到这里,ImsPhone被创建完成。

1.4 通知Modem turn On IMS

在PhoneBase.java的mImsIntentReceiver广播接收器中,除了创建ImsPhone对象,还调了ImsManager.java的updateImsServiceConfig()方法更新配置信息。

public static void

updateImsServiceConfig(Context context, int phoneId, boolean force) {

final ImsManager

imsManager = ImsManager.getInstance(context, phoneId);

//此时imsManager.mConfigUpdated的值还是false,说明还没有更新过

if (imsManager != null

&& (!imsManager.mConfigUpdated || force)) {

try {

//如果Volte、VideoCall、WfC(Wifi Calling)任意一项可用且enable的话,那么就要turn On IMS

boolean turnOn

= imsManager.updateVolteFeatureValue();

turnOn |=

imsManager.updateVideoCallFeatureValue();

turnOn |=

imsManager.updateWfcFeatureAndProvisionedValues();

if (turnOn)

{

//通知modem turn On IMS

imsManager.turnOnIms();

} else if

(getBooleanCarrierConfig(context,

CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL)) {

imsManager.turnOffIms();

}

//把标志位设成true,除非强制更新,否则不会再进来这里

imsManager.mConfigUpdated =

true;

} catch

(ImsException e) {

loge("updateImsServiceConfig: " + e);

imsManager.mConfigUpdated = false;

}

}

}

android ims注册流程,ims注册流程volte通话流程总结相关推荐

  1. VoLTE 通话流程及TFT

    VoLTE 通话流程及TFT 随想 IP地址分配及EPS bearer EPS承载及TFT VoLTE电话流程 附: 重要消息的内容例子 LTE NAS EMM Plain OTA Outgoing ...

  2. Android 9.0 IMS通话流程

    简介: VoLTE是基于IMS的语音业务,它是一种IP数据,就是我们熟知的高清语音通话. 第一部分 拨出流程(MO) IMS通话流程可以在GSM的通话流程的基础上进行研究,整体流程都差不多,就是在一些 ...

  3. Android广播管理二--广播注册(registerReceiver)流程分析

    前面分析了Android系统的广播机制,从本质来说,它是一种消息订阅/发布机制.因此,使用这种消息驱动模型的第一步便是订阅消息:而对Android应用程序来说,订阅消息其实就是注册广播接收器. 接下来 ...

  4. android volte功能,Android 8.0 Volte开关流程 HD图标显示

    android 8.0的Volte开关流程.. Volte按钮: vendor/qcom/proprietary/telephont-app/NetworkSetting/src/com/qualco ...

  5. Android 8.0 Volte开关流程 HD图标显示

    android 8.0的Volte开关流程 Volte按钮: vendor/qcom/proprietary/telephont-app/NetworkSetting/src/com/qualcomm ...

  6. ims sip不发起注册问题实操

    问题背景,需要将多家运营商的虚商ims调试起来并上线,过程遇到各种ims不注册问题. 问题1 Qtrace模块过滤volte_enable.发现为0,表示nv73833中的volte被关了,这个一般是 ...

  7. Activity启动流程(六)注册目标Activity进程到system_server进程以及创建目标Activity进程Application

    注册Activity应用进程到system_server以及创建Activity应用进程Application Android四大组件源码实现详解系列博客目录: Android应用进程创建流程大揭秘 ...

  8. linux加密框架 crypto 通用算法注册接口__crypto_register_alg注册流程

    函数介绍 __crypto_register_alg函数实现向加密框架注册算法(包括静态算法和动态算法)的功能,输入参数为算法说明alg,注册成功时返回算法注册用的算法幼虫larval,注册失败时返回 ...

  9. 阿里云账号怎么注册?新手注册流程多方法

    阿里云账号怎么注册?阿里云账号支持手机号注册.阿里云APP注册.支付宝和钉钉多种注册方式,账号注册后需要通过实名认证才可以购买或使用云产品,阿里云百科来详细说下不同途径注册阿里云账号图文流程: 目录 ...

最新文章

  1. 文件传输:二进制文件传输与文本传输(file transfer)
  2. leaflets + heatmap 加载地图
  3. 像个字段相减绝对值_【高考数学】33个知识点+66个易混点大整合
  4. 也谈贝叶斯分类(C#)版本
  5. 计算机网络专业的基础知识,计算机网络专业基础知识.doc
  6. 初识python之 APP store排行榜 蜘蛛抓取(一)
  7. Python多态原理与示例演示
  8. servlet文件实现弹出框
  9. Applying Rhetorical Structure Theory to Student Essays for Providing Automated Writing Feedback
  10. 解压速度更快, Zstandard 1.4.1 发布
  11. 智慧云linux安装命令,智能的shell命令行fish 3.0.0发布下载,附安装方法
  12. python的自省与反射机制
  13. Scipy总结(constants)
  14. 利用for循环打印图形
  15. thinkphp5+php微信公众号二维码扫码关注推广二维码事件实现
  16. 配置web.xml文件时报The word ‘***‘ is not correctly spelled的解决方案
  17. Python编程基础题(2-求一元二次方程的解Ⅱ)
  18. Java的7大设计原则和23种设计模式
  19. android应用程序隐私设置在哪,手机权限设置在哪里_手机设置应用软件权限的具体步骤...
  20. 敏感性、特异性、假阳性、假阴性

热门文章

  1. 蓝海卓越 计费管理系统 download.php 任意文件读取漏洞
  2. java如何根据模板填充数据生成word文档
  3. 用Swift做个游戏Lecture04 —— 仙人掌的狙击
  4. 关于Kernel的一点解释
  5. zzulioj新生周赛(6) 2733: 键盘霸主hrs
  6. Vue简单示例——weex
  7. 内网穿透 —— 利用 ISS 和 ngrok 搭建可以让外网访问的个人网站
  8. 海思AI芯片(Hi3519A/3559A)方案学习(十七)开发板上运行yolo3模型的代码分析
  9. 奇说妙语百度云_陶杰
  10. 输入一段字符,统计一段字符串中大小写字母的个数