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

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

Merge "Dynamic Audio Buffer (2/3)"

parents 4a3b01ce 431fcfc0
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -1239,6 +1239,16 @@ static jbyteArray obfuscateAddressNative(JNIEnv* env, jobject obj,
  return output_bytes;
}

static jboolean setBufferMillisNative(JNIEnv* env, jobject obj, jint codec,
                                      jint size) {
  ALOGV("%s", __func__);

  if (!sBluetoothInterface) return JNI_FALSE;

  int ret = sBluetoothInterface->set_dynamic_audio_buffer_size(codec, size);
  return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jint connectSocketNative(JNIEnv* env, jobject obj, jbyteArray address,
                                jint type, jbyteArray uuid, jint port,
                                jint flag, jint callingUid) {
@@ -1365,6 +1375,7 @@ static JNINativeMethod sMethods[] = {
    {"interopDatabaseClearNative", "()V", (void*)interopDatabaseClearNative},
    {"interopDatabaseAddNative", "(I[BI)V", (void*)interopDatabaseAddNative},
    {"obfuscateAddressNative", "([B)[B", (void*)obfuscateAddressNative},
    {"setBufferMillisNative", "(II)Z", (void*)setBufferMillisNative},
    {"getMetricIdNative", "([B)I", (void*)getMetricIdNative},
    {"connectSocketNative", "([BI[BIII)I", (void*)connectSocketNative},
    {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I",
+63 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.bluetooth.BluetoothCodecStatus;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.BufferConstraints;
import android.bluetooth.IBluetoothA2dp;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -873,6 +874,44 @@ public class A2dpService extends ProfileService {
        mDatabaseManager.setA2dpOptionalCodecsEnabled(device, value);
    }

    /**
     * Get dynamic audio buffer size supported type
     *
     * @return support <p>Possible values are
     * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_NONE},
     * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD},
     * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING}.
     */
    public int getDynamicBufferSupport() {
        enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
                "Need BLUETOOTH_PRIVILEGED permission");
        return mAdapterService.getDynamicBufferSupport();
    }

    /**
     * Get dynamic audio buffer size
     *
     * @return BufferConstraints
     */
    public BufferConstraints getBufferConstraints() {
        enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
                "Need BLUETOOTH_PRIVILEGED permission");
        return mAdapterService.getBufferConstraints();
    }

    /**
     * Set dynamic audio buffer size
     *
     * @param codec Audio codec
     * @param value buffer millis
     * @return true if the settings is successful, false otherwise
     */
    public boolean setBufferMillis(int codec, int value) {
        enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
                "Need BLUETOOTH_PRIVILEGED permission");
        return mAdapterService.setBufferMillis(codec, value);
    }

    // Handle messages from native (JNI) to Java
    void messageFromNative(A2dpStackEvent stackEvent) {
        Objects.requireNonNull(stackEvent.device,
@@ -1385,6 +1424,30 @@ public class A2dpService extends ProfileService {
            }
            service.setOptionalCodecsEnabled(device, value);
        }

        public int getDynamicBufferSupport() {
            A2dpService service = getService();
            if (service == null) {
                return BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE;
            }
            return service.getDynamicBufferSupport();
        }

        public BufferConstraints getBufferConstraints() {
            A2dpService service = getService();
            if (service == null) {
                return null;
            }
            return service.getBufferConstraints();
        }

        public boolean setBufferMillis(int codec, int value) {
            A2dpService service = getService();
            if (service == null) {
                return false;
            }
            return service.setBufferMillis(codec, value);
        }
    }

    @Override
+2 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ public final class AbstractionLayer {
    static final int BT_PROPERTY_REMOTE_VERSION_INFO = 0x0C;
    static final int BT_PROPERTY_LOCAL_LE_FEATURES = 0x0D;

    static final int BT_PROPERTY_DYNAMIC_AUDIO_BUFFER = 0x10;

    public static final int BT_DEVICE_TYPE_BREDR = 0x01;
    public static final int BT_DEVICE_TYPE_BLE = 0x02;
    public static final int BT_DEVICE_TYPE_DUAL = 0x03;
+82 −1
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ import android.bluetooth.BluetoothPbap;
import android.bluetooth.BluetoothPbapClient;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothSap;
import android.bluetooth.BufferConstraint;
import android.bluetooth.BufferConstraints;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -52,7 +54,9 @@ import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

class AdapterProperties {
@@ -115,6 +119,11 @@ class AdapterProperties {
    private boolean mIsLePeriodicAdvertisingSupported;
    private int mLeMaximumAdvertisingDataLength;

    private int mIsDynamicAudioBufferSizeSupported;
    private int mDynamicAudioBufferSizeSupportedCodecsGroup1;
    private int mDynamicAudioBufferSizeSupportedCodecsGroup2;
    private List<BufferConstraint> mBufferConstraintList;

    private boolean mReceiverRegistered;
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
@@ -512,6 +521,44 @@ class AdapterProperties {
        return mA2dpOffloadEnabled;
    }

    /**
     * @return Dynamic Audio Buffer support
     */
    int getDynamicBufferSupport() {
        if (!mA2dpOffloadEnabled) {
            // TODO: Enable Dynamic Audio Buffer for A2DP software encoding when ready.
            mIsDynamicAudioBufferSizeSupported =
                BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE;
        } else {
            if ((mDynamicAudioBufferSizeSupportedCodecsGroup1 != 0)
                    || (mDynamicAudioBufferSizeSupportedCodecsGroup2 != 0)) {
                mIsDynamicAudioBufferSizeSupported =
                    BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD;
            } else {
                mIsDynamicAudioBufferSizeSupported =
                    BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE;
            }
        }
        return mIsDynamicAudioBufferSizeSupported;
    }

    /**
     * @return Dynamic Audio Buffer Capability
     */
    BufferConstraints getBufferConstraints() {
        return new BufferConstraints(mBufferConstraintList);
    }

    /**
     * Set the dynamic audio buffer size
     *
     * @param codec the codecs to set
     * @param size the size to set
     */
    boolean setBufferMillis(int codec, int value) {
        return mService.setBufferMillisNative(codec, value);
    }

    /**
     * @return the mBondedDevices
     */
@@ -860,6 +907,10 @@ class AdapterProperties {
                        updateFeatureSupport(val);
                        break;

                    case AbstractionLayer.BT_PROPERTY_DYNAMIC_AUDIO_BUFFER:
                        updateDynamicAudioBufferSupport(val);
                        break;

                    case AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS:
                        mLocalIOCapability = Utils.byteArrayToInt(val);
                        debugLog("mLocalIOCapability set to " + mLocalIOCapability);
@@ -894,6 +945,10 @@ class AdapterProperties {
        mIsLePeriodicAdvertisingSupported = ((0xFF & ((int) val[17])) != 0);
        mLeMaximumAdvertisingDataLength =
                (0xFF & ((int) val[18])) + ((0xFF & ((int) val[19])) << 8);
        mDynamicAudioBufferSizeSupportedCodecsGroup1 =
                ((0xFF & ((int) val[21])) << 8) + (0xFF & ((int) val[20]));
        mDynamicAudioBufferSizeSupportedCodecsGroup2 =
                ((0xFF & ((int) val[23])) << 8) + (0xFF & ((int) val[22]));

        Log.d(TAG, "BT_PROPERTY_LOCAL_LE_FEATURES: update from BT controller"
                + " mNumOfAdvertisementInstancesSupported = "
@@ -909,10 +964,36 @@ class AdapterProperties {
                + mIsLe2MPhySupported + " mIsLeCodedPhySupported = " + mIsLeCodedPhySupported
                + " mIsLeExtendedAdvertisingSupported = " + mIsLeExtendedAdvertisingSupported
                + " mIsLePeriodicAdvertisingSupported = " + mIsLePeriodicAdvertisingSupported
                + " mLeMaximumAdvertisingDataLength = " + mLeMaximumAdvertisingDataLength);
                + " mLeMaximumAdvertisingDataLength = " + mLeMaximumAdvertisingDataLength
                + " mDynamicAudioBufferSizeSupportedCodecsGroup1 = "
                + mDynamicAudioBufferSizeSupportedCodecsGroup1
                + " mDynamicAudioBufferSizeSupportedCodecsGroup2 = "
                + mDynamicAudioBufferSizeSupportedCodecsGroup2);
        invalidateIsOffloadedFilteringSupportedCache();
    }

    private void updateDynamicAudioBufferSupport(byte[] val) {
        // bufferConstraints is the table indicates the capability of all the codecs
        // with buffer time. The raw is codec number, and the column is buffer type. There are 3
        // buffer types - default/maximum/minimum.
        // The maximum number of raw is BUFFER_CODEC_MAX_NUM(32).
        // The maximum number of column is BUFFER_TYPE_MAX(3).
        // The array element indicates the buffer time, the size is two octet.
        mBufferConstraintList = new ArrayList<BufferConstraint>();

        for (int i = 0; i < BufferConstraints.BUFFER_CODEC_MAX_NUM; i++) {
            int defaultBufferTime = ((0xFF & ((int) val[i * 6 + 1])) << 8)
                    + (0xFF & ((int) val[i * 6]));
            int maximumBufferTime = ((0xFF & ((int) val[i * 6 + 3])) << 8)
                    + (0xFF & ((int) val[i * 6 + 2]));
            int minimumBufferTime = ((0xFF & ((int) val[i * 6 + 5])) << 8)
                    + (0xFF & ((int) val[i * 6 + 4]));
            BufferConstraint bufferConstraint = new BufferConstraint(defaultBufferTime,
                    maximumBufferTime, minimumBufferTime);
            mBufferConstraintList.add(bufferConstraint);
        }
    }

    void onBluetoothReady() {
        debugLog("onBluetoothReady, state=" + BluetoothAdapter.nameForState(getState())
                + ", ScanMode=" + mScanMode);
+36 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.admin.DevicePolicyManager;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothActivityEnergyInfo;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter.ActiveDeviceUse;
@@ -40,6 +41,7 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProtoEnums;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.BufferConstraints;
import android.bluetooth.IBluetooth;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothConnectionCallback;
@@ -3193,6 +3195,38 @@ public class AdapterService extends Service {
        return obfuscateAddressNative(Utils.getByteAddress(device));
    }

    /**
     * Get dynamic audio buffer size supported type
     *
     * @return support <p>Possible values are
     * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_NONE},
     * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD},
     * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING}.
     */
    public int getDynamicBufferSupport() {
        return mAdapterProperties.getDynamicBufferSupport();
    }

    /**
     * Get dynamic audio buffer size
     *
     * @return BufferConstraints
     */
    public BufferConstraints getBufferConstraints() {
        return mAdapterProperties.getBufferConstraints();
    }

    /**
     * Set dynamic audio buffer size
     *
     * @param codec Audio codec
     * @param value buffer millis
     * @return true if the settings is successful, false otherwise
     */
    public boolean setBufferMillis(int codec, int value) {
        return mAdapterProperties.setBufferMillis(codec, value);
    }

    /**
     *  Get an incremental id of Bluetooth metrics and log
     *
@@ -3286,6 +3320,8 @@ public class AdapterService extends Service {

    private native byte[] obfuscateAddressNative(byte[] address);

    native boolean setBufferMillisNative(int codec, int value);

    private native int getMetricIdNative(byte[] address);

    /*package*/ native int connectSocketNative(