Android 14 CarAudioService

2023-12-05

新功能

  • AudioMirring

简单的说就是两个bus输出的是同一个音频数据。
构建的流程是: 一个输入src的bus,和两个输出dst的bus。 通过setParamter 设置到hal。 hal解析这些参数,将输入bus
的音频数据拷贝输出到两个dst的bus。

  • CarOemService

可以外部注册对应的carAudioFocusService、CarAudioVolumeService、CarAudioDuckingService.
分别为焦点请求,音量设置、音频闪避。
也就是oem 根据自己的需要去控制这三个方面的音频功能。
当有定义这三个service的时候,相应的处理会调用到对应的服务。 调用过程是基于binder 的 是需要IPC调用。
这一部处理是在java层处理。

  • 对于按键的处理

新增了CarInputService, 可以通过监听不同的InputService 来处理按键。 补齐了12上面无法多屏幕按键控制。

这个按键需要OEM 自己定义 通过vhal hal 上报到CarInputService。 然后audio这边去监听相关的按键事件。
vehicle hal中可以携带三个参数 是int类型的数组
第一个参数 是按键事件的代码 1001 - 1007
第二个是屏幕 可以主屏副屏等等。音量调节的时候 可以从这个display ID 获取zoneID。

AudioMirring

  • 如何配置mirror的区域
    • mirror的工作原理

首先在配置文件中添加的配置为, 在carAudioService 中进行标签的解析,然后设置mirror的device。

    <mirroringDevices>
        <mirroringDevice address="mirror_bus_device_1"/>
        <mirroringDevice address="mirror_bus_device_2"/>
    </mirroringDevices>

  • 基本的原理:
    在CarService 这一层是构造类似下面这样的keyvalue序列,然后这个序列通过AudioManager的setParameters给到hal。
    mirroring_src=bus_1000;mirroring_dest=bus_10,bus_20.

    而上述的keyValue 序列是要求hal层 实现所有写入到mirroring_src bus的数据 都要拷贝到bus_10 和bus_20进行输出。其中bus_10 和 bus_20是需要在zondID 中进行定义的,是已经有的输出设备。

详细来说: 首先解析xml中mirroringDevice,这个device 同时也需要在audio_policy_configuration.xml中定义。 跟正常的device address一样。在CarService 中

  1. 判断是不是支持mirror(通过判断mirroringDevice是不是至少有一个存在),支持的话,构造一个mix,将这个mix添加到audioPolicy当中。
  2. 构造mix,这个mix 的device是mirroringDevice,attribute是music。现有只支持music类型共享。mix添加到audiopolicy 说明 后续的音频
    数据通过mix线程都会写到mirror的device address。
  3. 构造parameter 参数列表(怎么构建的?)外部的接口是
    enableMirrorForAudioZones,传递的参数是需要mirror的zone id列表。carAudioService 中会经过一系列的判断确认zoneID可用时,
    通过zoneId来获取USAGE_MEDIA的DeviceAddress。
    然后将mirrorDevice 和 获取到的DeviceAddress 组成paramter传递给hal。
  • Hal 层的实现

    在有paramete的情况下。解析获取mirror src dst的address。 但不是打开的src的address,而是打开dst的address。
    然后将数据分别写入到这两个地址中。mirror的src相当于一个中转的地址。

oemCarService

  • oemCarService的作用

使用一个app的service 替换原生的focusrequest、duck和volume。

    private OemCarAudioFocusResult evaluateFocusRequestLocked(FocusEntry replacedCurrentEntry,
            AudioFocusInfo audioFocusInfo) {
        return isExternalFocusEnabled()
                ? evaluateFocusRequestExternallyLocked(audioFocusInfo, replacedCurrentEntry) :
                evaluateFocusRequestInternallyLocked(audioFocusInfo, replacedCurrentEntry);
    }


  • 如何启用

配置应用的的名字。比如想用 test的这个com.android.car.oemcarservice.testapp.OemCarServiceImpl

将名字config 到xml,然后编译这个应用 push到system/priv-app目录底下。

String componentName = res.getString(R.string.config_oemCarService);

        Intent intent = (new Intent())
                .setComponent(ComponentName.unflattenFromString(mComponentName));
        Slogf.i(TAG, "Binding to Oem Service with intent: %s", intent);
        mHandlerThread = CarServiceUtils.getHandlerThread("car_oem_service");
        mHandler = handler == null ? new Handler(mHandlerThread.getLooper()) : handler;
        mIsOemServiceBound = mContext.bindServiceAsUser(intent, mCarOemServiceConnection,
                Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM);


    private boolean isExternalFocusEnabled() {
        CarOemProxyService proxy = CarLocalServices.getService(CarOemProxyService.class);
        if (!proxy.isOemServiceEnabled()) {
            return false;
        }
        if (!proxy.isOemServiceReady()) {
            logFocusEvent("Focus was called but OEM service is not yet ready.");
            return false;
        }
        return proxy.getCarOemAudioFocusService() != null;
    }

  • 如何调用
    bindServiceAsUser的作用是什么?https://bbs.huaweicloud.com/blogs/325746

    • 客户端服务端都继承.stub.

    • 服务端实现具体的AIDL接口,主要是下面的这些接口。

          IOemCarAudioFocusService getOemAudioFocusService();
          IOemCarAudioVolumeService getOemAudioVolumeService();
          IOemCarAudioDuckingService getOemAudioDuckingService();
      
    • 在配置config中国oemCarService 后,现有的实现是packages/services/Car/tests/OemCarServiceTestApp/src/com/android/car/oemcarservice/testapp/OemCarServiceImpl.java。

    • 客户端获取服务, 通过package的名字构造一个intent,然后bindServiceAsUser。发送intent
      在onServiceConnected 通过binder获取到远程的mOemCarService。外部通过getService
      的方式获取CarOemProxyService的服务。 然后通过这个服务调用HIDL的接口。

         CarOemProxyService proxy = CarLocalServices.getService(CarOemProxyService.class);
         public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Slogf.i(TAG, "onServiceConnected: %s, %s", componentName, iBinder);
            synchronized (mLock) {
                if (mOemCarService == IOemCarService.Stub.asInterface(iBinder)) {
                    return; // already connected.
                }
                Slogf.i(TAG, "car oem service binder changed, was %s now: %s",
                        mOemCarService, iBinder);
                mOemCarService = IOemCarService.Stub.asInterface(iBinder);
                Slogf.i(TAG, "**CarOemService connected**");
                mIsOemServiceConnected = true;
                mLock.notifyAll();
            }
        }


  • 如何配置
  1. 在config.xml 中配置componet name
    com.android.car.oemcarservice.testapp/com.android.car.oemcarservice.testapp.OemCarServiceImpl
    componet name 根据app的package和service name一起组成的。
    形式为package name/service name 这两个名字可以从源码的AndroidManifest.xml中获取到。

  2. 编译carService 和 test app push 到system/priv_app即可。

    <!-- This is the component name for the OEM customization service. OEM can choose to implement
         this service to customize car service behavior for different policies. If OEMs choose to
         implement it, they have to implement a service extending OemCarService exposed by car-lib,
         and implement the needed component services.
         If the component name is invalid, CarService would not connect to any OEM service.
         Component name can not be a third party package. It should be pre-installed -->
   <string name="config_oemCarService" translatable="false">com.android.car.oemcarservice.testapp/com.android.car.oemcarservice.testapp.OemCarServiceImpl</string>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.android.car.oemcarservice.testapp">
    <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_SETTINGS" />
    <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" />
    <application>
        <service android:name="com.android.car.oemcarservice.testapp.OemCarServiceImpl"
                 android:directBootAware="true"
                 android:permission="android.car.permission.BIND_OEM_CAR_SERVICE"
                 android:exported="true">
        </service>
    </application>
</manifest>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 14 CarAudioService 的相关文章

随机推荐

  • LeetCode:1038. 从二叉搜索树到更大和树(反向中序遍历 C++、Java)

    目录 1038 从二叉搜索树到更大和树 题目描述 实现代码与解析 dfs 原理思路 1038 从二叉搜索树到更大和树 题目描述 给定一个二叉搜索树 root BST 请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值之和 提醒一
  • SSM 线上知识竞赛系统-计算机毕设 附源码 27170

    SSM线上知识竞赛系统 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化 电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用 信息时代的到来已成为不可阻挡的时尚潮流 人类发展的历史正进入一个新时代 在现实运用中 应
  • FL Studio2024中文语言版水果编曲软件

    FL Studio21 2这款软件在国内被广泛使用 因此又被称为 水果 它提供音符编辑器 可以针对作曲者的要求编辑出不同音律的节奏 例如鼓 镲 锣 钢琴 笛 大提琴 筝 扬琴等等任何乐器的节奏律动 此外 它还提供了方便快捷的音源输入 对于在
  • “丝路电商”与泛欧在线公共采购平台Peppol

    近期上海商务委员会公布 关于在上海市创建 丝路电商 合作先行区的方案 以下简称方案 方案中提出 全面贯彻落实党的二十大精神 立足新发展阶段 完整 准确 全面贯彻新发展理念 加快构建新发展格局 统筹发展和安全 发挥上海在改革开放中的突破攻坚作
  • Springboot养老院信息管理系统的开发-计算机毕设 附源码 27500

    Springboot养老院信息管理系统的开发 摘 要 随着互联网趋势的到来 各行各业都在考虑利用互联网将自己推广出去 最好方式就是建立自己的互联网系统 并对其进行维护和管理 在现实运用中 应用软件的工作规则和开发步骤 采用Springboo
  • 分治—快速选择算法

    文章目录 215 数组中的第K个最大元素 1 题目 2 算法原理 3 代码实现 LCR 159 库存管理 III
  • 分治-归并算法——LCR 170. 交易逆序对的总数

    文章目录 0 归并排序 1 题目 2 算法原理 3 代码实现 0 归并排序 归并排序是典型的分治 将数组分成若干个子数组 数组两两比较 不是很清楚的 可以查看此篇文章 数据结构 七大排序 这里以力扣 9
  • 分治-归并排序

    文章目录 315 计算右侧小于当前元素的个数 1 题目 2 算法原理 3 代码实现 493 翻转对
  • 小学全科教师是什么意思

    作为一名小学全科教师 我们的目标是提供全面的教育 帮助孩子们在各个学科领域中取得均衡发展 我们不仅教授语文 数学等传统学科 还注重培养孩子们的独立思考能力 创新精神和社交技巧 下面 我将从几个方面阐述小学全科教师的重要性和职责 小学全科教师
  • xampp环境安装

    XAMPP是完全免费且易于安装的Apache发行版 其中包含Apache MariaDB PHP和Perl 类似XAMPP的服务器套件还有很多 我用过的还有UPUPW 它们都极大的简化了开发环境的配置 下载链接 Download XAMPP
  • SiLM5350SBBCA-DG一款可提供分离输出 隔离门极驱动器完美UCC5350SBDR

    SiLM5350SBBCA DG是一款适用于IGBT MOSFET的单通道 隔离门极驱动器 具有10A拉电流和10A灌电流驱动能 力 提供分离输出 可单独控制 上升时间和下降时间 在SOP8W封装中具有5000 VRMS隔离耐压 在 SOP
  • 优维产品最佳实践第17期:善用控制台

    背 景 遇到页面报错时 是不是感到困扰 不知如何解决 页面响应缓慢时 是否感到迷茫 不清楚从何入手排查 面对主机高负载时 是不是觉得确认异常根因很有挑战 本期最佳实践为您讲解如何通过控制台排查定位 页面报错时 获取traceId确认报错组件
  • 【学习笔记】机器学习——GAN

    提出于2014年 GAN由两个神经网络组成 一个试图生成看起来与训练数据相似数据的 生成器 以及一个试图从虚假数据中分辨出真实数据的 判别器 生成器和判别器在训练期间相互竞争 对抗训练 训练竞争性网络 是一种重要的机器学习思想 生成器 G
  • CVE-2016-2510&CVE-2017-5586 BeanShell漏洞

    前言 首先我们需要了解BeanShell具体是做什么 BeanShell 是一种轻量级的可嵌入式脚本语言 用于在 Java 环境中执行脚本代码 它提供了一种简单 灵活的方式来扩展和定制 Java 应用程序的行为 允许开发人员动态地执行和评估
  • 2024年十大值得关注的编程语言

    探索2024年最有影响力的编程语言 Python的多功能无与伦比 JavaScript在Web领域的统治地位 Rust的高效性 等等 通过实际操作示例 发现适合您编程之旅的最佳选择 在技术世界不断变化的沙漂中导航是一段令人兴奋的旅程 充满了
  • react之封装有无Token(路由权限控制)的高阶组件

    TOC 前景 有些路由页面内的内容信息比较敏感 如果用户没有经过登录获取到有效Token 是没有权限跳转的 根据Token的有 无控制当前路由是否可以跳转就是路由的权限控制 技术方案 实现步骤 1 在 components 目录中 创建 A
  • Comparator接口

    Comparator接口 Comparator 是 Java 中用于比较对象的接口 它允许开发者实现自定义的比较逻辑 以用于对对象进行排序或者确定它们的顺序 主要方法 Comparator 接口中包含一个抽象方法 int compare T
  • MN316 OpenCPU丨HTTP使用介绍

    HTTP Hyper Text Transfer Protocol 即超文本传输协议 是一个简单的请求 响应协议 通常运行在 TCP 之上 它指定了客户端可能发送给服务器消息类型以及得到什么类型响应 HTTPS Hyper Text Tra
  • docker 内查看文件时间 docker动态查看日志最后100行

    ls all docker动态查看日志最后100行 docker logs f t tail 1 chat2db docker logs OPTIONS CONTAINER Options details 显示更多的信息 f follow
  • Android 14 CarAudioService

    文章目录 新功能 AudioMirring oemCarService 新功能 AudioMirring 简单的说就是两个bus输出的是同一个音频数据 构建的流程是 一个输入src的bus 和两个输出dst的bus 通过setParamte