Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +1 −0 Original line number Diff line number Diff line Loading @@ -490,6 +490,7 @@ public class BluetoothEventManager { } private void dispatchAudioModeChanged() { mDeviceManager.dispatchAudioModeChanged(); synchronized (mCallbacks) { for (BluetoothCallback callback : mCallbacks) { callback.onAudioModeChanged(); Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +56 −61 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; import android.content.Context; import android.content.SharedPreferences; import android.media.AudioManager; import android.os.ParcelUuid; import android.os.SystemClock; import android.text.TextUtils; Loading Loading @@ -51,6 +52,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private final Context mContext; private final LocalBluetoothAdapter mLocalAdapter; private final LocalBluetoothProfileManager mProfileManager; private final AudioManager mAudioManager; private final BluetoothDevice mDevice; //TODO: consider remove, BluetoothDevice.getName() is already cached private String mName; Loading Loading @@ -123,7 +125,6 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private boolean mIsActiveDeviceA2dp = false; private boolean mIsActiveDeviceHeadset = false; private boolean mIsActiveDeviceHearingAid = false; /** * Describes the current device and profile for logging. * Loading Loading @@ -185,6 +186,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> mContext = context; mLocalAdapter = adapter; mProfileManager = profileManager; mAudioManager = context.getSystemService(AudioManager.class); mDevice = device; mProfileConnectionState = new HashMap<LocalBluetoothProfile, Integer>(); fillData(); Loading Loading @@ -537,6 +539,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } } /** * Update the profile audio state. */ void onAudioModeChanged() { dispatchAttributesChanged(); } /** * Get the device status as active or non-active per Bluetooth profile. * Loading Loading @@ -972,12 +980,14 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> /** * @return resource for string that discribes the connection state of this device. * case 1: idle or playing media, show "Active" on the only one A2DP active device. * case 2: in phone call, show "Active" on the only one HFP active device */ public String getConnectionSummary() { boolean profileConnected = false; // at least one profile is connected boolean a2dpNotConnected = false; // A2DP is preferred but not connected boolean hfpNotConnected = false; // HFP is preferred but not connected boolean hearingAidNotConnected = false; // Hearing Aid is preferred but not connected boolean profileConnected = false; // Updated as long as BluetoothProfile is connected boolean a2dpConnected = true; // A2DP is connected boolean hfpConnected = true; // HFP is connected boolean hearingAidConnected = true; // Hearing Aid is connected for (LocalBluetoothProfile profile : getProfiles()) { int connectionStatus = getProfileConnectionState(profile); Loading @@ -995,12 +1005,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> if (profile.isProfileReady()) { if ((profile instanceof A2dpProfile) || (profile instanceof A2dpSinkProfile)) { a2dpNotConnected = true; a2dpConnected = false; } else if ((profile instanceof HeadsetProfile) || (profile instanceof HfpClientProfile)) { hfpNotConnected = true; hfpConnected = false; } else if (profile instanceof HearingAidProfile) { hearingAidNotConnected = true; hearingAidConnected = false; } } break; Loading @@ -1019,65 +1029,50 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> com.android.settingslib.Utils.formatPercentage(batteryLevel); } // 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) { activeDeviceString = activeDeviceStringsArray[1]; // Active for Media and Phone } else { if (mIsActiveDeviceA2dp) { activeDeviceString = activeDeviceStringsArray[2]; // Active for Media only } if (mIsActiveDeviceHeadset) { activeDeviceString = activeDeviceStringsArray[3]; // Active for Phone only } } if (!hearingAidNotConnected && mIsActiveDeviceHearingAid) { activeDeviceString = activeDeviceStringsArray[1]; return mContext.getString(R.string.bluetooth_connected, activeDeviceString); } int stringRes = R.string.bluetooth_pairing; //when profile is connected, information would be available if (profileConnected) { if (a2dpNotConnected && hfpNotConnected) { if (a2dpConnected || hfpConnected || hearingAidConnected) { //contain battery information if (batteryLevelPercentageString != null) { return mContext.getString( R.string.bluetooth_connected_no_headset_no_a2dp_battery_level, batteryLevelPercentageString, activeDeviceString); //device is in phone call if (com.android.settingslib.Utils.isAudioModeOngoingCall(mContext)) { if (mIsActiveDeviceHeadset) { stringRes = R.string.bluetooth_active_battery_level; } else { return mContext.getString(R.string.bluetooth_connected_no_headset_no_a2dp, activeDeviceString); stringRes = R.string.bluetooth_battery_level; } } else if (a2dpNotConnected) { if (batteryLevelPercentageString != null) { return mContext.getString(R.string.bluetooth_connected_no_a2dp_battery_level, batteryLevelPercentageString, activeDeviceString); } else {//device is not in phone call(ex. idle or playing media) //need to check if A2DP and HearingAid are exclusive if (mIsActiveDeviceHearingAid || mIsActiveDeviceA2dp) { stringRes = R.string.bluetooth_active_battery_level; } else { return mContext.getString(R.string.bluetooth_connected_no_a2dp, activeDeviceString); stringRes = R.string.bluetooth_battery_level; } } } else if (hfpNotConnected) { if (batteryLevelPercentageString != null) { return mContext.getString(R.string.bluetooth_connected_no_headset_battery_level, batteryLevelPercentageString, activeDeviceString); } else { return mContext.getString(R.string.bluetooth_connected_no_headset, activeDeviceString); //no battery information if (com.android.settingslib.Utils.isAudioModeOngoingCall(mContext)) { if (mIsActiveDeviceHeadset) { stringRes = R.string.bluetooth_active_no_battery_level; } } else { if (mIsActiveDeviceHearingAid || mIsActiveDeviceA2dp) { stringRes = R.string.bluetooth_active_no_battery_level; } } } } else {//unknown profile with battery information if (batteryLevelPercentageString != null) { return mContext.getString(R.string.bluetooth_connected_battery_level, batteryLevelPercentageString, activeDeviceString); } else { return mContext.getString(R.string.bluetooth_connected, activeDeviceString); stringRes = R.string.bluetooth_battery_level; } } } return getBondState() == BluetoothDevice.BOND_BONDING ? mContext.getString(R.string.bluetooth_pairing) : null; return (stringRes != R.string.bluetooth_pairing || getBondState() == BluetoothDevice.BOND_BONDING) ? mContext.getString(stringRes, batteryLevelPercentageString) : null; } /** Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -358,6 +358,12 @@ public class CachedBluetoothDeviceManager { } } public synchronized void dispatchAudioModeChanged() { for (CachedBluetoothDevice cachedDevice : mCachedDevices) { cachedDevice.onAudioModeChanged(); } } private void log(String msg) { if (DEBUG) { Log.d(TAG, msg); Loading packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +37 −30 Original line number Diff line number Diff line Loading @@ -23,23 +23,25 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.media.AudioManager; import com.android.settingslib.SettingsLibRobolectricTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowAudioManager; @RunWith(RobolectricTestRunner.class) @Config(resourceDir = "../../res") @RunWith(SettingsLibRobolectricTestRunner.class) public class CachedBluetoothDeviceTest { private final static String DEVICE_NAME = "TestName"; private final static String DEVICE_ALIAS = "TestAlias"; Loading @@ -60,6 +62,7 @@ public class CachedBluetoothDeviceTest { @Mock private BluetoothDevice mDevice; private CachedBluetoothDevice mCachedDevice; private ShadowAudioManager mShadowAudioManager; private Context mContext; private int mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; Loading @@ -67,6 +70,7 @@ public class CachedBluetoothDeviceTest { public void setUp() { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; mShadowAudioManager = shadowOf(mContext.getSystemService(AudioManager.class)); when(mDevice.getAddress()).thenReturn(DEVICE_ADDRESS); when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON); when(mHfpProfile.isProfileReady()).thenReturn(true); Loading @@ -83,7 +87,7 @@ public class CachedBluetoothDeviceTest { // 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("Connected"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set PAN profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -93,7 +97,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("Connected, battery 10%"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("10% battery"); // Set PAN profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -104,7 +108,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("Connected"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set PAN profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -119,23 +123,23 @@ 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("Connected, battery 10%"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("10% battery"); // Disconnect HFP only and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected (no phone), battery 10%"); "10% battery"); // Disconnect A2DP only and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected (no media), battery 10%"); "10% battery"); // Disconnect both HFP and A2DP and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected (no phone or media), battery 10%"); "10% battery"); // Disconnect all profiles and test connection state summary mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -147,16 +151,16 @@ public class CachedBluetoothDeviceTest { // 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"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set device as Active for A2DP and test connection state summary mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Test with battery level mBatteryLevel = 10; assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected, battery 10%, active(media)"); "Active, 10% battery"); // Set A2DP profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -167,7 +171,7 @@ public class CachedBluetoothDeviceTest { // Set A2DP profile to be connected, Active and test connection state summary mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Set A2DP profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -179,16 +183,18 @@ public class CachedBluetoothDeviceTest { // 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"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set device as Active for HFP and test connection state summary mCachedDevice.onAudioModeChanged(); mShadowAudioManager.setMode(AudioManager.MODE_IN_CALL); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Test with battery level mBatteryLevel = 10; assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected, battery 10%, active(phone)"); "Active, 10% battery"); // Set HFP profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -199,7 +205,7 @@ public class CachedBluetoothDeviceTest { // Set HFP profile to be connected, Active and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Set HFP profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -211,15 +217,16 @@ public class CachedBluetoothDeviceTest { // Test without battery level // Set Hearing Aid profile to be connected and test connection state summary mCachedDevice.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set device as Active for Hearing Aid and test connection state summary mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Set Hearing Aid profile to be disconnected and test connection state summary mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEARING_AID); mCachedDevice.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_DISCONNECTED); mCachedDevice. onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_DISCONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isNull(); } Loading @@ -229,23 +236,23 @@ public class CachedBluetoothDeviceTest { // 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"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set device as Active for A2DP and HFP and test connection state summary mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Test with battery level mBatteryLevel = 10; assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected, battery 10%, active"); "Active, 10% battery"); // Disconnect A2DP only and test connection state summary mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.A2DP); mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected (no media), battery 10%, active(phone)"); "10% battery"); // Disconnect HFP only and test connection state summary mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEADSET); Loading @@ -253,7 +260,7 @@ public class CachedBluetoothDeviceTest { mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected (no phone), battery 10%, active(media)"); "Active, 10% battery"); // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; Loading @@ -262,7 +269,7 @@ public class CachedBluetoothDeviceTest { mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Set A2DP and HFP profiles to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); Loading Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +1 −0 Original line number Diff line number Diff line Loading @@ -490,6 +490,7 @@ public class BluetoothEventManager { } private void dispatchAudioModeChanged() { mDeviceManager.dispatchAudioModeChanged(); synchronized (mCallbacks) { for (BluetoothCallback callback : mCallbacks) { callback.onAudioModeChanged(); Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +56 −61 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; import android.content.Context; import android.content.SharedPreferences; import android.media.AudioManager; import android.os.ParcelUuid; import android.os.SystemClock; import android.text.TextUtils; Loading Loading @@ -51,6 +52,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private final Context mContext; private final LocalBluetoothAdapter mLocalAdapter; private final LocalBluetoothProfileManager mProfileManager; private final AudioManager mAudioManager; private final BluetoothDevice mDevice; //TODO: consider remove, BluetoothDevice.getName() is already cached private String mName; Loading Loading @@ -123,7 +125,6 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private boolean mIsActiveDeviceA2dp = false; private boolean mIsActiveDeviceHeadset = false; private boolean mIsActiveDeviceHearingAid = false; /** * Describes the current device and profile for logging. * Loading Loading @@ -185,6 +186,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> mContext = context; mLocalAdapter = adapter; mProfileManager = profileManager; mAudioManager = context.getSystemService(AudioManager.class); mDevice = device; mProfileConnectionState = new HashMap<LocalBluetoothProfile, Integer>(); fillData(); Loading Loading @@ -537,6 +539,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } } /** * Update the profile audio state. */ void onAudioModeChanged() { dispatchAttributesChanged(); } /** * Get the device status as active or non-active per Bluetooth profile. * Loading Loading @@ -972,12 +980,14 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> /** * @return resource for string that discribes the connection state of this device. * case 1: idle or playing media, show "Active" on the only one A2DP active device. * case 2: in phone call, show "Active" on the only one HFP active device */ public String getConnectionSummary() { boolean profileConnected = false; // at least one profile is connected boolean a2dpNotConnected = false; // A2DP is preferred but not connected boolean hfpNotConnected = false; // HFP is preferred but not connected boolean hearingAidNotConnected = false; // Hearing Aid is preferred but not connected boolean profileConnected = false; // Updated as long as BluetoothProfile is connected boolean a2dpConnected = true; // A2DP is connected boolean hfpConnected = true; // HFP is connected boolean hearingAidConnected = true; // Hearing Aid is connected for (LocalBluetoothProfile profile : getProfiles()) { int connectionStatus = getProfileConnectionState(profile); Loading @@ -995,12 +1005,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> if (profile.isProfileReady()) { if ((profile instanceof A2dpProfile) || (profile instanceof A2dpSinkProfile)) { a2dpNotConnected = true; a2dpConnected = false; } else if ((profile instanceof HeadsetProfile) || (profile instanceof HfpClientProfile)) { hfpNotConnected = true; hfpConnected = false; } else if (profile instanceof HearingAidProfile) { hearingAidNotConnected = true; hearingAidConnected = false; } } break; Loading @@ -1019,65 +1029,50 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> com.android.settingslib.Utils.formatPercentage(batteryLevel); } // 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) { activeDeviceString = activeDeviceStringsArray[1]; // Active for Media and Phone } else { if (mIsActiveDeviceA2dp) { activeDeviceString = activeDeviceStringsArray[2]; // Active for Media only } if (mIsActiveDeviceHeadset) { activeDeviceString = activeDeviceStringsArray[3]; // Active for Phone only } } if (!hearingAidNotConnected && mIsActiveDeviceHearingAid) { activeDeviceString = activeDeviceStringsArray[1]; return mContext.getString(R.string.bluetooth_connected, activeDeviceString); } int stringRes = R.string.bluetooth_pairing; //when profile is connected, information would be available if (profileConnected) { if (a2dpNotConnected && hfpNotConnected) { if (a2dpConnected || hfpConnected || hearingAidConnected) { //contain battery information if (batteryLevelPercentageString != null) { return mContext.getString( R.string.bluetooth_connected_no_headset_no_a2dp_battery_level, batteryLevelPercentageString, activeDeviceString); //device is in phone call if (com.android.settingslib.Utils.isAudioModeOngoingCall(mContext)) { if (mIsActiveDeviceHeadset) { stringRes = R.string.bluetooth_active_battery_level; } else { return mContext.getString(R.string.bluetooth_connected_no_headset_no_a2dp, activeDeviceString); stringRes = R.string.bluetooth_battery_level; } } else if (a2dpNotConnected) { if (batteryLevelPercentageString != null) { return mContext.getString(R.string.bluetooth_connected_no_a2dp_battery_level, batteryLevelPercentageString, activeDeviceString); } else {//device is not in phone call(ex. idle or playing media) //need to check if A2DP and HearingAid are exclusive if (mIsActiveDeviceHearingAid || mIsActiveDeviceA2dp) { stringRes = R.string.bluetooth_active_battery_level; } else { return mContext.getString(R.string.bluetooth_connected_no_a2dp, activeDeviceString); stringRes = R.string.bluetooth_battery_level; } } } else if (hfpNotConnected) { if (batteryLevelPercentageString != null) { return mContext.getString(R.string.bluetooth_connected_no_headset_battery_level, batteryLevelPercentageString, activeDeviceString); } else { return mContext.getString(R.string.bluetooth_connected_no_headset, activeDeviceString); //no battery information if (com.android.settingslib.Utils.isAudioModeOngoingCall(mContext)) { if (mIsActiveDeviceHeadset) { stringRes = R.string.bluetooth_active_no_battery_level; } } else { if (mIsActiveDeviceHearingAid || mIsActiveDeviceA2dp) { stringRes = R.string.bluetooth_active_no_battery_level; } } } } else {//unknown profile with battery information if (batteryLevelPercentageString != null) { return mContext.getString(R.string.bluetooth_connected_battery_level, batteryLevelPercentageString, activeDeviceString); } else { return mContext.getString(R.string.bluetooth_connected, activeDeviceString); stringRes = R.string.bluetooth_battery_level; } } } return getBondState() == BluetoothDevice.BOND_BONDING ? mContext.getString(R.string.bluetooth_pairing) : null; return (stringRes != R.string.bluetooth_pairing || getBondState() == BluetoothDevice.BOND_BONDING) ? mContext.getString(stringRes, batteryLevelPercentageString) : null; } /** Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -358,6 +358,12 @@ public class CachedBluetoothDeviceManager { } } public synchronized void dispatchAudioModeChanged() { for (CachedBluetoothDevice cachedDevice : mCachedDevices) { cachedDevice.onAudioModeChanged(); } } private void log(String msg) { if (DEBUG) { Log.d(TAG, msg); Loading
packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +37 −30 Original line number Diff line number Diff line Loading @@ -23,23 +23,25 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.media.AudioManager; import com.android.settingslib.SettingsLibRobolectricTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowAudioManager; @RunWith(RobolectricTestRunner.class) @Config(resourceDir = "../../res") @RunWith(SettingsLibRobolectricTestRunner.class) public class CachedBluetoothDeviceTest { private final static String DEVICE_NAME = "TestName"; private final static String DEVICE_ALIAS = "TestAlias"; Loading @@ -60,6 +62,7 @@ public class CachedBluetoothDeviceTest { @Mock private BluetoothDevice mDevice; private CachedBluetoothDevice mCachedDevice; private ShadowAudioManager mShadowAudioManager; private Context mContext; private int mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; Loading @@ -67,6 +70,7 @@ public class CachedBluetoothDeviceTest { public void setUp() { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; mShadowAudioManager = shadowOf(mContext.getSystemService(AudioManager.class)); when(mDevice.getAddress()).thenReturn(DEVICE_ADDRESS); when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON); when(mHfpProfile.isProfileReady()).thenReturn(true); Loading @@ -83,7 +87,7 @@ public class CachedBluetoothDeviceTest { // 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("Connected"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set PAN profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -93,7 +97,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("Connected, battery 10%"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("10% battery"); // Set PAN profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -104,7 +108,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("Connected"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set PAN profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -119,23 +123,23 @@ 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("Connected, battery 10%"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("10% battery"); // Disconnect HFP only and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected (no phone), battery 10%"); "10% battery"); // Disconnect A2DP only and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected (no media), battery 10%"); "10% battery"); // Disconnect both HFP and A2DP and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected (no phone or media), battery 10%"); "10% battery"); // Disconnect all profiles and test connection state summary mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -147,16 +151,16 @@ public class CachedBluetoothDeviceTest { // 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"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set device as Active for A2DP and test connection state summary mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Test with battery level mBatteryLevel = 10; assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected, battery 10%, active(media)"); "Active, 10% battery"); // Set A2DP profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -167,7 +171,7 @@ public class CachedBluetoothDeviceTest { // Set A2DP profile to be connected, Active and test connection state summary mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Set A2DP profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -179,16 +183,18 @@ public class CachedBluetoothDeviceTest { // 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"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set device as Active for HFP and test connection state summary mCachedDevice.onAudioModeChanged(); mShadowAudioManager.setMode(AudioManager.MODE_IN_CALL); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Test with battery level mBatteryLevel = 10; assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected, battery 10%, active(phone)"); "Active, 10% battery"); // Set HFP profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -199,7 +205,7 @@ public class CachedBluetoothDeviceTest { // Set HFP profile to be connected, Active and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Set HFP profile to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); Loading @@ -211,15 +217,16 @@ public class CachedBluetoothDeviceTest { // Test without battery level // Set Hearing Aid profile to be connected and test connection state summary mCachedDevice.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set device as Active for Hearing Aid and test connection state summary mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Set Hearing Aid profile to be disconnected and test connection state summary mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEARING_AID); mCachedDevice.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_DISCONNECTED); mCachedDevice. onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_DISCONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isNull(); } Loading @@ -229,23 +236,23 @@ public class CachedBluetoothDeviceTest { // 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"); assertThat(mCachedDevice.getConnectionSummary()).isNull(); // Set device as Active for A2DP and HFP and test connection state summary mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Test with battery level mBatteryLevel = 10; assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected, battery 10%, active"); "Active, 10% battery"); // Disconnect A2DP only and test connection state summary mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.A2DP); mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected (no media), battery 10%, active(phone)"); "10% battery"); // Disconnect HFP only and test connection state summary mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEADSET); Loading @@ -253,7 +260,7 @@ public class CachedBluetoothDeviceTest { mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( "Connected (no phone), battery 10%, active(media)"); "Active, 10% battery"); // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; Loading @@ -262,7 +269,7 @@ public class CachedBluetoothDeviceTest { mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active"); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); // Set A2DP and HFP profiles to be disconnected and test connection state summary mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); Loading