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

Commit 41ee39a1 authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

hap: Improvements around the BluetoothHapPresetInfo builder

Since the BluetoothHapClient API pass BluetoothHapPresetInfo objects
only in one direction (when receiving BluetoothHapPresetInfo instances
from the service), the App shouldn't ever need to build them by itself.

From the Service point of view, preset index and name are both equally
important and are both mandatory thus should be both in Builder class
constructor, however in valid cases, preset info comes from the JNI
native code, wich does not use the builder class. In other rare cases
for invalid requests we should return null as API return params are
nullable. The builder can still be used in other parts like the unit
tests.

Bug: 150670922
Bug: 218682004
Bug: 220029662
Fixes: 218682004
Fixes: 220029662
Tag: #feature
Test: atest CtsBluetoothTestCases:android.bluetooth.cts.BluetoothHapClientTest BluetoothInstrumentationTests
Sponsor: jpawlowski@

Change-Id: I95c68406f531acc2056d3b16b3fcc8af4ca659cb
parent 83c130f9
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;

import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;

import android.annotation.Nullable;
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHapClient;
@@ -564,9 +565,9 @@ public class HapClientService extends ProfileService {
     * Gets the currently active preset info for a HA device
     *
     * @param device is the device for which we want to get the currently active preset info
     * @return active preset info
     * @return active preset info or null if not available
     */
    public BluetoothHapPresetInfo getActivePresetInfo(BluetoothDevice device) {
    public @Nullable BluetoothHapPresetInfo getActivePresetInfo(BluetoothDevice device) {
        int index = getActivePresetIndex(device);
        if (index == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return null;

@@ -684,11 +685,10 @@ public class HapClientService extends ProfileService {
     *
     * @param device is the device for which we want to get the preset name
     * @param presetIndex is an index of one of the available presets
     * @return a preset Info corresponding to the requested preset index
     * @return a preset Info corresponding to the requested preset index or null if not available
     */
    public BluetoothHapPresetInfo getPresetInfo(BluetoothDevice device, int presetIndex) {
        BluetoothHapPresetInfo defaultValue = new BluetoothHapPresetInfo.Builder().build();

    public @Nullable BluetoothHapPresetInfo getPresetInfo(BluetoothDevice device, int presetIndex) {
        BluetoothHapPresetInfo defaultValue = null;
        if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return defaultValue;

        List<BluetoothHapPresetInfo> current_presets = mPresetsMap.get(device);
@@ -1400,7 +1400,7 @@ public class HapClientService extends ProfileService {
        public void getPresetInfo(BluetoothDevice device, int presetIndex,
                AttributionSource source, SynchronousResultReceiver receiver) {
            try {
                BluetoothHapPresetInfo defaultValue = new BluetoothHapPresetInfo.Builder().build();
                BluetoothHapPresetInfo defaultValue = null;
                HapClientService service = getService(source);
                if (service != null) {
                    defaultValue = service.getPresetInfo(device, presetIndex);
+4 −12
Original line number Diff line number Diff line
@@ -746,9 +746,7 @@ public class HapClientTest {

        int info_reason = HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_UPDATE;
        BluetoothHapPresetInfo[] info =
                {new BluetoothHapPresetInfo.Builder()
                        .setIndex(0x01)
                        .setName("OneChangedToUnavailable")
                {new BluetoothHapPresetInfo.Builder(0x01, "OneChangedToUnavailable")
                        .setWritable(true)
                        .setAvailable(false)
                        .build()};
@@ -965,21 +963,15 @@ public class HapClientTest {
        // Inject some initial presets
        List<BluetoothHapPresetInfo> presets =
                new ArrayList<BluetoothHapPresetInfo>(Arrays.asList(
                        new BluetoothHapPresetInfo.Builder()
                                .setIndex(0x01)
                                .setName("One")
                        new BluetoothHapPresetInfo.Builder(0x01, "One")
                                .setAvailable(true)
                                .setWritable(false)
                                .build(),
                        new BluetoothHapPresetInfo.Builder()
                                .setIndex(0x02)
                                .setName("Two")
                        new BluetoothHapPresetInfo.Builder(0x02, "Two")
                                .setAvailable(true)
                                .setWritable(true)
                                .build(),
                        new BluetoothHapPresetInfo.Builder()
                                .setIndex(0x03)
                                .setName("Three")
                        new BluetoothHapPresetInfo.Builder(0x03, "Three")
                                .setAvailable(false)
                                .setWritable(false)
                                .build()));
+0 −9
Original line number Diff line number Diff line
@@ -289,15 +289,6 @@ package android.bluetooth {
    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHapPresetInfo> CREATOR;
  }

  public static final class BluetoothHapPresetInfo.Builder {
    ctor public BluetoothHapPresetInfo.Builder();
    method @NonNull public android.bluetooth.BluetoothHapPresetInfo build();
    method @NonNull public android.bluetooth.BluetoothHapPresetInfo.Builder setAvailable(boolean);
    method @NonNull public android.bluetooth.BluetoothHapPresetInfo.Builder setIndex(int);
    method @NonNull public android.bluetooth.BluetoothHapPresetInfo.Builder setName(@NonNull String);
    method @NonNull public android.bluetooth.BluetoothHapPresetInfo.Builder setWritable(boolean);
  }

  public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean connect(android.bluetooth.BluetoothDevice);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int connectAudio();
+16 −16
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

/**
 * Represents the Hearing Access Profile preset.
@@ -127,9 +128,10 @@ public final class BluetoothHapPresetInfo implements Parcelable {

    /**
     * Builder for {@link BluetoothHapPresetInfo}.
     * <p> By default, the codec type will be set to
     * <p> By default, the preset index will be set to
     * {@link BluetoothHapClient#PRESET_INDEX_UNAVAILABLE}, the name to an empty string,
     * writability and availability both to false.
     * @hide
     */
    public static final class Builder {
        private int mPresetIndex = BluetoothHapClient.PRESET_INDEX_UNAVAILABLE;
@@ -138,25 +140,23 @@ public final class BluetoothHapPresetInfo implements Parcelable {
        private boolean mIsAvailable = false;

        /**
         * Set preset index for HAP preset info.
         * Creates a new builder.
         *
         * @param index of this preset
         * @return the same Builder instance
         * @param index The preset index for HAP preset info
         * @param name The preset name for HAP preset info
         */
        public @NonNull Builder setIndex(int index) {
            mPresetIndex = index;
            return this;
        public Builder(int index, @NonNull String name) {
            if (TextUtils.isEmpty(name)) {
                throw new IllegalArgumentException("The size of the preset name for HAP shall be at"
                        + " least one character long.");
            }
            if (index < 0) {
                throw new IllegalArgumentException(
                        "Preset index for HAP shall be a non-negative value.");
            }

        /**
         * Set preset name for HAP preset info.
         *
         * @param name of this preset
         * @return the same Builder instance
         */
        public @NonNull Builder setName(@NonNull String name) {
            mPresetIndex = index;
            mPresetName = name;
            return this;
        }

        /**