ImsConference.java中会议成员更新处理详解
public class ConferenceParticipant implements Parcelable { //自定义数据结构
private static final String ANONYMOUS_INVALID_HOST
private final Uri mHandle;
private final String mDisplayName;
private final Uri mEndpoint;
private final int mState;
private long mConnectTime;
private long mConnectElapsedTime;
private int mCallDirection;}
public class DisconnectCause implements Parcelable { ...}
participant: ConferenceParticipantConnection.java
public void handleConferenceParticipantsUpdate( TelephonyConnection parent, List<ConferenceParticipant> participants) { //不支持会议管理,return if (parent != null && !parent.isManageImsConferenceCallSupported()) { Log.i(this, "handleConferenceParticipantsUpdate: manage conference is disallowed"); return; } Log.i(this, "handleConferenceParticipantsUpdate: size=%d", participants.size()); // 以同步方式执行更新。IMS framework可以快速连续地触发两次onConferenceParticipantsChanged callbacks。 // 第一次更新添加新的参与者,第二次更新其中一个参与者的状态。 synchronized (mUpdateSyncRoot) { //private final Object int oldParticipantCount = mConferenceParticipantConnections.size(); boolean newParticipantsAdded = false; boolean oldParticipantsRemoved = false; ArrayList<ConferenceParticipant> newParticipants = new ArrayList<>(participants.size()); HashSet<Pair<Uri,Uri>> participantUserEntities = new HashSet<>(participants.size()); // Determine if the conference event package represents a single party conference. // A single party conference :除了host外,只有1个会议成员. // Note: We consider 0 to still be a single party conference since some carriers will // send a conference event package with JUST the host in it when the conference is // disconnected. We don't want to change back to conference mode prior to disconnection // or we will not log the call. boolean isSinglePartyConference = participants.stream() //1.后面在解析 .filter(p -> { Pair<Uri, Uri> pIdent = new Pair<>(p.getHandle(), p.getEndpoint()); return !Objects.equals(mHostParticipantIdentity, pIdent); }).count() <= 1; if ((mIsEmulatingSinglePartyCall && !isSinglePartyConference) || !mIsEmulatingSinglePartyCall) { // Add any new participants and update existing. for (ConferenceParticipant participant : participants) { Pair<Uri, Uri> userEntity = new Pair<>(participant.getHandle(),participant.getEndpoint()); participantUserEntities.add(userEntity); if (!mConferenceParticipantConnections.containsKey(userEntity)) { //不存在 userEntity // Some carriers will also include the conference host in the CEP. We will filter that out here. if (!isParticipantHost(mConferenceHostAddress, participant.getHandle())) { createConferenceParticipantConnection(parent, participant); newParticipants.add(participant); newParticipantsAdded = true; } else { // Track the identity of the conference host; its useful to know when // we look at the CEP in the future. mHostParticipantIdentity = userEntity; } } else { //存在 userEntity ConferenceParticipantConnection connection = mConferenceParticipantConnections.get(userEntity); Log.i(this,"handleConferenceParticipantsUpdate: updateState, participant = %s",participant); connection.updateState(participant.getState()); connection.setVideoState(parent.getVideoState()); } } // Set state of new participants. if (newParticipantsAdded) { // Set the state of the new participants at once and add to the conference for (ConferenceParticipant newParticipant : newParticipants) { ConferenceParticipantConnection connection = mConferenceParticipantConnections.get(new Pair<>( newParticipant.getHandle(),newParticipant.getEndpoint())); connection.updateState(newParticipant.getState()); connection.setVideoState(parent.getVideoState()); } } //最后,从会议中删除不再存在于会议事件包数据中的任何参与者。 Iterator<Map.Entry<Pair<Uri, Uri>, ConferenceParticipantConnection>> entryIterator = mConferenceParticipantConnections.entrySet().iterator(); while (entryIterator.hasNext()) { Map.Entry<Pair<Uri, Uri>, ConferenceParticipantConnection> entry = entryIterator.next(); if (!participantUserEntities.contains(entry.getKey())) { ConferenceParticipantConnection participant = entry.getValue(); participant.setDisconnected(new DisconnectCause(DisconnectCause.CANCELED)); participant.removeConnectionListener(mParticipantListener); mTelephonyConnectionService.removeConnection(participant); removeConnection(participant); entryIterator.remove(); oldParticipantsRemoved = true; } } } int newParticipantCount = mConferenceParticipantConnections.size(); Log.v(this, "handleConferenceParticipantsUpdate: oldParticipantCount=%d, " + "newParticipantcount=%d", oldParticipantCount, newParticipantCount); // If the single party call emulation fature flag is enabled, we can potentially treat // the conference as a single party call when there is just one participant. if (mFeatureFlagProxy.isUsingSinglePartyCallEmulation()) { if (oldParticipantCount > 1 && newParticipantCount == 1) { // If number of participants goes to 1, emulate a single party call. startEmulatingSinglePartyCall(); } else if (mIsEmulatingSinglePartyCall && !isSinglePartyConference) { // Number of participants increased, so stop emulating a single party call. stopEmulatingSinglePartyCall(); } } // If new participants were added or old ones were removed, we need to ensure the state // of the manage conference capability is updated. if (newParticipantsAdded || oldParticipantsRemoved) { updateManageConference(); } } }
handleConferenceParticipantsUpdate: 1.ImsConferenceCallSupported判断 2.isSinglePartyConference判断 3.不EmulatingSinglePartyCall或EmulatingSinglePartyCall且SinglePartyConference条件下,添加成员,更新成员信息 4.新成员被添加到ConferenceParticipant中,更新信息 5.remove,从会议中删除不再存在于会议事件包数据中的任何参与者 6.startEmulatingSinglePartyCall()或stopEmulatingSinglePartyCall() 7.新成员增加或就成员remove, updateManageConference()
/** a single party call:会议电话成员只有1名与会者。 * 1. Set the name/address to that of the single participant. * 2. Remove the participant from Telecom and from local tracking; when we get a new CEP in * the future we'll just re-add the participant anyways. * 3. Tell telecom we're not a conference. * 4. Remove {@link Connection#CAPABILITY_MANAGE_CONFERENCE} capability. *注意:如果会议是通过sim call manager进行的,单方呼叫模拟将被禁用。模拟单方呼叫需要更改会议的属性(连接时间、地址、会议状态), sim call manager 不能保证将这些属性正确地转发到Telecom。 */ private void startEmulatingSinglePartyCall() { if (mIsUsingSimCallManager) { Log.i(this, "startEmulatingSinglePartyCall: using sim call manager; skip."); return; } Log.i(this, "startEmulatingSinglePartyCall: conference has a single " + "participant; downgrade to single party call."); mIsEmulatingSinglePartyCall = true; Iterator<ConferenceParticipantConnection> valueIterator = mConferenceParticipantConnections.values().iterator(); if (valueIterator.hasNext()) { ConferenceParticipantConnection entry = valueIterator.next(); // Set the conference name/number to that of the remaining participant. setAddress(entry.getAddress(), entry.getAddressPresentation()); setCallerDisplayName(entry.getCallerDisplayName(),entry.getCallerDisplayNamePresentation()); setConnectionStartElapsedRealTime(entry.getConnectElapsedTimeMillis()); setConnectionTime(entry.getConnectTimeMillis()); mLoneParticipantIdentity = new Pair<>(entry.getUserEntity(), entry.getEndpoint()); // Remove the participant from Telecom. It'll get picked up in a future CEP update again anyways. entry.setDisconnected(new DisconnectCause(DisconnectCause.CANCELED,DisconnectCause.REASON_EMULATING_SINGLE_CALL)); entry.removeConnectionListener(mParticipantListener); mTelephonyConnectionService.removeConnection(entry); removeConnection(entry); valueIterator.remove(); // Have Telecom pretend its not a conference. setConferenceState(false); //Remove manage conference capability. mCouldManageConference = can(Connection.CAPABILITY_MANAGE_CONFERENCE); int currentCapabilities = getConnectionCapabilities(); currentCapabilities &= ~Connection.CAPABILITY_MANAGE_CONFERENCE; setConnectionCapabilities(currentCapabilities); }
ImsConference.java中会议成员更新处理详解的更多相关文章
- Java 中的异常和处理详解
Java 中的异常和处理详解 原文出处: 代码钢琴家 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误 ...
- Java中的IO流系统详解(转载)
摘要: Java 流在处理上分为字符流和字节流.字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符.字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组. Java ...
- Java中的IO流系统详解
Java 流在处理上分为字符流和字节流.字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符.字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组. Java 内用 U ...
- java中内存结构及堆栈详解
一. java内存结构 1. Heap(堆):实例分配的地方,通过-Xms与-Xmx来设置 2. MethodArea(方法区域):类的信息及静态变量. 对应是Permanet Generation, ...
- java中的final和volatile详解
相比synchronized,final和volatile也是经常使用的关键字,下面聊一聊这两个关键字的使用和实现 1.使用 final使用: 修饰类表示该类为终态类,无法被继承 修饰方法表示该方法无 ...
- Java中23种经典设计模式详解
Java中23种设计模式目录1. 设计模式 31.1 创建型模式 41.1.1 工厂方法 41.1.2 抽象工厂 61.1.3 建造者模式 101.1.4 单态模式 131.1.5 原型模式 151. ...
- JAVA中堆栈和内存分配详解(摘抄)
在Java中,有六个不同的地方可以存储数据: 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存 ...
- 2018.8.1 Java中的反射和同步详解
为何要使用同步? java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他 ...
- Java中hashCode与equal方法详解
转载自http://blog.csdn.net/jiangwei0910410003/article/details/22739953 Java中的equals方法和hashCode方法是Object ...
随机推荐
- 畜禽免疫系统使用LODOP打印
<div class="btn_box"> <asp:Button ID="btnPrint" Text="预览并打印" ...
- libVEX学习
VEX IR是一种更加接近于compiler使用的中间语言/中间表示,它是不依赖于特定体系架构的. 1. Code Blocks code blocks是VEX处理代码的一个单元,使用IRSB结构体表 ...
- 2019牛客多校第⑨场E All men are brothers(并查集+组合数学)
原题:https://ac.nowcoder.com/acm/contest/889/E 思路: 做并查集,维护每个集合大小,初始化操作前的总方案数,每次合并两个集合时减少的数量=合并的两个集合大小相 ...
- php学习笔记(初学者入门)
<?php其他 isset() 变量是否存在 boolean empty() 检查变量是否存在,并判断值是否为非空或非0 void unset() 销毁变量 header('Content-Ty ...
- Day1 - 认识大数据& 企业需求分析 & 北风网简介
上午: 介绍: 海量的乱七八糟的数据中快速的计算出某些有用的信息 刑侦视频追踪 云栖大会 大数据分析/挖掘 ==> python <== 重点关注 大数据运维 ==> 运服务 ...
- linux基础重定向,用户,组,以及权限管理
一.重定向 标准输出standard output1>,>> 标准错误输出standard error output22>,2>> 标准输出设备::显示器 标准输入 ...
- javafx实现读者文摘上的文章预览及下载
功能设计: 1.实现读者文章的预览及下载 (实现了单击预览,双击下载) 2.实现文章查找 (实现了通过文章名查找(关键字)或者文章期数或年份(或者年份加期数)) 实现步骤: 首先是数据库设计: 数据库 ...
- 前端学习(八)sass和bootstrap(笔记)
less sass 和less基本上70%差不多(书写方式不一样) sass功能更多一点 1.定义一个变量 $b:blue; div{width:100px;height:100px; backgro ...
- 转帖:maven(二) maven项目构建ssh工程(父工程与子模块的拆分与聚合)
出处:http://www.cnblogs.com/whgk/p/7121336.html 前一节我们明白了maven是个什么玩意,这一节就来讲讲他的一个重要的应用场景,也就是通过maven将一个ss ...
- (微服务架构)Security + Oauth2 + Jwt + Zuul解决微服务系统的安全问题
前言 之前零零散散的学习过一点鉴权这方面的玩意儿,但自我感觉净他妈整些没用的,看代码还是看不懂,这次我们再统一对其进行学习一下,希望自己掌握这个技能,也希望屏幕面前的你能有点收获 此次的学习周期可能有 ...