From 9fa315263623e5eb3fdcd6b6f2820800745f4613 Mon Sep 17 00:00:00 2001 From: Pavlin Radoslavov Date: Tue, 6 Feb 2018 12:21:34 -0800 Subject: [PATCH] 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 (cherry picked from commit e6e080ff5cb9c7c56003695c1b787981e0114599) --- packages/SettingsLib/res/values/arrays.xml | 13 ++ packages/SettingsLib/res/values/strings.xml | 18 +-- .../bluetooth/CachedBluetoothDevice.java | 41 +++-- .../bluetooth/CachedBluetoothDeviceTest.java | 149 ++++++++++++++---- 4 files changed, 161 insertions(+), 60 deletions(-) diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml index 77df02bc5753b..3460ecdb49d55 100644 --- a/packages/SettingsLib/res/values/arrays.xml +++ b/packages/SettingsLib/res/values/arrays.xml @@ -250,6 +250,19 @@ Best Effort (Adaptive Bit Rate) + + + + + + + , active + + , active(media) + + , active(phone) + + Off diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index 6601451420841..74a6c649b0b04 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -128,27 +128,27 @@ Connecting\u2026 - Connected + Connected%1$s Pairing\u2026 - Connected (no phone) + Connected (no phone)%1$s - Connected (no media) + Connected (no media)%1$s - Connected (no message access) + Connected (no message access)%1$s - Connected (no phone or media) + Connected (no phone or media)%1$s - Connected, battery %1$s + Connected, battery %1$s%2$s - Connected (no phone), battery %1$s + Connected (no phone), battery %1$s%2$s - Connected (no media), battery %1$s + Connected (no media), battery %1$s%2$s - Connected (no phone or media), battery %1$s + Connected (no phone or media), battery %1$s%2$s Media audio diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index fb0f75b522b3d..e1ebbc4c166c3 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -940,60 +940,55 @@ public class CachedBluetoothDevice implements Comparable 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); } } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java index 4091ce1f173e2..1481161bcb6c0 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java @@ -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);