Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ef1b056 authored by Jason Hsu's avatar Jason Hsu Committed by Android (Google) Code Review
Browse files

Merge "Extract duplicate part for hearing audio routing into SettingsLib" into udc-dev

parents a7e606e4 06adc71b
Loading
Loading
Loading
Loading
+49 −108
Original line number Diff line number Diff line
@@ -20,24 +20,20 @@ import android.content.ContentResolver;
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.media.audiopolicy.AudioProductStrategy;
import android.util.Log;

import androidx.annotation.IntDef;
import androidx.annotation.VisibleForTesting;
import androidx.preference.ListPreference;
import androidx.preference.Preference;

import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants;
import com.android.settingslib.bluetooth.HearingAidAudioRoutingHelper;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.primitives.Ints;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@@ -49,16 +45,21 @@ public abstract class HearingDeviceAudioRoutingBasePreferenceController extends
        BasePreferenceController implements Preference.OnPreferenceChangeListener {

    private static final String TAG = "HARoutingBasePreferenceController";
    private static final boolean DEBUG = false;

    private static final AudioDeviceAttributes DEVICE_SPEAKER_OUT = new AudioDeviceAttributes(
            AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, "");

    private final AudioManager mAudioManager;
    private final HearingAidAudioRoutingHelper mHelper;

    public HearingDeviceAudioRoutingBasePreferenceController(Context context,
            String preferenceKey) {
        super(context, preferenceKey);
        mAudioManager = mContext.getSystemService(AudioManager.class);
        mHelper = new HearingAidAudioRoutingHelper(context);
    }

    @VisibleForTesting
    public HearingDeviceAudioRoutingBasePreferenceController(Context context,
            String preferenceKey, HearingAidAudioRoutingHelper helper) {
        super(context, preferenceKey);
        mHelper = helper;
    }

    @Override
@@ -77,48 +78,46 @@ public abstract class HearingDeviceAudioRoutingBasePreferenceController extends

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        final ListPreference listPreference = (ListPreference) preference;
        final Integer routingValue = Ints.tryParse((String) newValue);
        final AudioDeviceAttributes hearingDeviceAttribute = new AudioDeviceAttributes(
                AudioDeviceAttributes.ROLE_OUTPUT,
                AudioDeviceInfo.TYPE_HEARING_AID,
                getHearingDevice().getAddress());
        final List<AudioProductStrategy> supportedStrategies = getSupportedStrategies(
                getSupportedAttributeList());

        boolean status = false;
        if (routingValue != null) {
            switch (routingValue) {
                case RoutingValue.AUTO:
                    status = removePreferredDeviceForStrategies(supportedStrategies);
                    break;
                case RoutingValue.HEARING_DEVICE:
                    removePreferredDeviceForStrategies(supportedStrategies);
                    status = setPreferredDeviceForStrategies(supportedStrategies,
                            hearingDeviceAttribute);
                    break;
                case RoutingValue.DEVICE_SPEAKER:
                    removePreferredDeviceForStrategies(supportedStrategies);
                    status = setPreferredDeviceForStrategies(supportedStrategies,
                            DEVICE_SPEAKER_OUT);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected routingValue: " + routingValue);

        saveRoutingValue(mContext, routingValue);
        trySetAudioRoutingConfig(getSupportedAttributeList(), getHearingDevice(), routingValue);

        return true;
    }

    private void trySetAudioRoutingConfig(int[] audioAttributes,
            CachedBluetoothDevice hearingDevice,
            @HearingAidAudioRoutingConstants.RoutingValue int routingValue) {
        final List<AudioProductStrategy> supportedStrategies = mHelper.getSupportedStrategies(
                audioAttributes);
        final AudioDeviceAttributes hearingDeviceAttributes =
                mHelper.getMatchedHearingDeviceAttributes(hearingDevice);
        if (hearingDeviceAttributes == null) {
            if (DEBUG) {
                Log.d(TAG,
                        "Can not find expected AudioDeviceAttributes to config audio routing "
                                + "maybe device is offline: "
                                + hearingDevice.getDevice().getAnonymizedAddress());
            }
            return;
        }

        final boolean status = mHelper.setPreferredDeviceRoutingStrategies(supportedStrategies,
                hearingDeviceAttributes, routingValue);

        if (!status) {
            Log.w(TAG, "routingMode: " + listPreference.getKey() + "routingValue: " + routingValue
            final List<String> strategiesName = supportedStrategies.stream()
                    .map(AudioProductStrategy::getName)
                    .collect(Collectors.toList());
            Log.w(TAG, "routingMode: " + strategiesName + " routingValue: " + routingValue
                    + " fail to configure AudioProductStrategy");
        }

        saveRoutingValue(mContext, routingValue);
        updateState(listPreference);
        return true;
    }

    /**
     * Gets a list of usage value defined in {@link AudioAttributes} that is used to configure
     * audio routing via {@link AudioProductStrategy}.
     * Gets a list of usage values defined in {@link AudioAttributes} that are used to identify
     * {@link AudioProductStrategy} to configure audio routing.
     */
    protected abstract int[] getSupportedAttributeList();

@@ -129,77 +128,19 @@ public abstract class HearingDeviceAudioRoutingBasePreferenceController extends
    protected abstract CachedBluetoothDevice getHearingDevice();

    /**
     * Saves the {@link RoutingValue}.
     * Saves the routing value.
     *
     * @param context the valid context used to get the {@link ContentResolver}
     * @param routingValue the value defined in {@link RoutingValue}
     * @param routingValue one of the value defined in
     *                     {@link HearingAidAudioRoutingConstants.RoutingValue}
     */
    protected abstract void saveRoutingValue(Context context, int routingValue);

    /**
     * Restores the {@link RoutingValue} and used to reflect status on ListPreference.
     * Restores the routing value and used to reflect status on ListPreference.
     *
     * @param context the valid context used to get the {@link ContentResolver}
     * @return one of {@link RoutingValue}
     * @return one of the value defined in {@link HearingAidAudioRoutingConstants.RoutingValue}
     */
    protected abstract int restoreRoutingValue(Context context);

    private List<AudioProductStrategy> getSupportedStrategies(int[] attributeSdkUsageList) {
        final List<AudioAttributes> audioAttrList = new ArrayList<>(attributeSdkUsageList.length);
        for (int attributeSdkUsage : attributeSdkUsageList) {
            audioAttrList.add(new AudioAttributes.Builder().setUsage(attributeSdkUsage).build());
        }

        final List<AudioProductStrategy> allStrategies = getAudioProductStrategies();
        final List<AudioProductStrategy> supportedStrategies = new ArrayList<>();
        for (AudioProductStrategy strategy : allStrategies) {
            for (AudioAttributes audioAttr : audioAttrList) {
                if (strategy.supportsAudioAttributes(audioAttr)) {
                    supportedStrategies.add(strategy);
                }
            }
        }

        return supportedStrategies.stream().distinct().collect(Collectors.toList());
    }

    @VisibleForTesting
    List<AudioProductStrategy> getAudioProductStrategies() {
        return AudioManager.getAudioProductStrategies();
    }

    @VisibleForTesting
    boolean setPreferredDeviceForStrategies(List<AudioProductStrategy> strategies,
            AudioDeviceAttributes audioDevice) {
        boolean status = true;
        for (AudioProductStrategy strategy : strategies) {
            status &= mAudioManager.setPreferredDeviceForStrategy(strategy, audioDevice);
        }

        return status;
    }

    @VisibleForTesting
    boolean removePreferredDeviceForStrategies(List<AudioProductStrategy> strategies) {
        boolean status = true;
        for (AudioProductStrategy strategy : strategies) {
            status &= mAudioManager.removePreferredDeviceForStrategy(strategy);
        }

        return status;
    }

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
            RoutingValue.AUTO,
            RoutingValue.HEARING_DEVICE,
            RoutingValue.DEVICE_SPEAKER,
    })

    @VisibleForTesting
    protected @interface RoutingValue {
        int AUTO = 0;
        int HEARING_DEVICE = 1;
        int DEVICE_SPEAKER = 2;
    }
}
+4 −5
Original line number Diff line number Diff line
@@ -17,10 +17,10 @@
package com.android.settings.bluetooth;

import android.content.Context;
import android.media.AudioAttributes;
import android.provider.Settings;

import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants;

/**
 * The controller of the hearing device call routing list preference.
@@ -45,9 +45,7 @@ public class HearingDeviceCallRoutingPreferenceController extends

    @Override
    protected int[] getSupportedAttributeList() {
        return new int[]{
                AudioAttributes.USAGE_VOICE_COMMUNICATION,
                AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING};
        return HearingAidAudioRoutingConstants.CALL_ROUTING_ATTRIBUTES;
    }

    @Override
@@ -64,6 +62,7 @@ public class HearingDeviceCallRoutingPreferenceController extends
    @Override
    protected int restoreRoutingValue(Context context) {
        return Settings.Secure.getInt(context.getContentResolver(),
                Settings.Secure.HEARING_AID_CALL_ROUTING, RoutingValue.AUTO);
                Settings.Secure.HEARING_AID_CALL_ROUTING,
                HearingAidAudioRoutingConstants.RoutingValue.AUTO);
    }
}
+5 −5
Original line number Diff line number Diff line
@@ -17,10 +17,10 @@
package com.android.settings.bluetooth;

import android.content.Context;
import android.media.AudioAttributes;
import android.provider.Settings;

import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants;

/**
 * The controller of the hearing device media routing list preference.
@@ -45,9 +45,8 @@ public class HearingDeviceMediaRoutingPreferenceController extends

    @Override
    protected int[] getSupportedAttributeList() {
        return new int[]{
                AudioAttributes.USAGE_MEDIA,
                AudioAttributes.USAGE_GAME};
        return HearingAidAudioRoutingConstants.MEDIA_ROUTING_ATTRIBUTES;

    }

    @Override
@@ -64,6 +63,7 @@ public class HearingDeviceMediaRoutingPreferenceController extends
    @Override
    protected int restoreRoutingValue(Context context) {
        return Settings.Secure.getInt(context.getContentResolver(),
                Settings.Secure.HEARING_AID_MEDIA_ROUTING, RoutingValue.AUTO);
                Settings.Secure.HEARING_AID_MEDIA_ROUTING,
                HearingAidAudioRoutingConstants.RoutingValue.AUTO);
    }
}
+5 −3
Original line number Diff line number Diff line
@@ -17,10 +17,10 @@
package com.android.settings.bluetooth;

import android.content.Context;
import android.media.AudioAttributes;
import android.provider.Settings;

import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants;

/**
 * The controller of the hearing device ringtone routing list preference.
@@ -45,7 +45,8 @@ public class HearingDeviceRingtoneRoutingPreferenceController extends

    @Override
    protected int[] getSupportedAttributeList() {
        return new int[] {AudioAttributes.USAGE_NOTIFICATION_RINGTONE};
        return HearingAidAudioRoutingConstants.RINGTONE_ROUTING_ATTRIBUTE;

    }

    @Override
@@ -62,6 +63,7 @@ public class HearingDeviceRingtoneRoutingPreferenceController extends
    @Override
    protected int restoreRoutingValue(Context context) {
        return Settings.Secure.getInt(context.getContentResolver(),
                Settings.Secure.HEARING_AID_RINGTONE_ROUTING, RoutingValue.AUTO);
                Settings.Secure.HEARING_AID_RINGTONE_ROUTING,
                HearingAidAudioRoutingConstants.RoutingValue.AUTO);
    }
}
+5 −10
Original line number Diff line number Diff line
@@ -17,10 +17,10 @@
package com.android.settings.bluetooth;

import android.content.Context;
import android.media.AudioAttributes;
import android.provider.Settings;

import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants;

/**
 * The controller of the hearing device system sounds routing list preference.
@@ -46,14 +46,8 @@ public class HearingDeviceSystemSoundsRoutingPreferenceController extends

    @Override
    protected int[] getSupportedAttributeList() {
        return new int[]{
                AudioAttributes.USAGE_ALARM,
                AudioAttributes.USAGE_NOTIFICATION,
                AudioAttributes.USAGE_NOTIFICATION_EVENT,
                AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY,
                AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
                AudioAttributes.USAGE_ASSISTANCE_SONIFICATION,
                AudioAttributes.USAGE_ASSISTANT};
        return HearingAidAudioRoutingConstants.SYSTEM_SOUNDS_ROUTING_ATTRIBUTES;

    }

    @Override
@@ -71,6 +65,7 @@ public class HearingDeviceSystemSoundsRoutingPreferenceController extends
    @Override
    protected int restoreRoutingValue(Context context) {
        return Settings.Secure.getInt(context.getContentResolver(),
                Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING, RoutingValue.AUTO);
                Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING,
                HearingAidAudioRoutingConstants.RoutingValue.AUTO);
    }
}
Loading