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.BluetoothA2dpSink;
     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.ArrayList;
     34 import java.util.List;
     35 
     36 public class BluetoothA2dpSinkFacade extends RpcReceiver {
     37     static final ParcelUuid[] SOURCE_UUIDS = {
     38         BluetoothUuid.AudioSource,
     39     };
     40 
     41     private final Service mService;
     42     private final BluetoothAdapter mBluetoothAdapter;
     43 
     44     private static BluetoothA2dpSink sA2dpSinkProfile = null;
     45 
     46     public BluetoothA2dpSinkFacade(FacadeManager manager) {
     47         super(manager);
     48         mService = manager.getService();
     49         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
     50         mBluetoothAdapter.getProfileProxy(mService, new A2dpSinkServiceListener(),
     51         BluetoothProfile.A2DP_SINK);
     52     }
     53 
     54     class A2dpSinkServiceListener implements BluetoothProfile.ServiceListener {
     55         @Override
     56         public void onServiceConnected(int profile, BluetoothProfile proxy) {
     57             sA2dpSinkProfile = (BluetoothA2dpSink) proxy;
     58         }
     59 
     60         @Override
     61         public void onServiceDisconnected(int profile) {
     62             sA2dpSinkProfile = null;
     63         }
     64     }
     65 
     66     /**
     67      * Connect A2dp Sink profile.
     68      * @param device - the Bluetooth Device object to connect.
     69      * @return if the A2dp Sink Profile connection was successful or not.
     70      */
     71     public Boolean a2dpSinkConnect(BluetoothDevice device) {
     72         if (sA2dpSinkProfile == null) return false;
     73         return sA2dpSinkProfile.connect(device);
     74     }
     75 
     76     /**
     77      * Disconnect A2dp Sink profile.
     78      * @param device - the Bluetooth Device object to connect.
     79      * @return if the A2dp Sink Profile disconnection was successful or not.
     80      */
     81     public Boolean a2dpSinkDisconnect(BluetoothDevice device) {
     82         if (sA2dpSinkProfile == null) return false;
     83         return sA2dpSinkProfile.disconnect(device);
     84     }
     85 
     86     /**
     87      * Set priority of the profile.
     88      * @param deviceStr - Mac address of a Bluetooth device.
     89      * @param priority - Priority that needs to be set.
     90      */
     91     @Rpc(description = "Set priority of the profile")
     92     public void bluetoothA2dpSinkSetPriority(
     93             @RpcParameter(name = "device", description = "Mac address of a BT device.")
     94             String deviceStr,
     95             @RpcParameter(name = "priority", description = "Priority that needs to be set.")
     96             Integer priority)
     97             throws Exception {
     98         if (sA2dpSinkProfile == null) return;
     99         BluetoothDevice device =
    100                 BluetoothFacade.getDevice(
    101                         mBluetoothAdapter.getBondedDevices(), deviceStr);
    102         Log.d("Changing priority of device "
    103                 + device.getAliasName() + " p: " + priority);
    104         sA2dpSinkProfile.setPriority(device, priority);
    105     }
    106 
    107     /**
    108      * Get priority of the profile.
    109       * @param deviceStr - Mac address of a Bluetooth device.
    110       * @return priority of the device.
    111      */
    112     @Rpc(description = "get priority of the profile")
    113     public Integer bluetoothA2dpSinkGetPriority(
    114             @RpcParameter(name = "device", description = "Mac address of a BT device.")
    115                 String deviceStr)
    116             throws Exception {
    117         if (sA2dpSinkProfile == null) return BluetoothProfile.PRIORITY_UNDEFINED;
    118         BluetoothDevice device =
    119                 BluetoothFacade.getDevice(
    120                 mBluetoothAdapter.getBondedDevices(), deviceStr);
    121         return sA2dpSinkProfile.getPriority(device);
    122     }
    123 
    124     /**
    125      * Is A2dpSink profile ready.
    126      * @return if the Profile is ready or not.
    127      */
    128     @Rpc(description = "Is A2dpSink profile ready.")
    129     public Boolean bluetoothA2dpSinkIsReady() {
    130         return sA2dpSinkProfile != null;
    131     }
    132 
    133     /**
    134      * Connect to an A2DP Sink device.
    135      * @param deviceStr - Name or MAC address of a bluetooth device.
    136      * @return connection to A2DP was successful.
    137      */
    138     @Rpc(description = "Connect to an A2DP Sink device.")
    139     public Boolean bluetoothA2dpSinkConnect(
    140             @RpcParameter(name = "device", description =
    141                 "Name or MAC address of a bluetooth device.") String deviceStr)
    142             throws Exception {
    143         if (sA2dpSinkProfile == null) return false;
    144         BluetoothDevice device =
    145                 BluetoothFacade.getDevice(
    146                 BluetoothFacade.DiscoveredDevices, deviceStr);
    147         Log.d("Connecting to device " + device.getAliasName());
    148         return a2dpSinkConnect(device);
    149     }
    150 
    151     /**
    152      * Disconnect to an A2DP Sink device.
    153      * @param deviceStr - Name or MAC address of a bluetooth device.
    154      * @return disconnection to A2DP was successful or not.
    155      */
    156     @Rpc(description = "Disconnect an A2DP Sink device.")
    157     public Boolean bluetoothA2dpSinkDisconnect(
    158             @RpcParameter(name = "device", description = "Name or MAC address of a device.")
    159                 String deviceStr) {
    160         if (sA2dpSinkProfile == null) return false;
    161         Log.d("Connected devices: " + sA2dpSinkProfile.getConnectedDevices());
    162         BluetoothDevice device = null;
    163         try {
    164             device = BluetoothFacade.getDevice(
    165                     sA2dpSinkProfile.getConnectedDevices(), deviceStr);
    166             return a2dpSinkDisconnect(device);
    167         } catch (Exception e) {
    168             // Do nothing here. Since it is disconnect this function should force shutdown anyways.
    169             Log.d("bluetoothA2dpSinkDisconnect error while getDevice " + e);
    170         }
    171         return false;
    172     }
    173 
    174     /**
    175      * Get all the devices connected through A2DP Sink.
    176      * @return List of all the devices connected through A2dp Sink.
    177      */
    178     @Rpc(description = "Get all the devices connected through A2DP Sink.")
    179     public List<BluetoothDevice> bluetoothA2dpSinkGetConnectedDevices() {
    180         if (sA2dpSinkProfile == null) return new ArrayList<BluetoothDevice>();
    181         return sA2dpSinkProfile.getConnectedDevices();
    182     }
    183 
    184     /**
    185      * Get the connection status of a device.
    186      * @param deviceID - Name or MAC address of a bluetooth device.
    187      * @return connection status of the device.
    188      */
    189     @Rpc(description = "Get the connection status of a device.")
    190     public Integer bluetoothA2dpSinkGetConnectionStatus(
    191             @RpcParameter(name = "deviceID",
    192                 description = "Name or MAC address of a bluetooth device.")
    193                 String deviceID) {
    194         if (sA2dpSinkProfile == null) {
    195             return BluetoothProfile.STATE_DISCONNECTED;
    196         }
    197         List<BluetoothDevice> deviceList = sA2dpSinkProfile.getConnectedDevices();
    198         BluetoothDevice device;
    199         try {
    200             device = BluetoothFacade.getDevice(deviceList, deviceID);
    201         } catch (Exception e) {
    202             Log.e(e);
    203             return BluetoothProfile.STATE_DISCONNECTED;
    204         }
    205         return sA2dpSinkProfile.getConnectionState(device);
    206     }
    207 
    208     @Override
    209     public void shutdown() {
    210     }
    211 }
    212