diff options
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | core/java/android/bluetooth/BluetoothHeadset.java | 92 | ||||
-rw-r--r-- | core/java/android/bluetooth/IBluetoothManager.aidl | 4 | ||||
-rwxr-xr-x | core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl | 30 | ||||
-rw-r--r-- | services/core/java/com/android/server/BluetoothManagerService.java | 247 |
5 files changed, 37 insertions, 337 deletions
@@ -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 { |