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

Commit c04d3364 authored by Patty's avatar Patty Committed by Automerger Merge Worker
Browse files

Add API to set the codec preference for specific device am: 5aa4bd22

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/1958884

Change-Id: Ib88adf774771617b8f84e595040127534e4ec75f
parents 9321e8cb 5aa4bd22
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -960,6 +960,18 @@ package android.bluetooth {
    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setSampleRate(int);
  }

  public final class BluetoothLeAudioCodecStatus implements android.os.Parcelable {
    ctor public BluetoothLeAudioCodecStatus(@Nullable android.bluetooth.BluetoothLeAudioCodecConfig, @Nullable java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig>, @Nullable java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig>);
    method public int describeContents();
    method @Nullable public android.bluetooth.BluetoothLeAudioCodecConfig getCodecConfig();
    method @NonNull public java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig> getCodecsLocalCapabilities();
    method @NonNull public java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig> getCodecsSelectableCapabilities();
    method public boolean isCodecConfigSelectable(@Nullable android.bluetooth.BluetoothLeAudioCodecConfig);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothLeAudioCodecStatus> CREATOR;
    field public static final String EXTRA_LE_AUDIO_CODEC_STATUS = "android.bluetooth.extra.LE_AUDIO_CODEC_STATUS";
  }

  public final class BluetoothManager {
    method public android.bluetooth.BluetoothAdapter getAdapter();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(int);
+67 −0
Original line number Diff line number Diff line
@@ -158,6 +158,24 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
    public static final String ACTION_LE_AUDIO_CONF_CHANGED =
            "android.bluetooth.action.LE_AUDIO_CONF_CHANGED";

    /**
     * Intent used to broadcast the audio codec config changed information.
     *
     * <p>This intent will have 2 extras:
     * <ul>
     * <li> {@link BluetoothLeAudioCodecStatus#EXTRA_LE_AUDIO_CODEC_STATUS} - The codec status.
     * </li>
     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device if the device is currently
     * connected, otherwise it is not included.</li>
     * </ul>
     *
     * @hide
     */
    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_LE_AUDIO_CODEC_CONFIG_CHANGED =
            "android.bluetooth.action.LE_AUDIO_CODEC_CONFIG_CHANGED";

    /**
     * Indicates unspecified audio content.
     * @hide
@@ -906,4 +924,53 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
    private static void log(String msg) {
        Log.d(TAG, msg);
    }

    /**
     * Gets the current codec status (configuration and capability).
     *
     * @param device the remote Bluetooth device.
     * @return the current codec status
     * @hide
     */
    @RequiresBluetoothConnectPermission
    @RequiresPermission(allOf = {
            android.Manifest.permission.BLUETOOTH_CONNECT,
            android.Manifest.permission.BLUETOOTH_PRIVILEGED
    })
    public BluetoothLeAudioCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
        if (DBG) {
            Log.d(TAG, "getCodecStatus(" + device + ")");
        }

        final BluetoothLeAudioCodecStatus defaultValue = null;

        // TODO: Add the implementation to get codec status
        return defaultValue;
    }

    /**
     * Sets the codec configuration preference.
     *
     * @param device the remote Bluetooth device.
     * @param codecConfig the codec configuration preference
     * @hide
     */
    @RequiresBluetoothConnectPermission
    @RequiresPermission(allOf = {
            android.Manifest.permission.BLUETOOTH_CONNECT,
            android.Manifest.permission.BLUETOOTH_PRIVILEGED
    })
    public void setCodecConfigPreference(@NonNull BluetoothDevice device,
                                         @NonNull BluetoothLeAudioCodecConfig codecConfig) {
        if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");

        if (codecConfig == null) {
            Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
            throw new IllegalArgumentException("codecConfig cannot be null");
        }

        // TODO: Add the implementation to set config preference
        return;
    }

}
+26 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
 * Represents the codec configuration for a Bluetooth LE Audio source device.
@@ -346,6 +347,31 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
        return mOctetsPerFrame;
    }

    @Override
    public boolean equals(@NonNull Object o) {
        if (o instanceof BluetoothLeAudioCodecConfig) {
            BluetoothLeAudioCodecConfig other = (BluetoothLeAudioCodecConfig) o;
            return (other.getCodecType() == mCodecType
                    && other.getCodecPriority() == mCodecPriority
                    && other.getSampleRate() == mSampleRate
                    && other.getBitsPerSample() == mBitsPerSample
                    && other.getChannelMode() == mChannelMode
                    && other.getFrameDuration() == mFrameDuration
                    && other.getOctetsPerFrame() == mOctetsPerFrame);
        }
        return false;
    }

    /**
     * Returns a hash representation of this BluetoothLeAudioCodecConfig
     * based on all the config values.
     */
    @Override
    public int hashCode() {
        return Objects.hash(mCodecType, mCodecPriority, mSampleRate,
                mBitsPerSample, mChannelMode, mFrameDuration, mOctetsPerFrame);
    }

    /**
     * Builder for {@link BluetoothLeAudioCodecConfig}.
     * <p> By default, the codec type will be set to
+194 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.bluetooth;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * Represents the codec status (configuration and capability) for a Bluetooth
 * Le Audio source device.
 *
 * {@see BluetoothLeAudio}
 */
public final class BluetoothLeAudioCodecStatus implements Parcelable {
    /**
     * Extra for the codec configuration intents of the individual profiles.
     *
     * This extra represents the current codec status of the Le Audio
     * profile.
     */
    public static final String EXTRA_LE_AUDIO_CODEC_STATUS =
            "android.bluetooth.extra.LE_AUDIO_CODEC_STATUS";

    private final @Nullable BluetoothLeAudioCodecConfig mCodecConfig;
    private final @Nullable List<BluetoothLeAudioCodecConfig> mCodecsLocalCapabilities;
    private final @Nullable List<BluetoothLeAudioCodecConfig> mCodecsSelectableCapabilities;

    /**
     * Represents the codec status for a Bluetooth LE Audio source device.
     *
     * @param codecConfig the current code configutration.
     * @param codecsLocalCapabilities the local codecs capabilities.
     * @param codecsSelectableCapabilities the selectable codecs capabilities.
     */
    public BluetoothLeAudioCodecStatus(@Nullable BluetoothLeAudioCodecConfig codecConfig,
            @Nullable List<BluetoothLeAudioCodecConfig> codecsLocalCapabilities,
            @Nullable List<BluetoothLeAudioCodecConfig> codecsSelectableCapabilities) {
        mCodecConfig = codecConfig;
        mCodecsLocalCapabilities = codecsLocalCapabilities;
        mCodecsSelectableCapabilities = codecsSelectableCapabilities;
    }

    private BluetoothLeAudioCodecStatus(Parcel in) {
        mCodecConfig = in.readTypedObject(BluetoothLeAudioCodecConfig.CREATOR);
        mCodecsLocalCapabilities = in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
        mCodecsSelectableCapabilities =
                in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
    }

    @Override
    public boolean equals(@Nullable Object o) {
        if (o instanceof BluetoothLeAudioCodecStatus) {
            BluetoothLeAudioCodecStatus other = (BluetoothLeAudioCodecStatus) o;
            return (Objects.equals(other.mCodecConfig, mCodecConfig)
                    && sameCapabilities(other.mCodecsLocalCapabilities, mCodecsLocalCapabilities)
                    && sameCapabilities(other.mCodecsSelectableCapabilities,
                    mCodecsSelectableCapabilities));
        }
        return false;
    }

    /**
     * Checks whether two lists of capabilities contain same capabilities.
     * The order of the capabilities in each list is ignored.
     *
     * @param c1 the first list of capabilities to compare
     * @param c2 the second list of capabilities to compare
     * @return {@code true} if both lists contain same capabilities
     */
    private static boolean sameCapabilities(@Nullable List<BluetoothLeAudioCodecConfig> c1,
                                           @Nullable List<BluetoothLeAudioCodecConfig> c2) {
        if (c1 == null) {
            return (c2 == null);
        }
        if (c2 == null) {
            return false;
        }
        if (c1.size() != c2.size()) {
            return false;
        }
        return c1.containsAll(c2);
    }

    /**
     * Checks whether the codec config matches the selectable capabilities.
     * Any parameters of the codec config with NONE value will be considered a wildcard matching.
     *
     * @param codecConfig the codec config to compare against
     * @return {@code true} if the codec config matches, {@code false} otherwise
     */
    public boolean isCodecConfigSelectable(@Nullable BluetoothLeAudioCodecConfig codecConfig) {
        // TODO: Add the implementation to check the config is selectable
        return true;
    }

    /**
     * Returns a hash based on the codec config and local capabilities.
     */
    @Override
    public int hashCode() {
        return Objects.hash(mCodecConfig, mCodecsLocalCapabilities, mCodecsLocalCapabilities);
    }

    /**
     * Returns a {@link String} that describes each BluetoothLeAudioCodecStatus parameter
     * current value.
     */
    @Override
    public String toString() {
        return "{mCodecConfig:" + mCodecConfig
                + ",mCodecsLocalCapabilities:" + mCodecsLocalCapabilities
                + ",mCodecsSelectableCapabilities:" + mCodecsSelectableCapabilities
                + "}";
    }

    /**
     * @return 0
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * {@link Parcelable.Creator} interface implementation.
     */
    public static final @android.annotation.NonNull
            Parcelable.Creator<BluetoothLeAudioCodecStatus> CREATOR =
            new Parcelable.Creator<BluetoothLeAudioCodecStatus>() {
                public BluetoothLeAudioCodecStatus createFromParcel(Parcel in) {
                    return new BluetoothLeAudioCodecStatus(in);
                }

                public BluetoothLeAudioCodecStatus[] newArray(int size) {
                    return new BluetoothLeAudioCodecStatus[size];
                }
            };

    /**
     * Flattens the object to a parcel.
     *
     * @param out The Parcel in which the object should be written
     * @param flags Additional flags about how the object should be written
     */
    @Override
    public void writeToParcel(@NonNull Parcel out, int flags) {
        out.writeTypedObject(mCodecConfig, 0);
        out.writeTypedList(mCodecsLocalCapabilities);
        out.writeTypedList(mCodecsSelectableCapabilities);
    }

    /**
     * Returns the current codec configuration.
     */
    public @Nullable BluetoothLeAudioCodecConfig getCodecConfig() {
        return mCodecConfig;
    }

    /**
     * Returns the codecs local capabilities.
     */
    public @NonNull List<BluetoothLeAudioCodecConfig> getCodecsLocalCapabilities() {
        return (mCodecsLocalCapabilities == null)
                ? Collections.emptyList() : mCodecsLocalCapabilities;
    }

    /**
     * Returns the codecs selectable capabilities.
     */
    public @NonNull List<BluetoothLeAudioCodecConfig> getCodecsSelectableCapabilities() {
        return (mCodecsSelectableCapabilities == null)
                ? Collections.emptyList() : mCodecsSelectableCapabilities;
    }
}