device-bose-qc35 #2520

Merged
ashimokawa merged 12 commits from device-bose-qc35 into master 5 months ago
dakhnod commented 5 months ago

This PR adds not only the device Bose QC35,
it also adds the following autop-reconnect feature:
When the headphones are turned on, the initiate a connection with the phone.
With this change, GB is notified about said change, and tries to establish a connection to the newly connected device, if the appropriate device setting is set.

The QC35 headpones always have NC turned on after boot, thus the main feature of this implementation is to turn off NC as soon as the headphones are turned on and connected to the phone.

I am open for discussion regarding the implementation, but this seems like a good first proposal.

What is missing is the ability to connect to multiple devices, since in many cases headphones can be connected to the watch simultaniously to a smartwatch or other gadget.

This PR adds not only the device Bose QC35, it also adds the following autop-reconnect feature: When the headphones are turned on, the initiate a connection with the phone. With this change, GB is notified about said change, and tries to establish a connection to the newly connected device, if the appropriate device setting is set. The QC35 headpones always have NC turned on after boot, thus the main feature of this implementation is to turn off NC as soon as the headphones are turned on and connected to the phone. I am open for discussion regarding the implementation, but this seems like a good first proposal. What is missing is the ability to connect to multiple devices, since in many cases headphones can be connected to the watch simultaniously to a smartwatch or other gadget.
dakhnod added 6 commits 5 months ago
dakhnod added 1 commit 5 months ago
bc1ce50799 Device QC35: added battery info
Owner

I tested this with the Galaxy Buds and it works. This is a good progress and we should continue in this direction. There are a few caviats there and if over time we add multiconnection support, we will need to re-think this again, but for now...:

It kind of fights a bit with the last_device_address. If we use the logic of the last_device_address, we do not need the settings to auto-reconnect based on the device_auto_connect, simply the last connected device would re-connect when it would appear (via the ACL_CONNECTED signal), as long as the "Reconnect automatically" is checked, something like this:

            String btLastDeviceAddress = GBApplication.getPrefs().getPreferences().getString("last_device_address", null);

            for(GBDevice iterated : devices){
                if(iterated.getAddress().equals(mac)) {
                    if (btLastDeviceAddress.equals(mac)) {
                        LOG.info("Bluetooth turned on (ACL_CONNECTED) => connecting to {}", mac);
                        GBApplication.deviceService().connect(iterated);
                    }
                }
            }

Unrelated to this PR, there are moments, when the auto-connection fails (not a fault of this PR):

E/nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread: Server socket cannot be started.java.io.IOException: read failed, socket might closed or timeout, read ret: -1
    	at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:758) ~[na:0.0]
    	at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:711) ~[na:0.0]
    	at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:409) ~[na:0.0]
    	at nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread.connect(BtClassicIoThread.java:159) ~[na:0.0]
    	at nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread.run(BtClassicIoThread.java:96) ~[na:0.0]

Maybe we need to add a repeated attempt or extend the wait.

Interestingly enough, this issue happens a lot more when i use the code snippet as per above. Maybe we try to access the BluetoothSocket too early or something?

cc @ashimokawa

I tested this with the Galaxy Buds and it works. This is a good progress and we should continue in this direction. There are a few caviats there and if over time we add multiconnection support, we will need to re-think this again, but for now...: It kind of fights a bit with the `last_device_address`. If we use the logic of the last_device_address, we do not need the settings to auto-reconnect based on the device_auto_connect, simply the last connected device would re-connect when it would appear (via the ACL_CONNECTED signal), as long as the "Reconnect automatically" is checked, something like this: ```java String btLastDeviceAddress = GBApplication.getPrefs().getPreferences().getString("last_device_address", null); for(GBDevice iterated : devices){ if(iterated.getAddress().equals(mac)) { if (btLastDeviceAddress.equals(mac)) { LOG.info("Bluetooth turned on (ACL_CONNECTED) => connecting to {}", mac); GBApplication.deviceService().connect(iterated); } } } ``` Unrelated to this PR, there are moments, when the auto-connection fails (not a fault of this PR): ```java E/nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread: Server socket cannot be started.java.io.IOException: read failed, socket might closed or timeout, read ret: -1 at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:758) ~[na:0.0] at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:711) ~[na:0.0] at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:409) ~[na:0.0] at nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread.connect(BtClassicIoThread.java:159) ~[na:0.0] at nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread.run(BtClassicIoThread.java:96) ~[na:0.0] ``` Maybe we need to add a repeated attempt or extend the wait. Interestingly enough, this issue happens a lot more when i use the code snippet as per above. Maybe we try to access the BluetoothSocket too early or something? cc @ashimokawa
ashimokawa reviewed 5 months ago
android:name=".externalevents.BluetoothStateChangeReceiver"
android:exported="true"
android:permission="android.permission.BLUETOOTH,android.permission.BLUETOOTH_ADMIN">
android:exported="true">
Owner

Didn't doing this broke gadgetbridge in the past for some users?

Didn't doing this broke gadgetbridge in the past for some users?
Poster

the permission attribute inside a receiver means that the sender of an intent needs to have those permissions.
Removing that attribute should, theoretically, not break anything, since it just sets the requirements for the sender lower.

the permission attribute inside a receiver means that the sender of an intent needs to have those permissions. Removing that attribute should, theoretically, not break anything, since it just sets the requirements for the sender lower.

Having that permission requirement does break things for users whos phone is sending those intents from a system app that doesn't have the permission.

The intent itself being a system one is all the protection needed.

Having that permission requirement does break things for users whos phone is sending those intents from a system app that doesn't have the permission. The intent itself being a system one is all the protection needed.
Owner

copyright headers missing

copyright headers missing
Poster

Multi-device support is crucual for me, and I would like to get that down before merging this.

Also, I implemented my own logic instead of using last_device_address, since BLE devices don't trigger ACL_CONNECTED, I believe.

Since you guys sound like multi-device sounds acceptable, let me see what can be done there...

Multi-device support is crucual for me, and I would like to get that down before merging this. Also, I implemented my own logic instead of using last_device_address, since BLE devices don't trigger ACL_CONNECTED, I believe. Since you guys sound like multi-device sounds acceptable, let me see what can be done there...
Owner

Sounds good! Let me link #1039 here to prevent double effort and encourage cooperation :)

Sounds good! Let me link https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/1039 here to prevent double effort and encourage cooperation :)
dakhnod added 1 commit 5 months ago
dakhnod added 1 commit 5 months ago
Poster

Anyway, I removed all the reconnect logic from this PR, since it doesn't belong here.
Now, this PR feels ready to be merged, the ACL_CONNECTED stuff should be handled in #2526

Anyway, I removed all the reconnect logic from this PR, since it doesn't belong here. Now, this PR feels ready to be merged, the ACL_CONNECTED stuff should be handled in https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2526
dakhnod added 1 commit 5 months ago
ashimokawa added 1 commit 5 months ago
00a9ff668f revert unrelated change
ashimokawa added 1 commit 5 months ago
8fa32d9fe2 Add copyright headers
ashimokawa merged commit b0ed617072 into master 5 months ago
ashimokawa deleted branch device-bose-qc35 5 months ago
ashimokawa referenced this issue from a commit 5 months ago
Owner

Hi @dakhnod, would you please mind to make a simple wiki page, listing supported features, so users know what is implemented? Thank you very much!

Hi @dakhnod, would you please mind to make a simple wiki page, listing supported features, so users know what is implemented? Thank you very much!

It would be great to add the info to the readme that the bose qc-35 is now supported :)

It would be great to add the info to the readme that the bose qc-35 is now supported :)
continuous-integration/woodpecker the build was successful
The pull request has been merged as b0ed617072.
Sign in to join this conversation.
No reviewers
No Milestone
No Assignees
5 Participants
Notifications
Due Date

No due date set.

Dependencies

This pull request currently doesn't have any dependencies.

Loading…
There is no content yet.