Android R CarAudio行为变更

Android R CarAudio行为变更

本文主要梳理CarAudio模块,从Q升到R的行为变更,如有错误或者理解偏差,欢迎指正

一、CarAudioManager行为变更

1.1 成员变量

INVALID_AUDIO_ZONE用于CarOccupantService的初始化和判定,INVALID_VOLUME_GROUP_ID用于usage找groupId时,找不到对应groupId的情况,之前返回的-1。

    /**
     * Zone id of the invalid audio zone.
     * @hide
     */
    @SystemApi
    public static final int INVALID_AUDIO_ZONE = 0xffffffff;

    /**
     * Volume Group ID when volume group not found.
     * @hide
     */
    public static final int INVALID_VOLUME_GROUP_ID = -1;

1.2 新增API

getOutputDeviceForUsage

通过usage拿到对应的device address 如BUS media,然后通过audiomanger拿到所有的outputdevice后进行address匹配,匹配成功返回AudioDeviceInfo

    /**
     * Gets the output device for a given {@link AudioAttributes} usage in zoneId.
     *
     * <p><b>Note:</b> To be used for routing to a specific device. Most applications should
     * use the regular routing mechanism, which is to set audio attribute usage to
     * an audio track.
     *
     * @param zoneId zone id to query for device
     * @param usage usage where audio is routed
     * @return Audio device info, returns {@code null} if audio device usage fails to map to
     * an active audio device. This is different from the using an invalid value for
     * {@link AudioAttributes} usage. In the latter case the query will fail with a
     * RuntimeException indicating the issue.
     *
     * @hide
     */    
	@SystemApi
    @Nullable
    @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_SETTINGS)
    public AudioDeviceInfo getOutputDeviceForUsage(int zoneId,
            @AudioAttributes.AttributeUsage int usage) {
   
        try {
   
            String deviceAddress = mService.getOutputDeviceAddressForUsage(zoneId, usage);
            if (deviceAddress == null) {
   
                return null;
            }
            AudioDeviceInfo[] outputDevices =
                    mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
            for (AudioDeviceInfo info : outputDevices) {
   
                if (info.getAddress().equals(deviceAddress)) {
   
                    return info;
                }
            }
            return null;
        } catch (RemoteException e) {
   
            return handleRemoteExceptionFromCarService(e, null);
        }
    }
getInputDevicesForZoneId

先通过CarAudioService拿到对应zoneId的所有的inputDevices,然后通过audioManger拿到所有的InputDevice然后匹配对应的address,成功加入到list后一起返回

    /**
     * Gets the input devices for an audio zone
     *
     * @return list of input devices
     * @hide
     */
    @SystemApi
    @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_SETTINGS)
    public @NonNull List<AudioDeviceInfo> getInputDevicesForZoneId(int zoneId) {
   
        try {
   
            return convertInputDevicesToDeviceInfos(
                    mService.getInputDevicesForZoneId(zoneId),
                    AudioManager.GET_DEVICES_INPUTS);
        } catch (RemoteException e) {
   
            return handleRemoteExceptionFromCarService(e, new ArrayList<>());
        }
    }
    private List<AudioDeviceInfo> convertInputDevicesToDeviceInfos(
            List<AudioDeviceAttributes> devices, @AudioDeviceRole int flag) {
   
        int addressesSize = devices.size();
        Set<String> deviceAddressMap = new HashSet<>(addressesSize);
        for (int i = 0; i < addressesSize; ++i) {
   
            AudioDeviceAttributes device = devices.get(i);
            deviceAddressMap.add(device.getAddress());
        }
        List<AudioDeviceInfo> deviceInfoList = new ArrayList<>(devices.size());
        AudioDeviceInfo[] inputDevices = mAudioManager.getDevices(flag);
        for (int i = 0; i < inputDevices.length; ++i) {
   
            AudioDeviceInfo info = inputDevices[i];
            if (info.isSource() && deviceAddressMap.contains(info.getAddress())) {
   
                deviceInfoList.add(info);
            }
        }
        return deviceInfoList;
    }

1.3 移除API

getZoneIdForDisplay
getZoneIdForDisplayPortId

两个关于displayId和zoneId来回转换的API被移除了,通样的car_audio_configuration.xml里zones里绑定的display也被去掉了。

移除原因:carService里新增了CarOccupantZoneManger和service用来管理display和users,

/**
 * API to get information on displays and users in the car.
 */

该api移除后,需要进行适配到getAudioZoneIdForOccupant和getOccupantForAudioZoneId API上

    /**
     * Get the zone id for the display
     *
     * @param  display display to query
     * @return zone id for display or
     * CarAudioManager.PRIMARY_AUDIO_ZONE if no match is found.
     * @hide
     */
    @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_SETTINGS)
    public int getZoneIdForDisplay(Display display) {
   }    
	/**
     * Get the zone id for the display port id passed in
     *
     * @param  displayPortId display port id to query
     * @return zone id for display port id or
     * CarAudioManager.PRIMARY_AUDIO_ZONE if no match is found.
     * @hide
     */
    @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_SETTINGS)
    public int getZoneIdForDisplayPortId(byte displayPortId) {
   }
//======================================================================>

    /**
     * Gets the audio zone id for the occupant, or returns
     * {@code CarAudioManager.INVALID_AUDIO_ZONE} if no audio zone matches the requirements.
     * throws InvalidArgumentException if occupantZone does not exist.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_SETTINGS)
    public int getAudioZoneIdForOccupant(@NonNull OccupantZoneInfo occupantZone) {
   
        assertNonNullOccupant(occupantZone);
        try {
   
            return mService.getAudioZoneIdForOccupant(occupantZone.zoneId);
        } catch (RemoteException e) {
   
            return handleRemoteExceptionFromCarService(e, null);
        }
    }

    /**
     * Gets occupant for the audio zone id, or returns {@code null}
     * if no audio zone matches the requirements.
     *
     * @hide
     */
    @Nullable
    @SystemApi
    @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_SETTINGS)
    public OccupantZoneInfo getOccupantForAudioZoneId(int audioZoneId) {
   
        try {
   
            return mService.getOccupantForAudioZoneId(audioZoneId);
        } catch (RemoteException e) {
   
            return handleRemoteExceptionFromCarService(e, null);
        }
    }

二、CarAudioService的行为变更

Q的目录结构

src\com\android\car\audio\CarAudioDeviceInfo.java
src\com\android\car\audio\CarAudioDynamicRouting.java
src\com\android\car\audio\CarAudioFocus.java
src\com\android\car\audio\CarAudioService.java
src\com\android\car\audio\CarAudioZone.java
src\com\android\car\audio\CarAudioZonesHelper.java
src\com\android\car\audio\CarAudioZonesHelperLegacy.java
src\com\android\car\audio\CarVolumeGroup.java
src\com\android\car\audio\CarZonesAudioFocus.java

R的目录结构

src\com\android\car\audio\hal\AudioControlFactory.java
src\com\android\car\audio\hal\AudioControlWrapper.java
src\com\android\car\audio\hal\AudioControlWrapperV1.java
src\com\android\car\audio\hal\AudioControlWrapperV2.java
src\com\android\car\audio\hal\HalAudioFocus.java
src\com\android\car\audio\CarAudioContext.java
src\com\android\car\audio\CarAudioDeviceInfo.java
src\com\android\car\audio\CarAudioDynamicRouting.java
src\com\android\car\audio\CarAudioFocus.java
src\com\android\car\audio\CarAudioService.java
src\com\android\car\audio\CarAudioSettings.java
src\com\android\car\audio\CarAudioZone.java
src\com\android\car\audio\CarAudioZonesHelper.java
src\com\android\car\audio\CarAudioZonesHelperLegacy.java
src\com\android\car\audio\CarAudioZonesValidator.java
src\com\android\car\audio\CarVolume.java
src\com\android\car\audio\CarVolumeCallbackHandler.java
src\com\android\car\audio\CarVolumeGroup.java
src\com\android\car\audio\CarZonesAudioFocus.java
src\com\android\car\audio\FocusEntry.java
src\com\android\car\audio\FocusInteraction.java
src\com\android\car\audio\OWNERS

对比之后多了好多小模块,好多模块也做了优化

2.1 CarAudioZonesHelper解析car_audio_configuration 2.0

car_audio_configuration新增字段,新增字段后version也变成了2,如果使用了audioZoneId occupantZoneId inputDevices字段但是version没有生成2,会在解析阶段报异常。

<?xml version="1.0" encoding="utf-8"?>
<carAudioConfiguration version="2">
    <zones>
        <zone name="primary zone" isPrimary="true" audioZoneId="0" occupantZoneId="1">
            <volumeGroups>
                <group>
                    <device address="bus0_media_out">
                        <context context="music"/>
                    </device>
                    <device address="bus3_call_ring_out">
                        <context context="call_ring"/>
                    </device>
                </group>
                <group>
                    <device address="bus1_navigation_out">
                        <context context="navigation"/>
                        <context context="emergency"/>
                        <context context="safety"/>
                        <context context="vehicle_status"/>
                        <context context="announcement"/>
                    </device>
                </group>
            </volumeGroups>
            <inputDevices>
                <inputDevice address="fm_tuner"/>
                <inputDevice address="Built-In Mic"/>
            </inputDevices>
        </zone>
        <zone name="rear seat zone" audioZoneId="2">
            <volumeGroups>
                <group>
                    <device address="bus100_rear_seat">
                        <context context="music"/>
                        <context context="navigation"/>
                        <context context="voice_command"/>
                        <context context="call_ring"/>
                        <context context="call"/>
                        <context context="alarm"/>
                        <context context="system_sound"/>
                        <context context="notification"/>
                        <context context="emergency"/>
                        <context context="safety"/>
                        <context context="vehicle_status"/>
                        <context context="announcement"/>
                    </device>
                </group>
            </volumeGroups>
            <inputDevices>
                <inputDevice address="bus_1000_input"/>
                <inputDevice address="Built-In Back Mic"/>
            </inputDevices>
        </zone>
    </zones>
</carAudioConfiguration>

inputDevices

为了支持getInputDeviceForZoneId,CarAudioZones初始化时也会去读取xml里的inputDevice,如官方示例中

            <inputDevices>
                <inputDevice address
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值