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?