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

Commit a3c5cd49 authored by Sagar Verma's avatar Sagar Verma Committed by Linux Build Service Account
Browse files

Introduced Active device for volume updates and volume update in pause state

1.(a) For absolute volume change from DUT side the device which gets the volume
updates is 'active device'. In case of 2 headsets both supporting Absolute
volume (maintaining different volume granularity) in Multicast/SoftHand-off
scenario sending different volume updates to DUT simultaneously because of
DUT receiving different feedback from individual Headsets(old cached map value).
Hence we are maintaining only one device active at a time for these volume
updates.
(b) In non-multicast scenario we are making the device active on the basis of
their ConnectionState Change(single connection) and later A2dpAudioState change
if other device comes into picture(SoftHand-off case).
(c) In multicast scenario we are making the device active which is first one
to go for A2dpAudioState change. If second device connects then we disable the
support of absolute volume. If later on any device disconnects we make active
device to other one which is left in the connection.

2. Changed send update in volume (DUT triggered) to a check based on number of
connected devices instead of playing devices for getting volume updates.

CRs-Fixed: 1046431
Change-Id: I00e00bfcb160e02669884cf4207565e52589a599
parent 72c97ec3
Loading
Loading
Loading
Loading
+154 −115
Original line number Diff line number Diff line
@@ -295,6 +295,7 @@ public final class Avrcp {
        private boolean isMusicAppResponsePending;
        private boolean isBrowsingSupported;
        private boolean isAbsoluteVolumeSupportingDevice;
        private boolean isActiveDevice;

        private int mRemoteVolume;
        private int mLastRemoteVolume;
@@ -335,6 +336,7 @@ public final class Avrcp {
            isMusicAppResponsePending = false;
            isBrowsingSupported = false;
            isAbsoluteVolumeSupportingDevice = false;
            isActiveDevice = false;
            mRemoteVolume = -1;
            mInitialRemoteVolume = -1;
            mLastRemoteVolume = -1;
@@ -1211,6 +1213,12 @@ public final class Avrcp {
                                                 msg.arg2 == AVRC_RSP_CHANGED ||
                                                 msg.arg2 == AVRC_RSP_INTERIM)) {
                    /* If the volume has successfully changed */
                    if (!deviceFeatures[deviceIndex].isActiveDevice &&
                           (msg.arg2 == AVRC_RSP_CHANGED || msg.arg2 == AVRC_RSP_INTERIM)) {
                        Log.d(TAG, "Do not change volume from an inactive device");
                        break;
                    }

                    deviceFeatures[deviceIndex].mLocalVolume = volIndex;
                    if (deviceFeatures[deviceIndex].mLastLocalVolume != -1
                        && msg.arg2 == AVRC_RSP_ACCEPT) {
@@ -1267,18 +1275,18 @@ public final class Avrcp {
                    if (DEBUG) Log.v(TAG, "ignore MESSAGE_ADJUST_VOLUME");
                    break;
                }
                List<BluetoothDevice> playingDevice = mA2dpService.getA2dpPlayingDevice();

                if (mA2dpService.isMulticastFeatureEnabled() &&
                        areMultipleDevicesConnected()) {
                    if (DEBUG) Log.v(TAG, "Volume change not entertained as multicast is enabled & multiple devices are connected");
                    break;
                }
                if (DEBUG)
                    Log.d(TAG, "MESSAGE_ADJUST_VOLUME: direction=" + msg.arg1);
                for (int i = 0; i < playingDevice.size(); i++) {
                    Log.v(TAG, "event for device address " +
                            playingDevice.get(i).getAddress());
                    deviceIndex = getIndexForDevice(playingDevice.get(i));
                    if (deviceIndex == INVALID_DEVICE_INDEX) {
                        Log.e(TAG,"Unkown playing device");
                        sendAdjustVolume(msg.arg1);
                        continue;
                    }
                for (int i = 0; i < maxAvrcpConnections; i++) {
                    if (deviceFeatures[i].mCurrentDevice != null &&
                            deviceFeatures[i].isActiveDevice) {
                          deviceIndex = i;
                          if ((deviceFeatures[deviceIndex].mVolCmdAdjustInProgress) ||
                                (deviceFeatures[deviceIndex].mVolCmdSetInProgress)){
                          if (DEBUG)
@@ -1313,7 +1321,6 @@ public final class Avrcp {
                              synchronized (deviceFeatures[deviceIndex].mVolumeMapping) {
                                  j = deviceFeatures[deviceIndex].mVolumeMapping.get(targetVolIndex);
                           }

                           if (j != null) {
                                /* if we already know this volume mapping, use it */
                               setVol = j.byteValue();
@@ -1324,14 +1331,12 @@ public final class Avrcp {
                               }
                               if (DEBUG) Log.d(TAG, "set volume from mapping " + targetVolIndex + "-" + setVol);
                           }

                           if (setVol == -1) {
                               /* otherwise use phone steps */
                               setVol = Math.min(AVRCP_MAX_VOL,
                                        convertToAvrcpVolume(Math.max(0, targetVolIndex)));
                               if (DEBUG) Log.d(TAG, "set volume from local volume "+ targetVolIndex+"-"+ setVol);
                           }

                           boolean isSetVol = setVolumeNative(setVol ,
                                   getByteAddress(deviceFeatures[deviceIndex].mCurrentDevice));
                           if (isSetVol) {
@@ -1348,6 +1353,7 @@ public final class Avrcp {
                             Log.e(TAG, "Unknown direction in MESSAGE_ADJUST_VOLUME");
                        }
                    }
                }
                break;
            }
            case MESSAGE_SET_ABSOLUTE_VOLUME:
@@ -1356,23 +1362,22 @@ public final class Avrcp {
                    if (DEBUG) Log.v(TAG, "ignore MESSAGE_SET_ABSOLUTE_VOLUME");
                    break;
                }
                if (mA2dpService.isMulticastFeatureEnabled() &&
                        areMultipleDevicesConnected()) {
                    if (DEBUG) Log.v(TAG, "Volume change not entertained as multicast is enabled & multiple devices are connected");
                    break;
                }
                if (DEBUG)
                    Log.v(TAG, "MESSAGE_SET_ABSOLUTE_VOLUME");
                List<BluetoothDevice> playingDevice = mA2dpService.getA2dpPlayingDevice();
                if (playingDevice.size() == 0) {
                    Log.e(TAG,"Volume cmd without a2dp playing");
                }

                int avrcpVolume = convertToAvrcpVolume(msg.arg1);
                avrcpVolume = Math.min(AVRCP_MAX_VOL, Math.max(0, avrcpVolume));
                for (int i = 0; i < playingDevice.size(); i++) {
                    deviceIndex = getIndexForDevice(playingDevice.get(i));
                    if (deviceIndex == INVALID_DEVICE_INDEX) {
                        Log.e(TAG,"Unkown playing device for SetAbsVol");
                        sendSetAbsoluteVolume(msg.arg1);
                        continue;
                    }
                    Log.v(TAG, "event for device address " +
                            playingDevice.get(i).getAddress());
                for (int i = 0; i < maxAvrcpConnections; i++) {
                    if (deviceFeatures[i].mCurrentDevice != null &&
                            deviceFeatures[i].isActiveDevice) {

                          deviceIndex = i;

                          if ((deviceFeatures[deviceIndex].mVolCmdSetInProgress) ||
                                (deviceFeatures[deviceIndex].mVolCmdAdjustInProgress)){
                              if (DEBUG)
@@ -1398,6 +1403,7 @@ public final class Avrcp {
                            if (DEBUG) Log.d(TAG, "setVolumeNative failed");
                         }
                    }
                }
                break;
            }
            case MESSAGE_ABS_VOL_TIMEOUT:
@@ -1617,7 +1623,6 @@ public final class Avrcp {

    private void updateA2dpAudioState(int state, BluetoothDevice device) {
        boolean isPlaying = (state == BluetoothA2dp.STATE_PLAYING);

        Log.v(TAG,"updateA2dpAudioState");
        if ((isPlaying) && !mAudioManager.isMusicActive()) {
            /* Play state to be updated only for music streaming, not touchtone */
@@ -1629,14 +1634,21 @@ public final class Avrcp {
                    (device.equals(deviceFeatures[i].mCurrentDevice))) {
                PlaybackState.Builder builder = new PlaybackState.Builder();
                if (isPlaying) {
                    deviceFeatures[i].isActiveDevice = true;
                    builder.setState(PlaybackState.STATE_PLAYING,
                                     PlaybackState.PLAYBACK_POSITION_UNKNOWN, 1.0f);
                    Log.v(TAG,"updateA2dpAudioState: Active device is set true at index = " + i);
                } else {
                    builder.setState(PlaybackState.STATE_PAUSED,
                                     PlaybackState.PLAYBACK_POSITION_UNKNOWN, 0.0f);
                }
                updatePlaybackState(builder.build(), device);
                break;
            }

            if (!device.equals(deviceFeatures[i].mCurrentDevice) &&
                    deviceFeatures[i].isActiveDevice && isPlaying) {
                deviceFeatures[i].isActiveDevice = false;
                Log.v(TAG,"updateA2dpAudioState: Active device is set false at index = " + i);
            }
        }
    }
@@ -4822,6 +4834,11 @@ public final class Avrcp {
     * returns true only when both playing devices support absolute volume
     */
    public boolean isAbsoluteVolumeSupported() {
        if (mA2dpService.isMulticastFeatureEnabled() &&
                areMultipleDevicesConnected()) {
            if (DEBUG) Log.v(TAG, "isAbsoluteVolumeSupported : Absolute volume false multicast is enabled & multiple devices are connected");
            return false;
        }
        List<Byte> absVolumeSupported = new ArrayList<Byte>();
        for (int i = 0; i < maxAvrcpConnections; i++) {
            if (deviceFeatures[i].mCurrentDevice != null) {
@@ -5225,6 +5242,7 @@ public final class Avrcp {
        for (int i = 0; i < maxAvrcpConnections; i++ ) {
            if (deviceFeatures[i].mCurrentDevice == null) {
                deviceFeatures[i].mCurrentDevice = device;
                deviceFeatures[i].isActiveDevice = true;
                /*Playstate is explicitly updated here to take care of cases
                        where play state update is missed because of that happening
                        even before Avrcp connects*/
@@ -5232,9 +5250,19 @@ public final class Avrcp {
                Log.i(TAG,"play status updated on Avrcp connection as: " +
                                                    mCurrentPlayerState);
                Log.i(TAG,"device added at " + i);
                Log.i(TAG,"Active device set to true at index =  " + i);
                break;
            }
        }

        for (int i = 0; i < maxAvrcpConnections; i++ ) {
            if (deviceFeatures[i].mCurrentDevice != null &&
                    !(deviceFeatures[i].mCurrentDevice.equals(device)) &&
                    deviceFeatures[i].isActiveDevice) {
                deviceFeatures[i].isActiveDevice = false;
                Log.i(TAG,"Active device set to false at index =  " + i);
            }
        }
    }

    public boolean isAvrcpConnected() {
@@ -5287,6 +5315,7 @@ public final class Avrcp {
        deviceFeatures[index].mMediaUri = Uri.EMPTY;
        deviceFeatures[index].isMusicAppResponsePending = false;
        deviceFeatures[index].isBrowsingSupported = false;
        deviceFeatures[index].isActiveDevice = false;
        deviceFeatures[index].isAbsoluteVolumeSupportingDevice = false;
    }
    /**
@@ -5297,6 +5326,7 @@ public final class Avrcp {
            if (deviceFeatures[i].mCurrentDevice !=null &&
                    deviceFeatures[i].mCurrentDevice.equals(device)) {
                // initiate cleanup for all variables;

                Log.i(TAG,"Device removed is " + device);
                Log.i(TAG,"removed at " + i);
                deviceFeatures[i].mCurrentDevice = null;
@@ -5308,7 +5338,16 @@ public final class Avrcp {
                    Log.i(TAG,"clearing mBrowserDevice on disconnect");
                    mBrowserDevice = null;
                }
                break;
            }
            /* Multicast scenario both abs vol supported
               Active device got disconnected so make other
               device which is left supporting absolute
               volume as active device
            */
            if (deviceFeatures[i].mCurrentDevice != null &&
                    !(deviceFeatures[i].mCurrentDevice.equals(device))) {
                deviceFeatures[i].isActiveDevice = true;
                Log.i(TAG,"setAvrcpDisconnectedDevice : Active device changed to index = " + i);
            }
        }
        mAudioManager.avrcpSupportsAbsoluteVolume(device.getAddress(),