Android Enterprise - BluetoothAdapter.startDiscovery() does not start scan
Asked Answered
C

0

6

I am using BluetoothAdapter.startDiscovery() to find a specific Bluetooth device (it is Bluetooth 2.0 device, so I have to use BluetoothAdapter.startDiscovery()). I have all required permissions (Bluetooth, Location), and the app works just fine.

But now I have to use this app under Android Enterprise (Work Profile). Under Work Profile it does not start scan. All the limitations in the profile are disabled.
After investigation logcat I found such lines:

Non work profile log:

2019-07-29 10:23:13.109 10230-10446/? D/BluetoothAdapterService: startDiscovery() uid = 10126, pid = 6328
2019-07-29 10:23:13.110 10230-10446/? D/BluetoothAdapterService: startDiscovery

Work profile log:

2019-07-29 10:21:26.536 10230-13473/? D/BluetoothAdapterService: startDiscovery() uid = 1010126, pid = 13390
2019-07-29 10:21:26.536 10230-13473/? W/BluetoothAdapterService: startDiscovery() - Not allowed for non-active user

This is the log from OnePlus 6, but I observed similar logcat also on Samsung S10. Also customers said they have same problem on S9, S8 and on some Nokia device (actually all devices they tested on).

Searching through Android sources, I found the following code, producing this log:

    public boolean startDiscovery() {
        if (!Utils.checkCaller()) {
            Log.w(TAG, "startDiscovery() - Not allowed for non-active user");
            return false;
        }
        AdapterService service = getService();
        if (service == null) return false;
        return service.startDiscovery();
    }

Which calls Utils.checkCaller() to check:

public static boolean checkCaller() {
    boolean ok;
    // Get the caller's user id then clear the calling identity
    // which will be restored in the finally clause.
    int callingUser = UserHandle.getCallingUserId();
    int callingUid = Binder.getCallingUid();
    long ident = Binder.clearCallingIdentity();
    try {
        // With calling identity cleared the current user is the foreground user.
        int foregroundUser = ActivityManager.getCurrentUser();
        ok = (foregroundUser == callingUser);
        if (!ok) {
            // Always allow SystemUI/System access.
            int systemUiUid = ActivityThread.getPackageManager().getPackageUid(
                    "com.android.systemui", UserHandle.USER_OWNER);
            ok = (systemUiUid == callingUid) || (Process.SYSTEM_UID == callingUid);
        }
    } catch (Exception ex) {
        Log.e(TAG, "checkIfCallerIsSelfOrForegroundUser: Exception ex=" + ex);
        ok = false;
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
    return ok;
}

So startDiscovery() uid = 10126 and startDiscovery() uid = 1010126 differ in uid, which I think is caused by work profile, which as I think causes the check (foregroundUser == callingUser) to be false.

Finally the question: Am I right that it is a bug? If yes - is there any way to workaround it? If no - how can I enable Bluetooth classic scan in work profile?

Cladophyll answered 29/7, 2019 at 8:1 Comment(6)
I'm having the same problem. Did you find a solution to this?Translucent
Same problem too. Did you find a solution ?Tremor
@Romain Caron it's a bug in Android that I have reported to them, and themes like they are working on it: issuetracker.google.com/issues/138670165 No workaround so farCladophyll
@Translucent it's a bug in Android that I have reported to them, and themes like they are working on it: issuetracker.google.com/issues/138670165 No workaround so farCladophyll
@VladyslavMatviienko thank you. Now, wait and see :)Tremor
Running into the same problem. ... the UID differs because work user is user 10, where private user is user 0. workaround: use work profile only devices. hopefully Google will fix this soon.Groom

© 2022 - 2024 — McMap. All rights reserved.