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

Commit 9f5236d1 authored by Chen Chen's avatar Chen Chen Committed by Automerger Merge Worker
Browse files

Merge "SpatialAudio: Provide API to allow/disallow low latency audio" am: 68da9570

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

Change-Id: I32ab0c8b5f50123589d705e3472903ac3e9ac029
parents 15e86dbf 68da9570
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -1714,6 +1714,22 @@ static int getMetricIdNative(JNIEnv* env, jobject obj, jbyteArray address) {
  return sBluetoothInterface->get_metric_id(addr_obj);
}

static jboolean allowLowLatencyAudioNative(JNIEnv* env, jobject obj,
                                           jboolean allowed,
                                           jbyteArray address) {
  ALOGV("%s", __func__);
  if (!sBluetoothInterface) return false;
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (addr == nullptr) {
    jniThrowIOException(env, EINVAL);
    return false;
  }
  RawAddress addr_obj = {};
  addr_obj.FromOctets((uint8_t*)addr);
  sBluetoothInterface->allow_low_latency_audio(allowed, addr_obj);
  return true;
}

static JNINativeMethod sMethods[] = {
    /* name, signature, funcPtr */
    {"classInitNative", "()V", (void*)classInitNative},
@@ -1753,7 +1769,9 @@ static JNINativeMethod sMethods[] = {
    {"createSocketChannelNative", "(ILjava/lang/String;[BIII)I",
     (void*)createSocketChannelNative},
    {"requestMaximumTxDataLengthNative", "([B)V",
     (void*)requestMaximumTxDataLengthNative}};
     (void*)requestMaximumTxDataLengthNative},
    {"allowLowLatencyAudioNative", "(Z[B)Z", (void*)allowLowLatencyAudioNative},
};

int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) {
  return jniRegisterNativeMethods(
+23 −0
Original line number Diff line number Diff line
@@ -2633,6 +2633,16 @@ public class AdapterService extends Service {
            service.dump(fd, writer, args);
            writer.close();
        }

        @Override
        public boolean allowLowLatencyAudio(boolean allowed, BluetoothDevice device) {
            AdapterService service = getService();
            if (service == null) {
                return false;
            }
            enforceBluetoothPrivilegedPermission(service);
            return service.allowLowLatencyAudio(allowed, device);
        }
    }

    // ----API Methods--------
@@ -4121,6 +4131,17 @@ public class AdapterService extends Service {
        return getMetricIdNative(Utils.getByteAddress(device));
    }

    /**
     *  Allow audio low latency
     *
     *  @param allowed true if audio low latency is being allowed
     *  @param device device whose audio low latency will be allowed or disallowed
     *  @return boolean true if audio low latency is successfully allowed or disallowed
     */
    public boolean allowLowLatencyAudio(boolean allowed, BluetoothDevice device) {
        return allowLowLatencyAudioNative(allowed, Utils.getByteAddress(device));
    }

    static native void classInitNative();

    native boolean initNative(boolean startRestricted, boolean isCommonCriteriaMode,
@@ -4213,6 +4234,8 @@ public class AdapterService extends Service {

    /*package*/ native void requestMaximumTxDataLengthNative(byte[] address);

    private native boolean allowLowLatencyAudioNative(boolean allowed, byte[] address);

    // Returns if this is a mock object. This is currently used in testing so that we may not call
    // System.exit() while finalizing the object. Otherwise GC of mock objects unfortunately ends up
    // calling finalize() which in turn calls System.exit() and the process crashes.
+30 −0
Original line number Diff line number Diff line
@@ -2828,4 +2828,34 @@ public final class BluetoothDevice implements Parcelable, Attributable {
    public static @MetadataKey int getMaxMetadataKey() {
        return METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD;
    }

    /**
     * Enable or disable audio low latency for this {@link BluetoothDevice}.
     *
     * @param allowed true if low latency is allowed, false if low latency is disallowed.
     * @return true if the value is successfully set,
     * false if there is a error when setting the value.
     * @hide
     */
    @SystemApi
    @RequiresBluetoothConnectPermission
    @RequiresPermission(allOf = {
            android.Manifest.permission.BLUETOOTH_CONNECT,
            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
    })
    public boolean setLowLatencyAudioAllowed(boolean allowed) {
        final IBluetooth service = sService;
        Log.i(TAG, "Allowing bluetooth audio low latency: " + allowed);
        if (service == null) {
            Log.e(TAG, "Bluetooth is not enabled. Cannot allow low latency");
            return false;
        }
        try {
            service.allowLowLatencyAudio(allowed, this);
        } catch (RemoteException e) {
            Log.e(TAG, "allowLowLatencyAudio fail ", e);
            e.rethrowFromSystemServer();
        }
        return true;
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -253,4 +253,7 @@ interface IBluetooth
    boolean canBondWithoutDialog(in BluetoothDevice device, in AttributionSource attributionSource);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    void generateLocalOobData(in int transport, IBluetoothOobDataCallback callback, in AttributionSource attributionSource);

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    boolean allowLowLatencyAudio(in boolean allowed, in BluetoothDevice device);
}
+8 −1
Original line number Diff line number Diff line
@@ -591,6 +591,12 @@ static int set_dynamic_audio_buffer_size(int codec, int size) {
  return btif_set_dynamic_audio_buffer_size(codec, size);
}

static bool allow_low_latency_audio(bool allowed, const RawAddress& address) {
  LOG_INFO("%s %s", __func__, allowed ? "true" : "false");
  // Call HAL here
  return true;
}

EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
    sizeof(bluetoothInterface),
    init,
@@ -629,7 +635,8 @@ EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
    obfuscate_address,
    get_metric_id,
    set_dynamic_audio_buffer_size,
    generate_local_oob_data};
    generate_local_oob_data,
    allow_low_latency_audio};

// callback reporting helpers

Loading