目录:

  Phone的继承关系与PhoneFactory(GsmCdmaPhone、ImsPhone、SipPhone)

  Phone进程的启动

  Phone对象的初始化(DefaultPhoneNotifier和RIL对象,将作为创建GsmCdmaPhone参数)

  为Phone实例注册监听事件(CM,注册与注销)

  Phone有什么作用(监听、上报消息、modem交互)

1、在Android N中,Phone的继承关系:

Android中有三种PhoneFactory:
PhoneFactory.java ——–>用于创建GsmCdmaPhone对象;
ImsPhoneFactory.java ——–>用于创建ImsPhone对象;
SipPhoneFactory.java ——–>用于创建SipPhone对象。
其中,GsmCdmaPhone对象是在Phone进程启动之后创建的(步骤1~6);之后,等到ImsService启动之后,就会创建ImsPhone(步骤7~11)。

2.1 Phone进程的启动

在Android中进程名一般对应的是该APP的包名,所以我们可以在源码中找package=”com.android.phone”。
接着你就会在/packages/services/Telephony/AndroidManifest.xml文件中看到:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
package="com.android.phone"
coreApp="true"
android:sharedUserId="android.uid.phone"
android:sharedUserLabel="@string/phoneAppLabel" >
<application android:name="PhoneApp" 
//在系统启动之时,ActivityManagerService的systemReady() 会加载所有persistent为true的应用
android:persistent="true"
android:label="@string/phoneAppLabel"
android:icon="@mipmap/ic_launcher_phone"
android:allowBackup="false"
android:supportsRtl="true"
android:usesCleartextTraffic="true">

2.2 Phone对象的初始化

在PhoneFactory.java的makeDefaultPhone方法中(时序图中的步骤3)

    public static void makeDefaultPhone(Context context) {
......
//创建DefaultPhoneNotifier对象。
sPhoneNotifier = new DefaultPhoneNotifier(); //根据待机模式计算出要创建Phone对象的数量
int numPhones = TelephonyManager.getDefault().getPhoneCount();
//创建networkMode、PhoneProxy、RIL的数组,用于存储对应的对象
int[] networkModes = new int[numPhones];
//Android 6.0
//sProxyPhones = new PhoneProxy[numPhones];
//Android N中没有了PhoneProxy,所以通过getDefaultPhone()得到的就是Phone实例
sPhones = new Phone[numPhones];
sCommandsInterfaces = new RIL[numPhones];
for (int i = 0; i < numPhones; i++) {
// reads the system properties and makes commandsinterface
// Get preferred network type.
networkModes[i] = RILConstants.PREFERRED_NETWORK_MODE;
Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkModes[i]));
//创建RIL,此时的i对应的是PhoneID。
sCommandsInterfaces[i] = new RIL(context, networkModes[i],
cdmaSubscription, i);

}
......
for (int i = 0; i < numPhones; i++) {
Phone phone = null;
//根据不用的类型,创建不同的Phone对象
int phoneType = TelephonyManager.getPhoneType(networkModes[i]);
if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
phone = new GsmCdmaPhone(context,
sCommandsInterfaces[i], sPhoneNotifier, i,
PhoneConstants.PHONE_TYPE_GSM,
//Android N中新增TelephonyComponentFactory类,主要用来
//初始化CallTracker、ServiceStateTracker、DcTracker等对象
TelephonyComponentFactory.getInstance());
} else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
phone = new GsmCdmaPhone(context,
sCommandsInterfaces[i], sPhoneNotifier, i,
PhoneConstants.PHONE_TYPE_CDMA_LTE,
TelephonyComponentFactory.getInstance());
}
Rlog.i(LOG_TAG, "Creating Phone with type = " + phoneType + " sub = " + i); sPhones[i] = phone;
}
.....
// 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.
for (int i = 0; i < numPhones; i++) {
//开始监听ImsService,如果ImsService已启动,进而执行创建ImsPhone对象
sPhones[i].startMonitoringImsService();
}
}

2.3 为Phone实例注册监听事件

PhoneGlobals.java的onCreate()方法中

    public void onCreate() {
if (mCM == null) {
// Initialize the telephony framework
//先创建Phone实例
PhoneFactory.makeDefaultPhones(this);
mCM = CallManager.getInstance();
for (Phone phone : PhoneFactory.getPhones()) {
//把新创建的Phone实例传递进来
mCM.registerPhone(phone);
}
}
}

由CallManager来管理这些Phone实例并且为它们注册监听事件。

    // list of registered phones, which are PhoneBase objs
private final ArrayList<Phone> mPhones; public boolean registerPhone(Phone phone) {
Phone basePhone = getPhoneBase(phone); if (basePhone != null && !mPhones.contains(basePhone)) { if (DBG) {
Rlog.d(LOG_TAG, "registerPhone(" +
phone.getPhoneName() + " " + phone + ")");
}
if (mPhones.isEmpty()) {
mDefaultPhone = basePhone;
}
//管理Phone实例
mPhones.add(basePhone);
mRingingCalls.add(basePhone.getRingingCall());
mBackgroundCalls.add(basePhone.getBackgroundCall());
mForegroundCalls.add(basePhone.getForegroundCall());
//为Phone实例注册监听事件
registerForPhoneStates(basePhone);
return true;
}
return false;
}
private void registerForPhoneStates(Phone phone) {
......
phone.registerForDisconnect(handler, EVENT_DISCONNECT,mRegistrantidentifier);
phone.registerForIncomingRing(handler, EVENT_INCOMING_RING,mRegistrantidentifier);
......
}

3. Phone有什么作用

回忆第2小节创建GsmCdmaPhone对象时

      sPhoneNotifier = new DefaultPhoneNotifier();
sCommandsInterfaces[i] = new RIL(context, networkModes[i],
cdmaSubscription, i); phone = new GsmCdmaPhone(context,
sCommandsInterfaces[i], sPhoneNotifier, i,
PhoneConstants.PHONE_TYPE_GSM,
TelephonyComponentFactory.getInstance());

先初始化了DefaultPhoneNotifier和RIL对象,将它们作为参数,再创建GsmCdmaPhone。
所以在GsmCdmaPhone中可以直接操纵这两个对象的方法。
DefaultPhoneNotifier实现了PhoneNotifier接口,PhoneNotifier接口中定义了很多notifyXXX的接口,所以DefaultPhoneNotifier主要的作用就是上报消息

public interface PhoneNotifier {

    public void notifyPhoneState(Phone sender);
public void notifyServiceState(Phone sender);
...
}

而RIL对象主要作用是跟modem交互。
因此,Phone实例就间接地拥有了跟modem交互的能力和上报消息的能力,再加上Phone实例自身就有监听事件的能力,所以Phone的作用就是:
1.注册监听事件,及时上报消息(Call状态变化、Service状态变化、新来电等等)
2.间接地为其他类提供跟modem交互的服务。

————————————————
版权声明:本文为CSDN博主「linyongan」的原创文章,遵循undefined版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/linyongan/article/details/51994817

Android Telephony分析(一) ---- Phone详解的更多相关文章

  1. Android Telephony分析(五) ---- TelephonyRegistry详解

    本文紧接着上一篇文章<Android Telephony分析(四) —- TelephonyManager详解 >的1.4小节.从TelephonyRegistry的大部分方法中: 可以看 ...

  2. Android Telephony分析(三) ---- RILJ详解

    前言 本文主要讲解RILJ工作原理,以便更好地分析代码,分析业务的流程.这里说的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\andro ...

  3. Android Telephony分析(二) ---- RegistrantList详解

    前言 本文主要讲解RegistrantList的原理,以及如何快速分析RegistrantList相关的代码流程.在Telephony模块中,在RIL.Tracker(ServiceStateTrac ...

  4. Android Telephony分析(四) ---- TelephonyManager详解

    前言 TelephonyManager主要提供Telephony相关信息的查询/修改功能,以及Phone状态监听功能,封装的方法主要是提供给APP上层使用.TelephonyManager.java ...

  5. Android Telephony分析(六) ---- 接口扩展(实践篇)

    本文将结合前面五篇文章所讲解的知识,综合起来,实现一个接口扩展的功能.如果还没有阅读过前面五篇文章的内容,请先阅读:<Android Telephony分析(一) — Phone详解 >& ...

  6. Android Telephony分析(七) ---- 接口扩展(异步转同步)

    本文是基于上一篇<Android Telephony分析(六) —- 接口扩展(实践篇)>来写的.上一篇介绍的接口扩展的方法需要实现两部分代码:1. 从APP至RIL,发送请求:2. 从R ...

  7. Android不规则点击区域详解

    Android不规则点击区域详解 摘要 今天要和大家分享的是Android不规则点击区域,准确说是在视觉上不规则的图像点击响应区域分发. 其实这个问题比较简单,对于很多人来说根本不值得做为一篇博文写出 ...

  8. [Android新手区] SQLite 操作详解--SQL语法

    该文章完全摘自转自:北大青鸟[Android新手区] SQLite 操作详解--SQL语法  :http://home.bdqn.cn/thread-49363-1-1.html SQLite库可以解 ...

  9. 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解 (旧版本 | 仅作参考)

    . 基本上可以导入项目开始使用了 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21035637 ...

随机推荐

  1. Dubbo入门到精通学习笔记(十三):ZooKeeper集群的安装、配置、高可用测试、升级、迁移

    文章目录 ZooKeeper集群的安装.配置.高可用测试 ZooKeeper 与 Dubbo 服务集群架构图 1. 修改操作系统的/etc/hosts 文件,添加 IP 与主机名映射: 2. 下载或上 ...

  2. Rollei SL66 使用说明

    根据记忆,并用不规范的语言描述我对sl66的使用心得:一.上卷1.用摇把顺时针转到12点位置,再退回3点位置:2.安插刀:3.后背上方按钮向右拨,打开后背:4.取出,装卷,再放入:5.转动后背上旋钮, ...

  3. vue中记录页面的滚动距离

    业务需求:pageOne页面是一个商品列表页面,在这个页面点击商品,就会跳转到pageTwo商品详细页面.此时再从pageTwo页面返回到pageOne页面时,pageOne页面需要做到:1.记录pa ...

  4. eduCF#60 D. Magic Gems /// 矩阵快速幂

    题目大意: 给定n m (1≤N≤1e18, 2≤M≤100) 一个魔法水晶可以分裂成连续的m个普通水晶 求用水晶放慢n个位置的方案modulo 1000000007 (1e9+7) input 4 ...

  5. zabbix--监控的组件和进程介绍

    上图是zabbix的架构,zabbix proxy(代理),可以减小IO并发. zabbix web GUI是用php写的画图工具,从数据库抓取数据. zabbix database zabbix获取 ...

  6. OAuth2.0实例说明

    OAuth2.0 详细实列+Word文档清晰说明 实例下载地址:https://files.cnblogs.com/files/liyanbofly/OAuth2.0%E5%AE%9E%E4%BE%8 ...

  7. SpringMVC和spring常见面试题总结

    1.什么是Spring MVC ?简单介绍下你对springMVC的理解? Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,C ...

  8. python基础小点

    变量的命名规则 由字母.下划线.数字组成,且不能以数字开头 不能用关键字作为变量名 最好不要与python内置的一些方法和类名冲突 变量名应尽量简短且具有意义,多个单词之间用下划线连接 注释 #  - ...

  9. wpf 解决 WPF SelectionChanged事件向上传递造成重复执行不想执行的函数的问题

    例如 tabcontrol里有一个tabitem tabitem里有一个combox和一个datagrid tabcontrol combox datagrid都有SelectionChanged事件 ...

  10. 安装percona-toolkit.rpm时候报错:perl(Time::HiRes) is needed by percona-toolkit-2.2.16-1.noarch

    1.安装percona-toolkit.rpm时候报错: warning: percona-toolkit.rpm: Header V4 DSA/SHA1 Signature, key ID cd2e ...