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.BluetoothA2dp;
     21 import android.bluetooth.BluetoothAdapter;
     22 import android.bluetooth.BluetoothDevice;
     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.List;
     34 
     35 public class BluetoothA2dpFacade extends RpcReceiver {
     36     static final ParcelUuid[] SINK_UUIDS = {
     37         BluetoothUuid.AudioSink, BluetoothUuid.AdvAudioDist,
     38     };
     39     private final Service mService;
     40     private final BluetoothAdapter mBluetoothAdapter;
     41 
     42     private static boolean sIsA2dpReady = false;
     43     private static BluetoothA2dp sA2dpProfile = null;
     44 
     45     public BluetoothA2dpFacade(FacadeManager manager) {
     46         super(manager);
     47         mService = manager.getService();
     48         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
     49         mBluetoothAdapter.getProfileProxy(mService, new A2dpServiceListener(),
     50                 BluetoothProfile.A2DP);
     51     }
     52 
     53     class A2dpServiceListener implements BluetoothProfile.ServiceListener {
     54         @Override
     55         public void onServiceConnected(int profile, BluetoothProfile proxy) {
     56             sA2dpProfile = (BluetoothA2dp) proxy;
     57             sIsA2dpReady = true;
     58         }
     59 
     60         @Override
     61         public void onServiceDisconnected(int profile) {
     62             sIsA2dpReady = false;
     63         }
     64     }
     65 
     66     /**
     67      * Connect A2DP Profile to input BluetoothDevice
     68      *
     69      * @param device the BluetoothDevice object to connect to
     70      * @return if the connection was successfull or not
     71     */
     72     public Boolean a2dpConnect(BluetoothDevice device) {
     73         List<BluetoothDevice> sinks = sA2dpProfile.getConnectedDevices();
     74         if (sinks != null) {
     75             for (BluetoothDevice sink : sinks) {
     76                 sA2dpProfile.disconnect(sink);
     77             }
     78         }
     79         return sA2dpProfile.connect(device);
     80     }
     81 
     82     /**
     83      * Disconnect A2DP Profile from input BluetoothDevice
     84      *
     85      * @param device the BluetoothDevice object to disconnect from
     86      * @return if the disconnection was successfull or not
     87     */
     88     public Boolean a2dpDisconnect(BluetoothDevice device) {
     89         if (sA2dpProfile == null) return false;
     90         if (sA2dpProfile.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
     91             sA2dpProfile.setPriority(device, BluetoothProfile.PRIORITY_ON);
     92         }
     93         return sA2dpProfile.disconnect(device);
     94     }
     95 
     96     /**
     97      * Checks to see if the A2DP profile is ready for use.
     98      *
     99      * @return Returns true if the A2DP Profile is ready.
    100      */
    101     @Rpc(description = "Is A2dp profile ready.")
    102     public Boolean bluetoothA2dpIsReady() {
    103         return sIsA2dpReady;
    104     }
    105 
    106     /**
    107      * Set Bluetooth A2DP connection priority
    108      *
    109      * @param deviceStr the Bluetooth device's mac address to set the connection priority of
    110      * @param priority the integer priority to be set
    111      */
    112     @Rpc(description = "Set priority of the profile")
    113     public void bluetoothA2dpSetPriority(
    114             @RpcParameter(name = "device", description = "Mac address of a BT device.")
    115             String deviceStr,
    116             @RpcParameter(name = "priority", description = "Priority that needs to be set.")
    117             Integer priority)
    118             throws Exception {
    119         if (sA2dpProfile == null) return;
    120         BluetoothDevice device =
    121                 BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(), deviceStr);
    122         Log.d("Changing priority of device " + device.getAliasName() + " p: " + priority);
    123         sA2dpProfile.setPriority(device, priority);
    124     }
    125 
    126 
    127     /**
    128      * Connect to remote device using the A2DP profile.
    129      *
    130      * @param deviceID the name or mac address of the remote Bluetooth device.
    131      * @return True if connected successfully.
    132      * @throws Exception
    133      */
    134     @Rpc(description = "Connect to an A2DP device.")
    135     public Boolean bluetoothA2dpConnect(
    136             @RpcParameter(name = "deviceID",
    137                 description = "Name or MAC address of a bluetooth device.")
    138             String deviceID)
    139             throws Exception {
    140         if (sA2dpProfile == null) {
    141             return false;
    142         }
    143         BluetoothDevice mDevice = BluetoothFacade.getDevice(
    144                 BluetoothFacade.DiscoveredDevices, deviceID);
    145         Log.d("Connecting to device " + mDevice.getAliasName());
    146         return a2dpConnect(mDevice);
    147     }
    148 
    149     /**
    150      * Disconnect a remote device using the A2DP profile.
    151      *
    152      * @param deviceID the name or mac address of the remote Bluetooth device.
    153      * @return True if connected successfully.
    154      * @throws Exception
    155      */
    156     @Rpc(description = "Disconnect an A2DP device.")
    157     public Boolean bluetoothA2dpDisconnect(
    158             @RpcParameter(name = "deviceID", description = "Name or MAC address of a device.")
    159             String deviceID)
    160             throws Exception {
    161         if (sA2dpProfile == null) {
    162             return false;
    163         }
    164         List<BluetoothDevice> connectedA2dpDevices = sA2dpProfile.getConnectedDevices();
    165         Log.d("Connected a2dp devices " + connectedA2dpDevices);
    166         BluetoothDevice mDevice = BluetoothFacade.getDevice(connectedA2dpDevices, deviceID);
    167         return a2dpDisconnect(mDevice);
    168     }
    169 
    170     /**
    171      * Get the list of devices connected through the A2DP profile.
    172      *
    173      * @return List of bluetooth devices that are in one of the following states:
    174      *   connected, connecting, and disconnecting.
    175      */
    176     @Rpc(description = "Get all the devices connected through A2DP.")
    177     public List<BluetoothDevice> bluetoothA2dpGetConnectedDevices() {
    178         while (!sIsA2dpReady) {
    179             continue;
    180         }
    181         return sA2dpProfile.getDevicesMatchingConnectionStates(
    182                     new int[] {
    183                             BluetoothProfile.STATE_CONNECTED,
    184                             BluetoothProfile.STATE_CONNECTING,
    185                             BluetoothProfile.STATE_DISCONNECTING});
    186     }
    187 
    188     @Override
    189     public void shutdown() {
    190     }
    191 }
    192