17ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk/* 27ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Copyright (C) 2011 The Android Open Source Project 37ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * 47ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 57ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * you may not use this file except in compliance with the License. 67ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * You may obtain a copy of the License at 77ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * 87ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * http://www.apache.org/licenses/LICENSE-2.0 97ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * 107ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Unless required by applicable law or agreed to in writing, software 117ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * distributed under the License is distributed on an "AS IS" BASIS, 127ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * See the License for the specific language governing permissions and 147ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * limitations under the License. 157ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 167ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 177ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkpackage com.android.settingslib.bluetooth; 187ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 197ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothA2dp; 201bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwalimport android.bluetooth.BluetoothA2dpSink; 217ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothDevice; 227ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothHeadset; 23f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwalimport android.bluetooth.BluetoothHeadsetClient; 247ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothMap; 25631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport android.bluetooth.BluetoothMapClient; 267ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothInputDevice; 277ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothPan; 28563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzoimport android.bluetooth.BluetoothPbapClient; 297ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothProfile; 307ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothUuid; 317ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.content.Context; 327ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.content.Intent; 337ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.os.ParcelUuid; 347ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.util.Log; 357aeb3f54408a7bd0c1ca3020bca32900b2091b1dAndrew Sappersteinimport com.android.internal.R; 367ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport java.util.ArrayList; 377ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport java.util.Collection; 387ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport java.util.HashMap; 397ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport java.util.Map; 407ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 417ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk/** 427ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * LocalBluetoothProfileManager provides access to the LocalBluetoothProfile 437ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * objects for the available Bluetooth profiles. 447ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 45374d259815b801010cafd3c63aa0f1afb75a7fa6Antony Sargentpublic class LocalBluetoothProfileManager { 467ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final String TAG = "LocalBluetoothProfileManager"; 477ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final boolean DEBUG = Utils.D; 487ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** Singleton instance. */ 497ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static LocalBluetoothProfileManager sInstance; 507ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 517ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** 527ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * An interface for notifying BluetoothHeadset IPC clients when they have 537ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * been connected to the BluetoothHeadset service. 547ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Only used by com.android.settings.bluetooth.DockService. 557ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 567ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public interface ServiceListener { 577ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** 587ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Called to notify the client when this proxy object has been 597ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * connected to the BluetoothHeadset service. Clients must wait for 607ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * this callback before making IPC calls on the BluetoothHeadset 617ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * service. 627ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 637ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk void onServiceConnected(); 647ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 657ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** 667ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Called to notify the client that this proxy object has been 677ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * disconnected from the BluetoothHeadset service. Clients must not 687ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * make IPC calls on the BluetoothHeadset service after this callback. 697ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * This callback will currently only occur if the application hosting 707ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * the BluetoothHeadset service, but may be called more often in future. 717ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 727ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk void onServiceDisconnected(); 737ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 747ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 757ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private final Context mContext; 767ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private final LocalBluetoothAdapter mLocalAdapter; 777ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private final CachedBluetoothDeviceManager mDeviceManager; 787ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private final BluetoothEventManager mEventManager; 797ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 807ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private A2dpProfile mA2dpProfile; 811bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal private A2dpSinkProfile mA2dpSinkProfile; 827ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private HeadsetProfile mHeadsetProfile; 83f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal private HfpClientProfile mHfpClientProfile; 847ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private MapProfile mMapProfile; 85631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo private MapClientProfile mMapClientProfile; 867ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private final HidProfile mHidProfile; 877ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private OppProfile mOppProfile; 887ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private final PanProfile mPanProfile; 89563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo private PbapClientProfile mPbapClientProfile; 907ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private final PbapServerProfile mPbapProfile; 91563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo private final boolean mUsePbapPce; 92631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo private final boolean mUseMapClient; 937ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 947ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** 957ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Mapping from profile name, e.g. "HEADSET" to profile object. 967ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 977ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private final Map<String, LocalBluetoothProfile> 987ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mProfileNameMap = new HashMap<String, LocalBluetoothProfile>(); 997ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1007ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk LocalBluetoothProfileManager(Context context, 1017ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk LocalBluetoothAdapter adapter, 1027ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk CachedBluetoothDeviceManager deviceManager, 1037ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothEventManager eventManager) { 1047ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mContext = context; 1057ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1067ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mLocalAdapter = adapter; 1077ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mDeviceManager = deviceManager; 1087ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mEventManager = eventManager; 109563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo mUsePbapPce = mContext.getResources().getBoolean(R.bool.enable_pbap_pce_profile); 110631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo // MAP Client is typically used in the same situations as PBAP Client 111631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo mUseMapClient = mContext.getResources().getBoolean(R.bool.enable_pbap_pce_profile); 1127ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // pass this reference to adapter and event manager (circular dependency) 1137ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mLocalAdapter.setProfileManager(this); 1147ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mEventManager.setProfileManager(this); 1157ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1167ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk ParcelUuid[] uuids = adapter.getUuids(); 1177ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1187ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // uuids may be null if Bluetooth is turned off 1197ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (uuids != null) { 1207ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk updateLocalProfiles(uuids); 1217ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1227ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1237ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // Always add HID and PAN profiles 1247ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mHidProfile = new HidProfile(context, mLocalAdapter, mDeviceManager, this); 1257ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk addProfile(mHidProfile, HidProfile.NAME, 1267ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED); 1277ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1287ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mPanProfile = new PanProfile(context); 1297ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk addPanProfile(mPanProfile, PanProfile.NAME, 1307ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothPan.ACTION_CONNECTION_STATE_CHANGED); 1317ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1327ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if(DEBUG) Log.d(TAG, "Adding local MAP profile"); 133631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo if (mUseMapClient) { 134631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo mMapClientProfile = new MapClientProfile(mContext, mLocalAdapter, mDeviceManager, this); 135631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo addProfile(mMapClientProfile, MapClientProfile.NAME, 136631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED); 137631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo } else { 138631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo mMapProfile = new MapProfile(mContext, mLocalAdapter, mDeviceManager, this); 139631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo addProfile(mMapProfile, MapProfile.NAME, 140631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo BluetoothMap.ACTION_CONNECTION_STATE_CHANGED); 141631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo } 1427ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1437ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk //Create PBAP server profile, but do not add it to list of profiles 1447ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // as we do not need to monitor the profile as part of profile list 1457ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mPbapProfile = new PbapServerProfile(context); 1467ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1477ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (DEBUG) Log.d(TAG, "LocalBluetoothProfileManager construction complete"); 1487ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1497ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1507ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** 1517ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Initialize or update the local profile objects. If a UUID was previously 1527ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * present but has been removed, we print a warning but don't remove the 1537ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * profile object as it might be referenced elsewhere, or the UUID might 1547ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * come back and we don't want multiple copies of the profile objects. 1557ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * @param uuids 1567ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 1577ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk void updateLocalProfiles(ParcelUuid[] uuids) { 1581bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal // A2DP SRC 1597ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSource)) { 1607ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (mA2dpProfile == null) { 1611bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if(DEBUG) Log.d(TAG, "Adding local A2DP SRC profile"); 1627ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mA2dpProfile = new A2dpProfile(mContext, mLocalAdapter, mDeviceManager, this); 1637ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk addProfile(mA2dpProfile, A2dpProfile.NAME, 1647ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); 1657ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1667ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } else if (mA2dpProfile != null) { 1677ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk Log.w(TAG, "Warning: A2DP profile was previously added but the UUID is now missing."); 1687ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1697ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 170f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal // A2DP SINK 1711bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink)) { 1721bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (mA2dpSinkProfile == null) { 1731bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if(DEBUG) Log.d(TAG, "Adding local A2DP Sink profile"); 1741bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal mA2dpSinkProfile = new A2dpSinkProfile(mContext, mLocalAdapter, mDeviceManager, this); 1751bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal addProfile(mA2dpSinkProfile, A2dpSinkProfile.NAME, 1761bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED); 1771bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 1781bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } else if (mA2dpSinkProfile != null) { 1791bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal Log.w(TAG, "Warning: A2DP Sink profile was previously added but the UUID is now missing."); 1801bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 1811bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal 1827ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // Headset / Handsfree 1837ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) || 1847ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP_AG)) { 1857ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (mHeadsetProfile == null) { 1867ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (DEBUG) Log.d(TAG, "Adding local HEADSET profile"); 1877ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mHeadsetProfile = new HeadsetProfile(mContext, mLocalAdapter, 1887ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mDeviceManager, this); 1897ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk addProfile(mHeadsetProfile, HeadsetProfile.NAME, 1907ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); 1917ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1927ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } else if (mHeadsetProfile != null) { 1937ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk Log.w(TAG, "Warning: HEADSET profile was previously added but the UUID is now missing."); 1947ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1957ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 196f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal // Headset HF 197f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree)) { 198f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal if (mHfpClientProfile == null) { 199f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal if(DEBUG) Log.d(TAG, "Adding local HfpClient profile"); 200f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal mHfpClientProfile = 201f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal new HfpClientProfile(mContext, mLocalAdapter, mDeviceManager, this); 202f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal addProfile(mHfpClientProfile, HfpClientProfile.NAME, 203f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED); 204f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal } 205f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal } else if (mHfpClientProfile != null) { 206f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal Log.w(TAG, 207f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal "Warning: Hfp Client profile was previously added but the UUID is now missing."); 208f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal } else { 209f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal Log.d(TAG, "Handsfree Uuid not found."); 210f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal } 211f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal 212631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo // Message Access Profile Client 213631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.MNS)) { 214631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo if (mMapClientProfile == null) { 215631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo if(DEBUG) Log.d(TAG, "Adding local Map Client profile"); 216631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo mMapClientProfile = 217631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo new MapClientProfile(mContext, mLocalAdapter, mDeviceManager, this); 218631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo addProfile(mMapClientProfile, MapClientProfile.NAME, 219631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED); 220631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo } 221631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo } else if (mMapClientProfile != null) { 222631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo Log.w(TAG, 223631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo "Warning: MAP Client profile was previously added but the UUID is now missing."); 224631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo } else { 225631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo Log.d(TAG, "MAP Client Uuid not found."); 226631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo } 227631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo 2287ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // OPP 2297ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush)) { 2307ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (mOppProfile == null) { 2317ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if(DEBUG) Log.d(TAG, "Adding local OPP profile"); 2327ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mOppProfile = new OppProfile(); 2337ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // Note: no event handler for OPP, only name map. 2347ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mProfileNameMap.put(OppProfile.NAME, mOppProfile); 2357ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 2367ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } else if (mOppProfile != null) { 2377ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk Log.w(TAG, "Warning: OPP profile was previously added but the UUID is now missing."); 2387ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 239563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo 240563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo //PBAP Client 241563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if (mUsePbapPce) { 242563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if (mPbapClientProfile == null) { 243563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if(DEBUG) Log.d(TAG, "Adding local PBAP Client profile"); 244563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo mPbapClientProfile = new PbapClientProfile(mContext, mLocalAdapter, mDeviceManager, 245563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo this); 246563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo addProfile(mPbapClientProfile, PbapClientProfile.NAME, 247563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED); 248563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 249563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } else if (mPbapClientProfile != null) { 250563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo Log.w(TAG, 251563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo "Warning: PBAP Client profile was previously added but the UUID is now missing."); 252563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 253563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo 2547ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mEventManager.registerProfileIntentReceiver(); 2557ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 256563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo // There is no local SDP record for HID and Settings app doesn't control PBAP Server. 2577ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 2587ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 2597ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private final Collection<ServiceListener> mServiceListeners = 2607ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk new ArrayList<ServiceListener>(); 2617ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 2627ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private void addProfile(LocalBluetoothProfile profile, 2637ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk String profileName, String stateChangedAction) { 2647ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mEventManager.addProfileHandler(stateChangedAction, new StateChangedHandler(profile)); 2657ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mProfileNameMap.put(profileName, profile); 2667ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 2677ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 2687ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private void addPanProfile(LocalBluetoothProfile profile, 2697ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk String profileName, String stateChangedAction) { 2707ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mEventManager.addProfileHandler(stateChangedAction, 2717ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk new PanStateChangedHandler(profile)); 2727ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mProfileNameMap.put(profileName, profile); 2737ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 2747ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 2757ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public LocalBluetoothProfile getProfileByName(String name) { 2767ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return mProfileNameMap.get(name); 2777ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 2787ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 2797ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // Called from LocalBluetoothAdapter when state changes to ON 2807ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk void setBluetoothStateOn() { 2817ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk ParcelUuid[] uuids = mLocalAdapter.getUuids(); 2827ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (uuids != null) { 2837ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk updateLocalProfiles(uuids); 2847ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 2857ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mEventManager.readPairedDevices(); 2867ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 2877ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 2887ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** 2897ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Generic handler for connection state change events for the specified profile. 2907ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 2917ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private class StateChangedHandler implements BluetoothEventManager.Handler { 2927ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk final LocalBluetoothProfile mProfile; 2937ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 2947ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk StateChangedHandler(LocalBluetoothProfile profile) { 2957ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mProfile = profile; 2967ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 2977ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 2987ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public void onReceive(Context context, Intent intent, BluetoothDevice device) { 2997ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device); 3007ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (cachedDevice == null) { 3017ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk Log.w(TAG, "StateChangedHandler found new device: " + device); 3027ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk cachedDevice = mDeviceManager.addDevice(mLocalAdapter, 3037ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk LocalBluetoothProfileManager.this, device); 3047ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3057ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0); 3067ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0); 3077ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (newState == BluetoothProfile.STATE_DISCONNECTED && 3087ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk oldState == BluetoothProfile.STATE_CONNECTING) { 3097ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk Log.i(TAG, "Failed to connect " + mProfile + " device"); 3107ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3117ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 3127ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk cachedDevice.onProfileStateChanged(mProfile, newState); 3137ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk cachedDevice.refresh(); 3147ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3157ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3167ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 3177ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** State change handler for NAP and PANU profiles. */ 3187ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private class PanStateChangedHandler extends StateChangedHandler { 3197ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 3207ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk PanStateChangedHandler(LocalBluetoothProfile profile) { 3217ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk super(profile); 3227ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3237ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 3247ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk @Override 3257ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public void onReceive(Context context, Intent intent, BluetoothDevice device) { 3267ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk PanProfile panProfile = (PanProfile) mProfile; 3277ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk int role = intent.getIntExtra(BluetoothPan.EXTRA_LOCAL_ROLE, 0); 3287ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk panProfile.setLocalRole(device, role); 3297ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk super.onReceive(context, intent, device); 3307ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3317ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3327ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 3337ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // called from DockService 3347ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public void addServiceListener(ServiceListener l) { 3357ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mServiceListeners.add(l); 3367ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3377ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 3387ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // called from DockService 3397ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public void removeServiceListener(ServiceListener l) { 3407ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mServiceListeners.remove(l); 3417ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3427ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 3437ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // not synchronized: use only from UI thread! (TODO: verify) 3447ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk void callServiceConnectedListeners() { 3457ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk for (ServiceListener l : mServiceListeners) { 3467ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk l.onServiceConnected(); 3477ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3487ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3497ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 3507ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // not synchronized: use only from UI thread! (TODO: verify) 3517ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk void callServiceDisconnectedListeners() { 3527ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk for (ServiceListener listener : mServiceListeners) { 3537ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk listener.onServiceDisconnected(); 3547ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3557ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3567ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 3577ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // This is called by DockService, so check Headset and A2DP. 3587ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public synchronized boolean isManagerReady() { 3597ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // Getting just the headset profile is fine for now. Will need to deal with A2DP 3607ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // and others if they aren't always in a ready state. 3617ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk LocalBluetoothProfile profile = mHeadsetProfile; 3627ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (profile != null) { 3637ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return profile.isProfileReady(); 3647ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3657ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk profile = mA2dpProfile; 3667ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (profile != null) { 3677ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return profile.isProfileReady(); 3687ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3691bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal profile = mA2dpSinkProfile; 3701bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (profile != null) { 3711bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return profile.isProfileReady(); 3721bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 3737ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return false; 3747ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3757ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 3767ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public A2dpProfile getA2dpProfile() { 3777ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return mA2dpProfile; 3787ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3797ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 380f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal public A2dpSinkProfile getA2dpSinkProfile() { 381f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal if ((mA2dpSinkProfile != null) && (mA2dpSinkProfile.isProfileReady())) { 382f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal return mA2dpSinkProfile; 383f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal } else { 3841bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal return null; 385f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal } 3861bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal } 3871bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal 3887ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public HeadsetProfile getHeadsetProfile() { 3897ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return mHeadsetProfile; 3907ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 3917ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 392f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal public HfpClientProfile getHfpClientProfile() { 393f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal if ((mHfpClientProfile != null) && (mHfpClientProfile.isProfileReady())) { 394f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal return mHfpClientProfile; 395f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal } else { 396f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal return null; 397f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal } 398f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal } 399f8a1c9121dae665ec9dc29484f89adfb5f3f0886Sanket Agarwal 400563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo public PbapClientProfile getPbapClientProfile() { 401563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo return mPbapClientProfile; 402563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 403563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo 4047ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public PbapServerProfile getPbapProfile(){ 4057ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return mPbapProfile; 4067ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 4077ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 4087ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public MapProfile getMapProfile(){ 4097ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return mMapProfile; 4107ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 4117ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 412631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo public MapClientProfile getMapClientProfile() { 413631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo return mMapClientProfile; 414631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo } 415631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo 4167ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk /** 4177ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Fill in a list of LocalBluetoothProfile objects that are supported by 4187ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * the local device and the remote device. 4197ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * 4207ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * @param uuids of the remote device 4217ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * @param localUuids UUIDs of the local device 4227ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * @param profiles The list of profiles to fill 4237ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * @param removedProfiles list of profiles that were removed 4247ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 4257ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk synchronized void updateProfiles(ParcelUuid[] uuids, ParcelUuid[] localUuids, 4267ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk Collection<LocalBluetoothProfile> profiles, 4277ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk Collection<LocalBluetoothProfile> removedProfiles, 4287ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk boolean isPanNapConnected, BluetoothDevice device) { 4297ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // Copy previous profile list into removedProfiles 4307ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk removedProfiles.clear(); 4317ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk removedProfiles.addAll(profiles); 43299fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo if (DEBUG) { 43399fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo Log.d(TAG,"Current Profiles" + profiles.toString()); 43499fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo } 4357ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk profiles.clear(); 4367ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 4377ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (uuids == null) { 4387ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return; 4397ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 4407ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 4417ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (mHeadsetProfile != null) { 4427ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if ((BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.HSP_AG) && 4437ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP)) || 4447ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk (BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.Handsfree_AG) && 4457ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree))) { 4467ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk profiles.add(mHeadsetProfile); 4477ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk removedProfiles.remove(mHeadsetProfile); 4487ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 4497ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 4507ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 45199fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo if ((mHfpClientProfile != null) && 45299fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) && 45399fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.Handsfree)) { 45499fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo profiles.add(mHfpClientProfile); 45599fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo removedProfiles.remove(mHfpClientProfile); 45699fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo } 45799fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo 4587ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (BluetoothUuid.containsAnyUuid(uuids, A2dpProfile.SINK_UUIDS) && 4597ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mA2dpProfile != null) { 4607ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk profiles.add(mA2dpProfile); 4617ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk removedProfiles.remove(mA2dpProfile); 4627ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 4637ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 4641bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal if (BluetoothUuid.containsAnyUuid(uuids, A2dpSinkProfile.SRC_UUIDS) && 4651bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal mA2dpSinkProfile != null) { 4661bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal profiles.add(mA2dpSinkProfile); 4671bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal removedProfiles.remove(mA2dpSinkProfile); 46899fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo } 4691bec6a5b0d67f120b7013572f6b1a4f1e1b3c584Sanket Agarwal 4707ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush) && 4717ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mOppProfile != null) { 4727ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk profiles.add(mOppProfile); 4737ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk removedProfiles.remove(mOppProfile); 4747ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 4757ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 4767ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if ((BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hid) || 4777ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hogp)) && 4787ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mHidProfile != null) { 4797ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk profiles.add(mHidProfile); 4807ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk removedProfiles.remove(mHidProfile); 4817ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 4827ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 4837ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if(isPanNapConnected) 4847ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if(DEBUG) Log.d(TAG, "Valid PAN-NAP connection exists."); 4857ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if ((BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.NAP) && 4867ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mPanProfile != null) || isPanNapConnected) { 4877ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk profiles.add(mPanProfile); 4887ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk removedProfiles.remove(mPanProfile); 4897ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 4907ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 4917ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if ((mMapProfile != null) && 4927ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk (mMapProfile.getConnectionStatus(device) == BluetoothProfile.STATE_CONNECTED)) { 4937ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk profiles.add(mMapProfile); 4947ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk removedProfiles.remove(mMapProfile); 4957ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mMapProfile.setPreferred(device, true); 4967ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 4977ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 498631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo if (mMapClientProfile != null) { 499631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo profiles.add(mMapClientProfile); 500631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo removedProfiles.remove(mMapClientProfile); 501631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo } 502631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo 503563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo if (mUsePbapPce) { 504563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo profiles.add(mPbapClientProfile); 505563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo removedProfiles.remove(mPbapClientProfile); 506563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo profiles.remove(mPbapProfile); 507563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo removedProfiles.add(mPbapProfile); 508563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 50999fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo 51099fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo if (DEBUG) { 51199fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo Log.d(TAG,"New Profiles" + profiles.toString()); 51299fecc0dd7e1c2db0f4b173a69e2b3a96fef12ffJoseph Pirozzo } 513563c700f7025d2f792a52b7483725b3d58eaa7a6Joseph Pirozzo } 5147ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk} 515