summaryrefslogtreecommitdiffstats
path: root/src/com/android/bluetooth
diff options
context:
space:
mode:
authorBenjamin Franz <bfranz@google.com>2014-11-05 20:43:27 +0000
committerBenjamin Franz <bfranz@google.com>2014-12-02 11:20:57 +0000
commit2287bc2b01df774378123fe7bc7bca14fee549f7 (patch)
treed23b7139541e599f745e031cf6a1d8bcf7c916fc /src/com/android/bluetooth
parent63fce3b9cad29f241c2a71b638655a09d21acb46 (diff)
downloadandroid_packages_apps_Bluetooth-2287bc2b01df774378123fe7bc7bca14fee549f7.tar.gz
android_packages_apps_Bluetooth-2287bc2b01df774378123fe7bc7bca14fee549f7.tar.bz2
android_packages_apps_Bluetooth-2287bc2b01df774378123fe7bc7bca14fee549f7.zip
Allow managed profile apps to use some bluetooth functionality.
Adding a function that checks whether the calling user is the foreground user or a managed profile associated to this user. This function is deployed in selected spots to give managed profile apps access to some part of the bluetooth functionality including the HeadsetService. Bug: 16968338 Change-Id: Ib0db0847cf361b449484195553725c38ede3b618
Diffstat (limited to 'src/com/android/bluetooth')
-rw-r--r--src/com/android/bluetooth/Utils.java31
-rw-r--r--src/com/android/bluetooth/btservice/AdapterService.java24
-rwxr-xr-xsrc/com/android/bluetooth/hfp/HeadsetService.java2
-rw-r--r--src/com/android/bluetooth/hfp/HeadsetStateMachine.java10
4 files changed, 51 insertions, 16 deletions
diff --git a/src/com/android/bluetooth/Utils.java b/src/com/android/bluetooth/Utils.java
index 56d5a641b..6b19a78cb 100644
--- a/src/com/android/bluetooth/Utils.java
+++ b/src/com/android/bluetooth/Utils.java
@@ -19,10 +19,14 @@ package com.android.bluetooth;
import android.app.ActivityManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
+import android.content.Context;
import android.content.ContextWrapper;
+import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.ParcelUuid;
+import android.os.Process;
import android.os.UserHandle;
+import android.os.UserManager;
import android.util.Log;
import java.io.IOException;
@@ -208,6 +212,33 @@ final public class Utils {
return ok;
}
+ public static boolean checkCallerAllowManagedProfiles(Context mContext) {
+ if (mContext == null) {
+ return checkCaller();
+ }
+ boolean ok;
+ // Get the caller's user id and if it's a managed profile, get it's parents
+ // id, then clear the calling identity
+ // which will be restored in the finally clause.
+ int callingUser = UserHandle.getCallingUserId();
+ long ident = Binder.clearCallingIdentity();
+ try {
+ UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ UserInfo ui = um.getProfileParent(callingUser);
+ int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
+ // With calling identity cleared the current user is the foreground user.
+ int foregroundUser = ActivityManager.getCurrentUser();
+ ok = (foregroundUser == callingUser) ||
+ (foregroundUser == parentUser);
+ } catch (Exception ex) {
+ Log.e(TAG, "checkCallerAllowManagedProfiles: Exception ex=" + ex);
+ ok = false;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ return ok;
+ }
+
/**
* Enforce the context has android.Manifest.permission.BLUETOOTH_ADMIN permission. A
* {@link SecurityException} would be thrown if neither the calling process or the application
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index 7567442a7..48fe29aeb 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -685,7 +685,7 @@ public class AdapterService extends Service {
public String getAddress() {
if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
- (!Utils.checkCaller())) {
+ (!Utils.checkCallerAllowManagedProfiles(mService))) {
Log.w(TAG, "getAddress() - Not allowed for non-active user and non system user");
return null;
}
@@ -730,7 +730,7 @@ public class AdapterService extends Service {
}
public int getScanMode() {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getScanMode() - Not allowed for non-active user");
return BluetoothAdapter.SCAN_MODE_NONE;
}
@@ -795,7 +795,7 @@ public class AdapterService extends Service {
return service.cancelDiscovery();
}
public boolean isDiscovering() {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "isDiscovering() - Not allowed for non-active user");
return false;
}
@@ -820,7 +820,7 @@ public class AdapterService extends Service {
}
public int getProfileConnectionState(int profile) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getProfileConnectionState- Not allowed for non-active user");
return BluetoothProfile.STATE_DISCONNECTED;
}
@@ -879,7 +879,7 @@ public class AdapterService extends Service {
}
public String getRemoteName(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getRemoteName() - Not allowed for non-active user");
return null;
}
@@ -890,7 +890,7 @@ public class AdapterService extends Service {
}
public int getRemoteType(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getRemoteType() - Not allowed for non-active user");
return BluetoothDevice.DEVICE_TYPE_UNKNOWN;
}
@@ -901,7 +901,7 @@ public class AdapterService extends Service {
}
public String getRemoteAlias(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getRemoteAlias() - Not allowed for non-active user");
return null;
}
@@ -923,7 +923,7 @@ public class AdapterService extends Service {
}
public int getRemoteClass(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getRemoteClass() - Not allowed for non-active user");
return 0;
}
@@ -934,7 +934,7 @@ public class AdapterService extends Service {
}
public ParcelUuid[] getRemoteUuids(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getRemoteUuids() - Not allowed for non-active user");
return new ParcelUuid[0];
}
@@ -945,7 +945,7 @@ public class AdapterService extends Service {
}
public boolean fetchRemoteUuids(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "fetchRemoteUuids() - Not allowed for non-active user");
return false;
}
@@ -1052,7 +1052,7 @@ public class AdapterService extends Service {
public ParcelFileDescriptor connectSocket(BluetoothDevice device, int type,
ParcelUuid uuid, int port, int flag) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "connectSocket() - Not allowed for non-active user");
return null;
}
@@ -1064,7 +1064,7 @@ public class AdapterService extends Service {
public ParcelFileDescriptor createSocketChannel(int type, String serviceName,
ParcelUuid uuid, int port, int flag) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "createSocketChannel() - Not allowed for non-active user");
return null;
}
diff --git a/src/com/android/bluetooth/hfp/HeadsetService.java b/src/com/android/bluetooth/hfp/HeadsetService.java
index 0755c357a..1e8dc7f99 100755
--- a/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -129,7 +129,7 @@ public class HeadsetService extends ProfileService {
}
private HeadsetService getService() {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG,"Headset call not allowed for non-active user");
return null;
}
diff --git a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
index ba8f80a94..3bbaa35b4 100644
--- a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
+++ b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
@@ -53,6 +53,7 @@ import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.PowerManager;
+import android.os.UserHandle;
import android.os.PowerManager.WakeLock;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
@@ -2310,7 +2311,8 @@ final class HeadsetStateMachine extends StateMachine {
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- mService.sendBroadcast(intent, HeadsetService.BLUETOOTH_PERM);
+ mService.sendBroadcastAsUser(intent, UserHandle.ALL,
+ HeadsetService.BLUETOOTH_PERM);
}
private void broadcastAudioState(BluetoothDevice device, int newState, int prevState) {
@@ -2323,7 +2325,8 @@ final class HeadsetStateMachine extends StateMachine {
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- mService.sendBroadcast(intent, HeadsetService.BLUETOOTH_PERM);
+ mService.sendBroadcastAsUser(intent, UserHandle.ALL,
+ HeadsetService.BLUETOOTH_PERM);
log("Audio state " + device + ": " + prevState + "->" + newState);
}
@@ -2348,7 +2351,8 @@ final class HeadsetStateMachine extends StateMachine {
intent.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY
+ "." + Integer.toString(companyId));
- mService.sendBroadcast(intent, HeadsetService.BLUETOOTH_PERM);
+ mService.sendBroadcastAsUser(intent, UserHandle.ALL,
+ HeadsetService.BLUETOOTH_PERM);
}
private void configAudioParameters(BluetoothDevice device)