summaryrefslogtreecommitdiff
path: root/framework/java/android/bluetooth/BluetoothVolumeControl.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/java/android/bluetooth/BluetoothVolumeControl.java')
-rw-r--r--framework/java/android/bluetooth/BluetoothVolumeControl.java123
1 files changed, 116 insertions, 7 deletions
diff --git a/framework/java/android/bluetooth/BluetoothVolumeControl.java b/framework/java/android/bluetooth/BluetoothVolumeControl.java
index 27532aabc3..fb8abb1cf2 100644
--- a/framework/java/android/bluetooth/BluetoothVolumeControl.java
+++ b/framework/java/android/bluetooth/BluetoothVolumeControl.java
@@ -20,6 +20,7 @@ package android.bluetooth;
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
import android.Manifest;
+import android.annotation.CallbackExecutor;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -40,6 +41,7 @@ import com.android.modules.utils.SynchronousResultReceiver;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
/**
@@ -59,6 +61,33 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
private CloseGuard mCloseGuard;
/**
+ * This class provides a callback that is invoked when volume offset value changes on
+ * the remote device.
+ *
+ * <p> In order to balance volume on the group of Le Audio devices,
+ * Volume Offset Control Service (VOCS) shall be used. User can verify
+ * if the remote device supports VOCS by calling {@link #isVolumeOffsetAvailable(device)}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface Callback {
+ /**
+ * Callback invoked when callback is registered and when volume offset
+ * changes on the remote device. Change can be triggered autonomously by the remote device
+ * or after volume offset change on the user request done by calling
+ * {@link #setVolumeOffset(device, volumeOffset)}
+ *
+ * @param device remote device whose volume offset changed
+ * @param volumeOffset latest volume offset for this device
+ * @hide
+ */
+ @SystemApi
+ void onVolumeOffsetChanged(@NonNull BluetoothDevice device,
+ @IntRange(from = -255, to = 255) int volumeOffset);
+ }
+
+ /**
* Intent used to broadcast the change in connection state of the Volume Control
* profile.
*
@@ -217,10 +246,68 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
}
/**
- * Tells remote device to set an absolute volume.
+ * Register a {@link Callback} that will be invoked during the
+ * operation of this profile.
+ *
+ * Repeated registration of the same <var>callback</var> object will have no effect after
+ * the first call to this method, even when the <var>executor</var> is different. API caller
+ * would have to call {@link #unregisterCallback(Callback)} with
+ * the same callback object before registering it again.
+ *
+ * @param executor an {@link Executor} to execute given callback
+ * @param callback user implementation of the {@link Callback}
+ * @throws IllegalArgumentException if a null executor, sink, or callback is given
+ * @hide
+ */
+ @SystemApi
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ public void registerCallback(@NonNull @CallbackExecutor Executor executor,
+ @NonNull Callback callback) {
+ if (executor == null) {
+ throw new IllegalArgumentException("executor cannot be null");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("callback cannot be null");
+ }
+ if (DBG) log("registerCallback");
+ throw new UnsupportedOperationException("Not Implemented");
+ }
+
+ /**
+ * Unregister the specified {@link Callback}.
+ * <p>The same {@link Callback} object used when calling
+ * {@link #registerCallback(Executor, Callback)} must be used.
+ *
+ * <p>Callbacks are automatically unregistered when application process goes away
+ *
+ * @param callback user implementation of the {@link Callback}
+ * @throws IllegalArgumentException when callback is null or when no callback is registered
+ * @hide
+ */
+ @SystemApi
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ public void unregisterCallback(@NonNull Callback callback) {
+ if (callback == null) {
+ throw new IllegalArgumentException("callback cannot be null");
+ }
+ if (DBG) log("unregisterCallback");
+ throw new UnsupportedOperationException("Not Implemented");
+ }
+
+ /**
+ * Tells the remote device to set a volume offset to the absolute volume.
+ *
+ * @param device {@link BluetoothDevice} representing the remote device
+ * @param volumeOffset volume offset to be set on the remote device
*
- * @param volume Absolute volume to be set on remote device.
- * Minimum value is 0 and maximum value is 255
* @hide
*/
@SystemApi
@@ -229,9 +316,9 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
})
- public void setVolume(@Nullable BluetoothDevice device,
- @IntRange(from = 0, to = 255) int volume) {
- if (DBG) log("setVolume(" + volume + ")");
+ public void setVolumeOffset(@NonNull BluetoothDevice device,
+ @IntRange(from = -255, to = 255) int volumeOffset) {
+ if (DBG) log("setVolumeOffset(" + device + " volumeOffset: " + volumeOffset + ")");
final IBluetoothVolumeControl service = getService();
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
@@ -239,7 +326,7 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
} else if (isEnabled()) {
try {
final SynchronousResultReceiver recv = new SynchronousResultReceiver();
- service.setVolume(device, volume, mAttributionSource, recv);
+ service.setVolumeOffset(device, volumeOffset, mAttributionSource, recv);
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
} catch (RemoteException | TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
@@ -248,6 +335,28 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
}
/**
+ * Provides information about the possibility to set volume offset on the remote device.
+ * If the remote device supports Volume Offset Control Service, it is automatically
+ * connected.
+ *
+ * @param device {@link BluetoothDevice} representing the remote device
+ * @return {@code true} if volume offset function is supported and available to use on the
+ * remote device. When Bluetooth is off, the return value should always be
+ * {@code false}.
+ * @hide
+ */
+ @SystemApi
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ public boolean isVolumeOffsetAvailable(@NonNull BluetoothDevice device) {
+ if (DBG) log("isVolumeOffsetAvailable(" + device + ")");
+ return false;
+ }
+
+ /**
* Set connection policy of the profile
*
* <p> The device should already be paired.