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

Commit 9c4565b2 authored by Ajay Panicker's avatar Ajay Panicker Committed by Myles Watson
Browse files

Use lowercase bdaddr and fix improper string compare in Volume Manager

Currently Bluetooth Native code uses lowercase Bluetooth addresses.
Instead have AvrcpNativeInterface.java convert these to uppercase since
this is what BluetoothDevice.java uses. This is so that the addresses
used by the volume manager will match in case. Also fix an improper
comparison in AvrcpVolumeManager.java.

Bug: 30602783
Test: See that Sony MDR-1RBT connects after being switched to the active
device and the remembered volume is correctly restored.

Change-Id: I84df84586d3d1ad846a9ff8e88bc28b772c0b87b
parent 58240d26
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -186,11 +186,13 @@ public class AvrcpNativeInterface {
    }

    void setActiveDevice(String bdaddr) {
        bdaddr = bdaddr.toUpperCase();
        d("setActiveDevice: bdaddr=" + bdaddr);
        mAvrcpService.setActiveDevice(bdaddr);
    }

    void deviceConnected(String bdaddr, boolean absoluteVolume) {
        bdaddr = bdaddr.toUpperCase();
        d("deviceConnected: bdaddr=" + bdaddr + " absoluteVolume=" + absoluteVolume);
        if (mAvrcpService == null) {
            Log.w(TAG, "deviceConnected: AvrcpTargetService is null");
@@ -201,6 +203,7 @@ public class AvrcpNativeInterface {
    }

    void deviceDisconnected(String bdaddr) {
        bdaddr = bdaddr.toUpperCase();
        d("deviceDisconnected: bdaddr=" + bdaddr);
        if (mAvrcpService == null) {
            Log.w(TAG, "deviceDisconnected: AvrcpTargetService is null");
+1 −2
Original line number Diff line number Diff line
@@ -296,7 +296,7 @@ public class AvrcpTargetService extends ProfileService {
    void setActiveDevice(String address) {
        Log.i(TAG, "setActiveDevice: address=" + address);
        BluetoothDevice d =
                BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address.toUpperCase());
                BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
        if (d == null) {
            Log.wtfStack(TAG, "setActiveDevice: could not find device with address " + address);
        }
@@ -320,7 +320,6 @@ public class AvrcpTargetService extends ProfileService {
        }

        mVolumeManager.dump(sb);
        sb.append("\n");
    }

    private static class AvrcpTargetBinder extends IBluetoothAvrcpTarget.Stub
+49 −45
Original line number Diff line number Diff line
@@ -44,21 +44,58 @@ class AvrcpVolumeManager {
    String mCurrentDeviceAddr = "";
    boolean mAbsoluteVolumeSupported = false;

    int avrcpToSystemVolume(int avrcpVolume) {
    static int avrcpToSystemVolume(int avrcpVolume) {
        return (int) Math.floor((double) avrcpVolume * sDeviceMaxVolume / AVRCP_MAX_VOL);
    }

    int systemToAvrcpVolume(int deviceVolume) {
    static int systemToAvrcpVolume(int deviceVolume) {
        int avrcpVolume = (int) Math.floor((double) deviceVolume
                * AVRCP_MAX_VOL / sDeviceMaxVolume);
        if (avrcpVolume > 127) avrcpVolume = 127;
        return avrcpVolume;
    }

    SharedPreferences getVolumeMap() {
    private SharedPreferences getVolumeMap() {
        return mContext.getSharedPreferences(VOLUME_MAP, Context.MODE_PRIVATE);
    }

    private int getVolume(String bdaddr, int defaultValue) {
        if (!mVolumeMap.containsKey(bdaddr)) {
            Log.w(TAG, "getVolume: Couldn't find volume preference for device: " + bdaddr);
            return defaultValue;
        }

        return mVolumeMap.get(bdaddr);
    }

    private void switchVolumeDevice(String bdaddr) {
        // Inform the audio manager that the device has changed
        mAudioManager.avrcpSupportsAbsoluteVolume(bdaddr, mDeviceMap.get(bdaddr));

        // Get the current system volume and try to get the preference volume
        int currVolume = mAudioManager.getStreamVolume(STREAM_MUSIC);
        int savedVolume = getVolume(bdaddr, currVolume);

        // If the preference volume isn't equal to the current stream volume then that means
        // we had a stored preference.
        if (DEBUG) {
            Log.d(TAG, "switchVolumeDevice: currVolume=" + currVolume
                    + " savedVolume=" + savedVolume);
        }
        if (savedVolume != currVolume) {
            Log.i(TAG, "switchVolumeDevice: restoring volume level " + savedVolume);
            mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, savedVolume,
                    AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_BLUETOOTH_ABS_VOLUME);
        }

        // If absolute volume for the device is supported, set the volume for the device
        if (mDeviceMap.get(bdaddr)) {
            int avrcpVolume = systemToAvrcpVolume(savedVolume);
            Log.i(TAG, "switchVolumeDevice: Updating device volume: avrcpVolume=" + avrcpVolume);
            mNativeInterface.sendVolumeChanged(avrcpVolume);
        }
    }

    AvrcpVolumeManager(Context context, AudioManager audioManager,
            AvrcpNativeInterface nativeInterface) {
        mContext = context;
@@ -66,7 +103,7 @@ class AvrcpVolumeManager {
        mNativeInterface = nativeInterface;
        sDeviceMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

        // Load the volume map into a hash map since shared preferences are slow
        // Load the volume map into a hash map since shared preferences are slow to poll and update
        Map<String, ?> allKeys = getVolumeMap().getAll();
        for (Map.Entry<String, ?> entry : allKeys.entrySet()) {
            String key = entry.getKey();
@@ -77,15 +114,6 @@ class AvrcpVolumeManager {
        }
    }

    int getVolume(String bdaddr, int defaultValue) {
        if (!mVolumeMap.containsKey(bdaddr)) {
            Log.w(TAG, "getVolume: Couldn't find volume preference for device: " + bdaddr);
            return defaultValue;
        }

        return mVolumeMap.get(bdaddr);
    }

    void storeVolume() {
        SharedPreferences.Editor pref = getVolumeMap().edit();
        int storeVolume =  mAudioManager.getStreamVolume(STREAM_MUSIC);
@@ -101,18 +129,18 @@ class AvrcpVolumeManager {
            Log.d(TAG, "deviceConnected: bdaddr=" + bdaddr + " absoluteVolume=" + absoluteVolume);
        }

        mDeviceMap.put(bdaddr.toUpperCase(), absoluteVolume);
        mDeviceMap.put(bdaddr, absoluteVolume);

        // AVRCP features lookup has completed after the device became active. Switch to the new
        // device now.
        if (bdaddr == mCurrentDeviceAddr) {
        if (bdaddr.equals(mCurrentDeviceAddr)) {
            switchVolumeDevice(bdaddr);
        }
    }

    void volumeDeviceSwitched(String bdaddr) {
        if (DEBUG) {
            Log.d(TAG, "activeDeviceChanged: mCurrentDeviceAddr=" + mCurrentDeviceAddr
            Log.d(TAG, "volumeDeviceSwitched: mCurrentDeviceAddr=" + mCurrentDeviceAddr
                    + " bdaddr=" + bdaddr);
        }

@@ -137,53 +165,29 @@ class AvrcpVolumeManager {
        // device supports absolute volume. Defer switching the device until AVRCP returns the
        // info.
        if (!mDeviceMap.containsKey(bdaddr)) {
            Log.w(TAG, "Device isn't connected: " + bdaddr);
            Log.w(TAG, "volumeDeviceSwitched: Device isn't connected: " + bdaddr);
            return;
        }

        switchVolumeDevice(bdaddr);
    }

    void switchVolumeDevice(String bdaddr) {
        // Inform the audio manager that the device has changed
        mAudioManager.avrcpSupportsAbsoluteVolume(bdaddr, mDeviceMap.get(bdaddr));

        // Get the current system volume and try to get the preference volume
        int currVolume = mAudioManager.getStreamVolume(STREAM_MUSIC);
        int savedVolume = getVolume(bdaddr, currVolume);

        // If the preference volume isn't equal to the current stream volume then that means
        // we had a stored preference.
    void deviceDisconnected(String bdaddr) {
        if (DEBUG) {
            Log.d(TAG, "activeDeviceChanged: currVolume=" + currVolume
                    + " savedVolume=" + savedVolume);
        }
        if (savedVolume != currVolume) {
            mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, savedVolume,
                    AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_BLUETOOTH_ABS_VOLUME);
        }

        // If absolute volume for the device is supported, set the volume for the device
        if (mDeviceMap.get(bdaddr)) {
            int avrcpVolume = systemToAvrcpVolume(savedVolume);
            Log.e(TAG, "activeDeviceChanged: Updating device volume: avrcpVolume=" + avrcpVolume);
            mNativeInterface.sendVolumeChanged(avrcpVolume);
        }
            Log.d(TAG, "deviceDisconnected: bdaddr=" + bdaddr);
        }

    void deviceDisconnected(String bdaddr) {
        Log.e(TAG, "deviceDisconnected: bdaddr=" + bdaddr);
        mDeviceMap.remove(bdaddr);
    }

    public void dump(StringBuilder sb) {
        sb.append("Bluetooth Device Volume Map:\n");
        sb.append("  Device Address    : Volume\n");
        Map<String, ?> allKeys = getVolumeMap().getAll();
        for (Map.Entry<String, ?> entry : allKeys.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value instanceof Integer) {
                sb.append("    " + key + " - " + (Integer) value + "\n");
                sb.append("  " + key + " : " + (Integer) value + "\n");
                mVolumeMap.put(key, (Integer) value);
            }
        }