186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal/* 286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * Copyright (C) 2017 The Android Open Source Project 386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * 486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * Licensed under the Apache License, Version 2.0 (the "License"); 586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * you may not use this file except in compliance with the License. 686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * You may obtain a copy of the License at 786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * 886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * http://www.apache.org/licenses/LICENSE-2.0 986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * 1086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * Unless required by applicable law or agreed to in writing, software 1186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * distributed under the License is distributed on an "AS IS" BASIS, 1286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * See the License for the specific language governing permissions and 1486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal * limitations under the License. 1586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal */ 1686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 1786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalpackage com.android.bluetooth.btservice; 1886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 1986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.bluetooth.BluetoothA2dp; 2086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.bluetooth.BluetoothAdapter; 2186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.bluetooth.BluetoothDevice; 2286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.bluetooth.BluetoothHeadset; 2386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.bluetooth.BluetoothProfile; 2486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.bluetooth.BluetoothSap; 2586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.bluetooth.BluetoothUuid; 2686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.bluetooth.IBluetooth; 2786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.content.BroadcastReceiver; 2886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.content.Context; 2986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.content.Intent; 3086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.content.IntentFilter; 3186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.os.Handler; 3286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.os.Looper; 3386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.os.Message; 3486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.os.Parcelable; 3586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.os.ParcelUuid; 3686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport android.util.Log; 3786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 3886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport com.android.bluetooth.a2dp.A2dpService; 3986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport com.android.bluetooth.hid.HidService; 4086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport com.android.bluetooth.hfp.HeadsetService; 4186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport com.android.bluetooth.pan.PanService; 4286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport com.android.internal.R; 4386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 44ff5b7361a8db715a092bf93346408d342ebd354aJack Heimport java.util.HashSet; 4586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalimport java.util.List; 4686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 4786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// Describes the phone policy 4886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// 4986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// The policy should be as decoupled from the stack as possible. In an ideal world we should not 5086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// need to have this policy talk with any non-public APIs and one way to enforce that would be to 5186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// keep this file outside the Bluetooth process. Unfortunately, keeping a separate process alive is 5286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// an expensive and a tedious task. 5386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// 5486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// Best practices: 5586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// a) PhonePolicy should be ALL private methods 5686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// -- Use broadcasts which can be listened in on the BroadcastReceiver 5786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// b) NEVER call from the PhonePolicy into the Java stack, unless public APIs. It is OK to call into 5886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// the non public versions as long as public versions exist (so that a 3rd party policy can mimick) 5986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// us. 6086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// 6186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// Policy description: 6286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// 6386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// Policies are usually governed by outside events that may warrant an action. We talk about various 6486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// events and the resulting outcome from this policy: 6586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// 6686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// 1. Adapter turned ON: At this point we will try to auto-connect the (device, profile) pairs which 6786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// have PRIORITY_AUTO_CONNECT. The fact that we *only* auto-connect Headset and A2DP is something 6886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// that is hardcoded and specific to phone policy (see autoConnect() function) 6986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// 2. When the profile connection-state changes: At this point if a new profile gets CONNECTED we 7086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// will try to connect other profiles on the same device. This is to avoid collision if devices 7186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal// somehow end up trying to connect at same time or general connection issues. 7286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwalclass PhonePolicy { 7386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal final private static boolean DBG = true; 7486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal final private static String TAG = "BluetoothPhonePolicy"; 7586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 7686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // Message types for the handler (internal messages generated by intents or timeouts) 7786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal final private static int MESSAGE_PROFILE_CONNECTION_STATE_CHANGED = 1; 7886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal final private static int MESSAGE_PROFILE_INIT_PRIORITIES = 2; 7986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal final private static int MESSAGE_CONNECT_OTHER_PROFILES = 3; 8086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal final private static int MESSAGE_ADAPTER_STATE_TURNED_ON = 4; 8186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 8286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // Timeouts 8386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal final private static int CONNECT_OTHER_PROFILES_TIMEOUT = 6000; // 6s 8486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 8586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal final private AdapterService mAdapterService; 8686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal final private ServiceFactory mFactory; 8786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal final private Handler mHandler; 88ff5b7361a8db715a092bf93346408d342ebd354aJack He final private HashSet<BluetoothDevice> mHeadsetRetrySet = new HashSet<>(); 89ff5b7361a8db715a092bf93346408d342ebd354aJack He final private HashSet<BluetoothDevice> mA2dpRetrySet = new HashSet<>(); 9086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 9186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // Broadcast receiver for all changes to states of various profiles 9286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 9386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal @Override 9486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal public void onReceive(Context context, Intent intent) { 95b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He String action = intent.getAction(); 96b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He if (action == null) { 97b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He errorLog("Received intent with null action"); 98b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He return; 99b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He } 100b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He switch (action) { 101b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED: 102b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, 103b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He BluetoothProfile.HEADSET, 104b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He -1, // No-op argument 105b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He intent) 106b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He .sendToTarget(); 107b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He break; 108b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED: 109b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED, 110b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He BluetoothProfile.A2DP, 111b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He -1, // No-op argument 112b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He intent) 113b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He .sendToTarget(); 114b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He break; 115b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He case BluetoothAdapter.ACTION_STATE_CHANGED: 116b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He // Only pass the message on if the adapter has actually changed state from 117b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON. 118b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); 119b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He if (newState == BluetoothAdapter.STATE_ON) { 120b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He mHandler.obtainMessage(MESSAGE_ADAPTER_STATE_TURNED_ON).sendToTarget(); 121b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He } 122b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He break; 123b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He case BluetoothDevice.ACTION_UUID: 124b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES, intent).sendToTarget(); 125b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He break; 126b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He default: 127b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He Log.e(TAG, "Received unexpected intent, action=" + action); 128b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He break; 12986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 13086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 13186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal }; 13286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 13386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // ONLY for testing 13486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal public BroadcastReceiver getBroadcastReceiver() { 13586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal return mReceiver; 13686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 13786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 13886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // Handler to handoff intents to class thread 13986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal class PhonePolicyHandler extends Handler { 14086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal PhonePolicyHandler(Looper looper) { 14186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal super(looper); 14286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 14386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 14486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal @Override 14586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal public void handleMessage(Message msg) { 14686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal switch (msg.what) { 14786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal case MESSAGE_PROFILE_INIT_PRIORITIES: { 148b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He Intent intent = (Intent) msg.obj; 14986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal BluetoothDevice device = 150b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 151b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He Parcelable[] uuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID); 152b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("Received ACTION_UUID for device " + device); 1530068bdad22ffd70c90de67b6e85c8a0dfa838d90Sanket Agarwal if (uuids != null) { 1540068bdad22ffd70c90de67b6e85c8a0dfa838d90Sanket Agarwal ParcelUuid[] uuidsToSend = new ParcelUuid[uuids.length]; 1550068bdad22ffd70c90de67b6e85c8a0dfa838d90Sanket Agarwal for (int i = 0; i < uuidsToSend.length; i++) { 1560068bdad22ffd70c90de67b6e85c8a0dfa838d90Sanket Agarwal uuidsToSend[i] = (ParcelUuid) uuids[i]; 157b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("index=" + i + "uuid=" + uuidsToSend[i]); 1580068bdad22ffd70c90de67b6e85c8a0dfa838d90Sanket Agarwal } 1590068bdad22ffd70c90de67b6e85c8a0dfa838d90Sanket Agarwal processInitProfilePriorities(device, uuidsToSend); 1600068bdad22ffd70c90de67b6e85c8a0dfa838d90Sanket Agarwal } 16186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } break; 16286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 16386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal case MESSAGE_PROFILE_CONNECTION_STATE_CHANGED: { 16486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal Intent intent = (Intent) msg.obj; 16586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal BluetoothDevice device = 16686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 16786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal int prevState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1); 16886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal int nextState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); 16986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal processProfileStateChanged(device, msg.arg1, nextState, prevState); 17086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } break; 17186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 17286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal case MESSAGE_CONNECT_OTHER_PROFILES: 17386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // Called when we try connect some profiles in processConnectOtherProfiles but 17486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // we send a delayed message to try connecting the remaining profiles 17586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal processConnectOtherProfiles((BluetoothDevice) msg.obj); 17686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal break; 17786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 17886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal case MESSAGE_ADAPTER_STATE_TURNED_ON: 17986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // Call auto connect when adapter switches state to ON 180ff5b7361a8db715a092bf93346408d342ebd354aJack He resetStates(); 18186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal autoConnect(); 18286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal break; 18386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 18486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 18586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal }; 18686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 18786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // Policy API functions for lifecycle management (protected) 18886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal protected void start() { 18986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal IntentFilter filter = new IntentFilter(); 19086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); 19186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); 19286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal filter.addAction(BluetoothDevice.ACTION_UUID); 19386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 19486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal mAdapterService.registerReceiver(mReceiver, filter); 19586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 19686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal protected void cleanup() { 19786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal mAdapterService.unregisterReceiver(mReceiver); 198ff5b7361a8db715a092bf93346408d342ebd354aJack He resetStates(); 19986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 20086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 20186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal PhonePolicy(AdapterService service, ServiceFactory factory) { 20286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal mAdapterService = service; 20386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal mFactory = factory; 20486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal mHandler = new PhonePolicyHandler(service.getMainLooper()); 20586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 20686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 20786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // Policy implementation, all functions MUST be private 20886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal private void processInitProfilePriorities(BluetoothDevice device, ParcelUuid[] uuids) { 209b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("processInitProfilePriorities() - device " + device); 21086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal HidService hidService = mFactory.getHidService(); 21186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal A2dpService a2dpService = mFactory.getA2dpService(); 21286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal HeadsetService headsetService = mFactory.getHeadsetService(); 21386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal PanService panService = mFactory.getPanService(); 21486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 21586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // Set profile priorities only for the profiles discovered on the remote device. 21686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // This avoids needless auto-connect attempts to profiles non-existent on the remote device 21786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if ((hidService != null) 21886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hid) 21986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal || BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hogp)) 22086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (hidService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)) { 22186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal hidService.setPriority(device, BluetoothProfile.PRIORITY_ON); 22286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 22386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 22486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // If we do not have a stored priority for HFP/A2DP (all roles) then default to on. 22586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if ((headsetService != null) 22686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && ((BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP) 22786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal || BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree)) 22886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (headsetService.getPriority(device) 22986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal == BluetoothProfile.PRIORITY_UNDEFINED))) { 23086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal headsetService.setPriority(device, BluetoothProfile.PRIORITY_ON); 23186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 23286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 23386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if ((a2dpService != null) 23486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink) 23586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal || BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AdvAudioDist)) 23686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)) { 23786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal a2dpService.setPriority(device, BluetoothProfile.PRIORITY_ON); 23886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 23986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 24086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if ((panService != null) 24186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.PANU) 24286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (panService.getPriority(device) 24386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal == BluetoothProfile.PRIORITY_UNDEFINED) 24486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && mAdapterService.getResources().getBoolean( 24586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal R.bool.config_bluetooth_pan_enable_autoconnect))) { 24686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal panService.setPriority(device, BluetoothProfile.PRIORITY_ON); 24786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 24886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 24986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 25086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal private void processProfileStateChanged( 25186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal BluetoothDevice device, int profileId, int nextState, int prevState) { 252b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("processProfileStateChanged, device=" + device + ", profile=" + profileId + ", " 253b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He + prevState + " -> " + nextState); 25486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET)) 25586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (nextState == BluetoothProfile.STATE_CONNECTED)) { 256ff5b7361a8db715a092bf93346408d342ebd354aJack He switch (profileId) { 257ff5b7361a8db715a092bf93346408d342ebd354aJack He case BluetoothProfile.A2DP: 258ff5b7361a8db715a092bf93346408d342ebd354aJack He mA2dpRetrySet.remove(device); 259ff5b7361a8db715a092bf93346408d342ebd354aJack He break; 260ff5b7361a8db715a092bf93346408d342ebd354aJack He case BluetoothProfile.HEADSET: 261ff5b7361a8db715a092bf93346408d342ebd354aJack He mHeadsetRetrySet.remove(device); 262ff5b7361a8db715a092bf93346408d342ebd354aJack He break; 263ff5b7361a8db715a092bf93346408d342ebd354aJack He } 26486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal connectOtherProfile(device); 26586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal setProfileAutoConnectionPriority(device, profileId); 26686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 26786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 26886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 269ff5b7361a8db715a092bf93346408d342ebd354aJack He private void resetStates() { 270ff5b7361a8db715a092bf93346408d342ebd354aJack He mHeadsetRetrySet.clear(); 271ff5b7361a8db715a092bf93346408d342ebd354aJack He mA2dpRetrySet.clear(); 272ff5b7361a8db715a092bf93346408d342ebd354aJack He } 273ff5b7361a8db715a092bf93346408d342ebd354aJack He 27486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal private void autoConnect() { 27586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) { 27686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal errorLog("autoConnect() - BT is not ON. Exiting autoConnect"); 27786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal return; 27886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 27986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 280b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He if (!mAdapterService.isQuietModeEnabled()) { 28186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal debugLog("autoConnect() - Initiate auto connection on BT on..."); 28286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // Phone profiles. 28386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal autoConnectHeadset(); 28486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal autoConnectA2dp(); 28586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } else { 28686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal debugLog("autoConnect() - BT is in quiet mode. Not initiating auto connections"); 28786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 28886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 28986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 29086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal private void autoConnectHeadset() { 291b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He final HeadsetService hsService = mFactory.getHeadsetService(); 29286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (hsService == null) { 293b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He errorLog("autoConnectHeadset, service is null"); 29486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal return; 29586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 296b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He final BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices(); 29786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (bondedDevices == null) { 298b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He errorLog("autoConnectHeadset, bondedDevices are null"); 29986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal return; 30086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 30186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal for (BluetoothDevice device : bondedDevices) { 302b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("autoConnectHeadset, attempt auto-connect with device " + device); 30386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (hsService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) { 304b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("autoConnectHeadset, Connecting HFP with " + device); 30586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal hsService.connect(device); 30686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 30786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 30886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 30986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 31086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal private void autoConnectA2dp() { 311b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He final A2dpService a2dpService = mFactory.getA2dpService(); 312b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He if (a2dpService == null) { 313b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He errorLog("autoConnectA2dp, service is null"); 314b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He return; 315b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He } 316b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He final BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices(); 317b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He if (bondedDevices == null) { 318b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He errorLog("autoConnectA2dp, bondedDevices are null"); 31986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal return; 32086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 32186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal for (BluetoothDevice device : bondedDevices) { 322b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("autoConnectA2dp, attempt auto-connect with device " + device); 323b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He if (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) { 324b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("autoConnectA2dp, connecting A2DP with " + device); 325b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He a2dpService.connect(device); 32686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 32786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 32886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 32986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 330b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He private void connectOtherProfile(BluetoothDevice device) { 331b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He if ((!mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES)) 332b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He && (!mAdapterService.isQuietModeEnabled())) { 33386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES); 33486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal m.obj = device; 33586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal mHandler.sendMessageDelayed(m, CONNECT_OTHER_PROFILES_TIMEOUT); 33686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 33786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 33886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 33986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // This function is called whenever a profile is connected. This allows any other bluetooth 34086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // profiles which are not already connected or in the process of connecting to attempt to 34186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // connect to the device that initiated the connection. In the event that this function is 34286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal // invoked and there are no current bluetooth connections no new profiles will be connected. 34386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal private void processConnectOtherProfiles(BluetoothDevice device) { 344b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("processConnectOtherProfiles, device=" + device); 34586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) { 346b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He warnLog("processConnectOtherProfiles, adapter is not ON " + mAdapterService.getState()); 34786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal return; 34886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 34986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal HeadsetService hsService = mFactory.getHeadsetService(); 35086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal A2dpService a2dpService = mFactory.getA2dpService(); 35186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal PanService panService = mFactory.getPanService(); 35286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 35386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal boolean allProfilesEmpty = true; 35486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal List<BluetoothDevice> a2dpConnDevList = null; 35586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal List<BluetoothDevice> hsConnDevList = null; 35686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal List<BluetoothDevice> panConnDevList = null; 35786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 35886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (hsService != null) { 35986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal hsConnDevList = hsService.getConnectedDevices(); 36086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal allProfilesEmpty = allProfilesEmpty && hsConnDevList.isEmpty(); 36186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 36286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (a2dpService != null) { 36386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal a2dpConnDevList = a2dpService.getConnectedDevices(); 36486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal allProfilesEmpty = allProfilesEmpty && a2dpConnDevList.isEmpty(); 36586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 36686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (panService != null) { 36786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal panConnDevList = panService.getConnectedDevices(); 36886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal allProfilesEmpty = allProfilesEmpty && panConnDevList.isEmpty(); 36986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 37086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 37186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (allProfilesEmpty) { 372ff5b7361a8db715a092bf93346408d342ebd354aJack He // considered as fully disconnected, don't bother connecting others. 373b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("processConnectOtherProfiles, all profiles disconnected for " + device); 374ff5b7361a8db715a092bf93346408d342ebd354aJack He // reset retry status so that in the next round we can start retrying connections again 375ff5b7361a8db715a092bf93346408d342ebd354aJack He resetStates(); 37686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal return; 37786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 37886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 37986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (hsService != null) { 380ff5b7361a8db715a092bf93346408d342ebd354aJack He if (hsConnDevList.isEmpty() && !mHeadsetRetrySet.contains(device) 38186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) 38286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (hsService.getConnectionState(device) 38386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal == BluetoothProfile.STATE_DISCONNECTED)) { 384b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("Retrying connection to Headset with device " + device); 385ff5b7361a8db715a092bf93346408d342ebd354aJack He mHeadsetRetrySet.add(device); 38686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal hsService.connect(device); 38786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 38886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 38986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (a2dpService != null) { 390ff5b7361a8db715a092bf93346408d342ebd354aJack He if (a2dpConnDevList.isEmpty() && !mA2dpRetrySet.contains(device) 39186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) 39286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (a2dpService.getConnectionState(device) 39386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal == BluetoothProfile.STATE_DISCONNECTED)) { 39486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal debugLog("Retrying connection to A2DP with device " + device); 395ff5b7361a8db715a092bf93346408d342ebd354aJack He mA2dpRetrySet.add(device); 39686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal a2dpService.connect(device); 39786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 39886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 39986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (panService != null) { 40086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (panConnDevList.isEmpty() 40186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (panService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) 40286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && (panService.getConnectionState(device) 40386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal == BluetoothProfile.STATE_DISCONNECTED)) { 404b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He debugLog("Retrying connection to PAN with device " + device); 40586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal panService.connect(device); 40686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 40786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 40886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 40986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 410b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He private void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId) { 41186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal switch (profileId) { 41286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal case BluetoothProfile.HEADSET: 41386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal HeadsetService hsService = mFactory.getHeadsetService(); 414b8f2c708191ab9b31eaff709d4767f3e4fa03164xutianguo if ((hsService != null) 415b8f2c708191ab9b31eaff709d4767f3e4fa03164xutianguo && (BluetoothProfile.PRIORITY_AUTO_CONNECT 416b8f2c708191ab9b31eaff709d4767f3e4fa03164xutianguo != hsService.getPriority(device))) { 417b8f2c708191ab9b31eaff709d4767f3e4fa03164xutianguo List<BluetoothDevice> deviceList = hsService.getConnectedDevices(); 41886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal adjustOtherHeadsetPriorities(hsService, deviceList); 41986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal hsService.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT); 42086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 42186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal break; 42286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 42386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal case BluetoothProfile.A2DP: 42486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal A2dpService a2dpService = mFactory.getA2dpService(); 42586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if ((a2dpService != null) && (BluetoothProfile.PRIORITY_AUTO_CONNECT 42686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal != a2dpService.getPriority(device))) { 42786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal adjustOtherSinkPriorities(a2dpService, device); 42886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal a2dpService.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT); 42986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 43086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal break; 43186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 43286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal default: 433b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He Log.w(TAG, "Tried to set AutoConnect priority on invalid profile " + profileId); 43486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal break; 43586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 43686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 43786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 43886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal private void adjustOtherHeadsetPriorities( 43986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal HeadsetService hsService, List<BluetoothDevice> connectedDeviceList) { 44086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal for (BluetoothDevice device : mAdapterService.getBondedDevices()) { 44186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT 44286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && !connectedDeviceList.contains(device)) { 44386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal hsService.setPriority(device, BluetoothProfile.PRIORITY_ON); 44486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 44586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 44686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 44786c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal 44886c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal private void adjustOtherSinkPriorities( 44986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal A2dpService a2dpService, BluetoothDevice connectedDevice) { 45086c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal for (BluetoothDevice device : mAdapterService.getBondedDevices()) { 45186c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal if (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT 45286c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal && !device.equals(connectedDevice)) { 45386c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal a2dpService.setPriority(device, BluetoothProfile.PRIORITY_ON); 45486c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 45586c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 45686c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal } 457b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He 458b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He private static void debugLog(String msg) { 459b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He if (DBG) Log.d(TAG, msg); 460b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He } 461b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He 462b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He private static void warnLog(String msg) { 463b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He Log.w(TAG, msg); 464b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He } 465b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He 466b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He private static void errorLog(String msg) { 467b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He Log.e(TAG, msg); 468b7cafbaa7a50e61c5e473a874c14ea050f5c38abJack He } 46986c29fe88456bdcfbd4334647b04ef81ff384a06Sanket Agarwal} 470