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
17package com.googlecode.android_scripting.facade.bluetooth;
18
19import java.util.List;
20
21import android.app.Service;
22import android.bluetooth.BluetoothMap;
23import android.bluetooth.BluetoothAdapter;
24import android.bluetooth.BluetoothDevice;
25import android.bluetooth.BluetoothProfile;
26import android.bluetooth.BluetoothUuid;
27import android.os.ParcelUuid;
28
29import com.googlecode.android_scripting.Log;
30import com.googlecode.android_scripting.facade.FacadeManager;
31import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
32import com.googlecode.android_scripting.rpc.Rpc;
33import com.googlecode.android_scripting.rpc.RpcParameter;
34
35public 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
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
57    public void onServiceConnected(int profile, BluetoothProfile proxy) {
58      sMapProfile = (BluetoothMap) proxy;
59      sIsMapReady = true;
60    }
61
62    @Override
63    public void onServiceDisconnected(int profile) {
64      sIsMapReady = false;
65    }
66  }
67
68  public Boolean mapDisconnect(BluetoothDevice device) {
69    if (sMapProfile.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
70      sMapProfile.setPriority(device, BluetoothProfile.PRIORITY_ON);
71    }
72    return sMapProfile.disconnect(device);
73  }
74
75  @Rpc(description = "Is Map profile ready.")
76  public Boolean bluetoothMapIsReady() {
77    return sIsMapReady;
78  }
79
80  @Rpc(description = "Disconnect an MAP device.")
81  public Boolean bluetoothMapDisconnect(
82      @RpcParameter(name = "deviceID", description = "Name or MAC address of a device.")
83      String deviceID)
84      throws Exception {
85    if (sMapProfile == null) return false;
86    List<BluetoothDevice> connectedMapDevices = sMapProfile.getConnectedDevices();
87    Log.d("Connected map devices: " + connectedMapDevices);
88    BluetoothDevice mDevice = BluetoothFacade.getDevice(connectedMapDevices, deviceID);
89    if (!connectedMapDevices.isEmpty() && connectedMapDevices.get(0).equals(mDevice)) {
90        if (sMapProfile.getPriority(mDevice) > BluetoothProfile.PRIORITY_ON) {
91            sMapProfile.setPriority(mDevice, BluetoothProfile.PRIORITY_ON);
92        }
93        return sMapProfile.disconnect(mDevice);
94    } else {
95        return false;
96    }
97  }
98
99  @Rpc(description = "Get all the devices connected through MAP.")
100  public List<BluetoothDevice> bluetoothMapGetConnectedDevices() {
101    while (!sIsMapReady);
102    return sMapProfile.getDevicesMatchingConnectionStates(
103          new int[] {BluetoothProfile.STATE_CONNECTED,
104                     BluetoothProfile.STATE_CONNECTING,
105                     BluetoothProfile.STATE_DISCONNECTING});
106  }
107
108  @Rpc(description = "Get the currently connected remote Bluetooth device (PCE).")
109  public BluetoothDevice bluetoothMapGetClient() {
110    if (sMapProfile == null) { return null; }
111    return sMapProfile.getClient();
112  }
113
114  @Override
115  public void shutdown() {
116  }
117}
118