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.A2DP_SOURCE, 39 }; 40 41 private final Service mService; 42 private final BluetoothAdapter mBluetoothAdapter; 43 44 private static BluetoothA2dpSink sA2dpSinkProfile = null; 45 BluetoothA2dpSinkFacade(FacadeManager manager)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 onServiceConnected(int profile, BluetoothProfile proxy)56 public void onServiceConnected(int profile, BluetoothProfile proxy) { 57 sA2dpSinkProfile = (BluetoothA2dpSink) proxy; 58 } 59 60 @Override onServiceDisconnected(int profile)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 */ a2dpSinkConnect(BluetoothDevice device)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 */ a2dpSinkDisconnect(BluetoothDevice device)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") bluetoothA2dpSinkSetPriority( @pcParametername = "device", description = "Mac address of a BT device.") String deviceStr, @RpcParameter(name = "priority", description = "Priority that needs to be set.") Integer priority)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.getAlias() + " 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") bluetoothA2dpSinkGetPriority( @pcParametername = "device", description = "Mac address of a BT device.") String deviceStr)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.") bluetoothA2dpSinkIsReady()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.") bluetoothA2dpSinkConnect( @pcParametername = "device", description = "Name or MAC address of a bluetooth device.") String deviceStr)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.getAlias()); 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.") bluetoothA2dpSinkDisconnect( @pcParametername = "device", description = "Name or MAC address of a device.") String deviceStr)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.") bluetoothA2dpSinkGetConnectedDevices()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.") bluetoothA2dpSinkGetConnectionStatus( @pcParametername = "deviceID", description = "Name or MAC address of a bluetooth device.") String deviceID)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 shutdown()209 public void shutdown() { 210 } 211 } 212