aboutsummaryrefslogtreecommitdiff
path: root/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothA2dpFacade.java
blob: cee0fe9c8222d55de3d57c5dd7b6968e88397eeb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.android_scripting.facade.bluetooth;

import android.app.Service;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.os.ParcelUuid;

import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.facade.FacadeManager;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcParameter;

import java.util.List;

public class BluetoothA2dpFacade extends RpcReceiver {
    static final ParcelUuid[] SINK_UUIDS = {
        BluetoothUuid.AudioSink, BluetoothUuid.AdvAudioDist,
    };
    private final Service mService;
    private final BluetoothAdapter mBluetoothAdapter;

    private static boolean sIsA2dpReady = false;
    private static BluetoothA2dp sA2dpProfile = null;

    public BluetoothA2dpFacade(FacadeManager manager) {
        super(manager);
        mService = manager.getService();
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mBluetoothAdapter.getProfileProxy(mService, new A2dpServiceListener(),
                BluetoothProfile.A2DP);
    }

    class A2dpServiceListener implements BluetoothProfile.ServiceListener {
        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            sA2dpProfile = (BluetoothA2dp) proxy;
            sIsA2dpReady = true;
        }

        @Override
        public void onServiceDisconnected(int profile) {
            sIsA2dpReady = false;
        }
    }

    /**
     * Connect A2DP Profile to input BluetoothDevice
     *
     * @param device the BluetoothDevice object to connect to
     * @return if the connection was successfull or not
    */
    public Boolean a2dpConnect(BluetoothDevice device) {
        List<BluetoothDevice> sinks = sA2dpProfile.getConnectedDevices();
        if (sinks != null) {
            for (BluetoothDevice sink : sinks) {
                sA2dpProfile.disconnect(sink);
            }
        }
        return sA2dpProfile.connect(device);
    }

    /**
     * Disconnect A2DP Profile from input BluetoothDevice
     *
     * @param device the BluetoothDevice object to disconnect from
     * @return if the disconnection was successfull or not
    */
    public Boolean a2dpDisconnect(BluetoothDevice device) {
        if (sA2dpProfile == null) return false;
        if (sA2dpProfile.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
            sA2dpProfile.setPriority(device, BluetoothProfile.PRIORITY_ON);
        }
        return sA2dpProfile.disconnect(device);
    }

    /**
     * Checks to see if the A2DP profile is ready for use.
     *
     * @return Returns true if the A2DP Profile is ready.
     */
    @Rpc(description = "Is A2dp profile ready.")
    public Boolean bluetoothA2dpIsReady() {
        return sIsA2dpReady;
    }

    /**
     * Set Bluetooth A2DP connection priority
     *
     * @param deviceStr the Bluetooth device's mac address to set the connection priority of
     * @param priority the integer priority to be set
     */
    @Rpc(description = "Set priority of the profile")
    public void bluetoothA2dpSetPriority(
            @RpcParameter(name = "device", description = "Mac address of a BT device.")
            String deviceStr,
            @RpcParameter(name = "priority", description = "Priority that needs to be set.")
            Integer priority)
            throws Exception {
        if (sA2dpProfile == null) return;
        BluetoothDevice device =
                BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(), deviceStr);
        Log.d("Changing priority of device " + device.getAliasName() + " p: " + priority);
        sA2dpProfile.setPriority(device, priority);
    }


    /**
     * Connect to remote device using the A2DP profile.
     *
     * @param deviceID the name or mac address of the remote Bluetooth device.
     * @return True if connected successfully.
     * @throws Exception
     */
    @Rpc(description = "Connect to an A2DP device.")
    public Boolean bluetoothA2dpConnect(
            @RpcParameter(name = "deviceID",
                description = "Name or MAC address of a bluetooth device.")
            String deviceID)
            throws Exception {
        if (sA2dpProfile == null) {
            return false;
        }
        BluetoothDevice mDevice =
                BluetoothFacade.getDevice(
                        mBluetoothAdapter.getBondedDevices(), deviceID);
        Log.d("Connecting to device " + mDevice.getAliasName());
        return a2dpConnect(mDevice);
    }

    /**
     * Disconnect a remote device using the A2DP profile.
     *
     * @param deviceID the name or mac address of the remote Bluetooth device.
     * @return True if connected successfully.
     * @throws Exception
     */
    @Rpc(description = "Disconnect an A2DP device.")
    public Boolean bluetoothA2dpDisconnect(
            @RpcParameter(name = "deviceID", description = "Name or MAC address of a device.")
            String deviceID)
            throws Exception {
        if (sA2dpProfile == null) {
            return false;
        }
        List<BluetoothDevice> connectedA2dpDevices =
                sA2dpProfile.getConnectedDevices();
        Log.d("Connected a2dp devices " + connectedA2dpDevices);
        BluetoothDevice mDevice = BluetoothFacade.getDevice(
                connectedA2dpDevices, deviceID);
        return a2dpDisconnect(mDevice);
    }

    /**
     * Get the list of devices connected through the A2DP profile.
     *
     * @return List of bluetooth devices that are in one of the following states:
     *   connected, connecting, and disconnecting.
     */
    @Rpc(description = "Get all the devices connected through A2DP.")
    public List<BluetoothDevice> bluetoothA2dpGetConnectedDevices() {
        while (!sIsA2dpReady) {
            continue;
        }
        return sA2dpProfile.getDevicesMatchingConnectionStates(
                new int[] { BluetoothProfile.STATE_CONNECTED,
                    BluetoothProfile.STATE_CONNECTING,
                    BluetoothProfile.STATE_DISCONNECTING});
    }

    @Override
    public void shutdown() {
    }
}