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

Commit 1f80f071 authored by Haijie Hong's avatar Haijie Hong Committed by Android (Google) Code Review
Browse files

Merge "Implement Spatial audio toggle domain layer" into main

parents 9e701690 82648955
Loading
Loading
Loading
Loading
+66 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.net.Uri;
import android.provider.DeviceConfig;
@@ -41,9 +43,12 @@ import com.android.settingslib.flags.Flags;
import com.android.settingslib.widget.AdaptiveIcon;
import com.android.settingslib.widget.AdaptiveOutlineDrawable;

import com.google.common.collect.ImmutableSet;

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@@ -57,6 +62,9 @@ public class BluetoothUtils {
    public static final String BT_ADVANCED_HEADER_ENABLED = "bt_advanced_header_enabled";
    private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25;
    private static final String KEY_HEARABLE_CONTROL_SLICE = "HEARABLE_CONTROL_SLICE_WITH_WIDTH";
    private static final Set<Integer> SA_PROFILES =
            ImmutableSet.of(
                    BluetoothProfile.A2DP, BluetoothProfile.LE_AUDIO, BluetoothProfile.HEARING_AID);

    private static ErrorListener sErrorListener;

@@ -895,4 +903,62 @@ public class BluetoothUtils {
        }
        return null;
    }

    /**
     * Gets {@link AudioDeviceAttributes} of bluetooth device for spatial audio. Returns null if
     * it's not an audio device(no A2DP, LE Audio and Hearing Aid profile).
     */
    @Nullable
    public static AudioDeviceAttributes getAudioDeviceAttributesForSpatialAudio(
            CachedBluetoothDevice cachedDevice,
            @AudioManager.AudioDeviceCategory int audioDeviceCategory) {
        AudioDeviceAttributes saDevice = null;
        for (LocalBluetoothProfile profile : cachedDevice.getProfiles()) {
            // pick first enabled profile that is compatible with spatial audio
            if (SA_PROFILES.contains(profile.getProfileId())
                    && profile.isEnabled(cachedDevice.getDevice())) {
                switch (profile.getProfileId()) {
                    case BluetoothProfile.A2DP:
                        saDevice =
                                new AudioDeviceAttributes(
                                        AudioDeviceAttributes.ROLE_OUTPUT,
                                        AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
                                        cachedDevice.getAddress());
                        break;
                    case BluetoothProfile.LE_AUDIO:
                        if (audioDeviceCategory
                                == AudioManager.AUDIO_DEVICE_CATEGORY_SPEAKER) {
                            saDevice =
                                    new AudioDeviceAttributes(
                                            AudioDeviceAttributes.ROLE_OUTPUT,
                                            AudioDeviceInfo.TYPE_BLE_SPEAKER,
                                            cachedDevice.getAddress());
                        } else {
                            saDevice =
                                    new AudioDeviceAttributes(
                                            AudioDeviceAttributes.ROLE_OUTPUT,
                                            AudioDeviceInfo.TYPE_BLE_HEADSET,
                                            cachedDevice.getAddress());
                        }

                        break;
                    case BluetoothProfile.HEARING_AID:
                        saDevice =
                                new AudioDeviceAttributes(
                                        AudioDeviceAttributes.ROLE_OUTPUT,
                                        AudioDeviceInfo.TYPE_HEARING_AID,
                                        cachedDevice.getAddress());
                        break;
                    default:
                        Log.i(
                                TAG,
                                "unrecognized profile for spatial audio: "
                                        + profile.getProfileId());
                        break;
                }
                break;
            }
        }
        return saDevice;
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -108,6 +108,12 @@ public @interface DeviceSettingId {
    /** Device setting ID for device details footer. */
    int DEVICE_SETTING_ID_DEVICE_DETAILS_FOOTER = 19;

    /** Device setting ID for spatial audio group. */
    int DEVICE_SETTING_ID_SPATIAL_AUDIO_MULTI_TOGGLE = 20;

    /** Device setting ID for "More Settings" page. */
    int DEVICE_SETTING_ID_MORE_SETTINGS = 21;

    /** Device setting ID for ANC. */
    int DEVICE_SETTING_ID_ANC = 1001;
}
+4 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.settingslib.bluetooth.devicesettings.MultiTogglePreference
import com.android.settingslib.bluetooth.devicesettings.ToggleInfo
import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingConfigItemModel
import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingConfigModel
import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingIcon
import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingModel
import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingStateModel
import com.android.settingslib.bluetooth.devicesettings.shared.model.ToggleModel
@@ -117,7 +118,7 @@ class DeviceSettingRepositoryImpl(
                    id = settingId,
                    title = pref.title,
                    summary = pref.summary,
                    icon = pref.icon,
                    icon = pref.icon?.let { DeviceSettingIcon.BitmapIcon(it) },
                    isAllowedChangingState = pref.isAllowedChangingState,
                    intent = pref.intent,
                    switchState =
@@ -153,5 +154,6 @@ class DeviceSettingRepositoryImpl(
            else -> DeviceSettingModel.Unknown(cachedDevice, settingId)
        }

    private fun ToggleInfo.toModel(): ToggleModel = ToggleModel(label, icon)
    private fun ToggleInfo.toModel(): ToggleModel =
        ToggleModel(label, DeviceSettingIcon.BitmapIcon(icon))
}
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ sealed interface DeviceSettingConfigItemModel {
    /** A built-in item in Settings. */
    data class BuiltinItem(
        @DeviceSettingId override val settingId: Int,
        val preferenceKey: String
        val preferenceKey: String?
    ) : DeviceSettingConfigItemModel

    /** A remote item provided by other apps. */
+11 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.settingslib.bluetooth.devicesettings.shared.model

import android.content.Intent
import android.graphics.Bitmap
import androidx.annotation.DrawableRes
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.devicesettings.DeviceSettingId

@@ -32,7 +33,7 @@ sealed interface DeviceSettingModel {
        @DeviceSettingId override val id: Int,
        val title: String,
        val summary: String? = null,
        val icon: Bitmap? = null,
        val icon: DeviceSettingIcon? = null,
        val intent: Intent? = null,
        val switchState: DeviceSettingStateModel.ActionSwitchPreferenceState? = null,
        val isAllowedChangingState: Boolean = true,
@@ -59,4 +60,12 @@ sealed interface DeviceSettingModel {
}

/** Models a toggle in [DeviceSettingModel.MultiTogglePreference]. */
data class ToggleModel(val label: String, val icon: Bitmap)
data class ToggleModel(val label: String, val icon: DeviceSettingIcon)

/** Models an icon in device settings. */
sealed interface DeviceSettingIcon {

    data class BitmapIcon(val bitmap: Bitmap) : DeviceSettingIcon

    data class ResourceIcon(@DrawableRes val resId: Int) : DeviceSettingIcon
}
Loading