当前位置: 首页 > news >正文

AAOS CarMediaService 服务框架

文章目录

      • 前言
      • MediaSession
      • CarMediaService
        • 作用是什么?提供了哪些接口?如何使用?
        • CarMediaService的实现
        • 总结

前言

CarMediaService 是AAOS中统一管理媒体播放控制、信息显示和用户交互等功能的服务。这一服务依赖于android MediaSession框架。 所以首先需要简单的了解一下MediaSession。

MediaSession

MediaSession 框架规范了音视频应用中界面与播放器之间的通信接口,实现界面与播放器之间的完全解耦。MediaSession 框架定义了媒体会话和媒体控制器两个重要的类,它们为构建多媒体播放器应用提供了一个完善的技术架构。
在这里插入图片描述
AAOS上面的MediaSession的控制框图如上主要是MediaControl和MediaSession两个类直接的交互。

  • MediaControl是UI端控制Service端的类,在AAOS中所有的app播放控制客户端的实现都是carMediaApp中MediaControl的实现的(包括蓝牙audio localplayer界面中暂停播放,下一首 上一首等等)。

  • MediaSession是服务端, 这个服务端包括(蓝牙的src\com\android\bluetooth,和/apps/Car/LocalMediaPlayer)。这这里面实现了Mediassion 的callback 用来响应client 端UI的控制。 而响应之后的状态改变可以通过继承MediaControl的callback 在客户端实现。

CarMediaService

作用是什么?提供了哪些接口?如何使用?
  • 用途

    CarMediaService通过CarMediaManager给外部应用提供使用的API。
    这些api允许开发者控制车辆中的主要媒体源,以及获取与这一媒体源相关的更新信息。通过这个 API 来实现媒体播放控制、信息显示和用户交互等功能。

  • 接口

    CarMediaManger是客户端 通过AIDL的接口 调用到CarMediaService中。 提供的AIDIL的接口如下:

  1. 获取/设置提供模式下当前活动的媒体源。
    其中模式包括播放和浏览: 是指应用的操作可以是浏览媒体 或者是操作播放媒体。
    其中MediaSource的理解:可以认为是执行具体播放操作的一个应用 是媒体播放控制的对象比如蓝牙音乐播放器、本地的播放器等等。
  2. 注册/反注册回调,监听媒体活动源的更新。同样模式可以是浏览或者播放。

综上可以看到carMediaService 是实现所有媒体相关的ui 浏览和控制的统一管理。 监听媒体源的变化,控制活动和非活动媒体源的播放、退出、暂停等等。

interface ICarMedia {/** Gets the currently active media source for the provided mode */ComponentName getMediaSource(int mode);/** Sets the currently active media source for the provided mode */void setMediaSource(in ComponentName mediaSource, int mode);/** Register a callback that receives updates to the active media source */void registerMediaSourceListener(in ICarMediaSourceListener callback, int mode);/** Unregister a callback that receives updates to the active media source */void unregisterMediaSourceListener(in ICarMediaSourceListener callback, int mode);/** Retrieve a list of media sources, ordered by most recently used */List<ComponentName> getLastMediaSources(int mode);/** Returns whether the browse and playback sources can be changed independently. */boolean isIndependentPlaybackConfig();/** Sets whether the browse and playback sources can be changed independently. */void setIndependentPlaybackConfig(boolean independent);
}
  • 使用流程

首先获取CarMediaManager,然后注册MediaSource变化的监听,在mediasource有变化的时候更新ui。

        mHandler = new Handler(application.getMainLooper());mMediaSourceListener = componentName -> mHandler.post(() -> updateModelState(mInputFactory.getMediaSource(componentName)));try {mCarMediaManager = mInputFactory.getCarMediaManager(mCar);mCarMediaManager.addMediaSourceListener(mMediaSourceListener, mode);MediaSource src = mInputFactory.getMediaSource(mCarMediaManager.getMediaSource(mode));if (Log.isLoggable(TAG, Log.INFO)) {Log.i(TAG, "Initializing with " + src);}updateModelState(src);} catch (CarNotConnectedException e) {Log.e(TAG, "Car not connected", e);}
CarMediaService的实现

在这里插入图片描述

  • carMediaService中初始化流程
  1. 获取mPrimaryMediaComponents
    获取的方式是通过遍历系统的所有package、然后查看有MediaBroswerService的package。
    在AAOS 默认Bluetooth有MediaBroswerService,所以默认的package是com.android.bluetooth。
private ComponentName getMediaService(@NonNull ComponentName componentName) {String packageName = componentName.getPackageName();String className = componentName.getClassName();PackageManager packageManager = mContext.getPackageManager();Intent mediaIntent = new Intent();mediaIntent.setPackage(packageName);mediaIntent.setAction(MediaBrowserService.SERVICE_INTERFACE);List<ResolveInfo> mediaServices = packageManager.queryIntentServicesAsUser(mediaIntent,PackageManager.GET_RESOLVED_FILTER, ActivityManager.getCurrentUser());for (ResolveInfo service : mediaServices) {String serviceName = service.serviceInfo.name;if (!TextUtils.isEmpty(serviceName)// If className is not specified, returns the first service in the package;// otherwise returns the matched service.// TODO(b/136274456): find a proper way to handle the case where there are//  multiple services and the className is not specified.&& (TextUtils.isEmpty(className) || serviceName.equals(className))) {return new ComponentName(packageName, serviceName);}}}
  1. 注册MediaSessionActive的回调
    当服务端的MediaSession 设置为active的时候,回调到这个SessionChangedListener中

  2. 启动MediaConnectService
    MediaConnectorService会调用MediaConnectorService的onStartCommand。
    onStartCommand中会获取当前应用的MediaControl设置到PlaybackViewModel。
    PlaybackViewModel利用这个control对MediaSession的service端进行控制。
    控制是在service端实现mediaControl的onPrepare、onPlay等实现的。
    如果MediaSession当前是播放的状态那么会stop掉。如果不是的话 会先进行prepare操作。

    private void initUser(@UserIdInt int userId) {mPrimaryMediaComponents[MEDIA_SOURCE_MODE_PLAYBACK] = isCurrentUserEphemeral()? getDefaultMediaSource() : getLastMediaSource(MEDIA_SOURCE_MODE_PLAYBACK);mPrimaryMediaComponents[MEDIA_SOURCE_MODE_BROWSE] = isCurrentUserEphemeral()? getDefaultMediaSource() : getLastMediaSource(MEDIA_SOURCE_MODE_BROWSE);mActiveUserMediaController = null;updateMediaSessionCallbackForCurrentUser();notifyListeners(MEDIA_SOURCE_MODE_PLAYBACK);notifyListeners(MEDIA_SOURCE_MODE_BROWSE);startMediaConnectorService(shouldStartPlayback(mPlayOnBootConfig), currentUser);}}
  • SessionChanged 的回调
    在这里插入图片描述
    SessionChanged回调到onActiveSessionsChanged。回调的参数是所有active的mediaControl。这里面会遍历所有control,如果control的状态是playing 并且其MediaSource跟当前存储的PrimaryMediaSource不一样的话 会更新control的MediaSource到PrimaryMediaSource。
    private class SessionChangedListener implements OnActiveSessionsChangedListener {@Overridepublic void onActiveSessionsChanged(List<MediaController> controllers) {if (ActivityManager.getCurrentUser() != mCurrentUser) {Slog.e(CarLog.TAG_MEDIA, "Active session callback for old user: " + mCurrentUser);return;}mMediaSessionUpdater.registerCallbacks(controllers);}}
  • MediaController的回调
    在这里插入图片描述

    这个会回调到onPlaybackStateChanged,回调的状态是playing而且跟回调之前的状态不一样的时候 也会调用setPrimaryMediaSource进行primary mediasource的更新。

        public void onPlaybackStateChanged(@Nullable PlaybackState state) {if (state.getState() == PlaybackState.STATE_PLAYING&& state.getState() != mPreviousPlaybackState) {ComponentName mediaSource = getMediaSource(mMediaController.getPackageName(),getClassName(mMediaController));if (mediaSource != null) {setPrimaryMediaSource(mediaSource, MEDIA_SOURCE_MODE_PLAYBACK);}}mPreviousPlaybackState = state.getState();}}
总结

CarMediaService 的实现是通过注册MediaSessionActive 和 MediaController的callback 来监听当前用户所有应用 有关媒体播放浏览等事件。当事件发生时
更新AAOS界面的信息和控制的控件。

相关文章:

AAOS CarMediaService 服务框架

文章目录 前言MediaSessionCarMediaService作用是什么&#xff1f;提供了哪些接口&#xff1f;如何使用&#xff1f;CarMediaService的实现总结 前言 CarMediaService 是AAOS中统一管理媒体播放控制、信息显示和用户交互等功能的服务。这一服务依赖于android MediaSession框架…...

gRPC之gRPC转换HTTP

1、gRPC转换HTTP 我们通常把RPC用作内部通信&#xff0c;而使用Restful Api进行外部通信。为了避免写两套应用&#xff0c;我们使用grpc- gateway 把gRPC转成HTTP。服务接收到HTTP请求后&#xff0c;grpc-gateway把它转成gRPC进行处理&#xff0c;然后以JSON 形式返回数据。…...

【十四】记一次MySQL宕机恢复过程,MySQL INNODB 损坏恢复

记一次MySQL宕机恢复过程 简介&#xff1a;一个业务数据库疏于运维管理&#xff0c;突然在今天崩溃宕机了&#xff0c;真是让人抓狂&#xff0c;上面也不知道积累了多久的数据&#xff0c;平时也没有定期做好备份&#xff0c;这下岂不是瞎了啊&#xff0c;经过不断的收集信息和…...

从0开始在Vscode中搭建Vue2/3项目详细步骤

1.安装node.js:Node.js下载安装及环境配置教程【超详细】_nodejs下载_WHF__的博客-CSDN博客 node.js自带npm&#xff0c;无需单独安装。 验证&#xff1a; node -v npm -v 2.先简单创建一个空文件夹&#xff0c;vscode进入该文件夹&#xff0c;并打开终端。 3.安装cnpm&…...

JavaScript ES6类的定义与继承

文章目录 一、class方式定义类1.认识class定义类2.类和构造函数的异同3.类的构造函数4.类的实例方法5.类的访问器方法6.类的静态方法 二、继承1.extends实现继承2.super关键字3.继承内置类4.类的混入mixin 三、ES6转ES51.class转换2.extends转换 四、多态 一、class方式定义类 …...

中科芯与IAR共建生态合作,IAR集成开发环境全面支持CKS32系列MCU

中国上海–2023年10月18日–嵌入式开发软件和服务的全球领导者IAR今日宣布&#xff0c;与中科芯集成电路有限公司&#xff08;以下简称中科芯&#xff09;达成生态合作&#xff0c;IAR已全面支持CKS32系列MCU的应用开发。这一合作将进一步推动嵌入式系统的发展&#xff0c;并为…...

设计模式:外观模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

大家好&#xff01;本节主要介绍设计模式中的外观模式。 简介&#xff1a; 外观模式&#xff0c;它是一种设计模式&#xff0c;它为子系统中的一组接口提供一个统一的、简单的接口。这种模式主张按照描述和判断资料来评价课程&#xff0c;关键活动是在课程实施的全过程中进行…...

Leetcode—34.在排序数组中查找元素的第一个和最后一个位置【中等】

2023每日刷题&#xff08;六&#xff09; Leetcode—34.在排序数组中查找元素的第一个和最后一个位置 实现代码 /*** Note: The returned array must be malloced, assume caller calls free().*/ int lower_bound(int *arr, int numsSize, int target) {// 左闭右开区间[lef…...

Java 8 新特性 Ⅱ

方法引用 举例: Integer :: compare 理解: 可以看作是基于lambda表达式的进一步简化 当需要提供一个函数式接口的实例时, 可以使用lambda表达式提供实例 当满足一定条件下, 可以使用方法引用or构造器引用替换lambda表达式 实质: 方法引用作为函数式接口的实例 (注: 需要熟悉…...

C语言学习书籍推荐

C语言学习书籍推荐如下&#xff1a; 《C程序设计语言》&#xff08;The C Programming language&#xff09;&#xff1a;这本书由C语言创始人Brian W. Kernighan和Dennis M. Ritchie所写&#xff0c;是介绍标准C语言及其程序设计方法的权威性经典著作。《C陷阱与缺陷》&#…...

IntelliJ IDEA Maven加载超时问题

IDEA创建Maven项目遇到如下错误&#xff1a; Could not transfer artifact org.apache.maven.plugins:maven-compiler-plugin:pom:3.10.1 from/to central (Central Repository:): Connect to repo.maven.apache.org:443 [repo.maven.apache.org/146.75.112.215] failed: conn…...

Spring中事务失效的几种场景及解决办法

未抛出异常&#xff1a;如果在一个带有事务的方法中没有抛出异常&#xff0c;Spring无法检测到事务失败&#xff0c;从而无法回滚。解决方法是确保在事务中遇到错误时抛出异常。 异常被捕获&#xff1a;如果在一个带有事务的方法中抛出异常&#xff0c;但被捕获并处理了&#…...

第五届太原理工大学程序设计竞赛新生赛(初赛)题解

第五届太原理工大学程序设计竞赛新生赛&#xff08;初赛&#xff09;题解 时隔半年重做一次&#xff0c;还是有几道不会&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c; ⭐️A.饿饿饭饭 题目&#xff1a; &#x1f31f;题解&#xff1a; 很简单&#xff0c;签…...

微信小程序开发之后台数据交互及wxs应用

目录 一、后端准备 1. 应用配置 2. 数据源配置 二、数据库 1. 创建 2. 数据表 3. 数据测试 三、前端 1. 请求方法整合 2. 数据请求 3. WXS的使用 4. 样式美化 5. 页面 一、后端准备 通过SpringMVC及mybatis的技术学习&#xff0c;还有前后端分离的技术应用&…...

Java进阶篇--并发容器之ThreadLocal内存泄漏

目录 ThreadLocal内存泄漏的原因&#xff1f; 改进和优化 cleanSomeSlots方法 expungeStaleEntry方法 replaceStaleEntry方法 为什么使用弱引用&#xff1f; Thread.exit() ThreadLocal内存泄漏最佳解决方案 在使用完毕后立即清理ThreadLocal 使用InheritableThreadL…...

js实现红包雨功能(canvas,react,ts),包括图片不规则旋转、大小、转速、掉落速度控制、屏幕最大红包数量控制等功能

介绍 本文功能由canvas实现红包雨功能&#xff08;index.tsx&#xff09;本文为react的ts版。如有其他版本需求可评论区观赏地址&#xff0c;需过墙 import React, { Component } from react; // import ./index.css; import moneyx from /assets/images/RedEnvelopeRain/bal…...

【数字IC设计/FPGA】FIFO与流控机制

流控&#xff0c;简单来说就是控制数据流停止发送。常见的流控机制分为带内流控和带外流控。 FIFO的流水反压机制 一般来说&#xff0c;每一个fifo都有一个将满阈值afull_value&#xff08;almost full&#xff09;。当fifo内的数据量达到或超过afull_value时&#xff0c;将满…...

C++笔记之遍历vector的所有方式

C笔记之遍历vector的所有方式 —— 2023年4月15日 上海 code review 文章目录 C笔记之遍历vector的所有方式1.普通for循环2.迭代器版3.const迭代器4.C11引入的范围for循环5.使用auto关键字和迭代器6.使用std::for_each算法7.使用std::for_each和lambda表达式8.普通版vector::at…...

OpenCV 笔记(2):图像的属性以及像素相关的操作

Part11. 图像的属性 11.1 Mat 的主要属性 在前文中&#xff0c;我们大致了解了 Mat 的基本结构以及它的创建与赋值。接下来我们通过一个例子&#xff0c;来看看 Mat 所包含的常用属性。 先创建一个 3*4 的四通道的矩阵&#xff0c;并打印出其相关的属性&#xff0c;稍后会详细…...

基于指数分布优化的BP神经网络(分类应用) - 附代码

基于指数分布优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于指数分布优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.指数分布优化BP神经网络3.1 BP神经网络参数设置3.2 指数分布算法应用 4.测试结果…...

自动化立体仓库堆垛机控制系统STEP7 OB1功能块

1、堆垛机控制系统STEP7硬件组态如下图 CPU CPU 314C-2 PN/DP 6ES7 314-6EH04-0AB0 SM 338 POS-INPUT AO2x12Bit 6ES7 332-5HB01-0AB0 2、堆垛机控制系统STEP7内部变量 前进HMI M 0.0 BOOL 后退HMI M 0.1 BOOL 上升HMI M 0.2 B…...

ES海量数据更新及导入导出备份

一、根据查询条件更新字段 from elasticsearch import Elasticsearch import redis import json# 替换下面的用户名、密码和Elasticsearch服务器地址 username elastic password password es_host https://127.0.0.2:30674# 使用Elasticsearch实例化时传递用户名和密码 es…...

Redis知识体系

1. 概述 本文总结了Redis基本的核心知识体系&#xff0c;在学习Redis的过程中&#xff0c;可以将其作为学习框架&#xff0c;以此更好的从整体的角度去理解和学习Redis的内容和设计思想。同时知识框架带来的好处是可以帮助我们更好的进行记忆&#xff0c;在大脑中形成相应的知识…...

Vue项目PDF目录功能集成【一】——方案深度思考

文章目录 项目背景一、方案一&#xff1a;数据透传 外部开发模式二、方案二&#xff1a;内置组件 黑盒模式三、方案三&#xff1a;激活官方实现 可控定制总结 项目背景 本项目是Vue 3 项目&#xff0c;需要使用文件预览组件&#xff08;pdfjs 当前是作为sdk二次封装引入&am…...

佰力博科技与您探讨材料介电性能测试的影响因素

1、频率依赖性 材料的介电性能通常具有显著的频率依赖性。在低频下&#xff0c;偶极子的取向极化占主导&#xff0c;介电常数较高&#xff1b;而在高频下&#xff0c;偶极子的取向极化滞后&#xff0c;导致介电常数下降&#xff0c;同时介电损耗增加。例如&#xff0c;VHB4910…...

【MATLAB去噪算法】基于CEEMD联合小波阈值去噪算法(第三期)

02.去噪算法原理 1.引言 传统EMD方法存在模态混叠问题&#xff0c;即信号成分在不同IMF分量中出现碎片化分布。为改进这一问题&#xff0c;Huang等&#xff08;1999&#xff09;提出间歇性测试算法&#xff0c;但效果有限。Wu和Huang&#xff08;2009&#xff09;发展的集合经…...

【在线五子棋对战】二、websocket 服务器搭建

文章目录 Ⅰ. WebSocket1、简介2、特点3、原理解析4、报文格式 Ⅱ. WebSocketpp1、认识2、常用接口3、websocketpp库搭建服务器搭建流程主体框架填充回调函数细节 4、编写 makefile 文件5、websocket客户端 Ⅰ. WebSocket 1、简介 WebSocket 是从 HTML5 开始支持的一种网页端…...

解析“与此站点的连接不安全”警告:成因与应对策略

一、技术本质&#xff1a;SSL/TLS协议的信任链断裂 现代浏览器通过SSL/TLS协议建立加密通信&#xff0c;其核心在于证书颁发机构&#xff08;CA&#xff09;构建的信任链。当用户访问网站时&#xff0c;浏览器会验证服务器证书的有效性&#xff0c;包括&#xff1a; 证书链完…...

做题笔记(ctfshow)

一。ctfshow web13 文件扫描 存在upload.php.bak <?php header("content-type:text/html;charsetutf-8");$filename $_FILES[file][name];$temp_name $_FILES[file][tmp_name];$size $_FILES[file][size];$error $_FILES[file][error];$arr pathinfo($fi…...

Python爬虫实战:研究demiurge框架相关技术

1. 引言 在当今数字化时代,互联网上蕴含着海量的有价值信息。爬虫技术作为获取这些信息的重要手段,被广泛应用于学术研究、商业分析、舆情监测等多个领域。然而,构建一个高效、稳定且可维护的爬虫系统面临诸多挑战,如网页结构复杂多变、反爬机制日益严格、数据处理流程繁琐…...