Android 14 CarAudioService

news/2024/7/23 15:10:56 标签: android, CarService, 音频, java

文章目录

新功能

  • 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相当于一个中转的地址。

CarService_65">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>


http://www.niftyadmin.cn/n/5238877.html

相关文章

QGIS之二十六pbf转osm转shp

效果 步骤 1、下载工具 用于转换osm.pbf–>.osm,当然也可以反过来,还支持其它格式互相转换 osmconvert64-0.8.8p.exe 链接:https://pan.baidu.com/s/1Mj-6b30f6voOkQI8QFh_rw 提取码:1111 2、国内各省下载OSM数据 http://download.openstreetmap.fr/extracts/asia/c…

redis的keys命令和scan命令性能对比

项目场景 Redis的keys *命令在生产环境是慎用的&#xff0c;特别是一些并发量很大的项目&#xff0c;原因是Redis是单线程的&#xff0c;keys *会引发Redis锁&#xff0c;占用reids CPU&#xff0c;如果key数量很大而且并发是比较大的情况&#xff0c;效率是很慢的&#xff0c…

活动回顾|德州仪器嵌入式技术创新发展研讨会(上海站)成功举办,信驰达科技携手TI推动技术创新

2023年11月28日&#xff0c;德州仪器(TI)嵌入式技术创新发展研讨会在上海顺利举办。作为TI中国第三方IDH&#xff0c;深圳市信驰达科技有限公司受邀参加&#xff0c;并设置展位&#xff0c;展出CC2340系列低功耗蓝牙模块及TPMS、蓝牙数字钥匙解决方案&#xff0c;与众多业内伙伴…

【广州华锐互动】风电场检修VR情景模拟提供接近真实的实操体验

风电场检修VR情景模拟系统由广州华锐互动开发&#xff0c;这是一种新兴的培训方式&#xff0c;它通过虚拟现实技术将风力发电场全范围进行1:1仿真建模还原&#xff0c;模拟监视风力发电场各种运行工况下的运行参数和指标&#xff0c;同时可进行升压站系统的巡视&#xff0c;倒闸…

InnoDB的B+树索引(一)

文章目录 概要一、InnoDB行格式二、InnoDB数据页结构2.1 User Records2.2 两个虚拟行记录2.3 PageDirectory&#xff08;页目录&#xff09;2.4 File Header&#xff08;文件头部&#xff09; 三、B树索引3.1 B树索引结构3.2 先有根节点再有叶子节点3.3 一条记录在索引中的查找…

c# datagridview 常用属性设置

1. 列宽自适应 设置属性DataGridViewAutoSizeColumnMode 为AllCells 其他属性值&#xff1a; 属性说明NotSet列的大小调整行为从DataGridView.AutoSizeColumnsMode 属性继承。None列宽不会自动调整。AllCells调整列宽&#xff0c;以适合该列中的所有单元格的内容&#xff0c;包…

nginx对多个服务器的高可用,容易出现鉴权失败

高可用简单测试正常&#xff0c;但是出现高概率401鉴权错误 抓包发现&#xff0c;确实是401 &#xff0c; 而鉴权是两次交互&#xff1a; 抓包发现鉴权到不同服务器上了&#xff0c;导致鉴权没有完成。 此时就需要我们的ip_hash,把同一IP地址的请求,都分配给同一台后端服务器&…

【LeetCode:1038. 从二叉搜索树到更大和树 | BST+DFS+中序遍历】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…