Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot find camera when location services are disabled (Android 13 and possibly others) #10

Open
visionok opened this issue Dec 7, 2024 · 15 comments

Comments

@visionok
Copy link

visionok commented Dec 7, 2024

Using f-droid version of this app Version 0.18b (182)
Phone: Tank 2 Android 13
Camera: DSC-RX100M7

When I try to add camera after a few seconds it fails:

Error: discovery_timeout

@Staacks
Copy link
Owner

Staacks commented Dec 7, 2024

ok, first I should mention that version 1.00 should appear on F-Droid tomorrow (it has already been built, but their build cycle is still working on other apps and it will probably finish tomorrow). This will fix an important issue on Android 13, which would otherwise not allow your phone to reconnect to the camera once it has connected. If you want to, you can try the apk from the release on github before that, but you can just wait one day.

However, this is not what you describe. For this I would first ask if you have enabled the Bluetooth remote on the camera (this is typically a different setting in a different menu than the pairing option)?

@visionok
Copy link
Author

visionok commented Dec 7, 2024

I've followed the instructions in the camera's manual:

Bluetooth Rmt Ctrl is On
Then in Bluetooth Settings enter Pairing mode

I will try the new version when it's available. Thanks!

@Staacks
Copy link
Owner

Staacks commented Dec 7, 2024

ok, it will very likely be necessary for your phone. However, I suspect that you are seeing a different problem. I don't recall anyone trying the app with an RX100 VII and I suspect that there is something different in its Bluetooth advertisment packet which prevents it from being recognized.

f you don't mind, I would like to check this advertisement packet. If you have not yet dealt with Bluetooth before, I recommend installing the app "nRF connect" by Nordic Semiconductor for that. Open its "Scanner" tab, turn on the camera and see if it appears in the list. It should show up with a "connect" button next to it. Ignore that button and instead press the name of the camera on the Scanner tab, the entry will expand and show the information from the advertisement packet. If you tap "raw" below the data, you get an option to copy the raw data. That's what I would like to see.

@visionok
Copy link
Author

visionok commented Dec 8, 2024

Here you go:

0x02010717FF2D0103006400433422EC000000000000000000000000030300180C094453432D52583130304D37

@Staacks
Copy link
Owner

Staacks commented Dec 8, 2024

Thanks. This is almost identical to what my α6400 and should show up. Now I am a bit lost here and have to start looking for details that are different here...

In nRF Connect, does it have the "Connect" button next to the camera or does the button say something else (I am checking if some other app or system service is already connected to the camera)? Similarly, in the system's Bluetooth settings: Is the camera already listed there (if so, does deleting it there make a difference)?

If it is none of these, I am wondering if it might be something about your Tank 2. Not exactly a device I expect to easily find for testing, but would you see a chance to test the camera with a different phone from family/colleagues/friends? This would at least narrow down if we are looking at something related to the RX100 or the Tank 2.

@visionok
Copy link
Author

visionok commented Dec 8, 2024

nRF Connect does show "Connect..." clicking on it, it shows it's connected (but not bonded - whatever that means).

After I installed Alpha Remote and before running it for the first time, I went to the System Bluetooth settings and paired with my camera - I thought it would need to be paired for Alpha Remote to function. After running Alpha Remote I realised that it appears it will do the pairing itself. So I went back to System Bluetooth settings to forget the pairing. So to answer your question, no the System is not paired to the camera.

BTW I've already done the time honoured "Reboot phone" and "Shutoff and Restart Camera" many times.

To be honest the Tank 2 was not my first choice to try out this app - it's too bulky to carry around everyday - but it is the newest that I have and the only one that satisfies the Android version requirement. I would have preferred to install it on my Oneplus 7T Pro (where I already have Sony's Imaging Edge installed), but sadly that's too old for this app.

I'll see if I can find another phone to try - most of the people I know use iphones(!)

@visionok
Copy link
Author

visionok commented Dec 9, 2024

I'm sure there's a good reason for it: why can't the normal pairing procedure be used? System Bluetooth pairs OK, nRF Connect pairs OK, why isn't this app able to pair?

@Staacks
Copy link
Owner

Staacks commented Dec 9, 2024

The system actually has to do three things here. It has to...

  • Pair the camera: This links camera and phone to each other, so they can connect immediately without the need to tell them which device to connect to every time.
  • Bond the camera: This is almost the same as pairing, but it also exchanges an encryption key, so the connection is secured. Technically, this is the correct term for BLE devices like the camera, but you will hardly ever read this word in an app. Users do not care about the difference and usually only know the word "pairing", so apps usually just use "pairing" when they are "bonding".
  • Associate the camera with the app: This is not a Bluetooth term, but an Android term. It it the process of telling Android that the user agreed that a specific app is responsible for a specific device. So, in this case it tells Android that whenever your camera shows up, it should launch my app's service, which will connect and work with the device.

Associating the device is what makes my app different from what for example the Bluetooth geotagging feature in Imaging Edge does. Imaging Edge does not associate, but keeps its own service active and looks for new devices all the time. In contrast an associated app can ask the system to wake it when the device turns up.

A device can also be associated without being bonded and then the associated app can establish the bond if necessary - usually without additional permission from the user. In fact, my app establishes the bond when it is successfully associated, but if the device is already bonded at that point, the bond request is simply ignored. So, it should work if the device has already been bonded through the system, but it still needs to trigger the association process. The only reason I asked to try it without being "paired" first was to make sure that there is no other app/service jumping in and taking the connection before the camera shows up for the association. (Not even sure if that could actually happen to be honest.)

Now, my app cannot just tell Android that the user agreed to associate, because there would be no way to check that this is true and it would open the gates for a lot of dubious practices. Instead, my app gives Android a filter (in this case a pattern for an advertisement packet, which is why I wanted to check that first on an untested camera model) and tells it to start the association process. Android then scans for the device and should show a dialog to ask the user if the app should be associated with the device it found to match the filter.

Unfortunately, that's where manufacturers can do their own thing which often turns into a nightmare for hobby projects as devices might do something unusual here and I cannot just buy every phone that acts weird and I also cannot test the device-specific things in an emulator. In this case there are also not yet many apps that use association for Bluetooth devices as it was "only" introduced with Android 12 (hence the minimum Android version for my app). I even see several variants of this process among different Android versions and Google's own phones. There just has not yet been a process where apps and manufacturers had to smooth out some rough edges as the feature is not yet used enough.

In theory, it should be simple: Ask the system to start the association process and when the system reports that this was successful, create the bonding if necessary (and if it has not already beend done). The somewhat good news is that in your case it fails right at the beginning, so there is not that much to check. The word "discovery_timeout" is not in my app, but it is the result reported by the association process. It suggests that the device was not found within a timeout period, which means that either no matching advertisement packet was received, there is something wrong with the filter or the association process is somehow broken.

---- Enough background monologue, back to fixing :) ----

At this point I am not super optimistic to find a fix soon, but if you manage to test your camera with a different phone, I can at least narrow it down far enough to properly group this with similar problems that other users might report in the future or that I might be able to reproduce on other phone models (I have never seen a Tank 2, so I do not expect to randomly find a friend with one, but other devices might show the same behavior).

  • One little thing I'd like you to test is to turn off Bluetooth on your Oneplus while testing if it is nearby. The camera does not show it, but in my experience Sony's camera can be paired to multiple devices at the same time (probably because being paired to a phone for geotagging and Sony's Bluetooth remote is a common thing) and I am not sure if it is possible that the Oneplus might do something before the Tank 2 can associate if the camera is also still paired (or rather bonded) to the Oneplus.

One other thing that might or might not help is getting a log from the device. Some component of your device might be reporting a problem there. So, a log might help. Ideally without a filter, but we can keep it short and only include the few seconds from pressing "Add camera" in the app and the timeout message while the camera is in pairing mode.
Do you have an idea how to get a log or should I add some instructions?

@visionok
Copy link
Author

visionok commented Dec 9, 2024

Thanks, really appreciate the detailed background info. It's always good to know more about the "Secret Life of Apps - what they're doing when you're not looking" :)

I've never paired the Oneplus with the camera before (in fact I've never even enabled the Bluetooth settings on the camera before this). However just in case there could be some interference I turned off bluetooth on the Oneplus. But the result is the same: "discovery_timeout".

I would be happy to produce a log if you could tell me what I need to do.

Also please do not feel you're under any pressure or obligation to resolve this issue. Even if it's fixed I will most likely not be using it on the Tank 2 anyway. The main reason I tried the app in the first place is a combination of curiosity and your request for comments on whether the app works for other camera models.

@visionok
Copy link
Author

visionok commented Dec 9, 2024

About the log file - I already have developer settings enabled on the phone, and I have adb installed on computer.

@Staacks
Copy link
Owner

Staacks commented Dec 9, 2024

Also please do not feel you're under any pressure or obligation to resolve this issue. Even if it's fixed I will most likely not be using it on the Tank 2 anyway. The main reason I tried the app in the first place is a combination of curiosity and your request for comments on whether the app works for other camera models.

Same to you :) Don't feel pressured to do a bunch of stuff to help me fix my app. But I am happy if I can make this work on as many phones as possible.

If you already have adb and the phone in developer mode, it should be simple. All you need to do is adb logcat and you should see a lot of logging data flying at you. If not, you might need to switch your phone from "USB charging" to "USB mass storage" or to "USB file transfer" or something similar to enable the data connection (your phone should typically ask if you trust the computer at that point).

Now, normally I would add some filters to that command to avoid logging something that you would not like to share (no idea what other apps leak, but maybe there is an app that others should not know about and it logs its sync activity in just the wrong moment). But since in this case I have no idea what service might log something relevant and since it is only a few seconds, I would suggest to just capture the short duration and then review if there is something in there that should not be shared before you post it.

So, press "Add Camera" and start the logcat a few seconds before you continue (for me it sends a bunch of stuff right after starting the logcat, which I do not need). Then press "search camera" and wait until you get the error.

In the output search for a log entry "Associating." with the tag "alpharemote" as well as an entry "onFailure". I only need what's inbetween these two.

@visionok
Copy link
Author

Quick question: does alpha remote need "Location" to be enabled? When I used nRF Connect, it needed Location On before it did anything.

I read elsewhere that for "companiondevice" apps like this one, it is sufficient to give the app permission to access location but not necessary for Location to actually be On.

So the situation here is Location is OFF, but the app has permission to access "Nearby devices". A line that stands out from the logcat is:

BtGatt.ScanManager: Ignore start scan in location-off with associatedDevices is empty and eligibleForSanitizedExposureNotification is false. This scan will be resumed when location is on: 10

So is Location being OFF the problem? If so, then apologies for wasting your time.

@visionok
Copy link
Author

I briefly enabled Location, just enough time for the app to pair with the camera, and not enough time to get a fix :)

So yeah, it was Location being disabled that was the problem. Apologies for sending you on a wild goose chase.

It seems after the initial pairing Location does not need to be enabled anymore - I turned off the camera and turned it back on, it automatically connected (ie app controls reappeared in the Notifications). Because I had the camera off and back on almost immediately I think the auto reconnect was because of bluetooth's "lose of signal reconnect" mechanism kicking. When I tried later with the camera having been off for a few minutes, auto reconnect did not take place - so probably Location does have to be ON for the app to function correctly.

This is a great app with lots of useful features, but sadly I'll be sticking with Imaging Edge because of its ability to display the camera's viewfinder on the phone.

Thanks.

@Staacks
Copy link
Owner

Staacks commented Dec 10, 2024

I briefly enabled Location, just enough time for the app to pair with the camera, and not enough time to get a fix :)

So yeah, it was Location being disabled that was the problem. Apologies for sending you on a wild goose chase.

First of all: No need to apologize. You helped me figure out an issue that will certainly also affect others.

In fact, I will definitely leave this open as the app should be able to notice the problem and notify the user. Did you see any error from alpharemote in the logs? Because it seems as if both, the app as well as the system were not aware of a problem. It simply timed out because it did not get any results.

Bluetooth and location have always had a difficult relationship. The problem is that for example McDonalds could place a Bluetooth beacon at each of their restaurants and they could figure out when anyone with their app is at a McDonalds, which McDonalds they are at, how long they stay there, ... with enough beacons they could even tell if they used the bathroom and maybe even which stall. So, at some point Android started requiring location permissions and location services for any Bluetooth scan, which was a bit of a quick fix (in my opinion) and quite confusing for the users who would not understand why these apps suddenly wanted their location.

The CompanionDeviceService should actually resolve this as it cannot be abused to determine the users location, because the system does the scanning and you only get to see the device the user agreed to. In fact, my app does not request any location permissions and I can add my camera and connect to it with location services disabled on my Pixel 6 with Android 15. So, I now have to do some testing to see which exact devices or Android versions are affected and if I can tell if location services are disabled without needing location permissions...

This is a great app with lots of useful features, but sadly I'll be sticking with Imaging Edge because of its ability to display the camera's viewfinder on the phone.

I understand. I would love to have an app that could do both. Quickly connect via Bluetooth for simple triggers, but when you push a button to enable a preview, it would take a moment to also connect via Wifi. The cameras could do it, but with so many variants of the Wifi API I cannot do it without a stash of cameras and I somehow doubt that Sony will integrate the Bluetooth solution into their apps.

@Staacks Staacks changed the title Error: discovery_timeout pairing to DSC-RX100M7 Cannot find camera when location services are disabled (Android 13 and possibly others) Dec 10, 2024
@visionok
Copy link
Author

Here is a more complete log (I've only included the entries that I believe are relevant)

10:57:21.231 1868 2264 I BtGatt.ScanManager: Ignore start scan in location-off with associatedDevices is empty and eligibleForSanitizedExposureNotification is false. This scan will be resumed when location is on: 10
10:57:26.199 1877 1877 W BluetoothDiscovery: -MSG_DISCOVERY_BLE_TIMEOUT- stopBLEScan:
10:57:26.200 1877 1877 I BluetoothDiscovery: -stopBLEScan- >>>>>>
10:57:26.200 1877 1877 D BluetoothAdapter: isLeEnabled(): ON
10:57:26.201 1868 26861 I AppScanStats: BLE_SCAN_RESULT_RECEIVED[8]reportBleScanResults=0
10:57:26.202 1868 26861 I AppScanStats: BLE_SCAN_STATE_CHANGED[8]reportBleScanStopped=true
10:57:26.202 1868 26861 D ActivityAttributionService: notifyActivityAttributionInfo UID=1002 packageName=com.android.bluetooth deviceAddress=no_active_device_address
10:57:26.202 1868 26861 I bt_btif : get_profile_interface: get_profile_interface: id = activity_attribution
10:57:26.202 1868 26861 E bt_stack: [ERROR:com_android_bluetooth_btservice_ActivityAttribution.cpp(172)] Failed to get ActivityAttribution Interface
10:57:26.204 1868 2320 I bt_stack: [INFO:gatt_api.cc(1045)] GATT_Deregister gatt_if=8
10:57:26.204 1877 1877 I BluetoothDiscovery: -notifyDiscoveryStatus- bBle : true ,bStart : false
10:57:29.208 1877 1877 D BluetoothManager: ---scan--- type : 0,timeout : 30000
10:57:29.208 1877 1877 I BluetoothDiscovery: -notifyDiscoveryStatus- bBle : true ,bStart : true
10:57:29.209 1877 1877 D BluetoothAdapter: isLeEnabled(): ON
10:57:29.214 1868 2320 I bluetooth: GATT_Register: Allocated name:GattClient uuid:ce26e066-6b3f-0805-5867-074b4eac0b80 gatt_if:8 eatt_support:0
10:57:29.215 1877 1934 D BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=8 mScannerId=0
10:57:29.221 1868 26861 E BluetoothUtils: Permission denial: Location is off.
10:57:29.224 1868 26861 I AppScanStats: BLE_SCAN_STATE_CHANGED[8]reportBleScanStarted=true
10:57:29.225 1868 26861 D ActivityAttributionService: notifyActivityAttributionInfo UID=1002 packageName=com.android.bluetooth deviceAddress=no_active_device_address
10:57:29.225 1868 26861 I bt_btif : get_profile_interface: get_profile_interface: id = activity_attribution
10:57:29.225 1868 26861 E bt_stack: [ERROR:com_android_bluetooth_btservice_ActivityAttribution.cpp(172)] Failed to get ActivityAttribution Interface
10:57:29.226 1868 2264 I BtGatt.ScanManager: Cannot start unfiltered scan in location-off. This scan will be resumed when location is on: 8
10:57:29.226 1877 1877 I BluetoothDiscovery: -startBLEScan- >>>>>> startScan :>>
10:57:41.232 29738 29738 D BluetoothAdapter: isLeEnabled(): ON
10:57:41.236 1868 26861 I AppScanStats: BLE_SCAN_RESULT_RECEIVED[10]reportBleScanResults=0
10:57:41.237 1868 26861 I AppScanStats: BLE_SCAN_STATE_CHANGED[10]reportBleScanStopped=false
10:57:41.238 1868 26861 D ActivityAttributionService: notifyActivityAttributionInfo UID=1002 packageName=com.android.bluetooth deviceAddress=no_active_device_address
10:57:41.238 1868 26861 I bt_btif : get_profile_interface: get_profile_interface: id = activity_attribution
10:57:41.238 1868 26861 E bt_stack: [ERROR:com_android_bluetooth_btservice_ActivityAttribution.cpp(172)] Failed to get ActivityAttribution Interface
10:57:41.241 1868 2320 I bt_stack: [INFO:gatt_api.cc(1045)] GATT_Deregister gatt_if=10
10:57:41.244 1487 1500 I AppLockController: , pkg=org.staacks.alpharemote
10:57:41.245 29670 29670 D alpharemote: onFailure

So, at some point Android started requiring location permissions and location services for any Bluetooth scan, which was a bit of a quick fix (in my opinion) and quite confusing for the users who would not understand why these apps suddenly wanted their location.

As someone in this stackexchange post says:

Location needs to be enabled for Bluetooth Low Energy Scanning on Android 6.0

forcing GPS to search for Bluetooth is the most counter intuitive way to let user know their location may be used

Effectively the user is getting a double whammy: firstly by the "MacDonalds App" potentially knowing when you have used their toilet facilities without buying a meal, secondly by Google's slurping up your GPS data.

The CompanionDeviceService should actually resolve this as it cannot be abused to determine the users location, because the system does the scanning and you only get to see the device the user agreed to.

The question is whether Google will separate out the Location and Bluetooth scanning permissions again now that they have "solved" that problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants