Closed Bug 1160127 Opened 10 years ago Closed 10 years ago

Send profile level disconnection notification to make status bar reset connection status

Categories

(Firefox OS Graveyard :: Bluetooth, defect)

ARM
Gonk (Firefox OS)
defect
Not set
normal

Tracking

(blocking-b2g:2.2+, firefox39 wontfix, firefox40 wontfix, firefox41 fixed, b2g-v2.2 verified, b2g-master verified)

RESOLVED FIXED
2.2 S12 (15may)
blocking-b2g 2.2+
Tracking Status
firefox39 --- wontfix
firefox40 --- wontfix
firefox41 --- fixed
b2g-v2.2 --- verified
b2g-master --- verified

People

(Reporter: shawnjohnjr, Assigned: shawnjohnjr)

References

Details

(Whiteboard: [caf priority: p2][CR 830266])

Attachments

(4 files, 5 obsolete files)

5.46 KB, patch
Details | Diff | Splinter Review
5.47 KB, patch
Details | Diff | Splinter Review
4.79 MB, video/mp4
Details
5.83 MB, video/mp4
Details
Send profile level disconnection notification to make status bar reset connection status.
Assignee: nobody → shuang
blocking-b2g: --- → 2.2?
Attachment #8600853 - Attachment filename: bug1160127-mc.patch → (WIP)Bug 1160127 - Send profile level disconnection notification
Attachment #8600853 - Attachment description: bug1160127-mc.patch → (WIP)Bug 1160127 - Send profile level disconnection notification
Attachment #8600853 - Attachment filename: (WIP)Bug 1160127 - Send profile level disconnection notification → bug1160127-mc.patch
mark as 2.2+
blocking-b2g: 2.2? → 2.2+
(In reply to Shawn Huang [:shawnjohnjr] from comment #3) > Created attachment 8601433 [details] [diff] [review] > (WIP)Bug 1160127 - Send profile level disconnection notification The patch can reset connection status so that connection status bar icon and audio path can be correctly routed to accurate path. I tested after killing daemon, music paused and audio path switches to speaker, then connects with bluetooth headset, audio path routes to A2DP headset again. After killing bluetooth daemon twice, I found the first time can perfectly recover the situation, at the second time Settings UI "connect options" still remains 'disconnect/unpair', it seems like something's wrong with BluetoothProfileController or maybe it's related to Gaia. I still need to investigate this sub-problem a bit.
Comment on attachment 8601433 [details] [diff] [review] (WIP)Bug 1160127 - Send profile level disconnection notification Review of attachment 8601433 [details] [diff] [review]: ----------------------------------------------------------------- ::: dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp @@ +1171,5 @@ > + MOZ_ASSERT(NS_IsMainThread()); > + > + if (mConnectionState == HFP_CONNECTION_STATE_SLC_CONNECTED) { > + mConnectionState = HFP_CONNECTION_STATE_DISCONNECTED; > + mDeviceAddress.Truncate(); The problem I mentioned in Comment 4 caused by this line. I shouldn't clean up address before NotifyConnectionStateChanged completed.
The following use cases had been tested to make sure daemon recovery doesn't mess up profile-level usage: 1. HFP profile: a. Pair and cnnect HFP profile supported headset. b. Make an incoming/outgoing call and during call session, then kill daemon. c. Check audio routed back to earpiece. d. Go to 'Settings>Bluetooth Settings' and connects HFP profile. e. Check audio routed back to bluetooth headset. 2. A2DP profile a. Pair and connect A2DP profile headset. b. Play music. c. Verify audio routed to A2DP headset then kill daemon. d. Check audio routed to speaker. d. Go to 'Settings>Bluetooth Settings' and connects A2DP profile. e. Check audio routed back to bluetooth headset. 3. OPP profile (although not related to this patch) a. Send a file through OPP at the same time kill daemon. b. Verify that file transfer session will be canceled. c. Send the file again d. Verify the remote device can received the file.
Comment on attachment 8601951 [details] [diff] [review] Bug 1160127 - Send HFP/A2DP profile disconnection notification Review of attachment 8601951 [details] [diff] [review]: ----------------------------------------------------------------- Please see my comment below. ::: dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp @@ +727,5 @@ > } > } > > +/* > + * When bluetooth is been truned off, backend actually sends * When bluetooth is turned off, ... @@ +733,5 @@ > + * delivered to Gecko. It's important to update this status to make sure audio > + * routing and status bar update status correctly. > + */ > +void > +BluetoothA2dpManager::BackendRecoveryProcedure() How about make this function as HandsfreeDaemonInterface's BackendErrorNotification? Also can we simplify this function as following? { if (IsConnected()) { MOZ_ASSERT(!mDeviceAddress.IsEmpty()); ConnectionStateNotification(A2DP_CONNECTION_STATE_DISCONNECTED, mDeviceAddress); } } @@ +735,5 @@ > + */ > +void > +BluetoothA2dpManager::BackendRecoveryProcedure() > +{ > + if (!mDeviceAddress.IsEmpty() && mA2dpConnected) { What happens if state is CONNECTING? ::: dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ +351,5 @@ > profile = BluetoothA2dpManager::Get(); > NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE); > if (profile->IsConnected()) { > profile->Disconnect(nullptr); > + if (sIsRestart) { Can we do this inside |BackendErrorNotification|, right before |StopBluetooth|? ::: dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp @@ +1161,5 @@ > nsITelephonyService::CALL_STATE_CONNECTED; > } > > +/* > + * When bluetooth is been truned off, backend actually sends Ditto. @@ +1166,5 @@ > + * disconnection notification. If backend crashes, notification won't be > + * delivered to Gecko. It's important to update this status to make sure audio > + * routing and status bar update status correctly. > + */ > + nit: remove this newline. @@ +1168,5 @@ > + * routing and status bar update status correctly. > + */ > + > +void > +BluetoothHfpManager::BackendRecoveryProcedure() How about make this function as A2dpDaemonInterface's BackendErrorNotification? Also can we simplify this function as following? { MOZ_ASSERT(NS_IsMainThread()); if (IsConnected()) { ConnectionStateChangeNotification(HFP_CONNECTION_STATE_DISCONNECTED, mDeviceAddress); } AudioStateChangeNotification(HFP_AUDIO_STATE_DISCONNECTED, mDeviceAddress); } @@ +1172,5 @@ > +BluetoothHfpManager::BackendRecoveryProcedure() > +{ > + MOZ_ASSERT(NS_IsMainThread()); > + > + if (mConnectionState == HFP_CONNECTION_STATE_SLC_CONNECTED) { What happens if state is CONNECTING? @@ +1189,5 @@ > + } > + > + // Clean up address after NotifyConnectionStateChanged completed > + mDeviceAddress.Truncate(); > + Reset(); Why not |Cleanup| here? ::: dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h @@ +108,5 @@ > void AnswerWaitingCall(); > void IgnoreWaitingCall(); > void ToggleCalls(); > > + // Backend recovery procedure if the backend unexpectedly crashes Suggest to revise as // Backend recovery procedure for unexpected backend crashes
Attachment #8601951 - Flags: review?(btian)
Comment on attachment 8601951 [details] [diff] [review] Bug 1160127 - Send HFP/A2DP profile disconnection notification Review of attachment 8601951 [details] [diff] [review]: ----------------------------------------------------------------- ::: dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ +351,5 @@ > profile = BluetoothA2dpManager::Get(); > NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE); > if (profile->IsConnected()) { > profile->Disconnect(nullptr); > + if (sIsRestart) { Good idea, I will modify it in the new patch. ::: dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp @@ +1168,5 @@ > + * routing and status bar update status correctly. > + */ > + > +void > +BluetoothHfpManager::BackendRecoveryProcedure() You're right. Redo things here is stupid. Only one point I think it's better not check HFP connection status for SCO connection considering we might have voice recognition in the near future (it's possible hfp connection doesn't exist but only SCO connection established). @@ +1172,5 @@ > +BluetoothHfpManager::BackendRecoveryProcedure() > +{ > + MOZ_ASSERT(NS_IsMainThread()); > + > + if (mConnectionState == HFP_CONNECTION_STATE_SLC_CONNECTED) { Sure, this should be considered. Thanks for pointing out. @@ +1189,5 @@ > + } > + > + // Clean up address after NotifyConnectionStateChanged completed > + mDeviceAddress.Truncate(); > + Reset(); ProfileManager |Cleanup| will be triggered by later AdatperStateChanged, so I don't intend do it now.
Comment on attachment 8602044 [details] [diff] [review] Bug 1160127 - Send HFP/A2DP profile disconnection notification Review of attachment 8602044 [details] [diff] [review]: ----------------------------------------------------------------- Please see my comment below. ::: dom/bluetooth/BluetoothInterface.h @@ +149,5 @@ > { } > > + virtual void > + BackendErrorNotification() > + { } Remove the unused notification. @@ +301,5 @@ > { } > > + virtual void > + BackendErrorNotification() > + { } Ditto. ::: dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp @@ +727,5 @@ > } > } > > +/* > + * When bluetooth is truned off, backend actually sends Revise comment as following: /* * Reset connection state to DISCONNECTED to handle backend error. The state * change triggers UI status bar update as ordinary BT turn-off sequence. */ @@ +737,5 @@ > +BluetoothA2dpManager::BackendRecoveryProcedure() > +{ > + if (mSinkState == SinkState::SINK_CONNECTING || > + mSinkState == SinkState::SINK_CONNECTED || > + mSinkState == SinkState::SINK_PLAYING) { Notify only if sink state is not DISCONNECTED. ::: dom/bluetooth/bluedroid/BluetoothA2dpManager.h @@ +62,5 @@ > uint64_t GetMediaNumber(); > uint64_t GetTotalMediaNumber(); > void GetTitle(nsAString& aTitle); > void GetArtist(nsAString& aArtist); > + void BackendRecoveryProcedure(); Rename to |HandleBackendError|. ::: dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ +3095,4 @@ > #endif > > void > BluetoothServiceBluedroid::BackendErrorNotification(bool aCrashed) Do we have backend error other than crash? @@ +3096,5 @@ > > void > BluetoothServiceBluedroid::BackendErrorNotification(bool aCrashed) > { > MOZ_ASSERT(NS_IsMainThread()); nit: add newline after MOZ_ASSERT. @@ +3098,5 @@ > BluetoothServiceBluedroid::BackendErrorNotification(bool aCrashed) > { > MOZ_ASSERT(NS_IsMainThread()); > // Recovery step 2 stop bluetooth > if (aCrashed) { Replace with guardian clause: if (!aCrashed) { return; } ... @@ +3099,5 @@ > { > MOZ_ASSERT(NS_IsMainThread()); > // Recovery step 2 stop bluetooth > if (aCrashed) { > + nit: remove this newline. @@ +3101,5 @@ > // Recovery step 2 stop bluetooth > if (aCrashed) { > + > + // If backend crashes unexpectedly, it's impossible we can Get > + // disconnection notifications from backend. Reset audio path immediately. Simplify comment as following: /* * Reset following profile manager states for unexpected backend crash. * - HFP: connection state and audio state * - A2DP: connection state */ @@ +3103,5 @@ > + > + // If backend crashes unexpectedly, it's impossible we can Get > + // disconnection notifications from backend. Reset audio path immediately. > + BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get(); > + a2dp->BackendRecoveryProcedure(); Ensure |a2dp| is not null before using it. Also call |hfp->HandleBackendError| first to conform with ordinary disconnection order. @@ +3105,5 @@ > + // disconnection notifications from backend. Reset audio path immediately. > + BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get(); > + a2dp->BackendRecoveryProcedure(); > + BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); > + hfp->BackendRecoveryProcedure(); Ensure |hfp| is not null before using it. nit: add newline after this line. ::: dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp @@ +1161,5 @@ > nsITelephonyService::CALL_STATE_CONNECTED; > } > > +/* > + * When bluetooth is truned off, backend actually sends Revise comment as following: /* * Reset connection state and audio state to DISCONNECTED to handle backend error. * The state change triggers UI status bar update as ordinary BT turn-off sequence. */ @@ +1166,5 @@ > + * disconnection notification. If backend crashes, notification won't be > + * delivered to Gecko. It's important to update this status to make sure audio > + * routing and status bar update status correctly. > + */ > + nit: remove the newline. @@ +1173,5 @@ > +{ > + MOZ_ASSERT(NS_IsMainThread()); > + > + if (mConnectionState == HFP_CONNECTION_STATE_SLC_CONNECTED || > + mConnectionState == HFP_CONNECTION_STATE_CONNECTING) { Notify only if state is not DISCONNECTED. @@ +1179,5 @@ > + mDeviceAddress); > + } > + > + if (mAudioState == HFP_AUDIO_STATE_CONNECTED || > + mAudioState == HFP_AUDIO_STATE_CONNECTING) { Notify only if audio state is not DISCONNECTED. ::: dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h @@ +109,5 @@ > void IgnoreWaitingCall(); > void ToggleCalls(); > > + // Backend recovery procedure if the backend unexpectedly crashes > + void BackendRecoveryProcedure(); Rename to |HandleBackendError| as following: // Handle unexpected backend crash void HandleBackendError();
Attachment #8602044 - Flags: review?(btian)
Comment on attachment 8602044 [details] [diff] [review] Bug 1160127 - Send HFP/A2DP profile disconnection notification Review of attachment 8602044 [details] [diff] [review]: ----------------------------------------------------------------- ::: dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ +3095,4 @@ > #endif > > void > BluetoothServiceBluedroid::BackendErrorNotification(bool aCrashed) We should have, but currently the last bluetooth recovery patch does not handle that situation.
Comment on attachment 8602604 [details] [diff] [review] Bug 1160127 - Send HFP/A2DP profile disconnection notification Review of attachment 8602604 [details] [diff] [review]: ----------------------------------------------------------------- r=me with comment addressed. ::: dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp @@ +733,5 @@ > + */ > +void > +BluetoothA2dpManager::HandleBackendError() > +{ > + if (!(mSinkState == SinkState::SINK_DISCONNECTED)) { Simplify to |mSinkState != SinkState::SINK_DISCONNECTED|. ::: dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ +3100,5 @@ > MOZ_ASSERT(NS_IsMainThread()); > + > + if (!aCrashed) { > + return; > + } nit: newline here. @@ +3111,5 @@ > + NS_ENSURE_TRUE_VOID(a2dp); > + a2dp->HandleBackendError(); > + BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); > + NS_ENSURE_TRUE_VOID(hfp); > + hfp->HandleBackendError(); Still I prefer to call |hfp->HandleBackendError| first and then |a2dp->HandleBackendError|, to conform with ordinary disconnection order. ::: dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp @@ +1170,5 @@ > +BluetoothHfpManager::HandleBackendError() > +{ > + MOZ_ASSERT(NS_IsMainThread()); > + > + if (!(mConnectionState == HFP_CONNECTION_STATE_DISCONNECTED)) { Simplify to |mConnectionState != HFP_CONNECTION_STATE_DISCONNECTED|. @@ +1175,5 @@ > + ConnectionStateNotification(HFP_CONNECTION_STATE_DISCONNECTED, > + mDeviceAddress); > + } > + > + if (!(mAudioState == HFP_AUDIO_STATE_DISCONNECTED)) { Simplify to |mAudioState != HFP_AUDIO_STATE_DISCONNECTED|.
Attachment #8602604 - Flags: review?(btian) → review+
Comment on attachment 8602604 [details] [diff] [review] Bug 1160127 - Send HFP/A2DP profile disconnection notification Review of attachment 8602604 [details] [diff] [review]: ----------------------------------------------------------------- ::: dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ +3111,5 @@ > + NS_ENSURE_TRUE_VOID(a2dp); > + a2dp->HandleBackendError(); > + BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); > + NS_ENSURE_TRUE_VOID(hfp); > + hfp->HandleBackendError(); I did it on purpose, following by Bluetooth SIG whitepaper 'SIMULTANEOUS USE OF HFP, A2DP, AND AVRCP PROFILES'. But because this is not 'real' disconnection, I'm happy to modify it in any order. See: HFP+AVDTP+AVCTP CONNECTION RELEASE Figure 12: HFP+AVDTP+AVCTP Connection Release initiated from AG_MP. Figure 13: HFP+AVDTP+AVCTP Connection Release initiated from HF_RD HFP disconnects after A2DP disconnected.
Got it. Should we revise disconnection order in profile controller? Profile controller always triggers HFP manager first no matter connection/disconnection. (In reply to Shawn Huang [:shawnjohnjr] from comment #15) > See: > HFP+AVDTP+AVCTP CONNECTION RELEASE > Figure 12: HFP+AVDTP+AVCTP Connection Release initiated from AG_MP. > Figure 13: HFP+AVDTP+AVCTP Connection Release initiated from HF_RD > > HFP disconnects after A2DP disconnected.
Flags: needinfo?(shuang)
Attachment #8602604 - Attachment is obsolete: true
Flags: needinfo?(shuang)
Comment on attachment 8602656 [details] [diff] [review] Bug 1160127 - Send HFP/A2DP profile disconnection notification, r=btian (v2.2) NOTE: Please see https://wiki.mozilla.org/Release_Management/B2G_Landing to better understand the B2G approval process and landings. [Approval Request Comment] Bug caused by (feature/regressing bug #): daemon recovery follow-up bug User impact if declined: audio path goes wrong Testing completed: 1. HFP profile: a. Pair and cnnect HFP profile supported headset. b. Make an incoming/outgoing call and during call session, then kill daemon. c. Check audio routed back to earpiece. d. Go to 'Settings>Bluetooth Settings' and connects HFP profile. e. Check audio routed back to bluetooth headset. 2. A2DP profile a. Pair and connect A2DP profile headset. b. Play music. c. Verify audio routed to A2DP headset then kill daemon. d. Check audio routed to speaker. d. Go to 'Settings>Bluetooth Settings' and connects A2DP profile. e. Check audio routed back to bluetooth headset. Risk to taking this patch (and alternatives if risky): none String or UUID changes made by this patch: none
Attachment #8602656 - Flags: approval-mozilla-b2g37?
waiting for central landing here.
Hmm, I cannot push to b2g-inbound. b2g-inbound is CLOSED! Reason: Widespread infra issues, this closed means CLOSED To push despite the closed tree, include "CLOSED TREE" in your push comment
Keywords: checkin-needed
(In reply to Ben Tian [:btian] from comment #16) > Got it. Should we revise disconnection order in profile controller? Profile > controller always triggers HFP manager first no matter > connection/disconnection. > > (In reply to Shawn Huang [:shawnjohnjr] from comment #15) > > See: > > HFP+AVDTP+AVCTP CONNECTION RELEASE > > Figure 12: HFP+AVDTP+AVCTP Connection Release initiated from AG_MP. > > Figure 13: HFP+AVDTP+AVCTP Connection Release initiated from HF_RD > > > > HFP disconnects after A2DP disconnected. The whitepaper recommends for connection establishment: HFP first; as for connection release: HFP last.
Keywords: checkin-needed
Whiteboard: [ETA:5/8]
Ryan, are we waiting anything to land comment 25 into m-c?
Flags: needinfo?(ryanvm)
Status: NEW → RESOLVED
Closed: 10 years ago
Resolution: --- → FIXED
Looks like it was merged a little bit ago. Yesterday was busy, sorry. In the future, you're better off pinging the sheriff on duty on IRC rather than ni? in the bug.
Flags: needinfo?(ryanvm)
Target Milestone: --- → 2.2 S12 (15may)
Hi Josh, STR: 1. Turn on bluetooth 2. Get pid of bluetooth daemon: "adb shell ps bluetoothd" You will see pid number. For example, USER PID PPID VSIZE RSS WCHAN PC NAME bluetooth 896 1 19152 4404 ffffffff b6ee0894 S /system/bin/bluetoothd 3. Kill bluetooth daemon by sending command: "adb shell kill -9 <pid of bluetoothd>", for example 896. So, just type: adb shell kill -9 896
Flags: needinfo?(jocheng)
Comment on attachment 8602656 [details] [diff] [review] Bug 1160127 - Send HFP/A2DP profile disconnection notification, r=btian (v2.2) Approving and requesting QA verify on central and 2.2 when land. STR at comment 30
Flags: needinfo?(jocheng) → needinfo?(fan.luo)
Attachment #8602656 - Flags: approval-mozilla-b2g37? → approval-mozilla-b2g37+
Whiteboard: [CR 830266]
Whiteboard: [CR 830266] → [caf priority: p2][CR 830266]
This problem has been verified as pass on latest build of Flame v3.0 STR: 1. Turn on bluetooth and connect a bluetooth headset. 2. Get pid of bluetooth daemon: "adb shell ps bluetoothd" You will see pid number. For example, USER PID PPID VSIZE RSS WCHAN PC NAME bluetooth 896 1 19152 4404 ffffffff b6ee0894 S /system/bin/bluetoothd 3. Kill bluetooth daemon by sending command: "adb shell kill -9 <pid of bluetoothd>", for example 896. So, just type: adb shell kill -9 896 See Video:1305.mp4 Bulid information: FLame3.0: Build ID 20150518010206 Gaia Revision afea16de7a76c3b6d15c35fb4c37bac71c8ddc6a Gaia Date 2015-05-17 03:33:40 Gecko Revision https://hg.mozilla.org/mozilla-central/rev/35918b0441b4 Gecko Version 41.0a1 Device Name flame Firmware(Release) 4.4.2 Firmware(Incremental) eng.cltbld.20150518.042019 Firmware Date Mon May 18 04:20:30 EDT 2015 Bootloader L1TC000118D0
QA Whiteboard: [MGSEI-Triage+]
Flags: needinfo?(fan.luo)
Keywords: verifyme
Attached video v2.2.mp4
This bug has been verified as pass on latest build of Flame v2.2 and Nexus5 v2.2 by the STR in Comment 30. Actual results: The Bluetooth process is terminated, the Bluetooth headset icon disappears and the Bluetooth function switch is gray. See Video:v2.2.mp4 Reproduce rate: 0/10 Device: FLame v2.2 build(Pass) Build ID 20150604002503 Gaia Revision b96e657ce2822df5da5da1a8ba91c38ad3281bc9 Gaia Date 2015-06-04 05:59:57 Gecko Revision https://hg.mozilla.org/releases/mozilla-b2g37_v2_2/rev/273f8ee45c88 Gecko Version 37.0 Device Name flame Firmware(Release) 4.4.2 Firmware(Incremental) eng.cltbld.20150604.102004 Firmware Date Thu Jun 4 10:20:13 EDT 2015 Bootloader L1TC000118D0 Device: Nexus v2.2 build(Pass) Build ID 20150604162503 Gaia Revision 8fc797527a3eca7665bc1d1828848f2fb77ca99f Gaia Date 2015-06-04 07:46:11 Gecko Revision https://hg.mozilla.org/releases/mozilla-b2g37_v2_2/rev/f2157a04d75b Gecko Version 37.0 Device Name hammerhead Firmware(Release) 5.1 Firmware(Incremental) eng.cltbld.20150604.195634 Firmware Date Thu Jun 4 19:56:49 EDT 2015 Bootloader HHZ12f
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: