diff options
author | Gaurav Asati <gasati@codeaurora.org> | 2015-08-11 12:07:45 +0530 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2015-10-06 03:25:52 -0600 |
commit | e9b5ace257010e5b6dc325159a980f09a6437630 (patch) | |
tree | 5f0caeadcf9be3079026b48e22acf3effd165992 | |
parent | bc5700f34a1a892e8a76d1bbbd6cf06596ebd5e6 (diff) | |
download | android_packages_apps_Bluetooth-e9b5ace257010e5b6dc325159a980f09a6437630.tar.gz android_packages_apps_Bluetooth-e9b5ace257010e5b6dc325159a980f09a6437630.tar.bz2 android_packages_apps_Bluetooth-e9b5ace257010e5b6dc325159a980f09a6437630.zip |
Bluetooth: Update Connected Icon properly.
- add connected device list to maintain
connection status for each device.
- add device when state has changed to connected
- for fake broadcast check device in list before adding
- remove device when disconnect is broadcast for device
- cleanup device list when bt is turned off.
Change-Id: I2236a0fcab884fbf5134fbc67e05d27d5a6e837f
CRs-Fixed: 722184
Bluetooth: Proper update of the tracknumber and initialize
- Proper update of the tracknumber.
- initialize mCurrentPosMs with -1L.
- when music app does not send current track position
-1L should be sent when requested by remote.
Change-Id: Ie424a8de27cd1eca8bed332295977a3f952a6d2a
CRs-Fixed: 775209
Add device to blacklist.
- add Roman 9020 Headset to black-list
- add Bose HS to black-list
Change-Id: I715b6f616346b9c58a3061c2495da6325dcb8377
Change-Id: Ifde711b4a01ed602c7d8be9771930e24d9df0671
-rw-r--r-- | jni/com_android_bluetooth_avrcp.cpp | 5 | ||||
-rw-r--r-- | src/com/android/bluetooth/a2dp/A2dpStateMachine.java | 4 | ||||
-rw-r--r-- | src/com/android/bluetooth/avrcp/Avrcp.java | 16 | ||||
-rw-r--r-- | src/com/android/bluetooth/btservice/AdapterProperties.java | 47 | ||||
-rw-r--r-- | src/com/android/bluetooth/btservice/AdapterService.java | 73 |
5 files changed, 113 insertions, 32 deletions
diff --git a/jni/com_android_bluetooth_avrcp.cpp b/jni/com_android_bluetooth_avrcp.cpp index 701679853..4983221c9 100644 --- a/jni/com_android_bluetooth_avrcp.cpp +++ b/jni/com_android_bluetooth_avrcp.cpp @@ -81,14 +81,13 @@ static void btavrcp_remote_features_callback(bt_bdaddr_t* bd_addr, btrc_remote_f return; } + sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr); if (mCallbacksObj) { - sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr); sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getRcFeatures, addr, (jint)features, addr); } else { ALOGE("%s: mCallbacksObj is null", __FUNCTION__); } - checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); sCallbackEnv->DeleteLocalRef(addr); @@ -1834,7 +1833,7 @@ static jboolean getItemAttrRspNative(JNIEnv *env, jobject object, jbyte numAttr, pAttrs[i].attr_id = attr[i]; if (utfStringLength >= BTRC_MAX_ATTR_STR_LEN) { ALOGE("get_item_attr_rsp: string length exceed maximum"); - strlcpy((char *)pAttrs[i].text, textStr, BTRC_MAX_ATTR_STR_LEN-1); + strlcpy((char *)pAttrs[i].text, textStr, BTRC_MAX_ATTR_STR_LEN); pAttrs[i].text[BTRC_MAX_ATTR_STR_LEN-1] = 0; } else { strlcpy((char *)pAttrs[i].text, textStr, utfStringLength + 1); diff --git a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java index 46dc253c7..1c6610ff4 100644 --- a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java +++ b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java @@ -406,7 +406,6 @@ final class A2dpStateMachine extends StateMachine { StackEvent event = (StackEvent) message.obj; switch (event.type) { case EVENT_TYPE_CONNECTION_STATE_CHANGED: - removeMessages(CONNECT_TIMEOUT); processConnectionEvent(event.valueInt, event.device); break; default: @@ -1650,10 +1649,9 @@ final class A2dpStateMachine extends StateMachine { Log.i(TAG,"connectoin state change " + device + " state " + newState); if (newState == BluetoothProfile.STATE_DISCONNECTING || - newState == BluetoothProfile.STATE_CONNECTING) { + newState == BluetoothProfile.STATE_CONNECTING) { delay = 0; } - mWakeLock.acquire(); mIntentBroadcastHandler.sendMessageDelayed(mIntentBroadcastHandler.obtainMessage( MSG_CONNECTION_STATE_CHANGED, diff --git a/src/com/android/bluetooth/avrcp/Avrcp.java b/src/com/android/bluetooth/avrcp/Avrcp.java index 67647c37f..7947fc084 100644 --- a/src/com/android/bluetooth/avrcp/Avrcp.java +++ b/src/com/android/bluetooth/avrcp/Avrcp.java @@ -292,6 +292,7 @@ public final class Avrcp { mLastDirection = 0; mVolCmdInProgress = false; mAbsVolRetryTimes = 0; + mSkipAmount = 0; keyPressState = KEY_STATE_RELEASE; //Key release state mAddressedPlayerChangedNT = NOTIFICATION_TYPE_CHANGED; mAvailablePlayersChangedNT = NOTIFICATION_TYPE_CHANGED; @@ -385,7 +386,7 @@ public final class Avrcp { mAdapter = BluetoothAdapter.getDefaultAdapter(); mMetadata = new Metadata(); mTrackNumber = -1L; - mCurrentPosMs = 0L; + mCurrentPosMs = -1L; mPlayStartTimeMs = -1L; mSongLengthMs = 0L; mA2dpService = svc; @@ -785,8 +786,10 @@ public final class Avrcp { } mMediaUriStatic = uri; if (handler != null) { + // Don't send the complete path to CK as few gets confused by that + // Send only the name of the root folder handler.obtainMessage(MSG_UPDATE_BROWSED_PLAYER_FOLDER, NUM_ROOT_ELEMENTS, - SplitPath.length, SplitPath).sendToTarget(); + 1, SplitPath).sendToTarget(); } } else { handler.obtainMessage(MSG_UPDATE_BROWSED_PLAYER_FOLDER, 0, 0, null) @@ -1469,7 +1472,8 @@ public final class Avrcp { } private void updatePlayStatusForDevice(int deviceIndex,int state) { - Log.i(TAG,"updatePlayStatusForDevice"); + Log.i(TAG,"updatePlayStatusForDevice: device: " + + deviceFeatures[deviceIndex].mCurrentDevice); int oldPlayStatus = convertPlayStateToPlayStatus( deviceFeatures[deviceIndex].mCurrentPlayState); int newPlayStatus = convertPlayStateToPlayStatus(state); @@ -1964,7 +1968,7 @@ public final class Avrcp { trackTitle = null; albumTitle = null; genre = null; - tracknum = 0; + tracknum = -1L; } public String toString() { @@ -1982,7 +1986,7 @@ public final class Avrcp { mMetadata.trackTitle = data.getString(MediaMetadataRetriever.METADATA_KEY_TITLE, null); mMetadata.albumTitle = data.getString(MediaMetadataRetriever.METADATA_KEY_ALBUM, null); mMetadata.genre = data.getString(MediaMetadataRetriever.METADATA_KEY_GENRE, null); - //mTrackNumber = data.getLong(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS, -1L); + mTrackNumber = data.getLong(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS, 0L); mMetadata.tracknum = data.getLong(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER, 0L); Log.v(TAG,"old Metadata = " + oldMetadata); @@ -2105,6 +2109,8 @@ public final class Avrcp { } else { packageName = di.RetrievePlayerPackageName(); } + } else { + retError = PLAYER_NOT_BROWSABLE; } } } diff --git a/src/com/android/bluetooth/btservice/AdapterProperties.java b/src/com/android/bluetooth/btservice/AdapterProperties.java index a79445622..d0dcdb282 100644 --- a/src/com/android/bluetooth/btservice/AdapterProperties.java +++ b/src/com/android/bluetooth/btservice/AdapterProperties.java @@ -75,6 +75,33 @@ class AdapterProperties { // can be added here. private Object mObject = new Object(); + private class DeviceState { + private BluetoothDevice device = null; + private int currentState = 0; + private int profileId = 0; + + public DeviceState(BluetoothDevice device, int profile, + int state) { + this.device = device; + this.profileId = profile; + this.currentState = state; + } + @Override + public boolean equals(Object o) { + if (o instanceof DeviceState) { + if (this.device.equals(((DeviceState) o).device) && + this.profileId == ((DeviceState) o).profileId && + this.currentState == ((DeviceState) o).currentState) { + return true; + } + } + return false; + } + }; + + private ArrayList<DeviceState> mConnectedDeviceList = + new ArrayList<DeviceState>(); + public AdapterProperties(AdapterService service) { mService = service; mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -350,6 +377,26 @@ class AdapterProperties { } void sendConnectionStateChange(BluetoothDevice device, int profile, int state, int prevState) { + // add device in connection list for first connected + // and remove it in disconnected + if (state == BluetoothProfile.STATE_CONNECTED) { + DeviceState newDevice = new DeviceState(device, profile, state); + if (!mConnectedDeviceList.contains(newDevice)) { + mConnectedDeviceList.add(newDevice); + Log.v(TAG,"device is added to list"); + } else { + Log.v(TAG,"Fake broadcast for device, ignore"); + return; + } + } else if (state == BluetoothProfile.STATE_DISCONNECTED) { + DeviceState deviceState = new DeviceState(device, profile, + BluetoothProfile.STATE_CONNECTED); + if(mConnectedDeviceList.contains(deviceState)) { + Log.v(TAG,"device is removed from list"); + mConnectedDeviceList.remove(deviceState); + } + } + if (!validateProfileConnectionState(state) || !validateProfileConnectionState(prevState)) { // Previously, an invalid state was broadcast anyway, diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java index 7357dff5d..52332bcee 100644 --- a/src/com/android/bluetooth/btservice/AdapterService.java +++ b/src/com/android/bluetooth/btservice/AdapterService.java @@ -63,6 +63,7 @@ import com.android.bluetooth.hid.HidService; import com.android.bluetooth.hid.HidDevService; import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.hdp.HealthService; +import com.android.bluetooth.hfpclient.HeadsetClientService; import com.android.bluetooth.pan.PanService; import com.android.bluetooth.sdp.SdpManager; import com.android.internal.R; @@ -91,7 +92,11 @@ public class AdapterService extends Service { private static final int MIN_ADVT_INSTANCES_FOR_MA = 5; private static final int MIN_OFFLOADED_FILTERS = 10; private static final int MIN_OFFLOADED_SCAN_STORAGE_BYTES = 1024; - private static final String delayConnectTimeoutDevice[] = {"00:23:3D"}; // volkswagen carkit + private static final String delayConnectTimeoutDevice[] = + {"00:23:3D", // volkswagen carkit + "00:23:01", // Roman 9020 HS + "00:0C:8A", // Bose HS + "00:0C:8A"};// Bose series 2 HS //For Debugging only private static int sRefCount=0; private static int mScanmode; @@ -254,9 +259,9 @@ public class AdapterService extends Service { // If we do not have a stored priority for A2DP then default to on. if ((a2dpService != null) && - (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink) || + ((BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink) || BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AdvAudioDist)) && - (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ + (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED))){ a2dpService.setPriority(device,BluetoothProfile.PRIORITY_ON); } @@ -617,7 +622,7 @@ public class AdapterService extends Service { private static final int CONNECT_OTHER_PROFILES_TIMEOUT= 6000; private static final int CONNECT_OTHER_PROFILES_TIMEOUT_DELAYED = 10000; private static final int MESSAGE_AUTO_CONNECT_PROFILES = 50; - private static final int AUTO_CONNECT_PROFILES_TIMEOUT= 500; + private static final int AUTO_CONNECT_PROFILES_TIMEOUT = 500; private final Handler mHandler = new Handler() { @Override @@ -1730,51 +1735,46 @@ public class AdapterService extends Service { // This change makes sure that we try to re-connect // the profile if its connection failed and priority // for desired profile is ON. - Log.i(TAG," is HF connected" + hfConnDevList.contains(device)); - Log.i(TAG,"is a2dp connected" + a2dpConnDevList.contains(device)); + Log.i(TAG, "HF connected for device : " + device + " " + hfConnDevList.contains(device)); + Log.i(TAG, "A2DP connected for device : " + device + " " + a2dpConnDevList.contains(device)); if((hfConnDevList.isEmpty() || !(hfConnDevList.contains(device))) && (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (a2dpConnected || (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_OFF))) { - int maxConnections = 1; int maxHfpConnectionSysProp = SystemProperties.getInt("persist.bt.max.hs.connections", 1); - if (maxHfpConnectionSysProp == 2) - maxConnections = maxHfpConnectionSysProp; - if (!hfConnDevList.isEmpty() && maxConnections == 1) { + if (!hfConnDevList.isEmpty() && maxHfpConnectionSysProp == 1) { Log.v(TAG,"HFP is already connected, ignore"); return; } // proceed connection only if a2dp is connected to this device // add here as if is already overloaded - if (a2dpConnDevList.contains(device) || - (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)) { + if (a2dpConnDevList.contains(device) || + (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)) { hsService.connect(device); } else { - Log.v(TAG,"do not initiate connect as A2dp is not connected"); + Log.d(TAG, "do not initiate connect as A2dp is not connected"); } } else if((a2dpConnDevList.isEmpty() || !(a2dpConnDevList.contains(device))) && (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (hsConnected || (hsService.getPriority(device) == BluetoothProfile.PRIORITY_OFF))) { - int maxConnections = 1; int maxA2dpConnectionSysProp = SystemProperties.getInt("persist.bt.max.a2dp.connections", 1); - if (maxA2dpConnectionSysProp == 2) - maxConnections = maxA2dpConnectionSysProp; - if (!a2dpConnDevList.isEmpty() && maxConnections == 1) { - Log.v(TAG,"a2dp is already connected, ignore"); + if (!a2dpConnDevList.isEmpty() && maxA2dpConnectionSysProp == 1) { + Log.v(TAG,"A2DP is already connected, ignore"); return; } + // proceed connection only if HFP is connected to this device // add here as if is already overloaded if (hfConnDevList.contains(device) || - (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)) { + (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)) { a2dpService.connect(device); } else { - Log.v(TAG,"do not initiate connect as HFP is not connected"); + Log.v(TAG, "do not initiate connect as HFP is not connected"); } } } @@ -1821,9 +1821,9 @@ public class AdapterService extends Service { } else if (profileId == BluetoothProfile.A2DP) { A2dpService a2dpService = A2dpService.getA2dpService(); - List<BluetoothDevice> deviceList = a2dpService.getConnectedDevices(); if ((a2dpService != null) && (BluetoothProfile.PRIORITY_AUTO_CONNECT != a2dpService.getPriority(device))){ + List<BluetoothDevice> deviceList = a2dpService.getConnectedDevices(); adjustOtherSinkPriorities(a2dpService, deviceList); a2dpService.setPriority(device,BluetoothProfile.PRIORITY_AUTO_CONNECT); } @@ -2464,4 +2464,35 @@ public class AdapterService extends Service { setProfileServiceState(a2dp_src, BluetoothAdapter.STATE_ON); } } + + @SuppressWarnings("rawtypes") + private synchronized void checkHfpState() { + final Class hfp_ag[] = { HeadsetService.class }; + final Class hfp_hs[] = { HeadsetClientService.class }; + + boolean isHfpClientEnabled = SystemProperties.getBoolean("persist.service.bt.hfp.client", + false); + Log.d(TAG, "checkHfpState: isHfpClientEnabled = " + isHfpClientEnabled); + + if (isHfpClientEnabled) { + mDisabledProfiles.add(HeadsetService.class.getName()); + mDisabledProfiles.remove(HeadsetClientService.class.getName()); + } else { + mDisabledProfiles.remove(HeadsetService.class.getName()); + mDisabledProfiles.add(HeadsetClientService.class.getName()); + } + + if (mAdapterStateMachine.isTurningOn() || mAdapterStateMachine.isTurningOff()) { + Log.e(TAG, "checkHfpState: returning"); + return; + } + + if (isHfpClientEnabled) { + setProfileServiceState(hfp_ag, BluetoothAdapter.STATE_OFF); + setProfileServiceState(hfp_hs, BluetoothAdapter.STATE_ON); + } else { + setProfileServiceState(hfp_hs, BluetoothAdapter.STATE_OFF); + setProfileServiceState(hfp_ag, BluetoothAdapter.STATE_ON); + } + } } |