summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--core/java/android/bluetooth/BluetoothHeadset.java92
-rw-r--r--core/java/android/bluetooth/IBluetoothManager.aidl4
-rwxr-xr-xcore/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl30
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java247
5 files changed, 37 insertions, 337 deletions
diff --git a/Android.mk b/Android.mk
index df4d94b..9684271 100644
--- a/Android.mk
+++ b/Android.mk
@@ -103,7 +103,6 @@ LOCAL_SRC_FILES += \
core/java/android/bluetooth/IBluetoothA2dpSink.aidl \
core/java/android/bluetooth/IBluetoothAvrcpController.aidl \
core/java/android/bluetooth/IBluetoothCallback.aidl \
- core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl \
core/java/android/bluetooth/IBluetoothHeadset.aidl \
core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl \
core/java/android/bluetooth/IBluetoothHealth.aidl \
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index adfb4b8..8d4742b 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -20,10 +20,9 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.ComponentName;
import android.content.Context;
-import android.os.Handler;
+import android.content.Intent;
+import android.content.ServiceConnection;
import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
@@ -243,8 +242,6 @@ public final class BluetoothHeadset implements BluetoothProfile {
*/
public static final int STATE_AUDIO_CONNECTED = 12;
- private static final int MESSAGE_HEADSET_SERVICE_CONNECTED = 100;
- private static final int MESSAGE_HEADSET_SERVICE_DISCONNECTED = 101;
private Context mContext;
private ServiceListener mServiceListener;
@@ -257,7 +254,14 @@ public final class BluetoothHeadset implements BluetoothProfile {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG,"Unbinding service...");
- doUnbind();
+ synchronized (mConnection) {
+ try {
+ mService = null;
+ mContext.unbindService(mConnection);
+ } catch (Exception re) {
+ Log.e(TAG,"",re);
+ }
+ }
} else {
synchronized (mConnection) {
try {
@@ -294,26 +298,15 @@ public final class BluetoothHeadset implements BluetoothProfile {
}
boolean doBind() {
- try {
- return mAdapter.getBluetoothManager().bindBluetoothProfileService(
- BluetoothProfile.HEADSET, mConnection);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to bind HeadsetService", e);
- }
- return false;
- }
-
- void doUnbind() {
- synchronized (mConnection) {
- if (mService != null) {
- try {
- mAdapter.getBluetoothManager().unbindBluetoothProfileService(
- BluetoothProfile.HEADSET, mConnection);
- } catch (RemoteException e) {
- Log.e(TAG,"Unable to unbind HeadsetService", e);
- }
- }
+ Intent intent = new Intent(IBluetoothHeadset.class.getName());
+ ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+ intent.setComponent(comp);
+ if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+ android.os.Process.myUserHandle())) {
+ Log.e(TAG, "Could not bind to Bluetooth Headset Service with " + intent);
+ return false;
}
+ return true;
}
/**
@@ -333,8 +326,18 @@ public final class BluetoothHeadset implements BluetoothProfile {
Log.e(TAG,"",e);
}
}
+
+ synchronized (mConnection) {
+ if (mService != null) {
+ try {
+ mService = null;
+ mContext.unbindService(mConnection);
+ } catch (Exception re) {
+ Log.e(TAG,"",re);
+ }
+ }
+ }
mServiceListener = null;
- doUnbind();
}
/**
@@ -948,21 +951,21 @@ public final class BluetoothHeadset implements BluetoothProfile {
return false;
}
- private final IBluetoothProfileServiceConnection mConnection
- = new IBluetoothProfileServiceConnection.Stub() {
- @Override
+ private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
mService = IBluetoothHeadset.Stub.asInterface(service);
- mHandler.sendMessage(mHandler.obtainMessage(
- MESSAGE_HEADSET_SERVICE_CONNECTED));
+
+ if (mServiceListener != null) {
+ mServiceListener.onServiceConnected(BluetoothProfile.HEADSET, BluetoothHeadset.this);
+ }
}
- @Override
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
mService = null;
- mHandler.sendMessage(mHandler.obtainMessage(
- MESSAGE_HEADSET_SERVICE_DISCONNECTED));
+ if (mServiceListener != null) {
+ mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
+ }
}
};
@@ -986,25 +989,4 @@ public final class BluetoothHeadset implements BluetoothProfile {
private static void log(String msg) {
Log.d(TAG, msg);
}
-
- private final Handler mHandler = new Handler(Looper.getMainLooper()) {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_HEADSET_SERVICE_CONNECTED: {
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.HEADSET,
- BluetoothHeadset.this);
- }
- break;
- }
- case MESSAGE_HEADSET_SERVICE_DISCONNECTED: {
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
- }
- break;
- }
- }
- }
- };
}
diff --git a/core/java/android/bluetooth/IBluetoothManager.aidl b/core/java/android/bluetooth/IBluetoothManager.aidl
index b4778aa..bd8c6c9 100644
--- a/core/java/android/bluetooth/IBluetoothManager.aidl
+++ b/core/java/android/bluetooth/IBluetoothManager.aidl
@@ -19,7 +19,6 @@ package android.bluetooth;
import android.bluetooth.IBluetooth;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManagerCallback;
-import android.bluetooth.IBluetoothProfileServiceConnection;
import android.bluetooth.IBluetoothStateChangeCallback;
/**
@@ -39,9 +38,6 @@ interface IBluetoothManager
boolean disable(boolean persist);
IBluetoothGatt getBluetoothGatt();
- boolean bindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy);
- void unbindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy);
-
String getAddress();
String getName();
diff --git a/core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl b/core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl
deleted file mode 100755
index 96c59e2..0000000
--- a/core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.content.ComponentName;
-import android.os.IBinder;
-
-/**
- * Callback for bluetooth profile connections.
- *
- * {@hide}
- */
-interface IBluetoothProfileServiceConnection {
- void onServiceConnected(in ComponentName comp, in IBinder service);
- void onServiceDisconnected(in ComponentName comp);
-}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 30a8853..f1ca85f 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -24,14 +24,11 @@ import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
import android.bluetooth.IBluetooth;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothGatt;
-import android.bluetooth.IBluetoothHeadset;
import android.bluetooth.IBluetoothManager;
import android.bluetooth.IBluetoothManagerCallback;
-import android.bluetooth.IBluetoothProfileServiceConnection;
import android.bluetooth.IBluetoothStateChangeCallback;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -41,7 +38,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.os.Binder;
import android.os.Handler;
@@ -54,7 +50,6 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.Log;
@@ -84,8 +79,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private static final int ERROR_RESTART_TIME_MS = 3000;
//Maximum msec to delay MESSAGE_USER_SWITCHED
private static final int USER_SWITCHED_TIME_MS = 200;
- // Delay for the addProxy function in msec
- private static final int ADD_PROXY_DELAY_MS = 100;
private static final int MESSAGE_ENABLE = 1;
private static final int MESSAGE_DISABLE = 2;
@@ -102,8 +95,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private static final int MESSAGE_GET_NAME_AND_ADDRESS=200;
private static final int MESSAGE_SAVE_NAME_AND_ADDRESS=201;
private static final int MESSAGE_USER_SWITCHED = 300;
- private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
- private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
private static final int MAX_SAVE_RETRIES=3;
private static final int MAX_ERROR_RESTART_RETRIES=6;
@@ -157,11 +148,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private final int mSystemUiUid;
private boolean mIntentPending = false;
- // Save a ProfileServiceConnections object for each of the bound
- // bluetooth profile services
- private final Map <Integer, ProfileServiceConnections> mProfileServices =
- new HashMap <Integer, ProfileServiceConnections>();
-
private void registerForAirplaneMode(IntentFilter filter) {
final ContentResolver resolver = mContext.getContentResolver();
final String airplaneModeRadios = Settings.Global.getString(resolver,
@@ -718,69 +704,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
return mBluetoothGatt;
}
- @Override
- public boolean bindBluetoothProfileService(int bluetoothProfile,
- IBluetoothProfileServiceConnection proxy) {
- if (!mEnable) {
- if (DBG) {
- Log.d(TAG, "Trying to bind to profile: " + bluetoothProfile +
- ", while Bluetooth was disabled");
- }
- return false;
- }
- synchronized (mProfileServices) {
- ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
- if (psc == null) {
- if (DBG) {
- Log.d(TAG, "Creating new ProfileServiceConnections object for"
- + " profile: " + bluetoothProfile);
- }
-
- if (bluetoothProfile != BluetoothProfile.HEADSET) return false;
-
- Intent intent = new Intent(IBluetoothHeadset.class.getName());
- psc = new ProfileServiceConnections(intent);
- if (!psc.bindService()) return false;
-
- mProfileServices.put(new Integer(bluetoothProfile), psc);
- }
- }
-
- // Introducing a delay to give the client app time to prepare
- Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
- addProxyMsg.arg1 = bluetoothProfile;
- addProxyMsg.obj = proxy;
- mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
- return true;
- }
-
- @Override
- public void unbindBluetoothProfileService(int bluetoothProfile,
- IBluetoothProfileServiceConnection proxy) {
- synchronized (mProfileServices) {
- ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
- if (psc == null) {
- return;
- }
- psc.removeProxy(proxy);
- }
- }
-
- private void unbindAllBluetoothProfileServices() {
- synchronized (mProfileServices) {
- for (Integer i : mProfileServices.keySet()) {
- ProfileServiceConnections psc = mProfileServices.get(i);
- try {
- mContext.unbindService(psc);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
- }
- psc.removeAllProxies();
- }
- mProfileServices.clear();
- }
- }
-
/**
* Send enable message and set adapter name and address. Called when the boot phase becomes
* PHASE_SYSTEM_SERVICES_READY.
@@ -806,148 +729,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0));
}
- /**
- * This class manages the clients connected to a given ProfileService
- * and maintains the connection with that service.
- */
- final private class ProfileServiceConnections implements ServiceConnection,
- IBinder.DeathRecipient {
- final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
- new RemoteCallbackList <IBluetoothProfileServiceConnection>();
- IBinder mService;
- ComponentName mClassName;
- Intent mIntent;
- boolean mInvokingProxyCallbacks = false;
-
- ProfileServiceConnections(Intent intent) {
- mService = null;
- mClassName = null;
- mIntent = intent;
- }
-
- private boolean bindService() {
- if (mIntent != null && mService == null &&
- doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
- Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
- msg.obj = this;
- mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
- return true;
- }
- Log.w(TAG, "Unable to bind with intent: " + mIntent);
- return false;
- }
-
- private void addProxy(IBluetoothProfileServiceConnection proxy) {
- mProxies.register(proxy);
- if (mService != null) {
- try{
- proxy.onServiceConnected(mClassName, mService);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to connect to proxy", e);
- }
- } else {
- if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
- Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
- msg.obj = this;
- mHandler.sendMessage(msg);
- }
- }
- }
-
- private void removeProxy(IBluetoothProfileServiceConnection proxy) {
- if (proxy != null) {
- if (mProxies.unregister(proxy)) {
- try {
- proxy.onServiceDisconnected(mClassName);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to disconnect proxy", e);
- }
- }
- } else {
- Log.w(TAG, "Trying to remove a null proxy");
- }
- }
-
- private void removeAllProxies() {
- onServiceDisconnected(mClassName);
- mProxies.kill();
- }
-
- @Override
- public void onServiceConnected(ComponentName className, IBinder service) {
- // remove timeout message
- mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
- mService = service;
- mClassName = className;
- try {
- mService.linkToDeath(this, 0);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to linkToDeath", e);
- }
-
- if (mInvokingProxyCallbacks) {
- Log.e(TAG, "Proxy callbacks already in progress.");
- return;
- }
- mInvokingProxyCallbacks = true;
-
- final int n = mProxies.beginBroadcast();
- try {
- for (int i = 0; i < n; i++) {
- try {
- mProxies.getBroadcastItem(i).onServiceConnected(className, service);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to connect to proxy", e);
- }
- }
- } finally {
- mProxies.finishBroadcast();
- mInvokingProxyCallbacks = false;
- }
- }
-
- @Override
- public void onServiceDisconnected(ComponentName className) {
- if (mService == null) return;
- mService.unlinkToDeath(this, 0);
- mService = null;
- mClassName = null;
-
- if (mInvokingProxyCallbacks) {
- Log.e(TAG, "Proxy callbacks already in progress.");
- return;
- }
- mInvokingProxyCallbacks = true;
-
- final int n = mProxies.beginBroadcast();
- try {
- for (int i = 0; i < n; i++) {
- try {
- mProxies.getBroadcastItem(i).onServiceDisconnected(className);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to disconnect from proxy", e);
- }
- }
- } finally {
- mProxies.finishBroadcast();
- mInvokingProxyCallbacks = false;
- }
- }
-
- @Override
- public void binderDied() {
- if (DBG) {
- Log.w(TAG, "Profile service for profile: " + mClassName
- + " died.");
- }
- onServiceDisconnected(mClassName);
- // Trigger rebind
- Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
- msg.obj = this;
- mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
- }
- }
-
private void sendBluetoothStateCallback(boolean isUp) {
try {
int n = mStateChangeCallbacks.beginBroadcast();
@@ -1269,28 +1050,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
break;
}
- case MESSAGE_ADD_PROXY_DELAYED:
- {
- ProfileServiceConnections psc = mProfileServices.get(
- new Integer(msg.arg1));
- if (psc == null) {
- break;
- }
- IBluetoothProfileServiceConnection proxy =
- (IBluetoothProfileServiceConnection) msg.obj;
- psc.addProxy(proxy);
- break;
- }
- case MESSAGE_BIND_PROFILE_SERVICE:
- {
- ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
- removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
- if (psc == null) {
- break;
- }
- psc.bindService();
- break;
- }
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
{
if (DBG) Log.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
@@ -1500,7 +1259,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
}
- unbindAllBluetoothProfileServices();
// disable
handleDisable();
// Pbap service need receive STATE_TURNING_OFF intent to close
@@ -1626,21 +1384,16 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
int callingUser = UserHandle.getCallingUserId();
int callingUid = Binder.getCallingUid();
long callingIdentity = Binder.clearCallingIdentity();
- UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- UserInfo ui = um.getProfileParent(callingUser);
- int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
int callingAppId = UserHandle.getAppId(callingUid);
boolean valid = false;
try {
foregroundUser = ActivityManager.getCurrentUser();
valid = (callingUser == foregroundUser) ||
- parentUser == foregroundUser ||
callingAppId == Process.NFC_UID ||
callingAppId == mSystemUiUid;
if (DBG) {
Log.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid
+ " callingUser=" + callingUser
- + " parentUser=" + parentUser
+ " foregroundUser=" + foregroundUser);
}
} finally {