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

Commit ce7d2ba4 authored by Zach Johnson's avatar Zach Johnson Committed by Gerrit Code Review
Browse files

Merge "Dynamic Audio Buffer (1/3)"

parents a8e0a85d 1f7f1762
Loading
Loading
Loading
Loading
+114 −0
Original line number Diff line number Diff line
@@ -225,6 +225,39 @@ public final class BluetoothA2dp implements BluetoothProfile {
    @SystemApi
    public static final int OPTIONAL_CODECS_PREF_ENABLED = 1;

    /** @hide */
    @IntDef(prefix = "DYNAMIC_BUFFER_SUPPORT_", value = {
            DYNAMIC_BUFFER_SUPPORT_NONE,
            DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD,
            DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Type {}

    /**
     * Indicates the supported type of Dynamic Audio Buffer is not supported.
     *
     * @hide
     */
    @SystemApi
    public static final int DYNAMIC_BUFFER_SUPPORT_NONE = 0;

    /**
     * Indicates the supported type of Dynamic Audio Buffer is A2DP offload.
     *
     * @hide
     */
    @SystemApi
    public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD = 1;

    /**
     * Indicates the supported type of Dynamic Audio Buffer is A2DP software encoding.
     *
     * @hide
     */
    @SystemApi
    public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING = 2;

    private BluetoothAdapter mAdapter;
    private final BluetoothProfileConnector<IBluetoothA2dp> mProfileConnector =
            new BluetoothProfileConnector(this, BluetoothProfile.A2DP, "BluetoothA2dp",
@@ -844,6 +877,87 @@ public final class BluetoothA2dp implements BluetoothProfile {
        }
    }

    /**
     * Get the supported type of the Dynamic Audio Buffer.
     * <p>Possible return values are
     * {@link #DYNAMIC_BUFFER_SUPPORT_NONE},
     * {@link #DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD},
     * {@link #DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING}.
     *
     * @return supported type of Dynamic Audio Buffer feature
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
    public @Type int getDynamicBufferSupport() {
        if (VDBG) log("getDynamicBufferSupport()");
        try {
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                return service.getDynamicBufferSupport();
            }
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return DYNAMIC_BUFFER_SUPPORT_NONE;
        } catch (RemoteException e) {
            Log.e(TAG, "failed to get getDynamicBufferSupport, error: ", e);
            return DYNAMIC_BUFFER_SUPPORT_NONE;
        }
    }

    /**
     * Return the record of {@link BufferConstraints} object that
     * has the default/maximum/minimum audio buffer. This can be used to inform what the controller
     * has support for the audio buffer.
     *
     * @return a record with {@link BufferConstraints} or null if report is unavailable
     * or unsupported
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
    public @Nullable BufferConstraints getBufferConstraints() {
        if (VDBG) log("getBufferConstraints()");
        try {
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                return service.getBufferConstraints();
            }
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return null;
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
            return null;
        }
    }

    /**
     * Set Dynamic Audio Buffer Size.
     *
     * @param codec audio codec
     * @param value buffer millis
     * @return true to indicate success, or false on immediate error
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
    public boolean setBufferMillis(@BluetoothCodecConfig.SourceCodecType int codec, int value) {
        if (VDBG) log("setBufferMillis(" + codec + ", " + value + ")");
        try {
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                return service.setBufferMillis(codec, value);
            }
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return false;
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
            return false;
        }
    }

    /**
     * Helper for converting a state to a string.
     *
+105 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * Stores a codec's constraints on buffering length in milliseconds.
 *
 * {@hide}
 */
@SystemApi
public final class BufferConstraint implements Parcelable {

    private static final String TAG = "BufferConstraint";
    private int mDefaultMillis;
    private int mMaxMillis;
    private int mMinMillis;

    public BufferConstraint(int defaultMillis, int maxMillis,
            int minMillis) {
        mDefaultMillis = defaultMillis;
        mMaxMillis = maxMillis;
        mMinMillis = minMillis;
    }

    BufferConstraint(Parcel in) {
        mDefaultMillis = in.readInt();
        mMaxMillis = in.readInt();
        mMinMillis = in.readInt();
    }

    public static final @NonNull Parcelable.Creator<BufferConstraint> CREATOR =
            new Parcelable.Creator<BufferConstraint>() {
                public BufferConstraint createFromParcel(Parcel in) {
                    return new BufferConstraint(in);
                }

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

    @Override
    public void writeToParcel(@NonNull Parcel out, int flags) {
        out.writeInt(mDefaultMillis);
        out.writeInt(mMaxMillis);
        out.writeInt(mMinMillis);
    }

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

    /**
     * Get the default buffer millis
     *
     * @return default buffer millis
     * @hide
     */
    @SystemApi
    public int getDefaultMillis() {
        return mDefaultMillis;
    }

    /**
     * Get the maximum buffer millis
     *
     * @return maximum buffer millis
     * @hide
     */
    @SystemApi
    public int getMaxMillis() {
        return mMaxMillis;
    }

    /**
     * Get the minimum buffer millis
     *
     * @return minimum buffer millis
     * @hide
     */
    @SystemApi
    public int getMinMillis() {
        return mMinMillis;
    }
}
+96 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * A parcelable collection of buffer constraints by codec type.
 *
 * {@hide}
 */
@SystemApi
public final class BufferConstraints implements Parcelable {
    public static final int BUFFER_CODEC_MAX_NUM = 32;

    private static final String TAG = "BufferConstraints";

    private Map<Integer, BufferConstraint> mBufferConstraints;
    private List<BufferConstraint> mBufferConstraintList;

    public BufferConstraints(@NonNull List<BufferConstraint>
            bufferConstraintList) {

        mBufferConstraintList = new ArrayList<BufferConstraint>(bufferConstraintList);
        mBufferConstraints = new HashMap<Integer, BufferConstraint>();
        for (int i = 0; i < BUFFER_CODEC_MAX_NUM; i++) {
            mBufferConstraints.put(i, bufferConstraintList.get(i));
        }
    }

    BufferConstraints(Parcel in) {
        mBufferConstraintList = new ArrayList<BufferConstraint>();
        mBufferConstraints = new HashMap<Integer, BufferConstraint>();
        in.readList(mBufferConstraintList, BufferConstraint.class.getClassLoader());
        for (int i = 0; i < mBufferConstraintList.size(); i++) {
            mBufferConstraints.put(i, mBufferConstraintList.get(i));
        }
    }

    public static final @NonNull Parcelable.Creator<BufferConstraints> CREATOR =
            new Parcelable.Creator<BufferConstraints>() {
                public BufferConstraints createFromParcel(Parcel in) {
                    return new BufferConstraints(in);
                }

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

    @Override
    public void writeToParcel(@NonNull Parcel out, int flags) {
        out.writeList(mBufferConstraintList);
    }

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

    /**
     * Get the buffer constraints by codec type.
     *
     * @param codec Audio codec
     * @return buffer constraints by codec type.
     * @hide
     */
    @SystemApi
    public @Nullable BufferConstraint getCodec(@BluetoothCodecConfig.SourceCodecType int codec) {
        return mBufferConstraints.get(codec);
    }
}