Loading android/app/jni/com_android_bluetooth_vc.cpp +58 −0 Original line number Original line Diff line number Diff line Loading @@ -357,6 +357,60 @@ static void setVolumeGroupNative(JNIEnv* env, jobject object, jint group_id, sVolumeControlInterface->SetVolume(group_id, volume); sVolumeControlInterface->SetVolume(group_id, volume); } } static void muteNative(JNIEnv* env, jobject object, jbyteArray address) { if (!sVolumeControlInterface) { LOG(ERROR) << __func__ << ": Failed to get the Bluetooth Volume Control Interface"; return; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { jniThrowIOException(env, EINVAL); return; } RawAddress* tmpraw = (RawAddress*)addr; sVolumeControlInterface->Mute(*tmpraw); env->ReleaseByteArrayElements(address, addr, 0); } static void muteGroupNative(JNIEnv* env, jobject object, jint group_id) { if (!sVolumeControlInterface) { LOG(ERROR) << __func__ << ": Failed to get the Bluetooth Volume Control Interface"; return; } sVolumeControlInterface->Mute(group_id); } static void unmuteNative(JNIEnv* env, jobject object, jbyteArray address) { if (!sVolumeControlInterface) { LOG(ERROR) << __func__ << ": Failed to get the Bluetooth Volume Control Interface"; return; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { jniThrowIOException(env, EINVAL); return; } RawAddress* tmpraw = (RawAddress*)addr; sVolumeControlInterface->Unmute(*tmpraw); env->ReleaseByteArrayElements(address, addr, 0); } static void unmuteGroupNative(JNIEnv* env, jobject object, jint group_id) { if (!sVolumeControlInterface) { LOG(ERROR) << __func__ << ": Failed to get the Bluetooth Volume Control Interface"; return; } sVolumeControlInterface->Unmute(group_id); } /* Native methods for exterbak audio outputs */ /* Native methods for exterbak audio outputs */ static jboolean getExtAudioOutVolumeOffsetNative(JNIEnv* env, jobject object, static jboolean getExtAudioOutVolumeOffsetNative(JNIEnv* env, jobject object, jbyteArray address, jbyteArray address, Loading Loading @@ -494,6 +548,10 @@ static JNINativeMethod sMethods[] = { (void*)disconnectVolumeControlNative}, (void*)disconnectVolumeControlNative}, {"setVolumeNative", "([BI)V", (void*)setVolumeNative}, {"setVolumeNative", "([BI)V", (void*)setVolumeNative}, {"setVolumeGroupNative", "(II)V", (void*)setVolumeGroupNative}, {"setVolumeGroupNative", "(II)V", (void*)setVolumeGroupNative}, {"muteNative", "([B)V", (void*)muteNative}, {"muteGroupNative", "(I)V", (void*)muteGroupNative}, {"unmuteNative", "([B)V", (void*)unmuteNative}, {"unmuteGroupNative", "(I)V", (void*)unmuteGroupNative}, {"getExtAudioOutVolumeOffsetNative", "([BI)Z", {"getExtAudioOutVolumeOffsetNative", "([BI)Z", (void*)getExtAudioOutVolumeOffsetNative}, (void*)getExtAudioOutVolumeOffsetNative}, {"setExtAudioOutVolumeOffsetNative", "([BII)Z", {"setExtAudioOutVolumeOffsetNative", "([BII)Z", Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +42 −0 Original line number Original line Diff line number Diff line Loading @@ -176,6 +176,8 @@ public class LeAudioService extends ProfileService { private BroadcastReceiver mBondStateChangedReceiver; private BroadcastReceiver mBondStateChangedReceiver; private BroadcastReceiver mConnectionStateChangedReceiver; private BroadcastReceiver mConnectionStateChangedReceiver; private BroadcastReceiver mMuteStateChangedReceiver; private int mStoredRingerMode = -1; private Handler mHandler = new Handler(Looper.getMainLooper()); private Handler mHandler = new Handler(Looper.getMainLooper()); private final Map<Integer, Integer> mBroadcastStateMap = new HashMap<>(); private final Map<Integer, Integer> mBroadcastStateMap = new HashMap<>(); Loading Loading @@ -239,6 +241,11 @@ public class LeAudioService extends ProfileService { filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); mConnectionStateChangedReceiver = new ConnectionStateChangedReceiver(); mConnectionStateChangedReceiver = new ConnectionStateChangedReceiver(); registerReceiver(mConnectionStateChangedReceiver, filter); registerReceiver(mConnectionStateChangedReceiver, filter); filter = new IntentFilter(); filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); mMuteStateChangedReceiver = new MuteStateChangedReceiver(); registerReceiver(mMuteStateChangedReceiver, filter); mLeAudioCallbacks = new RemoteCallbackList<IBluetoothLeAudioCallback>(); mLeAudioCallbacks = new RemoteCallbackList<IBluetoothLeAudioCallback>(); int tmapRoleMask = int tmapRoleMask = Loading Loading @@ -330,6 +337,8 @@ public class LeAudioService extends ProfileService { mBondStateChangedReceiver = null; mBondStateChangedReceiver = null; unregisterReceiver(mConnectionStateChangedReceiver); unregisterReceiver(mConnectionStateChangedReceiver); mConnectionStateChangedReceiver = null; mConnectionStateChangedReceiver = null; unregisterReceiver(mMuteStateChangedReceiver); mMuteStateChangedReceiver = null; // Destroy state machines and stop handler thread // Destroy state machines and stop handler thread synchronized (mStateMachines) { synchronized (mStateMachines) { Loading Loading @@ -1542,6 +1551,39 @@ public class LeAudioService extends ProfileService { } } } } private synchronized boolean isSilentModeEnabled() { return mStoredRingerMode != AudioManager.RINGER_MODE_NORMAL; } private class MuteStateChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (!AudioManager.RINGER_MODE_CHANGED_ACTION.equals(intent.getAction())) { return; } final String action = intent.getAction(); if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { int ringerMode = intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1); if (ringerMode < 0 || ringerMode == mStoredRingerMode) return; mStoredRingerMode = ringerMode; int activeGroupId = getActiveGroupId(); if (activeGroupId == LE_AUDIO_GROUP_ID_INVALID) return; VolumeControlService service = mServiceFactory.getVolumeControlService(); if (service == null) return; if (isSilentModeEnabled()) { service.muteGroup(activeGroupId); } else { service.unmuteGroup(activeGroupId); } } } } /** /** * Check whether can connect to a peer device. * Check whether can connect to a peer device. * The check considers a number of factors during the evaluation. * The check considers a number of factors during the evaluation. Loading android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java +42 −0 Original line number Original line Diff line number Diff line Loading @@ -117,6 +117,44 @@ public class VolumeControlNativeInterface { setVolumeGroupNative(groupId, volume); setVolumeGroupNative(groupId, volume); } } /** * Mute the VolumeControl volume * @param device * @param unmute */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void mute(BluetoothDevice device) { muteNative(getByteAddress(device)); } /** * Mute the VolumeControl volume in the group * @param groupId * @param unmute */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void muteGroup(int groupId) { muteGroupNative(groupId); } /** * Unmute the VolumeControl volume */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void unmute(BluetoothDevice device) { unmuteNative(getByteAddress(device)); } /** * Unmute the VolumeControl volume group * @param groupId * @param unmute */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void unmuteGroup(int groupId) { unmuteGroupNative(groupId); } /** /** * Gets external audio output volume offset from a remote device. * Gets external audio output volume offset from a remote device. * * Loading Loading @@ -333,6 +371,10 @@ public class VolumeControlNativeInterface { private native boolean disconnectVolumeControlNative(byte[] address); private native boolean disconnectVolumeControlNative(byte[] address); private native void setVolumeNative(byte[] address, int volume); private native void setVolumeNative(byte[] address, int volume); private native void setVolumeGroupNative(int groupId, int volume); private native void setVolumeGroupNative(int groupId, int volume); private native void muteNative(byte[] address); private native void muteGroupNative(int groupId); private native void unmuteNative(byte[] address); private native void unmuteGroupNative(int groupId); private native boolean getExtAudioOutVolumeOffsetNative(byte[] address, int externalOutputId); private native boolean getExtAudioOutVolumeOffsetNative(byte[] address, int externalOutputId); private native boolean setExtAudioOutVolumeOffsetNative(byte[] address, int externalOutputId, private native boolean setExtAudioOutVolumeOffsetNative(byte[] address, int externalOutputId, int offset); int offset); Loading android/app/src/com/android/bluetooth/vc/VolumeControlService.java +98 −0 Original line number Original line Diff line number Diff line Loading @@ -582,6 +582,34 @@ public class VolumeControlService extends ProfileService { mVolumeControlNativeInterface.setVolumeGroup(groupId, volume); mVolumeControlNativeInterface.setVolumeGroup(groupId, volume); } } /** * {@hide} */ public void mute(BluetoothDevice device) { mVolumeControlNativeInterface.mute(device); } /** * {@hide} */ public void muteGroup(int groupId) { mVolumeControlNativeInterface.muteGroup(groupId); } /** * {@hide} */ public void unmute(BluetoothDevice device) { mVolumeControlNativeInterface.unmute(device); } /** * {@hide} */ public void unmuteGroup(int groupId) { mVolumeControlNativeInterface.unmuteGroup(groupId); } void handleVolumeControlChanged(BluetoothDevice device, int groupId, void handleVolumeControlChanged(BluetoothDevice device, int groupId, int volume, boolean mute, boolean isAutonomous) { int volume, boolean mute, boolean isAutonomous) { if (!isAutonomous) { if (!isAutonomous) { Loading Loading @@ -1113,6 +1141,76 @@ public class VolumeControlService extends ProfileService { } } } } @Override public void mute(BluetoothDevice device, AttributionSource source, SynchronousResultReceiver receiver) { try { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); Objects.requireNonNull(receiver, "receiver cannot be null"); VolumeControlService service = getService(source); if (service != null) { service.mute(device); } receiver.send(null); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void muteGroup(int groupId, AttributionSource source, SynchronousResultReceiver receiver) { try { Objects.requireNonNull(source, "source cannot be null"); Objects.requireNonNull(receiver, "receiver cannot be null"); VolumeControlService service = getService(source); if (service != null) { service.muteGroup(groupId); } receiver.send(null); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void unmute(BluetoothDevice device, AttributionSource source, SynchronousResultReceiver receiver) { try { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); Objects.requireNonNull(receiver, "receiver cannot be null"); VolumeControlService service = getService(source); if (service != null) { service.unmute(device); } receiver.send(null); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void unmuteGroup(int groupId, AttributionSource source, SynchronousResultReceiver receiver) { try { Objects.requireNonNull(source, "source cannot be null"); Objects.requireNonNull(receiver, "receiver cannot be null"); VolumeControlService service = getService(source); if (service != null) { service.unmuteGroup(groupId); } receiver.send(null); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override @Override public void registerCallback(IBluetoothVolumeControlCallback callback, public void registerCallback(IBluetoothVolumeControlCallback callback, AttributionSource source, SynchronousResultReceiver receiver) { AttributionSource source, SynchronousResultReceiver receiver) { Loading system/binder/android/bluetooth/IBluetoothVolumeControl.aidl +10 −0 Original line number Original line Diff line number Diff line Loading @@ -52,6 +52,16 @@ oneway interface IBluetoothVolumeControl { @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void setVolumeGroup(int group_id, int volume, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); void setVolumeGroup(int group_id, int volume, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void mute(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void muteGroup(int group_id, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void unmute(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void unmuteGroup(int group_id, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") void registerCallback(in IBluetoothVolumeControlCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); void registerCallback(in IBluetoothVolumeControlCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") Loading Loading
android/app/jni/com_android_bluetooth_vc.cpp +58 −0 Original line number Original line Diff line number Diff line Loading @@ -357,6 +357,60 @@ static void setVolumeGroupNative(JNIEnv* env, jobject object, jint group_id, sVolumeControlInterface->SetVolume(group_id, volume); sVolumeControlInterface->SetVolume(group_id, volume); } } static void muteNative(JNIEnv* env, jobject object, jbyteArray address) { if (!sVolumeControlInterface) { LOG(ERROR) << __func__ << ": Failed to get the Bluetooth Volume Control Interface"; return; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { jniThrowIOException(env, EINVAL); return; } RawAddress* tmpraw = (RawAddress*)addr; sVolumeControlInterface->Mute(*tmpraw); env->ReleaseByteArrayElements(address, addr, 0); } static void muteGroupNative(JNIEnv* env, jobject object, jint group_id) { if (!sVolumeControlInterface) { LOG(ERROR) << __func__ << ": Failed to get the Bluetooth Volume Control Interface"; return; } sVolumeControlInterface->Mute(group_id); } static void unmuteNative(JNIEnv* env, jobject object, jbyteArray address) { if (!sVolumeControlInterface) { LOG(ERROR) << __func__ << ": Failed to get the Bluetooth Volume Control Interface"; return; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { jniThrowIOException(env, EINVAL); return; } RawAddress* tmpraw = (RawAddress*)addr; sVolumeControlInterface->Unmute(*tmpraw); env->ReleaseByteArrayElements(address, addr, 0); } static void unmuteGroupNative(JNIEnv* env, jobject object, jint group_id) { if (!sVolumeControlInterface) { LOG(ERROR) << __func__ << ": Failed to get the Bluetooth Volume Control Interface"; return; } sVolumeControlInterface->Unmute(group_id); } /* Native methods for exterbak audio outputs */ /* Native methods for exterbak audio outputs */ static jboolean getExtAudioOutVolumeOffsetNative(JNIEnv* env, jobject object, static jboolean getExtAudioOutVolumeOffsetNative(JNIEnv* env, jobject object, jbyteArray address, jbyteArray address, Loading Loading @@ -494,6 +548,10 @@ static JNINativeMethod sMethods[] = { (void*)disconnectVolumeControlNative}, (void*)disconnectVolumeControlNative}, {"setVolumeNative", "([BI)V", (void*)setVolumeNative}, {"setVolumeNative", "([BI)V", (void*)setVolumeNative}, {"setVolumeGroupNative", "(II)V", (void*)setVolumeGroupNative}, {"setVolumeGroupNative", "(II)V", (void*)setVolumeGroupNative}, {"muteNative", "([B)V", (void*)muteNative}, {"muteGroupNative", "(I)V", (void*)muteGroupNative}, {"unmuteNative", "([B)V", (void*)unmuteNative}, {"unmuteGroupNative", "(I)V", (void*)unmuteGroupNative}, {"getExtAudioOutVolumeOffsetNative", "([BI)Z", {"getExtAudioOutVolumeOffsetNative", "([BI)Z", (void*)getExtAudioOutVolumeOffsetNative}, (void*)getExtAudioOutVolumeOffsetNative}, {"setExtAudioOutVolumeOffsetNative", "([BII)Z", {"setExtAudioOutVolumeOffsetNative", "([BII)Z", Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +42 −0 Original line number Original line Diff line number Diff line Loading @@ -176,6 +176,8 @@ public class LeAudioService extends ProfileService { private BroadcastReceiver mBondStateChangedReceiver; private BroadcastReceiver mBondStateChangedReceiver; private BroadcastReceiver mConnectionStateChangedReceiver; private BroadcastReceiver mConnectionStateChangedReceiver; private BroadcastReceiver mMuteStateChangedReceiver; private int mStoredRingerMode = -1; private Handler mHandler = new Handler(Looper.getMainLooper()); private Handler mHandler = new Handler(Looper.getMainLooper()); private final Map<Integer, Integer> mBroadcastStateMap = new HashMap<>(); private final Map<Integer, Integer> mBroadcastStateMap = new HashMap<>(); Loading Loading @@ -239,6 +241,11 @@ public class LeAudioService extends ProfileService { filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); mConnectionStateChangedReceiver = new ConnectionStateChangedReceiver(); mConnectionStateChangedReceiver = new ConnectionStateChangedReceiver(); registerReceiver(mConnectionStateChangedReceiver, filter); registerReceiver(mConnectionStateChangedReceiver, filter); filter = new IntentFilter(); filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); mMuteStateChangedReceiver = new MuteStateChangedReceiver(); registerReceiver(mMuteStateChangedReceiver, filter); mLeAudioCallbacks = new RemoteCallbackList<IBluetoothLeAudioCallback>(); mLeAudioCallbacks = new RemoteCallbackList<IBluetoothLeAudioCallback>(); int tmapRoleMask = int tmapRoleMask = Loading Loading @@ -330,6 +337,8 @@ public class LeAudioService extends ProfileService { mBondStateChangedReceiver = null; mBondStateChangedReceiver = null; unregisterReceiver(mConnectionStateChangedReceiver); unregisterReceiver(mConnectionStateChangedReceiver); mConnectionStateChangedReceiver = null; mConnectionStateChangedReceiver = null; unregisterReceiver(mMuteStateChangedReceiver); mMuteStateChangedReceiver = null; // Destroy state machines and stop handler thread // Destroy state machines and stop handler thread synchronized (mStateMachines) { synchronized (mStateMachines) { Loading Loading @@ -1542,6 +1551,39 @@ public class LeAudioService extends ProfileService { } } } } private synchronized boolean isSilentModeEnabled() { return mStoredRingerMode != AudioManager.RINGER_MODE_NORMAL; } private class MuteStateChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (!AudioManager.RINGER_MODE_CHANGED_ACTION.equals(intent.getAction())) { return; } final String action = intent.getAction(); if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { int ringerMode = intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1); if (ringerMode < 0 || ringerMode == mStoredRingerMode) return; mStoredRingerMode = ringerMode; int activeGroupId = getActiveGroupId(); if (activeGroupId == LE_AUDIO_GROUP_ID_INVALID) return; VolumeControlService service = mServiceFactory.getVolumeControlService(); if (service == null) return; if (isSilentModeEnabled()) { service.muteGroup(activeGroupId); } else { service.unmuteGroup(activeGroupId); } } } } /** /** * Check whether can connect to a peer device. * Check whether can connect to a peer device. * The check considers a number of factors during the evaluation. * The check considers a number of factors during the evaluation. Loading
android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java +42 −0 Original line number Original line Diff line number Diff line Loading @@ -117,6 +117,44 @@ public class VolumeControlNativeInterface { setVolumeGroupNative(groupId, volume); setVolumeGroupNative(groupId, volume); } } /** * Mute the VolumeControl volume * @param device * @param unmute */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void mute(BluetoothDevice device) { muteNative(getByteAddress(device)); } /** * Mute the VolumeControl volume in the group * @param groupId * @param unmute */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void muteGroup(int groupId) { muteGroupNative(groupId); } /** * Unmute the VolumeControl volume */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void unmute(BluetoothDevice device) { unmuteNative(getByteAddress(device)); } /** * Unmute the VolumeControl volume group * @param groupId * @param unmute */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void unmuteGroup(int groupId) { unmuteGroupNative(groupId); } /** /** * Gets external audio output volume offset from a remote device. * Gets external audio output volume offset from a remote device. * * Loading Loading @@ -333,6 +371,10 @@ public class VolumeControlNativeInterface { private native boolean disconnectVolumeControlNative(byte[] address); private native boolean disconnectVolumeControlNative(byte[] address); private native void setVolumeNative(byte[] address, int volume); private native void setVolumeNative(byte[] address, int volume); private native void setVolumeGroupNative(int groupId, int volume); private native void setVolumeGroupNative(int groupId, int volume); private native void muteNative(byte[] address); private native void muteGroupNative(int groupId); private native void unmuteNative(byte[] address); private native void unmuteGroupNative(int groupId); private native boolean getExtAudioOutVolumeOffsetNative(byte[] address, int externalOutputId); private native boolean getExtAudioOutVolumeOffsetNative(byte[] address, int externalOutputId); private native boolean setExtAudioOutVolumeOffsetNative(byte[] address, int externalOutputId, private native boolean setExtAudioOutVolumeOffsetNative(byte[] address, int externalOutputId, int offset); int offset); Loading
android/app/src/com/android/bluetooth/vc/VolumeControlService.java +98 −0 Original line number Original line Diff line number Diff line Loading @@ -582,6 +582,34 @@ public class VolumeControlService extends ProfileService { mVolumeControlNativeInterface.setVolumeGroup(groupId, volume); mVolumeControlNativeInterface.setVolumeGroup(groupId, volume); } } /** * {@hide} */ public void mute(BluetoothDevice device) { mVolumeControlNativeInterface.mute(device); } /** * {@hide} */ public void muteGroup(int groupId) { mVolumeControlNativeInterface.muteGroup(groupId); } /** * {@hide} */ public void unmute(BluetoothDevice device) { mVolumeControlNativeInterface.unmute(device); } /** * {@hide} */ public void unmuteGroup(int groupId) { mVolumeControlNativeInterface.unmuteGroup(groupId); } void handleVolumeControlChanged(BluetoothDevice device, int groupId, void handleVolumeControlChanged(BluetoothDevice device, int groupId, int volume, boolean mute, boolean isAutonomous) { int volume, boolean mute, boolean isAutonomous) { if (!isAutonomous) { if (!isAutonomous) { Loading Loading @@ -1113,6 +1141,76 @@ public class VolumeControlService extends ProfileService { } } } } @Override public void mute(BluetoothDevice device, AttributionSource source, SynchronousResultReceiver receiver) { try { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); Objects.requireNonNull(receiver, "receiver cannot be null"); VolumeControlService service = getService(source); if (service != null) { service.mute(device); } receiver.send(null); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void muteGroup(int groupId, AttributionSource source, SynchronousResultReceiver receiver) { try { Objects.requireNonNull(source, "source cannot be null"); Objects.requireNonNull(receiver, "receiver cannot be null"); VolumeControlService service = getService(source); if (service != null) { service.muteGroup(groupId); } receiver.send(null); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void unmute(BluetoothDevice device, AttributionSource source, SynchronousResultReceiver receiver) { try { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); Objects.requireNonNull(receiver, "receiver cannot be null"); VolumeControlService service = getService(source); if (service != null) { service.unmute(device); } receiver.send(null); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void unmuteGroup(int groupId, AttributionSource source, SynchronousResultReceiver receiver) { try { Objects.requireNonNull(source, "source cannot be null"); Objects.requireNonNull(receiver, "receiver cannot be null"); VolumeControlService service = getService(source); if (service != null) { service.unmuteGroup(groupId); } receiver.send(null); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override @Override public void registerCallback(IBluetoothVolumeControlCallback callback, public void registerCallback(IBluetoothVolumeControlCallback callback, AttributionSource source, SynchronousResultReceiver receiver) { AttributionSource source, SynchronousResultReceiver receiver) { Loading
system/binder/android/bluetooth/IBluetoothVolumeControl.aidl +10 −0 Original line number Original line Diff line number Diff line Loading @@ -52,6 +52,16 @@ oneway interface IBluetoothVolumeControl { @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void setVolumeGroup(int group_id, int volume, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); void setVolumeGroup(int group_id, int volume, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void mute(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void muteGroup(int group_id, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void unmute(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void unmuteGroup(int group_id, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") void registerCallback(in IBluetoothVolumeControlCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); void registerCallback(in IBluetoothVolumeControlCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") Loading