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

Commit e6e080ff authored by Pavlin Radoslavov's avatar Pavlin Radoslavov
Browse files

Use proper string formatting for the "Active device" string

* The hard-coded "active" / "active(media)" / "active(phone)" strings
  are removed and replaced with proper XML-based string formatting.
* Added the appropriate strings for Bluetooth Audio Active Device status:
  "bluetooth_audio_active_device_summaries". For now those strings are
  marked as translatable="false" until the actual UI is finalized.
* Updated all "bluetooth_connected*" strings to include the new
  "active_device" component.
* Added unit tests for the new "active" strings.
  Also, updated existing unit tests to check the getConnectionSummary()
  strings by comparing against strings embedded within the unit tests.

Bug: 72317067
Test: Unit tests added: make RunSettingsLibRoboTests -j40
      Manual: two headsets and switching the active device
Change-Id: Ide639b5dfb45c1db8114155240f193249aeaf3be
parent a20833c0
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -250,6 +250,19 @@
        <item>Best Effort (Adaptive Bit Rate)</item>
    </string-array>

    <!-- TODO: Enable for translation per b/73007419 -->
    <!-- Summaries for Bluetooth Audio Active Device status. [CHAR LIMIT=50]-->
    <string-array name="bluetooth_audio_active_device_summaries" translatable="false" >
        <!-- Status message when the device is not Active. -->
        <item></item>
        <!-- Status message when the device is Active for Media and Phone. -->
        <item>, active</item>
        <!-- Status message when the device is Active for Media only. -->
        <item>, active(media)</item>
        <!-- Status message when the device is Active for Phone only. -->
        <item>, active(phone)</item>
    </string-array>

    <!-- Titles for logd limit size selection preference. [CHAR LIMIT=14] -->
    <string-array name="select_logd_size_titles">
        <item>Off</item>
+9 −9
Original line number Diff line number Diff line
@@ -128,27 +128,27 @@
     <!-- Bluetooth settings.  Message when connecting to a device -->
    <string name="bluetooth_connecting">Connecting\u2026</string>
    <!-- Bluetooth settings.  Message when connected to a device. [CHAR LIMIT=40] -->
    <string name="bluetooth_connected">Connected</string>
    <string name="bluetooth_connected">Connected<xliff:g id="active_device">%1$s</xliff:g></string>
    <!--Bluetooth settings screen, summary text under individual Bluetooth devices when pairing -->
    <string name="bluetooth_pairing">Pairing\u2026</string>

    <!-- Bluetooth settings.  Message when connected to a device, except for phone audio. [CHAR LIMIT=40] -->
    <string name="bluetooth_connected_no_headset">Connected (no phone)</string>
    <string name="bluetooth_connected_no_headset">Connected (no phone)<xliff:g id="active_device">%1$s</xliff:g></string>
    <!-- Bluetooth settings.  Message when connected to a device, except for media audio. [CHAR LIMIT=40] -->
    <string name="bluetooth_connected_no_a2dp">Connected (no media)</string>
    <string name="bluetooth_connected_no_a2dp">Connected (no media)<xliff:g id="active_device">%1$s</xliff:g></string>
    <!-- Bluetooth settings.  Message when connected to a device, except for map. [CHAR LIMIT=40] -->
    <string name="bluetooth_connected_no_map">Connected (no message access)</string>
    <string name="bluetooth_connected_no_map">Connected (no message access)<xliff:g id="active_device">%1$s</xliff:g></string>
    <!-- Bluetooth settings.  Message when connected to a device, except for phone/media audio. [CHAR LIMIT=40] -->
    <string name="bluetooth_connected_no_headset_no_a2dp">Connected (no phone or media)</string>
    <string name="bluetooth_connected_no_headset_no_a2dp">Connected (no phone or media)<xliff:g id="active_device">%1$s</xliff:g></string>

    <!-- Bluetooth settings.  Message when connected to a device, showing remote device battery level. [CHAR LIMIT=NONE] -->
    <string name="bluetooth_connected_battery_level">Connected, battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
    <string name="bluetooth_connected_battery_level">Connected, battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g><xliff:g id="active_device">%2$s</xliff:g></string>
    <!-- Bluetooth settings.  Message when connected to a device, except for phone audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
    <string name="bluetooth_connected_no_headset_battery_level">Connected (no phone), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
    <string name="bluetooth_connected_no_headset_battery_level">Connected (no phone), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g><xliff:g id="active_device">%2$s</xliff:g></string>
    <!-- Bluetooth settings.  Message when connected to a device, except for media audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
    <string name="bluetooth_connected_no_a2dp_battery_level">Connected (no media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
    <string name="bluetooth_connected_no_a2dp_battery_level">Connected (no media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g><xliff:g id="active_device">%2$s</xliff:g></string>
    <!-- Bluetooth settings.  Message when connected to a device, except for phone/media audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level">Connected (no phone or media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level">Connected (no phone or media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g><xliff:g id="active_device">%2$s</xliff:g></string>

    <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the A2DP profile. -->
    <string name="bluetooth_profile_a2dp">Media audio</string>
+18 −23
Original line number Diff line number Diff line
@@ -940,60 +940,55 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
                    com.android.settingslib.Utils.formatPercentage(batteryLevel);
        }

        // TODO: A temporary workaround solution using string description the device is active.
        // Issue tracked by b/72317067 .
        // An alternative solution would be visual indication.
        // Intentionally not adding the strings to strings.xml for now:
        //  1) If this is just a short-term solution, no need to waste translation effort
        //  2) The number of strings with all possible combinations becomes enormously large.
        // If string description becomes part of the final solution, we MUST NOT
        // concatenate the strings here: this does not translate well.
        String activeString = null;
        // Prepare the string for the Active Device summary
        String[] activeDeviceStringsArray = mContext.getResources().getStringArray(
                R.array.bluetooth_audio_active_device_summaries);
        String activeDeviceString = activeDeviceStringsArray[0];  // Default value: not active
        if (mIsActiveDeviceA2dp && mIsActiveDeviceHeadset) {
            activeString = ", active";
            activeDeviceString = activeDeviceStringsArray[1];     // Active for Media and Phone
        } else {
            if (mIsActiveDeviceA2dp) {
                activeString = ", active(media)";
                activeDeviceString = activeDeviceStringsArray[2]; // Active for Media only
            }
            if (mIsActiveDeviceHeadset) {
                activeString = ", active(phone)";
                activeDeviceString = activeDeviceStringsArray[3]; // Active for Phone only
            }
        }
        if (activeString == null) activeString = "";

        if (profileConnected) {
            if (a2dpNotConnected && hfpNotConnected) {
                if (batteryLevelPercentageString != null) {
                    return mContext.getString(
                            R.string.bluetooth_connected_no_headset_no_a2dp_battery_level,
                            batteryLevelPercentageString) + activeString;
                            batteryLevelPercentageString, activeDeviceString);
                } else {
                    return mContext.getString(R.string.bluetooth_connected_no_headset_no_a2dp) +
                        activeString;
                    return mContext.getString(R.string.bluetooth_connected_no_headset_no_a2dp,
                            activeDeviceString);
                }

            } else if (a2dpNotConnected) {
                if (batteryLevelPercentageString != null) {
                    return mContext.getString(R.string.bluetooth_connected_no_a2dp_battery_level,
                            batteryLevelPercentageString) + activeString;
                            batteryLevelPercentageString, activeDeviceString);
                } else {
                    return mContext.getString(R.string.bluetooth_connected_no_a2dp) + activeString;
                    return mContext.getString(R.string.bluetooth_connected_no_a2dp,
                            activeDeviceString);
                }

            } else if (hfpNotConnected) {
                if (batteryLevelPercentageString != null) {
                    return mContext.getString(R.string.bluetooth_connected_no_headset_battery_level,
                            batteryLevelPercentageString) + activeString;
                            batteryLevelPercentageString, activeDeviceString);
                } else {
                    return mContext.getString(R.string.bluetooth_connected_no_headset)
                          + activeString;
                    return mContext.getString(R.string.bluetooth_connected_no_headset,
                            activeDeviceString);
                }
            } else {
                if (batteryLevelPercentageString != null) {
                    return mContext.getString(R.string.bluetooth_connected_battery_level,
                            batteryLevelPercentageString) + activeString;
                            batteryLevelPercentageString, activeDeviceString);
                } else {
                    return mContext.getString(R.string.bluetooth_connected) + activeString;
                    return mContext.getString(R.string.bluetooth_connected, activeDeviceString);
                }
            }
        }
+121 −28
Original line number Diff line number Diff line
@@ -80,22 +80,12 @@ public class CachedBluetoothDeviceTest {
        doAnswer((invocation) -> mBatteryLevel).when(mCachedDevice).getBatteryLevel();
    }

    /**
     * Test to verify the current test context object works so that we are not checking null
     * against null
     */
    @Test
    public void testContextMock() {
        assertThat(mContext.getString(R.string.bluetooth_connected)).isEqualTo("Connected");
    }

    @Test
    public void testGetConnectionSummary_testSingleProfileConnectDisconnect() {
        // Test without battery level
        // Set PAN profile to be connected and test connection state summary
        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
                R.string.bluetooth_connected));
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");

        // Set PAN profile to be disconnected and test connection state summary
        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
@@ -105,9 +95,7 @@ public class CachedBluetoothDeviceTest {
        mBatteryLevel = 10;
        // Set PAN profile to be connected and test connection state summary
        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
                R.string.bluetooth_connected_battery_level,
                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, battery 10%");

        // Set PAN profile to be disconnected and test connection state summary
        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
@@ -118,8 +106,7 @@ public class CachedBluetoothDeviceTest {

        // Set PAN profile to be connected and test connection state summary
        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
                R.string.bluetooth_connected));
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");

        // Set PAN profile to be disconnected and test connection state summary
        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
@@ -134,34 +121,140 @@ public class CachedBluetoothDeviceTest {
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
                R.string.bluetooth_connected_battery_level,
                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, battery 10%");

        // Disconnect HFP only and test connection state summary
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
                R.string.bluetooth_connected_no_headset_battery_level,
                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                "Connected (no phone), battery 10%");

        // Disconnect A2DP only and test connection state summary
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
                R.string.bluetooth_connected_no_a2dp_battery_level,
                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                "Connected (no media), battery 10%");

        // Disconnect both HFP and A2DP and test connection state summary
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
                R.string.bluetooth_connected_no_headset_no_a2dp_battery_level,
                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                "Connected (no phone or media), battery 10%");

        // Disconnect all profiles and test connection state summary
        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isNull();
    }

    @Test
    public void testGetConnectionSummary_testSingleProfileActiveDeviceA2dp() {
        // Test without battery level
        // Set A2DP profile to be connected and test connection state summary
        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");

        // Set device as Active for A2DP and test connection state summary
        mCachedDevice.setActiveDevice(true, BluetoothProfile.A2DP);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)");

        // Test with battery level
        mBatteryLevel = 10;
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                "Connected, battery 10%, active(media)");

        // Set A2DP profile to be disconnected and test connection state summary
        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isNull();

        // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
        mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
        // Set A2DP profile to be connected, Active and test connection state summary
        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
        mCachedDevice.setActiveDevice(true, BluetoothProfile.A2DP);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)");

        // Set A2DP profile to be disconnected and test connection state summary
        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isNull();
    }

    @Test
    public void testGetConnectionSummary_testSingleProfileActiveDeviceHfp() {
        // Test without battery level
        // Set HFP profile to be connected and test connection state summary
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");

        // Set device as Active for HFP and test connection state summary
        mCachedDevice.setActiveDevice(true, BluetoothProfile.HEADSET);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)");

        // Test with battery level
        mBatteryLevel = 10;
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                "Connected, battery 10%, active(phone)");

        // Set HFP profile to be disconnected and test connection state summary
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isNull();

        // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
        mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
        // Set HFP profile to be connected, Active and test connection state summary
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
        mCachedDevice.setActiveDevice(true, BluetoothProfile.HEADSET);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)");

        // Set HFP profile to be disconnected and test connection state summary
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isNull();
    }

    @Test
    public void testGetConnectionSummary_testMultipleProfilesActiveDevice() {
        // Test without battery level
        // Set A2DP and HFP profiles to be connected and test connection state summary
        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");

        // Set device as Active for A2DP and HFP and test connection state summary
        mCachedDevice.setActiveDevice(true, BluetoothProfile.A2DP);
        mCachedDevice.setActiveDevice(true, BluetoothProfile.HEADSET);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active");

        // Test with battery level
        mBatteryLevel = 10;
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                "Connected, battery 10%, active");

        // Disconnect A2DP only and test connection state summary
        mCachedDevice.setActiveDevice(false, BluetoothProfile.A2DP);
        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                "Connected (no media), battery 10%, active(phone)");

        // Disconnect HFP only and test connection state summary
        mCachedDevice.setActiveDevice(false, BluetoothProfile.HEADSET);
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
        mCachedDevice.setActiveDevice(true, BluetoothProfile.A2DP);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                "Connected (no phone), battery 10%, active(media)");

        // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
        mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
        // Set A2DP and HFP profiles to be connected, Active and test connection state summary
        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
        mCachedDevice.setActiveDevice(true, BluetoothProfile.A2DP);
        mCachedDevice.setActiveDevice(true, BluetoothProfile.HEADSET);
        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active");

        // Set A2DP and HFP profiles to be disconnected and test connection state summary
        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mCachedDevice.getConnectionSummary()).isNull();
    }

    @Test
    public void testDeviceName_testAliasNameAvailable() {
        when(mDevice.getAliasName()).thenReturn(DEVICE_ALIAS);