Home | History | Annotate | Download | only in bluetooth
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.googlecode.android_scripting.facade.bluetooth;
     18 
     19 import android.app.Service;
     20 import android.bluetooth.BluetoothAdapter;
     21 import android.bluetooth.BluetoothDevice;
     22 import android.bluetooth.BluetoothHeadsetClient;
     23 import android.bluetooth.BluetoothProfile;
     24 import android.bluetooth.BluetoothUuid;
     25 import android.os.ParcelUuid;
     26 
     27 import com.googlecode.android_scripting.Log;
     28 import com.googlecode.android_scripting.facade.FacadeManager;
     29 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
     30 import com.googlecode.android_scripting.rpc.Rpc;
     31 import com.googlecode.android_scripting.rpc.RpcParameter;
     32 
     33 import java.util.ArrayList;
     34 import java.util.List;
     35 
     36 public class BluetoothHfpClientFacade extends RpcReceiver {
     37     static final ParcelUuid[] UUIDS = {
     38         BluetoothUuid.Handsfree_AG,
     39     };
     40 
     41     private final Service mService;
     42     private final BluetoothAdapter mBluetoothAdapter;
     43 
     44     private static boolean sIsHfpClientReady = false;
     45     private static BluetoothHeadsetClient sHfpClientProfile = null;
     46 
     47     public BluetoothHfpClientFacade(FacadeManager manager) {
     48         super(manager);
     49         mService = manager.getService();
     50         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
     51         mBluetoothAdapter.getProfileProxy(mService,
     52                 new HfpClientServiceListener(),
     53                 BluetoothProfile.HEADSET_CLIENT);
     54     }
     55 
     56     class HfpClientServiceListener implements BluetoothProfile.ServiceListener {
     57         @Override
     58         public void onServiceConnected(int profile, BluetoothProfile proxy) {
     59             sHfpClientProfile = (BluetoothHeadsetClient) proxy;
     60             sIsHfpClientReady = true;
     61         }
     62 
     63         @Override
     64         public void onServiceDisconnected(int profile) {
     65             sIsHfpClientReady = false;
     66         }
     67     }
     68 
     69     /**
     70      * Connect to HfpClient.
     71      * @param device - the BluetoothDevice object to connect Hfp client.
     72      * @return if the connection was successfull or not.
     73      */
     74     public Boolean hfpClientConnect(BluetoothDevice device) {
     75         if (sHfpClientProfile == null) return false;
     76         return sHfpClientProfile.connect(device);
     77     }
     78 
     79     /**
     80      * Disconnect from HfpClient.
     81      * @param device - the BluetoothDevice object to disconnect from Hfp client.
     82      * @return if the disconnection was successfull or not.
     83      */
     84     public Boolean hfpClientDisconnect(BluetoothDevice device) {
     85         if (sHfpClientProfile == null) return false;
     86         return sHfpClientProfile.disconnect(device);
     87     }
     88 
     89     /**
     90      * Is Hfp Client profile ready.
     91      * @return Hfp Client profile is ready or not.
     92      */
     93     @Rpc(description = "Is HfpClient profile ready.")
     94     public Boolean bluetoothHfpClientIsReady() {
     95         return sIsHfpClientReady;
     96     }
     97 
     98     /**
     99      * Set priority of the profile.
    100      * @param deviceStr - Mac address of a BT device.
    101      * @param priority - Priority that needs to be set.
    102      */
    103     @Rpc(description = "Set priority of the profile")
    104     public void bluetoothHfpClientSetPriority(
    105             @RpcParameter(name = "device",
    106                 description = "Mac address of a BT device.") String deviceStr,
    107             @RpcParameter(name = "priority",
    108                 description = "Priority that needs to be set.")
    109                     Integer priority) throws Exception {
    110         if (sHfpClientProfile == null) return;
    111         BluetoothDevice device =
    112                 BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(),
    113                     deviceStr);
    114         Log.d("Changing priority of device " + device.getAliasName()
    115                 + " p: " + priority);
    116         sHfpClientProfile.setPriority(device, priority);
    117     }
    118 
    119     /**
    120      * Get priority of the profile.
    121      * @param deviceStr - Mac address of a BT device.
    122      * @return Priority of the device.
    123      */
    124     @Rpc(description = "Get priority of the profile")
    125     public Integer bluetoothHfpClientGetPriority(
    126             @RpcParameter(name = "device", description =
    127                     "Mac address of a BT device.") String deviceStr)
    128                     throws Exception {
    129         if (sHfpClientProfile == null) return BluetoothProfile.PRIORITY_UNDEFINED;
    130         BluetoothDevice device = BluetoothFacade.getDevice(
    131                 mBluetoothAdapter.getBondedDevices(), deviceStr);
    132         return sHfpClientProfile.getPriority(device);
    133     }
    134 
    135     /**
    136      * Connect to an HFP Client device.
    137      * @param deviceStr - Name or MAC address of a bluetooth device.
    138      * @return Hfp Client was connected or not.
    139      */
    140     @Rpc(description = "Connect to an HFP Client device.")
    141     public Boolean bluetoothHfpClientConnect(
    142             @RpcParameter(name = "device",
    143                 description = "Name or MAC address of a bluetooth device.")
    144                     String deviceStr)
    145                         throws Exception {
    146         if (sHfpClientProfile == null) return false;
    147         try {
    148             BluetoothDevice device = BluetoothFacade.getDevice(
    149                     BluetoothFacade.DiscoveredDevices, deviceStr);
    150             Log.d("Connecting to device " + device.getAliasName());
    151             return hfpClientConnect(device);
    152         } catch (Exception e) {
    153             Log.e("bluetoothHfpClientConnect failed on getDevice "
    154                     + deviceStr + " with " + e);
    155             return false;
    156         }
    157     }
    158 
    159     /**
    160      * Disconnect an HFP Client device.
    161      * @param deviceStr - Name or MAC address of a bluetooth device.
    162      * @return Hfp Client was disconnected or not.
    163      */
    164     @Rpc(description = "Disconnect an HFP Client device.")
    165     public Boolean bluetoothHfpClientDisconnect(
    166             @RpcParameter(name = "device",
    167                 description = "Name or MAC address of a device.")
    168                     String deviceStr) {
    169         if (sHfpClientProfile == null) return false;
    170         Log.d("Connected devices: " + sHfpClientProfile.getConnectedDevices());
    171         try {
    172             BluetoothDevice device = BluetoothFacade.getDevice(
    173                     sHfpClientProfile.getConnectedDevices(), deviceStr);
    174             return hfpClientDisconnect(device);
    175         } catch (Exception e) {
    176             // Do nothing since it is disconnect and this
    177             // function should force disconnect.
    178             Log.e("bluetoothHfpClientConnect getDevice failed " + e);
    179         }
    180         return false;
    181     }
    182 
    183     /**
    184      * Get all the devices connected through HFP Client.
    185      * @return List of all the devices connected through HFP Client.
    186      */
    187     @Rpc(description = "Get all the devices connected through HFP Client.")
    188     public List<BluetoothDevice> bluetoothHfpClientGetConnectedDevices() {
    189         if (sHfpClientProfile == null) return new ArrayList<BluetoothDevice>();
    190         return sHfpClientProfile.getConnectedDevices();
    191     }
    192 
    193     /**
    194      * Get the connection status of a device.
    195      * @param deviceID - Name or MAC address of a bluetooth device.
    196      * @return connection status of the device.
    197      */
    198     @Rpc(description = "Get the connection status of a device.")
    199     public Integer bluetoothHfpClientGetConnectionStatus(
    200             @RpcParameter(name = "deviceID",
    201                 description = "Name or MAC address of a bluetooth device.")
    202                     String deviceID) {
    203         if (sHfpClientProfile == null) {
    204             return BluetoothProfile.STATE_DISCONNECTED;
    205         }
    206         List<BluetoothDevice> deviceList =
    207                 sHfpClientProfile.getConnectedDevices();
    208         BluetoothDevice device;
    209         try {
    210             device = BluetoothFacade.getDevice(deviceList, deviceID);
    211         } catch (Exception e) {
    212             Log.e(e);
    213             return BluetoothProfile.STATE_DISCONNECTED;
    214         }
    215         return sHfpClientProfile.getConnectionState(device);
    216     }
    217 
    218     /**
    219      * Get the audio routing state of specified device.
    220      * @param deviceStr the Bluetooth MAC address of remote device
    221      * @return Audio State of the device.
    222      */
    223     @Rpc(description = "Get all the devices connected through HFP Client.")
    224     public Integer bluetoothHfpClientGetAudioState(
    225             @RpcParameter(name = "device",
    226                 description = "MAC address of a bluetooth device.")
    227                 String deviceStr) {
    228         if (sHfpClientProfile == null) return -1;
    229         BluetoothDevice device;
    230         try {
    231             device =  BluetoothFacade.getDevice(sHfpClientProfile.getConnectedDevices(), deviceStr);
    232         } catch (Exception e) {
    233             // Do nothing since it is disconnect and this function should force disconnect.
    234             Log.e("bluetoothHfpClientConnect getDevice failed " + e);
    235             return -1;
    236         }
    237         return sHfpClientProfile.getAudioState(device);
    238     }
    239 
    240     /**
    241      * Start Voice Recognition on remote device
    242      *
    243      * @param deviceStr the Bluetooth MAC address of remote device
    244      * @return True if command was sent
    245      */
    246     @Rpc(description = "Start Remote device Voice Recognition through HFP Client.")
    247     public boolean bluetoothHfpClientStartVoiceRecognition(
    248             @RpcParameter(name = "device",
    249                 description = "MAC address of a bluetooth device.")
    250                     String deviceStr) {
    251         if (sHfpClientProfile == null) return false;
    252         BluetoothDevice device;
    253         try {
    254             device = BluetoothFacade.getDevice(
    255                     sHfpClientProfile.getConnectedDevices(), deviceStr);
    256         } catch (Exception e) {
    257             // Do nothing since it is disconnect and this function should force disconnect.
    258             Log.e("bluetoothHfpClientConnect getDevice failed " + e);
    259             return false;
    260         }
    261         return sHfpClientProfile.startVoiceRecognition(device);
    262     }
    263 
    264     /**
    265      * Stop Voice Recognition on remote device
    266      *
    267      * @param deviceStr the Bluetooth MAC address of remote device
    268      * @return True if command was sent
    269      */
    270     @Rpc(description = "Stop Remote device Voice Recognition through HFP Client.")
    271     public boolean bluetoothHfpClientStopVoiceRecognition(
    272             @RpcParameter(name = "device",
    273                 description = "MAC address of a bluetooth device.")
    274                     String deviceStr) {
    275         if (sHfpClientProfile == null) return false;
    276         BluetoothDevice device;
    277         try {
    278             device = BluetoothFacade.getDevice(
    279                     sHfpClientProfile.getConnectedDevices(), deviceStr);
    280         } catch (Exception e) {
    281             // Do nothing since it is disconnect
    282             // and this function should force disconnect.
    283             Log.e("bluetoothHfpClientConnect getDevice failed " + e);
    284             return false;
    285         }
    286         return sHfpClientProfile.stopVoiceRecognition(device);
    287     }
    288 
    289     @Override
    290     public void shutdown() {
    291     }
    292 }
    293