Ims开机注册流程

news2024/11/27 2:19:21

                   

目录

  1. 概述
  2. Ims注册时序图
  3. PhoneApp的启动过程
  4. Ims注册主要代码
  5. 总结

  • 概述

IMS(IP Multimedia Subsystem)是IP多媒体系统, 是一种新的多媒体业务形式,ims service 结构主要包括 ImsService、ImsManager、MmTelFeatureConnection、ImsCallSession。其中:

  1. ImsService:ims的Service,实现了所有的ImsFeature(MmTelFeature和RcsFeature)和ims协议行为。通过ImsResolver绑定。由ImsServiceController来负责管理其生命周期及这个service所支持的ImsFeatures。其主要操作可以通过IImsServiceController来调用。
  2. ImsManager:单例类。提供了与IMS services交互的API,如创建ims call。这个类是所有ims相关操作的起点。
  3. MmTelFeatureConnection:IImsServiceController binder的容器类。
  4. ImsCallSession:负责ImsCall的发起和终止,以及两个ims端点间的媒体交换。它和ImsService直接交互。
  • Ims注册时序图


  时序图从开机后PhoneApp启动开始到最终发出请求

PhoneApp是如何开机启动的呢,下面我们简要说明一下。

三、PhoneApp的启动过程

首先PhoneApp的主要功能是什么呢?

  1. 负责实例化创建Telephony应用框架层(phone),且和phone一起运行在com.android.phone进程中。
  2. 管理(CallManager),控制通话相关的UI、功能操作、业务逻辑实现

这里我们需要知道,Android系统中多个应用程序(Apk)是可以运行在同一个进程中的,PhoneApp就是这样,连同Stk、SMSProvider、TelephonyProvider等模块都运行在com.android.phone进程中(简称phone进程)。

    <application android:name="PhoneApp"
            android:persistent="true"
            android:label="@string/phoneAppLabel"
            android:icon="@mipmap/ic_launcher_phone"
            android:allowBackup="false"
            android:supportsRtl="true"
            android:usesCleartextTraffic="true"
            android:defaultToDeviceProtectedStorage="true"
            android:directBootAware="true">


PhoneApp的路径是:packages\services\Telephony,我们来看看它的AndroidManifest.xml内容:

  1. persistent属性的作用:开机时被系统自动初始化;该模块所在的进程(com.android.phone)由于任何原因被kill掉之后,都会自动重启(这种情况只针对系统内置app,第三方安装的app不会被重启)
  2. directBootAware属性的作用:该属性使得用户在加密状态(未解锁)下能够正常使用一些手机功能,如闹钟、接电话等,但不允许访问私有应用数据


系统在启动时会先启动SystemService,SystemService会启动各种系统服务,包括AMS:

private void startBootstrapServices() {
.....
   mActivityManagerService = mSystemServiceManager.startService(
   ActivityManagerService.Lifecycle.class).getService(); 
   mActivityManagerService.setSystemServiceManager(mSystemServiceManager); 
   mActivityManagerService.setInstaller(installer);
......
}

 而ActivityManagerService的SystemReady方法中就有一个启动PersistentApps的方法,且该应用还需要MATCH_DIRECT_BOOT_AWARE,而PhoneApp正满足此需求:

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
......
    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
......
}

由此可见,PhoneApp会在系统启动起来的时候由系统自动启动

四、Ims注册主要代码

PhoneApp启动后会先执行onCreate()方法

packages\services\Telephony\src\com\android\phone\PhoneApp.java

public class PhoneApp extends Application {
    PhoneGlobals mPhoneGlobals;
    TelephonyGlobals mTelephonyGlobals;
    public PhoneApp() {
    }
    @Override
    public void onCreate() {
        if (UserHandle.myUserId() == 0) {
            // We are running as the primary user, so should bring up the
            // global phone state.
            mPhoneGlobals = new PhoneGlobals(this);// 创建PhoneGlobals,即Phone的全局状态
            mPhoneGlobals.onCreate();
            mTelephonyGlobals = new TelephonyGlobals(this);
            mTelephonyGlobals.onCreate();
        }
    }

PhoenApp的onCreate()方法主要创建了mPhoneGlobals对象和mTelephonyGlobals对象,并执行了两个对象的onCreate()方法,接下来的流程也将围绕mPhoneGlobals对象的onCreate展开:
packages\services\Telephony\src\com\android\phone\PhoneGlobals.java

    public void onCreate() {
    ......
        if (mCM == null) {
            // Initialize the telephony framework
            PhoneFactory.makeDefaultPhones(this);
        }
    ......
    }

首先通过PhoneFactory makeDefaultPhones,下面看一下makeDefaultPhones方法主要执行的动作
frameworks\opt\telephony\src\java\com\android\internal\telephony\PhoneFactory.java

public static void makeDefaultPhone(Context context) {
......
      for (int i = 0; i < numPhones; i++) {
      Phone phone = null;
      int phoneType = TelephonyManager.getPhoneType(networkModes[i]);
          if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
               phone = telephonyComponentFactory.makePhone(context,
                       sCommandsInterfaces[i], sPhoneNotifier, i,
                       PhoneConstants.PHONE_TYPE_GSM,
                       telephonyComponentFactory);
          } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
               phone = telephonyComponentFactory.makePhone(context,
                       sCommandsInterfaces[i], sPhoneNotifier, i,
                       PhoneConstants.PHONE_TYPE_CDMA_LTE,
                                telephonyComponentFactory);
          }
         Rlog.i(LOG_TAG, "Creating Phone with type = " + phoneType + " sub = " + i);
         sPhones[i] = phone;
        }
         // Set the default phone in base class.
         // FIXME: This is a first best guess at what the defaults will be. It
         // FIXME: needs to be done in a more controlled manner in the future.
         sPhone = sPhones[0];
        sCommandsInterface = sCommandsInterfaces[0];
        ......
        // Start monitoring after defaults have been made.
        // Default phone must be ready before ImsPhone is created because ImsService might
        // need it when it is being opened. This should initialize multiple ImsPhones for
        // ImsResolver implementations of ImsService.
        for (int i = 0; i < numPhones; i++) {
           sPhones[i].startMonitoringImsService();
        }
}

主要贴了创建GSMPhone和CDMAPhone的方法。

总结一下makeDefaultPhone()方法:

  1. 初始化各种控制接口SubscriptionController,UiccController,主要负责SIM卡状态信息的控制监听
  2. 根据SIM卡数量创建Phone和RIL实例,并且设置默认Phone和RIL,Phone分为GSM和CDMA两大种类
  3. 启动ImsResolver并绑定到ImsServices

Android中有三种PhoneFactory:

1.PhoneFactory.java ——–>用于创建GsmCdmaPhone对象

2.ImsPhoneFactory.java ——–>用于创建ImsPhone对象

3.SipPhoneFactory.java ——–>用于创建SipPhone对象

下面跟进startMonitoringImsService方法

frameworks\opt\telephony\src\java\com\android\internal\telephony\Phone.java

public void startMonitoringImsService() {
    if (getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
        return;
    }
    synchronized(Phone.lockForRadioTechnologyChange) {
        IntentFilter filter = new IntentFilter();
        ImsManager imsManager = ImsManager.getInstance(mContext, getPhoneId());
        // Don't listen to deprecated intents using the new dynamic binding.
        if (imsManager != null && !imsManager.isDynamicBinding()) {
            filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);
            filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);
        }
        mContext.registerReceiver(mImsIntentReceiver, filter);
        if (imsManager != null) {
            if (imsManager.isDynamicBinding() || imsManager.isServiceAvailable()) {
                mImsServiceReady = true;
                updateImsPhone();
            }
        }
    }
}

从上面的代码中可以看到,startMonitoringImsService() 做了如下动作:

  1. 初始化ImsManager
  2. 注册ImsService的UP/DOWN两个广播
  3. 更新ImsPhone.

当接收到UP广播后

private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() {
   @Override
   public void onReceive(Context context, Intent intent) {
......
     synchronized (Phone.lockForRadioTechnologyChange) {
       if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) {
          mImsServiceReady = true;
          updateImsPhone();
          ImsManager.getInstance(mContext, mPhoneId).updateImsServiceConfig(false);
       } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) {
          mImsServiceReady = false;
          updateImsPhone();
       }
    }
}

通过ImsManager更新ImsService的配置
frameworks\opt\net\ims\src\java\com\android\ims\ImsManager.java


    public void updateImsServiceConfig(boolean force) {
......
        if (!mConfigUpdated || force) {
            try {
                boolean isImsUsed = updateVolteFeatureValue();
                isImsUsed |= updateWfcFeatureAndProvisionedValues();
                isImsUsed |= updateVideoCallFeatureValue();
                if (isImsUsed || !isTurnOffImsAllowedByPlatform()) {
                    log("updateImsServiceConfig: turnOnIms");
                    turnOnIms();
                } else {
                    // Turn off IMS if it is not used AND turning off is allowed for carrier.
                    log("updateImsServiceConfig: turnOffIms");
                    turnOffIms();
                }
                mConfigUpdated = true;
            } catch (ImsException e) {
                loge("updateImsServiceConfig: ", e);
                mConfigUpdated = false;
            }
        }
    }

此处turnOnIms()会经过TelephonyManager、ImsResolver、ImsServiceController等类的实现、重写等。最终在高通私有类ImsService中实现。

下面是高通私有类的流程

vendor\qcom\proprietary\commonsys\telephony-apps\ims\src\org\codeaurora\ims\ ImsService.java

    @Override
    public void enableIms(int slotId) {
        Log.i(this, "enableIms :: slotId=" + slotId);
        if (slotId > INVALID_SLOT_ID && slotId < getNumSlots()) {
            mServiceSubs[slotId].turnOnIms();
        } else {
            Log.e(this, "enableIms :: Invalid slotId " + slotId);
        }
    }

vendor\qcom\proprietary\commonsys\telephony-apps\ims\src\org\codeaurora\ims\ ImsServiceSub.java

    public void turnOnIms() {
        mCi.sendImsRegistrationState(ImsRegistrationInfo.REGISTERED,
                mHandler.obtainMessage(EVENT_SET_IMS_STATE));
    }

vendor\qcom\proprietary\commonsys\telephony-apps\ims\src\org\codeaurora\ims\ ImsSenderRxr.java

   public void sendImsRegistrationState(int imsRegState, Message result) {
        ……
        queueRequest(rr);
        try {
        ……         
         imsRadioV10().requestRegistrationChange(rr.mSerial,
                    ImsRadioUtils.regStateToHal(imsRegState));
        } catch (Exception ex) {
            removeFromQueueAndSendResponse(rr.mSerial);
            Log.e(this, msgIdString + "request to IImsRadio: Exception: " + ex);
        }
   }

最后通过ImsSenderRxr把请求发出去。

上述就是ims从开机到注册的主要流程,关于时序图中的ImsPhone那块,就不在详细说明了。

五、总结

Ims的概念很大,上述只是介绍了它很小的一部分。IMS是一个在分组域(PS)上的多媒体控制/呼叫控制平台,IMS使得PS具有电路域(CS)的部分功能,支持会话类和非会话类的多媒体业务。IMS为未来的多媒体应用提供了一个通用的业务平台。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/88726.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于java 操作word的几种方式

1.apose word <dependency><groupId>com.luhuiguo</groupId><artifactId>aspose-words</artifactId><version>22.4</version><type>pom</type> </dependency> 一般用来转换文件格式&#xff0c;对于读取创建段…

ArcGIS:Excel/Txt 文件生成点图层、属性表编辑的基本方法、属性表之间的连接(合并)和关联的操作、属性表的字段计算器的使用

目录 01 说明 02 实验目的及要求 03 实验设备及软件平台 03 实验原理 04 实验内容与步骤 01 说明 由于这次的作业是从word上粘贴过来&#xff0c;所以有一些格式修改不了&#xff0c;也没有时间和精力修改&#xff0c;所以没有详细目录等等&#xff0c;浏览的时候应该非常难受.…

前端基础(六)_CSS单位

CSS单位 px px 相对于显示器屏幕分辨率而言&#xff0c;值固定&#xff0c;计算比较容易 em em 相对长度单位 和父元素的字号大小有关系 font-size属性值而言 浏览器默认字号为16像素&#xff0c;未经调整的浏览器都符合1em16px div p都设置了font-size 那em就是随p特点&am…

2022-12-10 Set类型

set类型 新的存储需求&#xff0c;存储大量的数据&#xff0c;在查询方面提供更高的效率。 需要的存储结构&#xff1a;能够保存大量的数据&#xff0c;高效的内部存储机制&#xff0c;便于查询。 set类型&#xff1a;与hash存储结构完全相同&#xff0c;仅存储键&#xff0c…

考研证件照要求?如何制作考研用的证件照?

考研报报名网上确认环节&#xff0c;网上确认的时候需要准备电子照片。疫情阶段今天教给大家不需要出门就可以方便&#xff0c;快捷的制作合格的证件照&#xff0c;免去出门办理和审核不过的麻烦&#xff01; 考研证件照要求&#xff1a; 1. 本人近三个月内正面、免冠、无妆、彩…

基于遗传算法优化的lssvm回归预测matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

华为云WeLink协作文档,助您开启职场高效办公

Word、PPT、Excel&#xff0c;是大家在日常工作中最常用的Office三件套&#xff0c;很多人都经历过&#xff0c;写一份Word或者PPT&#xff0c;从v1写到v10&#xff0c;不断接收、汇总、修改同事提供的素材&#xff0c;不断向领导或客户发送最新审核版本&#xff0c;最后可能还…

前端框架搭建(四)改造导入项目插件流程【vite】

1.改造为函数 默认模板创建的vite.config.ts文件是这样的 我们在上一节也提到过&#xff0c;这样将使得vite的一些配置十分杂乱&#xff0c;无法统一进行管理&#xff0c;因此我们可以将其函数化 export default defineConfig(configEnv > {const viteEnv loadEnv(config…

Python基础语法之注释、缩进、数字类型、一句多行和多行一句等的讲解及演示(超详细 附源码)

Python是实现了平台无关性的高级程序设计语言&#xff0c;它是在源代码程序与各平台的机器码之间插入了一个虚拟机&#xff0c;也就是说源代码程序不再直接翻译成机器码&#xff0c;而是先编译成虚拟机的字节码&#xff0c;再将字节码解释成各平台可执行的机器码。 Python源代…

传输层协议 —— TCP(图解2)

​ 目录 一、前言 二、重传机制 1. 超时重传 2. 快速重传 3. SACK 4. D-SACK 三、滑动窗口 1. 发送方的滑动窗口 2. 程序是如何表示发送方的四个部分 3. 接收方的滑动窗口 四、流量控制 五、拥塞控制 1. 慢启动 2. 拥塞避免 3. 拥塞发生 4. 快速恢复 六、TCP…

Moonbeam生态说|聊聊平行链Bifrost及其与Moonbeam集成最新动态

「Moonbeam生态说」是Moonbeam中文爱好者社区联合Moonbeam中文高级大使组织的社区AMA活动。 该活动为已部署Moonriver或Moonbeam的项目方提供了在主流Moonbeam非官方中文社区内介绍自己的项目信息&#xff0c;包括&#xff1a;项目介绍、团队介绍、技术优势等&#xff0c;帮助社…

[附源码]Node.js计算机毕业设计高校本科毕业及资料存档管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

基于Android的迷你桌球游戏设计与实现

目录 摘要11 关键词11 绪论11 1 游戏开发概述22 1.1 背景22 1.2 课题来源33 1.3 国内外研究现状33 1.4 Android应用程序构成44 1.4.1 应用程序55 1.4.2 应用程序框架55 1.4.3 库与运行环境55 1.4.4 内核55 2 游戏开发平台搭建55 2.1 SDK的下载与安装55 2.2 Ecli…

Chrome 解决 主页被qsearch 拦截

原文地址&#xff1a;谷歌浏览器被劫持如何解决&#xff08;附完美攻略&#xff09; - 知乎 今天&#xff0c;发现Chrome浏览器主页被修改了&#xff0c;尝试使用设置里主页&#xff0c;外观设置&#xff0c;都没有效果。改好了&#xff0c;但只要一刷新&#xff0c;主页又恢复…

短链是什么原理?怎么实现呢?

目录一、为什么需要短链二、短链跳转访问原理三、短链生成实现方案1、自增序列算法2、Hash算法四、代码示例1、表结构及索引2、外部依赖3、Base62Utils4、DAO层5、业务层五、测试用例一、为什么需要短链 内容营销中给用户推送营销消息最常见的方式就是发短信&#xff0c;比如三…

Hadoop的MapReduce基本流程体验

目录 MapReduce 编程规范 Mapper阶段 Reducer阶段 Driver阶段 常用数据序列化类型 案例实施 WordCountMapper类 WordCountReducer类 WordCountDriverr 驱动类 HDFS测试 MapReduce 编程规范 用户编写的程序分成三个部分&#xff1a;Mapper、Reducer 和 Driver。 Mappe…

使用粒子效果动画组成模型[自定义shader实现]

文章目录优点实现思路传递给Shader的数据根据模型数据生成数据传递给Shader自定义shader 连接cpu与gpu顶点着色器 计算位置片元着色器优点 性能卓越 上一篇使用的更改坐标实现 9万个点 页面非常卡顿 光是计算9万个点坐标更替的js就已经造成了堵塞 尝试了在顶点着色器中实现动画…

大数据Kudu(五):Kudu基于Cloudera Manager安装及配置

文章目录 Kudu基于Cloudera Manager安装及配置 一、启动CM集群 二、登录ClouderaManager平台安装Kudu

TCO-PEG-RGD 反式环辛烯聚乙二醇线肽RGD

反式环辛烯(TCO)作为亲双烯体与S-四嗪(Tetrazine)在生理条件下的反应有无需催化剂、反应速率快的优点&#xff0c;被广泛应用于生物和材料科学的研究中。 产品名称 TCO-PEG-RGD 反式环辛烯聚乙二醇线肽RGD 中文名称 线肽-聚乙二醇-反式环辛烯 英文名称 TCO-PEG-RGD 分…

“引进来,走出去”,锦江国际集团多重创新力引领绿色新发展

2022年12月13日&#xff0c;由南方财经全媒体集团指导&#xff0c;21世纪经济报道主办的“21世纪住宿业高峰论坛&#xff08;2022&#xff09;暨2022&#xff08;第十九届&#xff09;【金枕头】酒店大赏发布典礼”在上海如期举行。锦江国际集团副总裁周维应邀出席并发表“创新…