AAOS CarMediaService 服务框架

2023-10-20 09:44

本文主要是介绍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 服务框架的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/246291

相关文章

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

数据治理框架-ISO数据治理标准

引言 "数据治理"并不是一个新的概念,国内外有很多组织专注于数据治理理论和实践的研究。目前国际上,主要的数据治理框架有ISO数据治理标准、GDI数据治理框架、DAMA数据治理管理框架等。 ISO数据治理标准 改标准阐述了数据治理的标准、基本原则和数据治理模型,是一套完整的数据治理方法论。 ISO/IEC 38505标准的数据治理方法论的核心内容如下: 数据治理的目标:促进组织高效、合理地

ZooKeeper 中的 Curator 框架解析

Apache ZooKeeper 是一个为分布式应用提供一致性服务的软件。它提供了诸如配置管理、分布式同步、组服务等功能。在使用 ZooKeeper 时,Curator 是一个非常流行的客户端库,它简化了 ZooKeeper 的使用,提供了高级的抽象和丰富的工具。本文将详细介绍 Curator 框架,包括它的设计哲学、核心组件以及如何使用 Curator 来简化 ZooKeeper 的操作。 1

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

Spring Framework系统框架

序号表示的是学习顺序 IoC(控制反转)/DI(依赖注入): ioc:思想上是控制反转,spring提供了一个容器,称为IOC容器,用它来充当IOC思想中的外部。 我的理解就是spring把这些对象集中管理,放在容器中,这个容器就叫Ioc这些对象统称为Bean 用对象的时候不用new,直接外部提供(bean) 当外部的对象有关系的时候,IOC给它俩绑好(DI) DI和IO

Sentinel 高可用流量管理框架

Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 Sentinel 具有以下特性: 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应

利用Django框架快速构建Web应用:从零到上线

随着互联网的发展,Web应用的需求日益增长,而Django作为一个高级的Python Web框架,以其强大的功能和灵活的架构,成为了众多开发者的选择。本文将指导你如何从零开始使用Django框架构建一个简单的Web应用,并将其部署到线上,让世界看到你的作品。 Django简介 Django是由Adrian Holovaty和Simon Willison于2005年开发的一个开源框架,旨在简