HeadsetClientService.java revision ca6e7c65b87c52f5e81b273d7ad979a81b52f991
1aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta/* 2aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * Copyright (c) 2014 The Android Open Source Project 3aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * 4aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * Licensed under the Apache License, Version 2.0 (the "License"); 5aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * you may not use this file except in compliance with the License. 6aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * You may obtain a copy of the License at 7aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * 8aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * http://www.apache.org/licenses/LICENSE-2.0 9aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * 10aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * Unless required by applicable law or agreed to in writing, software 11aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * distributed under the License is distributed on an "AS IS" BASIS, 12aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * See the License for the specific language governing permissions and 14aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * limitations under the License. 15aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta */ 16aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 17aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptapackage com.android.bluetooth.hfpclient; 18aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 19aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.bluetooth.BluetoothDevice; 20aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.bluetooth.BluetoothProfile; 218d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwoodimport android.bluetooth.BluetoothHeadsetClient; 228d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwoodimport android.bluetooth.BluetoothHeadsetClientCall; 238d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwoodimport android.bluetooth.IBluetoothHeadsetClient; 24aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.content.BroadcastReceiver; 25aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.content.Context; 26aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.content.Intent; 27aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.content.IntentFilter; 28aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.media.AudioManager; 29aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.os.Bundle; 30aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.os.Message; 31aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.provider.Settings; 32aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.util.Log; 33eb7b90f5b93db1230a5b64caa3d8d05a642e33a6Marie Janssen 34aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport com.android.bluetooth.btservice.ProfileService; 35a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwalimport com.android.bluetooth.hfpclient.connserv.HfpClientConnectionService; 36aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport com.android.bluetooth.Utils; 37eb7b90f5b93db1230a5b64caa3d8d05a642e33a6Marie Janssen 38aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport java.util.ArrayList; 39aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport java.util.List; 40ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwalimport java.util.UUID; 41a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal 42aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta/** 438d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood * Provides Bluetooth Headset Client (HF Role) profile, as a service in the 44aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * Bluetooth application. 45aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * 46aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * @hide 47aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta */ 488d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwoodpublic class HeadsetClientService extends ProfileService { 49aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private static final boolean DBG = false; 508d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private static final String TAG = "HeadsetClientService"; 51aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 528d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private HeadsetClientStateMachine mStateMachine; 538d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private static HeadsetClientService sHeadsetClientService; 54aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 55a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal public static String HFP_CLIENT_STOP_TAG = "hfp_client_stop_tag"; 56a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal 57aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 58aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta protected String getName() { 59aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return TAG; 60aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 61aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 62aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 63aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public IProfileServiceBinder initBinder() { 648d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood return new BluetoothHeadsetClientBinder(this); 65aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 66aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 67aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 68aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta protected boolean start() { 698d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mStateMachine = HeadsetClientStateMachine.make(this); 70aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta IntentFilter filter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION); 71aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); 72aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta try { 73aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta registerReceiver(mBroadcastReceiver, filter); 74aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } catch (Exception e) { 75aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.w(TAG, "Unable to register broadcat receiver", e); 76aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 778d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setHeadsetClientService(this); 78a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal 79a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal // Start the HfpClientConnectionService to create connection with telecom when HFP 80a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal // connection is available. 81a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal Intent startIntent = new Intent(this, HfpClientConnectionService.class); 82a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal startService(startIntent); 83a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal 84aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 85aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 86aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 87aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 88aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta protected boolean stop() { 89aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta try { 90aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta unregisterReceiver(mBroadcastReceiver); 91aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } catch (Exception e) { 92aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.w(TAG, "Unable to unregister broadcast receiver", e); 93aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 94562547733c2dd517f3bdd30f29bfe43732fe9a13Chenjie Luo 95bebc4dd9edb40710d9588b4a2010eef227756a8eLianchao Song if (mStateMachine != null) { 96bebc4dd9edb40710d9588b4a2010eef227756a8eLianchao Song mStateMachine.doQuit(); 97bebc4dd9edb40710d9588b4a2010eef227756a8eLianchao Song } 98a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal 99a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal // Stop the HfpClientConnectionService. 100a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal Intent stopIntent = new Intent(this, HfpClientConnectionService.class); 101a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal stopIntent.putExtra(HFP_CLIENT_STOP_TAG, true); 102a8fc504fed7dcb5dc074980b9d4cfa7a56445424Sanket Agarwal startService(stopIntent); 103aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 104aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 105aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 106aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 107aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta protected boolean cleanup() { 108aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mStateMachine != null) { 109aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mStateMachine.cleanup(); 110aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1118d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood clearHeadsetClientService(); 112aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 113aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 114aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 115aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 116aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 117aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public void onReceive(Context context, Intent intent) { 118aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta String action = intent.getAction(); 119aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1203076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // We handle the volume changes for Voice calls here since HFP audio volume control does 1213076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // not go through audio manager (audio mixer). We check if the voice call volume has 1223076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // changed and subsequently change the SCO volume see 1233076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // ({@link HeadsetClientStateMachine#SET_SPEAKER_VOLUME} in 1243076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // {@link HeadsetClientStateMachine} for details. 125aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) { 1263076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal Log.d(TAG, "Volume changed for stream: " + 1273076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal intent.getExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE)); 128aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1); 1293076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal if (streamType == AudioManager.STREAM_VOICE_CALL) { 130aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int streamValue = intent 131aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta .getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1); 132aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int streamPrevValue = intent.getIntExtra( 133aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, -1); 134aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 135aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (streamValue != -1 && streamValue != streamPrevValue) { 136aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mStateMachine.sendMessage(mStateMachine.obtainMessage( 1378d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientStateMachine.SET_SPEAKER_VOLUME, streamValue, 0)); 138aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 139aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 140aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 141aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 142aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta }; 143aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 144aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta /** 145aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * Handlers for incoming service calls 146aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta */ 1478d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private static class BluetoothHeadsetClientBinder extends IBluetoothHeadsetClient.Stub 148aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta implements IProfileServiceBinder { 1498d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private HeadsetClientService mService; 150aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1518d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood public BluetoothHeadsetClientBinder(HeadsetClientService svc) { 152aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService = svc; 153aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 154aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 155aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 156aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean cleanup() { 157aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService = null; 158aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 159aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 160aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1618d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private HeadsetClientService getService() { 162aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!Utils.checkCaller()) { 1638d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Log.w(TAG, "HeadsetClient call not allowed for non-active user"); 164aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return null; 165aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 166aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 167aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mService != null && mService.isAvailable()) { 168aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return mService; 169aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 170aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return null; 171aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 172aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 173aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 174aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean connect(BluetoothDevice device) { 1758d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 176aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 177aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 178aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 179aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.connect(device); 180aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 181aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 182aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 183aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean disconnect(BluetoothDevice device) { 1848d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 185aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 186aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 187aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 188aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.disconnect(device); 189aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 190aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 191aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 192aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public List<BluetoothDevice> getConnectedDevices() { 1938d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 194aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 195aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return new ArrayList<BluetoothDevice>(0); 196aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 197aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.getConnectedDevices(); 198aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 199aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 200aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 201aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 2028d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 203aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 204aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return new ArrayList<BluetoothDevice>(0); 205aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 206aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.getDevicesMatchingConnectionStates(states); 207aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 208aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 209aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 210aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public int getConnectionState(BluetoothDevice device) { 2118d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 212aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 213aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return BluetoothProfile.STATE_DISCONNECTED; 214aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 215aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.getConnectionState(device); 216aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 217aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 218aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 219aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean setPriority(BluetoothDevice device, int priority) { 2208d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 221aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 222aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 223aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 224aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.setPriority(device, priority); 225aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 226aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 227aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 228aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public int getPriority(BluetoothDevice device) { 2298d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 230aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 231aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return BluetoothProfile.PRIORITY_UNDEFINED; 232aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 233aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.getPriority(device); 234aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 235aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 236aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 237aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean startVoiceRecognition(BluetoothDevice device) { 2388d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 239aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 240aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 241aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 242aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.startVoiceRecognition(device); 243aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 244aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 245aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 246aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean stopVoiceRecognition(BluetoothDevice device) { 2478d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 248aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 249aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 250aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 251aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.stopVoiceRecognition(device); 252aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 253aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 254aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 255aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean acceptIncomingConnect(BluetoothDevice device) { 2568d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 257aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 258aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 259aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 260aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.acceptIncomingConnect(device); 261aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 262aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 263aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 264aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean rejectIncomingConnect(BluetoothDevice device) { 2658d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 266aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 267aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 268aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 269aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.rejectIncomingConnect(device); 270aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 271aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 272aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 273aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public int getAudioState(BluetoothDevice device) { 2748d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 275aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 2768d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood return BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; 277aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 278aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.getAudioState(device); 279aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 280aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 281aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 28222bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee public void setAudioRouteAllowed(boolean allowed) { 28322bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee HeadsetClientService service = getService(); 28422bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee if (service != null) { 28522bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee service.setAudioRouteAllowed(allowed); 28622bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee } 28722bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee } 28822bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee 28922bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee @Override 29022bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee public boolean getAudioRouteAllowed() { 29122bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee HeadsetClientService service = getService(); 29222bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee if (service != null) { 29322bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee return service.getAudioRouteAllowed(); 29422bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee } 29522bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee 29622bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee return false; 29722bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee } 29822bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee 29922bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee @Override 300aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean connectAudio() { 3018d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 302aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 303aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 304aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 305aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.connectAudio(); 306aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 307aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 308aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 309aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean disconnectAudio() { 3108d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 311aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 312aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 313aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 314aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.disconnectAudio(); 315aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 316aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 317aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 318aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean acceptCall(BluetoothDevice device, int flag) { 3198d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 320aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 321aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 322aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 323aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.acceptCall(device, flag); 324aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 325aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 326aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 327aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean rejectCall(BluetoothDevice device) { 3288d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 329aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 330aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 331aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 332aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.rejectCall(device); 333aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 334aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 335aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 336aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean holdCall(BluetoothDevice device) { 3378d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 338aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 339aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 340aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 341aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.holdCall(device); 342aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 343aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 344aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 345ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal public boolean terminateCall(BluetoothDevice device, BluetoothHeadsetClientCall call) { 3468d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 347aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 348aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 349aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 350ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal return service.terminateCall(device, call.getUUID()); 351aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 352aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 353aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 354aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean explicitCallTransfer(BluetoothDevice device) { 3558d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 356aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 357aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 358aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 359aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.explicitCallTransfer(device); 360aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 361aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 362aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 363aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean enterPrivateMode(BluetoothDevice device, int index) { 3648d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 365aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 366aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 367aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 368aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.enterPrivateMode(device, index); 369aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 370aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 371aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 372ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal public BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) { 3738d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 374aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 375ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal return null; 376aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 377aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.dial(device, number); 378aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 379aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 380aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 3818d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) { 3828d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 383aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 384aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return null; 385aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 386aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.getCurrentCalls(device); 387aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 388aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 389aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 390aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean sendDTMF(BluetoothDevice device, byte code) { 3918d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 392aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 393aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 394aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 395aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.sendDTMF(device, code); 396aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 397aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 398aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 399aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean getLastVoiceTagNumber(BluetoothDevice device) { 4008d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 401aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 402aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 403aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 404aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.getLastVoiceTagNumber(device); 405aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 406aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 407aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 408aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public Bundle getCurrentAgEvents(BluetoothDevice device) { 4098d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 410aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 411aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return null; 412aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 413aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.getCurrentAgEvents(device); 414aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 415aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 416aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 417aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public Bundle getCurrentAgFeatures(BluetoothDevice device) { 4188d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientService service = getService(); 419aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (service == null) { 420aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return null; 421aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 422aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return service.getCurrentAgFeatures(device); 423aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 424aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta }; 425aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 426aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // API methods 4278d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood public static synchronized HeadsetClientService getHeadsetClientService() { 4288d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (sHeadsetClientService != null && sHeadsetClientService.isAvailable()) { 429aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (DBG) { 4308d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Log.d(TAG, "getHeadsetClientService(): returning " + sHeadsetClientService); 431aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 4328d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood return sHeadsetClientService; 433aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 434aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (DBG) { 4358d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (sHeadsetClientService == null) { 4368d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Log.d(TAG, "getHeadsetClientService(): service is NULL"); 4378d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood } else if (!(sHeadsetClientService.isAvailable())) { 4388d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Log.d(TAG, "getHeadsetClientService(): service is not available"); 439aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 440aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 441aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return null; 442aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 443aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 4448d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private static synchronized void setHeadsetClientService(HeadsetClientService instance) { 445aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (instance != null && instance.isAvailable()) { 446aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (DBG) { 4478d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Log.d(TAG, "setHeadsetClientService(): set to: " + sHeadsetClientService); 448aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 4498d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood sHeadsetClientService = instance; 450aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 451aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (DBG) { 4528d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (sHeadsetClientService == null) { 4538d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Log.d(TAG, "setHeadsetClientService(): service not available"); 4548d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood } else if (!sHeadsetClientService.isAvailable()) { 4558d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Log.d(TAG, "setHeadsetClientService(): service is cleaning up"); 456aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 457aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 458aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 459aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 460aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 4618d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private static synchronized void clearHeadsetClientService() { 4628d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood sHeadsetClientService = null; 463aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 464aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 465aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean connect(BluetoothDevice device) { 466aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 467aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "Need BLUETOOTH ADMIN permission"); 468aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 469aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) { 470aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 471aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 472aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 473aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 474aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState == BluetoothProfile.STATE_CONNECTED || 475aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState == BluetoothProfile.STATE_CONNECTING) { 476aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 477aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 478aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 4798d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mStateMachine.sendMessage(HeadsetClientStateMachine.CONNECT, device); 480aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 481aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 482aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 483aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean disconnect(BluetoothDevice device) { 484aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 485aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "Need BLUETOOTH ADMIN permission"); 486aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 487aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 488aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 489aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 490aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 491aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 4928d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mStateMachine.sendMessage(HeadsetClientStateMachine.DISCONNECT, device); 493aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 494aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 495aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 496aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public List<BluetoothDevice> getConnectedDevices() { 497aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 498aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return mStateMachine.getConnectedDevices(); 499aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 500aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 501aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 502aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 503aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return mStateMachine.getDevicesMatchingConnectionStates(states); 504aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 505aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 506aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int getConnectionState(BluetoothDevice device) { 507aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 508aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return mStateMachine.getConnectionState(device); 509aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 510aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 5118d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood // TODO Should new setting for HeadsetClient priority be created? 512aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean setPriority(BluetoothDevice device, int priority) { 513aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 514aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "Need BLUETOOTH_ADMIN permission"); 515aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Settings.Global.putInt(getContentResolver(), 516aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Settings.Global.getBluetoothHeadsetPriorityKey(device.getAddress()), 517aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta priority); 518aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (DBG) { 519aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Saved priority " + device + " = " + priority); 520aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 521aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 522aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 523aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 524aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public int getPriority(BluetoothDevice device) { 525aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 526aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "Need BLUETOOTH_ADMIN permission"); 527aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int priority = Settings.Global.getInt(getContentResolver(), 528aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Settings.Global.getBluetoothHeadsetPriorityKey(device.getAddress()), 529aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.PRIORITY_UNDEFINED); 530aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return priority; 531aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 532aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 533aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean startVoiceRecognition(BluetoothDevice device) { 534aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 535aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 536aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 537aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 538aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 539aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 5408d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mStateMachine.sendMessage(HeadsetClientStateMachine.VOICE_RECOGNITION_START); 541aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 542aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 543aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 544aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean stopVoiceRecognition(BluetoothDevice device) { 545aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 546aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // It seem that we really need to check the AudioOn state. 547aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // But since we allow startVoiceRecognition in STATE_CONNECTED and 548aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // STATE_CONNECTING state, we do these 2 in this method 549aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 550aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 551aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 552aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 553aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 5548d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mStateMachine.sendMessage(HeadsetClientStateMachine.VOICE_RECOGNITION_STOP); 555aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 556aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 557aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 558aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean acceptIncomingConnect(BluetoothDevice device) { 559aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // TODO(BT) remove it if stack does access control 560aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 561aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 562aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 563aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean rejectIncomingConnect(BluetoothDevice device) { 564aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // TODO(BT) remove it if stack does access control 565aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 566aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 567aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 568aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int getAudioState(BluetoothDevice device) { 569aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return mStateMachine.getAudioState(device); 570aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 571aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 57222bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee public void setAudioRouteAllowed(boolean allowed) { 57322bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee mStateMachine.setAudioRouteAllowed(allowed); 57422bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee } 57522bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee 57622bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee public boolean getAudioRouteAllowed() { 57722bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee return mStateMachine.getAudioRouteAllowed(); 57822bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee } 57922bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee 580aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean connectAudio() { 581aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); 582aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!mStateMachine.isConnected()) { 583aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 584aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 585aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mStateMachine.isAudioOn()) { 586aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 587aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 5888d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mStateMachine.sendMessage(HeadsetClientStateMachine.CONNECT_AUDIO); 589aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 590aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 591aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 592aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean disconnectAudio() { 593aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); 594aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!mStateMachine.isAudioOn()) { 595aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 596aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 5978d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mStateMachine.sendMessage(HeadsetClientStateMachine.DISCONNECT_AUDIO); 598aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 599aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 600aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 601aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean holdCall(BluetoothDevice device) { 602aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 603aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 604aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 605aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 606aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 607aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 6088d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Message msg = mStateMachine.obtainMessage(HeadsetClientStateMachine.HOLD_CALL); 609aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mStateMachine.sendMessage(msg); 610aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 611aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 612aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 613aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean acceptCall(BluetoothDevice device, int flag) { 614aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 615aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 616aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 617aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 618aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 619aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 6208d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Message msg = mStateMachine.obtainMessage(HeadsetClientStateMachine.ACCEPT_CALL); 621aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta msg.arg1 = flag; 622aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mStateMachine.sendMessage(msg); 623aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 624aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 625aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 626aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean rejectCall(BluetoothDevice device) { 627aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 628aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 629aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 630aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 631aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 632aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 633aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 6348d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Message msg = mStateMachine.obtainMessage(HeadsetClientStateMachine.REJECT_CALL); 635aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mStateMachine.sendMessage(msg); 636aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 637aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 638aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 639ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal boolean terminateCall(BluetoothDevice device, UUID uuid) { 640aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 641aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 642aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 643aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 644aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 645aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 646aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 6478d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Message msg = mStateMachine.obtainMessage(HeadsetClientStateMachine.TERMINATE_CALL); 648ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal msg.obj = uuid; 649aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mStateMachine.sendMessage(msg); 650aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 651aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 652aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 653aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean enterPrivateMode(BluetoothDevice device, int index) { 654aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 655aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 656aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 657aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 658aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 659aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 660aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 6618d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Message msg = mStateMachine.obtainMessage(HeadsetClientStateMachine.ENTER_PRIVATE_MODE); 662aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta msg.arg1 = index; 663aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mStateMachine.sendMessage(msg); 664aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 665aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 666aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 667ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) { 668aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 669aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 670aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 671aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 672ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal return null; 673aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 674aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 675ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal BluetoothHeadsetClientCall call = new BluetoothHeadsetClientCall( 676ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal device, HeadsetClientStateMachine.HF_ORIGINATED_CALL_ID, 677ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal BluetoothHeadsetClientCall.CALL_STATE_DIALING, number, false /* multiparty */, 678ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal true /* outgoing */); 6798d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Message msg = mStateMachine.obtainMessage(HeadsetClientStateMachine.DIAL_NUMBER); 680ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal msg.obj = call; 681aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mStateMachine.sendMessage(msg); 682ca6e7c65b87c52f5e81b273d7ad979a81b52f991Sanket Agarwal return call; 683aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 684aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 685aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean sendDTMF(BluetoothDevice device, byte code) { 686aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 687aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 688aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 689aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 690aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 691aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 6928d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Message msg = mStateMachine.obtainMessage(HeadsetClientStateMachine.SEND_DTMF); 693aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta msg.arg1 = code; 694aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mStateMachine.sendMessage(msg); 695aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 696aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 697aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 698aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean getLastVoiceTagNumber(BluetoothDevice device) { 699aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 700aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 701aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 702aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 703aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 704aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 7058d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Message msg = mStateMachine.obtainMessage(HeadsetClientStateMachine.LAST_VTAG_NUMBER); 706aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mStateMachine.sendMessage(msg); 707aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 708aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 709aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 7108d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) { 711aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 712aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 713aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED) { 714aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return null; 715aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 716aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return mStateMachine.getCurrentCalls(); 717aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 718aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 719aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public boolean explicitCallTransfer(BluetoothDevice device) { 720aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 721aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 722aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED && 723aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState != BluetoothProfile.STATE_CONNECTING) { 724aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 725aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 726aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Message msg = mStateMachine 7278d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood .obtainMessage(HeadsetClientStateMachine.EXPLICIT_CALL_TRANSFER); 728aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mStateMachine.sendMessage(msg); 729aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 730aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 731aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 732aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public Bundle getCurrentAgEvents(BluetoothDevice device) { 733aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 734aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 735aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED) { 736aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return null; 737aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 738aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return mStateMachine.getCurrentAgEvents(); 739aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 740aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 741aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public Bundle getCurrentAgFeatures(BluetoothDevice device) { 742aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 743aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState = mStateMachine.getConnectionState(device); 744aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState != BluetoothProfile.STATE_CONNECTED) { 745aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return null; 746aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 747aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return mStateMachine.getCurrentAgFeatures(); 748aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 749838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood 750838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood @Override 751838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood public void dump(StringBuilder sb) { 752838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood super.dump(sb); 753838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood if (mStateMachine != null) { 754838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood mStateMachine.dump(sb); 755838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 756838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 757aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta} 758