summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoseph Pirozzo <pirozzoj@google.com>2019-06-24 17:08:50 -0700
committerJoseph Pirozzo <pirozzoj@google.com>2020-03-16 18:45:11 +0000
commit7c3a74093b155ffea85038c75621fb73a1a46b36 (patch)
tree2cf7599a9c75ca23e12c0ed66519e7cad77a671e
parent4d931c8105fd62a7e2290f2e0e37d601fd0942d2 (diff)
downloadandroid_packages_apps_Bluetooth-7c3a74093b155ffea85038c75621fb73a1a46b36.tar.gz
android_packages_apps_Bluetooth-7c3a74093b155ffea85038c75621fb73a1a46b36.tar.bz2
android_packages_apps_Bluetooth-7c3a74093b155ffea85038c75621fb73a1a46b36.zip
AVRCP Controller AbsoluteVolumeNotification
Update AbsoluteVolumeNotification request to properly respond to requests based upon the Fixed vs Dynamic volume levels. Bug: 129478624 Test: atest com.android.bluetooth.avrcpcontroller.AvrcpControllerStateMachineTest#testRegisterAbsVolumeNotification Change-Id: Ic9b745641a84712c005d40ecec50e55e9684d3ef (cherry picked from commit 8fd119d8a27d42e09a90280020925859fd0a1678) Merged-In: Ic9b745641a84712c005d40ecec50e55e9684d3ef Change-Id: I1212a70ab84e3aed926bcfcac04dc62efed4b489
-rw-r--r--src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java90
-rw-r--r--tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java20
2 files changed, 84 insertions, 26 deletions
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
index 7a6c54126..83ba8505d 100644
--- a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
@@ -94,7 +94,14 @@ class AvrcpControllerStateMachine extends StateMachine {
*/
private static final int ABS_VOL_BASE = 127;
+ /*
+ * Notification types for Avrcp protocol JNI.
+ */
+ private static final byte NOTIFICATION_RSP_TYPE_INTERIM = 0x00;
+ private static final byte NOTIFICATION_RSP_TYPE_CHANGED = 0x01;
+
private final AudioManager mAudioManager;
+ private final boolean mIsVolumeFixed;
protected final BluetoothDevice mDevice;
protected final byte[] mDeviceAddress;
@@ -113,6 +120,7 @@ class AvrcpControllerStateMachine extends StateMachine {
private int mAddressedPlayerId = -1;
private SparseArray<AvrcpPlayer> mAvailablePlayerList = new SparseArray<AvrcpPlayer>();
private int mVolumeChangedNotificationsToIgnore = 0;
+ private int mVolumeNotificationLabel = -1;
GetFolderList mGetFolderList = null;
@@ -142,6 +150,7 @@ class AvrcpControllerStateMachine extends StateMachine {
mGetFolderList = new GetFolderList();
addState(mGetFolderList, mConnected);
mAudioManager = (AudioManager) service.getSystemService(Context.AUDIO_SERVICE);
+ mIsVolumeFixed = mAudioManager.isVolumeFixed();
setInitialState(mDisconnected);
}
@@ -311,7 +320,14 @@ class AvrcpControllerStateMachine extends StateMachine {
removeMessages(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT);
sendMessageDelayed(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT,
ABS_VOL_TIMEOUT_MILLIS);
- setAbsVolume(msg.arg1, msg.arg2);
+ handleAbsVolumeRequest(msg.arg1, msg.arg2);
+ return true;
+
+ case MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION:
+ mVolumeNotificationLabel = msg.arg1;
+ mService.sendRegisterAbsVolRspNative(mDeviceAddress,
+ NOTIFICATION_RSP_TYPE_INTERIM,
+ getAbsVolume(), mVolumeNotificationLabel);
return true;
case MESSAGE_GET_FOLDER_ITEMS:
@@ -587,24 +603,9 @@ class AvrcpControllerStateMachine extends StateMachine {
}
break;
- case CONNECT:
- case DISCONNECT:
- case MSG_AVRCP_PASSTHRU:
- case MESSAGE_PROCESS_SET_ABS_VOL_CMD:
- case MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION:
- case MESSAGE_PROCESS_TRACK_CHANGED:
- case MESSAGE_PROCESS_PLAY_POS_CHANGED:
- case MESSAGE_PROCESS_PLAY_STATUS_CHANGED:
- case MESSAGE_PROCESS_VOLUME_CHANGED_NOTIFICATION:
- case MESSAGE_PLAY_ITEM:
- case MESSAGE_PROCESS_ADDRESSED_PLAYER_CHANGED:
+ default:
// All of these messages should be handled by parent state immediately.
return false;
-
- default:
- logD(STATE_TAG + " deferring message " + msg.what
- + " to connected!");
- deferMessage(msg);
}
return true;
}
@@ -717,23 +718,60 @@ class AvrcpControllerStateMachine extends StateMachine {
}
}
+ /**
+ * Handle a request to align our local volume with the volume of a remote device. If
+ * we're assuming the source volume is fixed then a response of ABS_VOL_MAX will always be
+ * sent and no volume adjustment action will be taken on the sink side.
+ *
+ * @param absVol A volume level based on a domain of [0, ABS_VOL_MAX]
+ * @param label Volume notification label
+ */
+ private void handleAbsVolumeRequest(int absVol, int label) {
+ logD("handleAbsVolumeRequest: absVol = " + absVol + ", label = " + label);
+ if (mIsVolumeFixed) {
+ logD("Source volume is assumed to be fixed, responding with max volume");
+ absVol = ABS_VOL_BASE;
+ } else {
+ mVolumeChangedNotificationsToIgnore++;
+ removeMessages(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT);
+ sendMessageDelayed(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT,
+ ABS_VOL_TIMEOUT_MILLIS);
+ setAbsVolume(absVol);
+ }
+ mService.sendAbsVolRspNative(mDeviceAddress, absVol, label);
+ }
+
+ /**
+ * Align our volume with a requested absolute volume level
+ *
+ * @param absVol A volume level based on a domain of [0, ABS_VOL_MAX]
+ */
+ private void setAbsVolume(int absVol) {
+ int maxLocalVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ int curLocalVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+ int reqLocalVolume = (maxLocalVolume * absVol) / ABS_VOL_BASE;
+ logD("setAbsVolme: absVol = " + absVol + ", reqLocal = " + reqLocalVolume
+ + ", curLocal = " + curLocalVolume + ", maxLocal = " + maxLocalVolume);
- private void setAbsVolume(int absVol, int label) {
- int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
- int currIndex = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
- int newIndex = (maxVolume * absVol) / ABS_VOL_BASE;
- logD(" setAbsVolume =" + absVol + " maxVol = " + maxVolume
- + " cur = " + currIndex + " new = " + newIndex);
/*
* In some cases change in percentage is not sufficient enough to warrant
* change in index values which are in range of 0-15. For such cases
* no action is required
*/
- if (newIndex != currIndex) {
- mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, newIndex,
+ if (reqLocalVolume != curLocalVolume) {
+ mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, reqLocalVolume,
AudioManager.FLAG_SHOW_UI);
}
- mService.sendAbsVolRspNative(mDeviceAddress, absVol, label);
+ }
+
+ private int getAbsVolume() {
+ if (mIsVolumeFixed) {
+ return ABS_VOL_BASE;
+ }
+ int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ int currIndex = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+ int newIndex = (currIndex * ABS_VOL_BASE) / maxVolume;
+ return newIndex;
}
MediaSessionCompat.Callback mSessionCallbacks = new MediaSessionCompat.Callback() {
diff --git a/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java b/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java
index 0ebb31e9e..4c77e0afa 100644
--- a/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java
+++ b/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java
@@ -23,6 +23,7 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
+import android.media.AudioManager;
import android.os.Looper;
import android.support.v4.media.session.MediaControllerCompat;
@@ -70,6 +71,8 @@ public class AvrcpControllerStateMachineTest {
@Mock
private AdapterService mAdapterService;
@Mock
+ private AudioManager mAudioManager;
+ @Mock
private AvrcpControllerService mAvrcpControllerService;
AvrcpControllerStateMachine mAvrcpStateMachine;
@@ -90,6 +93,11 @@ public class AvrcpControllerStateMachineTest {
TestUtils.setAdapterService(mAdapterService);
TestUtils.startService(mServiceRule, AvrcpControllerService.class);
doReturn(mTargetContext.getResources()).when(mAvrcpControllerService).getResources();
+ doReturn(15).when(mAudioManager).getStreamMaxVolume(anyInt());
+ doReturn(8).when(mAudioManager).getStreamVolume(anyInt());
+ doReturn(true).when(mAudioManager).isVolumeFixed();
+ doReturn(mAudioManager).when(mAvrcpControllerService)
+ .getSystemService(Context.AUDIO_SERVICE);
// This line must be called to make sure relevant objects are initialized properly
mAdapter = BluetoothAdapter.getDefaultAdapter();
@@ -525,6 +533,18 @@ public class AvrcpControllerStateMachineTest {
}
/**
+ * Test that Absolute Volume Registration is working
+ */
+ @Test
+ public void testRegisterAbsVolumeNotification() {
+ setUpConnectedState(true, true);
+ mAvrcpStateMachine.sendMessage(
+ AvrcpControllerStateMachine.MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION);
+ verify(mAvrcpControllerService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1))
+ .sendRegisterAbsVolRspNative(any(), anyByte(), eq(127), anyInt());
+ }
+
+ /**
* Setup Connected State
*
* @return number of times mAvrcpControllerService.sendBroadcastAsUser() has been invoked