BluetoothInputDevice.java revision 545e6708adda6859932b55fd824794b1401f5318
1/*
2 * Copyright (C) 2010 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 android.bluetooth;
18
19import android.annotation.SdkConstant;
20import android.annotation.SdkConstant.SdkConstantType;
21import android.content.Context;
22import android.os.IBinder;
23import android.os.RemoteException;
24import android.os.ServiceManager;
25import android.util.Log;
26
27import java.util.Arrays;
28import java.util.Collections;
29import java.util.HashSet;
30import java.util.Set;
31
32/**
33 * Public API for controlling the Bluetooth HID (Input Device) Profile
34 *
35 * BluetoothInputDevice is a proxy object used to make calls to Bluetooth Service
36 * which handles the HID profile.
37 *
38 * Creating a BluetoothInputDevice object will initiate a binding with the
39 * Bluetooth service. Users of this object should call close() when they
40 * are finished, so that this proxy object can unbind from the service.
41 *
42 * Currently the Bluetooth service runs in the system server and this
43 * proxy object will be immediately bound to the service on construction.
44 *
45 *  @hide
46 */
47public final class BluetoothInputDevice {
48    private static final String TAG = "BluetoothInputDevice";
49    private static final boolean DBG = false;
50
51    /** int extra for ACTION_INPUT_DEVICE_STATE_CHANGED */
52    public static final String EXTRA_INPUT_DEVICE_STATE =
53        "android.bluetooth.inputdevice.extra.INPUT_DEVICE_STATE";
54    /** int extra for ACTION_INPUT_DEVICE_STATE_CHANGED */
55    public static final String EXTRA_PREVIOUS_INPUT_DEVICE_STATE =
56        "android.bluetooth.inputdevice.extra.PREVIOUS_INPUT_DEVICE_STATE";
57
58    /** Indicates the state of an input device has changed.
59     * This intent will always contain EXTRA_INPUT_DEVICE_STATE,
60     * EXTRA_PREVIOUS_INPUT_DEVICE_STATE and BluetoothDevice.EXTRA_DEVICE
61     * extras.
62     */
63    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
64    public static final String ACTION_INPUT_DEVICE_STATE_CHANGED =
65        "android.bluetooth.inputdevice.action.INPUT_DEVICE_STATE_CHANGED";
66
67    public static final int STATE_DISCONNECTED = 0;
68    public static final int STATE_CONNECTING   = 1;
69    public static final int STATE_CONNECTED    = 2;
70    public static final int STATE_DISCONNECTING = 3;
71
72    /**
73     * Auto connection, incoming and outgoing connection are allowed at this
74     * priority level.
75     */
76    public static final int PRIORITY_AUTO_CONNECT = 1000;
77    /**
78     * Incoming and outgoing connection are allowed at this priority level
79     */
80    public static final int PRIORITY_ON = 100;
81    /**
82     * Connections to the device are not allowed at this priority level.
83     */
84    public static final int PRIORITY_OFF = 0;
85    /**
86     * Default priority level when the device is unpaired.
87     */
88    public static final int PRIORITY_UNDEFINED = -1;
89
90    private final IBluetooth mService;
91    private final Context mContext;
92
93    /**
94     * Create a BluetoothInputDevice proxy object for interacting with the local
95     * Bluetooth Service which handle the HID profile.
96     * @param c Context
97     */
98    public BluetoothInputDevice(Context c) {
99        mContext = c;
100
101        IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
102        if (b != null) {
103            mService = IBluetooth.Stub.asInterface(b);
104        } else {
105            Log.w(TAG, "Bluetooth Service not available!");
106
107            // Instead of throwing an exception which prevents people from going
108            // into Wireless settings in the emulator. Let it crash later when it is actually used.
109            mService = null;
110        }
111    }
112
113    /** Initiate a connection to an Input device.
114     *
115     *  This function returns false on error and true if the connection
116     *  attempt is being made.
117     *
118     *  Listen for INPUT_DEVICE_STATE_CHANGED_ACTION to find out when the
119     *  connection is completed.
120     *  @param device Remote BT device.
121     *  @return false on immediate error, true otherwise
122     *  @hide
123     */
124    public boolean connectInputDevice(BluetoothDevice device) {
125        if (DBG) log("connectInputDevice(" + device + ")");
126        try {
127            return mService.connectInputDevice(device);
128        } catch (RemoteException e) {
129            Log.e(TAG, "", e);
130            return false;
131        }
132    }
133
134    /** Initiate disconnect from an Input Device.
135     *  This function return false on error and true if the disconnection
136     *  attempt is being made.
137     *
138     *  Listen for INPUT_DEVICE_STATE_CHANGED_ACTION to find out when
139     *  disconnect is completed.
140     *
141     *  @param device Remote BT device.
142     *  @return false on immediate error, true otherwise
143     *  @hide
144     */
145    public boolean disconnectInputDevice(BluetoothDevice device) {
146        if (DBG) log("disconnectInputDevice(" + device + ")");
147        try {
148            return mService.disconnectInputDevice(device);
149        } catch (RemoteException e) {
150            Log.e(TAG, "", e);
151            return false;
152        }
153    }
154
155    /** Check if a specified InputDevice is connected.
156     *
157     *  @param device Remote BT device.
158     *  @return True if connected , false otherwise and on error.
159     *  @hide
160     */
161    public boolean isInputDeviceConnected(BluetoothDevice device) {
162        if (DBG) log("isInputDeviceConnected(" + device + ")");
163        int state = getInputDeviceState(device);
164        if (state == STATE_CONNECTED) return true;
165        return false;
166    }
167
168    /** Check if any Input Device is connected.
169     *
170     * @return a unmodifiable set of connected Input Devices, or null on error.
171     * @hide
172     */
173    public Set<BluetoothDevice> getConnectedInputDevices() {
174        if (DBG) log("getConnectedInputDevices()");
175        try {
176            return Collections.unmodifiableSet(
177                    new HashSet<BluetoothDevice>(
178                        Arrays.asList(mService.getConnectedInputDevices())));
179        } catch (RemoteException e) {
180            Log.e(TAG, "", e);
181            return null;
182        }
183    }
184
185    /** Get the state of an Input Device.
186     *
187     *  @param device Remote BT device.
188     *  @return The current state of the Input Device
189     *  @hide
190     */
191    public int getInputDeviceState(BluetoothDevice device) {
192        if (DBG) log("getInputDeviceState(" + device + ")");
193        try {
194            return mService.getInputDeviceState(device);
195        } catch (RemoteException e) {
196            Log.e(TAG, "", e);
197            return STATE_DISCONNECTED;
198        }
199    }
200
201    /**
202     * Set priority of an input device.
203     *
204     * Priority is a non-negative integer. Priority can take the following
205     * values:
206     * {@link PRIORITY_ON}, {@link PRIORITY_OFF}, {@link PRIORITY_AUTO_CONNECT}
207     *
208     * @param device Paired device.
209     * @param priority Integer priority
210     * @return true if priority is set, false on error
211     */
212    public boolean setInputDevicePriority(BluetoothDevice device, int priority) {
213        if (DBG) log("setInputDevicePriority(" + device + ", " + priority + ")");
214        try {
215            return mService.setInputDevicePriority(device, priority);
216        } catch (RemoteException e) {
217            Log.e(TAG, "", e);
218            return false;
219        }
220    }
221
222    /**
223     * Get the priority associated with an Input Device.
224     *
225     * @param device Input Device
226     * @return non-negative priority, or negative error code on error.
227     */
228    public int getInputDevicePriority(BluetoothDevice device) {
229        if (DBG) log("getInputDevicePriority(" + device + ")");
230        try {
231            return mService.getInputDevicePriority(device);
232        } catch (RemoteException e) {
233            Log.e(TAG, "", e);
234            return PRIORITY_OFF;
235        }
236    }
237
238    private static void log(String msg) {
239        Log.d(TAG, msg);
240    }
241}
242