diff options
author | Benjamin Franz <bfranz@google.com> | 2014-11-05 20:43:27 +0000 |
---|---|---|
committer | Benjamin Franz <bfranz@google.com> | 2014-12-02 11:20:57 +0000 |
commit | 2287bc2b01df774378123fe7bc7bca14fee549f7 (patch) | |
tree | d23b7139541e599f745e031cf6a1d8bcf7c916fc /src/com/android/bluetooth | |
parent | 63fce3b9cad29f241c2a71b638655a09d21acb46 (diff) | |
download | android_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.java | 31 | ||||
-rw-r--r-- | src/com/android/bluetooth/btservice/AdapterService.java | 24 | ||||
-rwxr-xr-x | src/com/android/bluetooth/hfp/HeadsetService.java | 2 | ||||
-rw-r--r-- | src/com/android/bluetooth/hfp/HeadsetStateMachine.java | 10 |
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) |