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.BluetoothMap;
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 BluetoothMapFacade extends RpcReceiver {
36     static final ParcelUuid[] MAP_UUIDS = {
37         BluetoothUuid.MAP,
38         BluetoothUuid.MNS,
39         BluetoothUuid.MAS,
40     };
41     private final Service mService;
42     private final BluetoothAdapter mBluetoothAdapter;
43 
44     private static boolean sIsMapReady = false;
45     private static BluetoothMap sMapProfile = null;
46 
BluetoothMapFacade(FacadeManager manager)47     public BluetoothMapFacade(FacadeManager manager) {
48         super(manager);
49         mService = manager.getService();
50         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
51         mBluetoothAdapter.getProfileProxy(mService, new MapServiceListener(),
52         BluetoothProfile.MAP);
53     }
54 
55     class MapServiceListener implements BluetoothProfile.ServiceListener {
56         @Override
onServiceConnected(int profile, BluetoothProfile proxy)57         public void onServiceConnected(int profile, BluetoothProfile proxy) {
58             sMapProfile = (BluetoothMap) proxy;
59             sIsMapReady = true;
60         }
61 
62         @Override
onServiceDisconnected(int profile)63         public void onServiceDisconnected(int profile) {
64             sIsMapReady = false;
65         }
66     }
67 
68     /**
69      * Disconnect Map Profile.
70      * @param device - the BluetoothDevice object to connect to.
71      * @return if the disconnection was successfull or not.
72      */
mapDisconnect(BluetoothDevice device)73     public Boolean mapDisconnect(BluetoothDevice device) {
74         if (sMapProfile.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
75             sMapProfile.setPriority(device, BluetoothProfile.PRIORITY_ON);
76         }
77         return sMapProfile.disconnect(device);
78     }
79 
80     /**
81      * Is Map profile ready.
82      * @return if Map profile is ready or not.
83      */
84     @Rpc(description = "Is Map profile ready.")
bluetoothMapIsReady()85     public Boolean bluetoothMapIsReady() {
86     return sIsMapReady;
87     }
88 
89     /**
90      * Disconnect an MAP device.
91      * @param deviceID - Name or MAC address of a bluetooth device.
92      * @return True if the disconnection was successful; otherwise False.
93      */
94     @Rpc(description = "Disconnect an MAP device.")
bluetoothMapDisconnect( @pcParametername = "deviceID", description = "Name or MAC address of a device.") String deviceID)95     public Boolean bluetoothMapDisconnect(
96             @RpcParameter(name = "deviceID",
97                 description = "Name or MAC address of a device.")
98                     String deviceID) throws Exception {
99         if (sMapProfile == null) return false;
100         List<BluetoothDevice> connectedMapDevices =
101                 sMapProfile.getConnectedDevices();
102         Log.d("Connected map devices: " + connectedMapDevices);
103         BluetoothDevice mDevice = BluetoothFacade.getDevice(connectedMapDevices, deviceID);
104         if (!connectedMapDevices.isEmpty()
105                 && connectedMapDevices.get(0).equals(mDevice)) {
106             if (sMapProfile.getPriority(mDevice)
107                     > BluetoothProfile.PRIORITY_ON) {
108                 sMapProfile.setPriority(mDevice, BluetoothProfile.PRIORITY_ON);
109             }
110             return sMapProfile.disconnect(mDevice);
111         } else {
112             return false;
113         }
114     }
115 
116     /**
117      * Get all the devices connected through MAP.
118      * @return List of all the devices connected through MAP.
119      */
120     @Rpc(description = "Get all the devices connected through MAP.")
bluetoothMapGetConnectedDevices()121     public List<BluetoothDevice> bluetoothMapGetConnectedDevices() {
122         if (!sIsMapReady) return null;
123         return sMapProfile.getDevicesMatchingConnectionStates(
124                 new int[] {BluetoothProfile.STATE_CONNECTED,
125                     BluetoothProfile.STATE_CONNECTING,
126                     BluetoothProfile.STATE_DISCONNECTING});
127     }
128 
129     /**
130      * Get the currently connected remote Bluetooth device (PCE).
131      * @return remote Bluetooth device which is currently conencted.
132      */
133     @Rpc(description =
134             "Get the currently connected remote Bluetooth device (PCE).")
bluetoothMapGetClient()135     public BluetoothDevice bluetoothMapGetClient() {
136         if (sMapProfile == null) return null;
137         return sMapProfile.getClient();
138     }
139 
140     @Override
shutdown()141     public void shutdown() {
142     }
143 }
144