blob: 478a9d3b6929dae32ec897cfba5e7a3c5a6e6947 [file] [log] [blame]
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07001/*
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -08002 * Copyright (C) 2011 The Android Open Source Project
Jaikumar Ganesh545e6702010-06-04 10:23:03 -07003 *
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;
Matthew Xiebf246ef2012-03-21 23:15:06 -070021import android.content.ComponentName;
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070022import android.content.Context;
Matthew Xiebf246ef2012-03-21 23:15:06 -070023import android.content.Intent;
24import android.content.ServiceConnection;
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070025import android.os.IBinder;
26import android.os.RemoteException;
Priti Aghera349e62f2012-04-09 12:13:17 -070027import android.os.ServiceManager;
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070028import android.util.Log;
29
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070030import java.util.ArrayList;
31import java.util.List;
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070032
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080033
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070034/**
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080035 * This class provides the public APIs to control the Bluetooth Input
36 * Device Profile.
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070037 *
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080038 *<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth
39 * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
40 * the BluetoothInputDevice proxy object.
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070041 *
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080042 *<p>Each method is protected with its appropriate permission.
43 *@hide
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070044 */
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080045public final class BluetoothInputDevice implements BluetoothProfile {
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070046 private static final String TAG = "BluetoothInputDevice";
47 private static final boolean DBG = false;
48
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080049 /**
50 * Intent used to broadcast the change in connection state of the Input
51 * Device profile.
52 *
53 * <p>This intent will have 3 extras:
54 * <ul>
55 * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
56 * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
57 * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
58 * </ul>
59 *
60 * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
61 * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
62 * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
63 *
64 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
65 * receive.
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070066 */
67 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080068 public static final String ACTION_CONNECTION_STATE_CHANGED =
69 "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070070
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -080071 /**
Priti Aghera349e62f2012-04-09 12:13:17 -070072 * @hide
73 */
74 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
75 public static final String ACTION_PROTOCOL_MODE_CHANGED =
76 "android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED";
77
78
79 /**
80 * @hide
81 */
82 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
83 public static final String ACTION_VIRTUAL_UNPLUG_STATUS =
84 "android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS";
85
86
87 /**
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -080088 * Return codes for the connect and disconnect Bluez / Dbus calls.
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080089 * @hide
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -080090 */
91 public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
92
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080093 /**
94 * @hide
95 */
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -080096 public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
97
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080098 /**
99 * @hide
100 */
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -0800101 public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
102
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800103 /**
104 * @hide
105 */
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -0800106 public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
107
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800108 /**
109 * @hide
110 */
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -0800111 public static final int INPUT_OPERATION_SUCCESS = 5004;
112
Priti Aghera349e62f2012-04-09 12:13:17 -0700113 /**
114 * @hide
115 */
116 public static final int PROTOCOL_REPORT_MODE = 0;
117
118 /**
119 * @hide
120 */
121 public static final int PROTOCOL_BOOT_MODE = 1;
122
123 /**
124 * @hide
125 */
126 public static final int PROTOCOL_UNSUPPORTED_MODE = 255;
127
128 /* int reportType, int reportType, int bufferSize */
129 /**
130 * @hide
131 */
132 public static final byte REPORT_TYPE_INPUT = 0;
133
134 /**
135 * @hide
136 */
137 public static final byte REPORT_TYPE_OUTPUT = 1;
138
139 /**
140 * @hide
141 */
142 public static final byte REPORT_TYPE_FEATURE = 2;
143
144 /**
145 * @hide
146 */
147 public static final int VIRTUAL_UNPLUG_STATUS_SUCCESS = 0;
148
149 /**
150 * @hide
151 */
152 public static final int VIRTUAL_UNPLUG_STATUS_FAIL = 1;
153
154 /**
155 * @hide
156 */
157 public static final String EXTRA_PROTOCOL_MODE = "android.bluetooth.BluetoothInputDevice.extra.PROTOCOL_MODE";
158
159 /**
160 * @hide
161 */
162 public static final String EXTRA_REPORT_TYPE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_TYPE";
163
164 /**
165 * @hide
166 */
167 public static final String EXTRA_REPORT_ID = "android.bluetooth.BluetoothInputDevice.extra.REPORT_ID";
168
169 /**
170 * @hide
171 */
172 public static final String EXTRA_REPORT_BUFFER_SIZE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_BUFFER_SIZE";
173
174 /**
175 * @hide
176 */
177 public static final String EXTRA_REPORT = "android.bluetooth.BluetoothInputDevice.extra.REPORT";
178
179 /**
180 * @hide
181 */
182 public static final String EXTRA_VIRTUAL_UNPLUG_STATUS = "android.bluetooth.BluetoothInputDevice.extra.VIRTUAL_UNPLUG_STATUS";
183
Matthew Xiebf246ef2012-03-21 23:15:06 -0700184 private Context mContext;
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800185 private ServiceListener mServiceListener;
186 private BluetoothAdapter mAdapter;
Matthew Xiebf246ef2012-03-21 23:15:06 -0700187 private IBluetoothInputDevice mService;
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700188
189 /**
190 * Create a BluetoothInputDevice proxy object for interacting with the local
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800191 * Bluetooth Service which handles the InputDevice profile
192 *
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700193 */
Matthew Xiebf246ef2012-03-21 23:15:06 -0700194 /*package*/ BluetoothInputDevice(Context context, ServiceListener l) {
195 mContext = context;
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800196 mServiceListener = l;
197 mAdapter = BluetoothAdapter.getDefaultAdapter();
Matthew Xiebf246ef2012-03-21 23:15:06 -0700198 if (!context.bindService(new Intent(IBluetoothInputDevice.class.getName()),
199 mConnection, 0)) {
200 Log.e(TAG, "Could not bind to Bluetooth HID Service");
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700201 }
202 }
203
Jaikumar Ganesh9bb27512011-11-28 09:59:08 -0800204 /*package*/ void close() {
Matthew Xiebf246ef2012-03-21 23:15:06 -0700205 if (DBG) log("close()");
206 if (mConnection != null) {
207 mContext.unbindService(mConnection);
208 mConnection = null;
209 }
Jaikumar Ganesh9bb27512011-11-28 09:59:08 -0800210 mServiceListener = null;
211 }
212
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800213 /**
Jaikumar Ganeshf8789162011-05-26 13:56:40 -0700214 * Initiate connection to a profile of the remote bluetooth device.
215 *
216 * <p> The system supports connection to multiple input devices.
217 *
218 * <p> This API returns false in scenarios like the profile on the
219 * device is already connected or Bluetooth is not turned on.
220 * When this API returns true, it is guaranteed that
221 * connection state intent for the profile will be broadcasted with
222 * the state. Users can get the connection state of the profile
223 * from this intent.
224 *
225 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
226 * permission.
227 *
228 * @param device Remote Bluetooth Device
229 * @return false on immediate error,
230 * true otherwise
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800231 * @hide
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700232 */
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800233 public boolean connect(BluetoothDevice device) {
234 if (DBG) log("connect(" + device + ")");
Matthew Xiebf246ef2012-03-21 23:15:06 -0700235 if (mService != null && isEnabled() && isValidDevice(device)) {
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800236 try {
Matthew Xiebf246ef2012-03-21 23:15:06 -0700237 return mService.connect(device);
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800238 } catch (RemoteException e) {
239 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
240 return false;
Matthew Xiebf246ef2012-03-21 23:15:06 -0700241 }
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700242 }
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800243 if (mService == null) Log.w(TAG, "Proxy not attached to service");
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700244 return false;
245 }
246
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800247 /**
Jaikumar Ganeshf8789162011-05-26 13:56:40 -0700248 * Initiate disconnection from a profile
249 *
250 * <p> This API will return false in scenarios like the profile on the
251 * Bluetooth device is not in connected state etc. When this API returns,
252 * true, it is guaranteed that the connection state change
253 * intent will be broadcasted with the state. Users can get the
254 * disconnection state of the profile from this intent.
255 *
256 * <p> If the disconnection is initiated by a remote device, the state
257 * will transition from {@link #STATE_CONNECTED} to
258 * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
259 * host (local) device the state will transition from
260 * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
261 * state {@link #STATE_DISCONNECTED}. The transition to
262 * {@link #STATE_DISCONNECTING} can be used to distinguish between the
263 * two scenarios.
264 *
265 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
266 * permission.
267 *
268 * @param device Remote Bluetooth Device
269 * @return false on immediate error,
270 * true otherwise
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700271 * @hide
272 */
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800273 public boolean disconnect(BluetoothDevice device) {
274 if (DBG) log("disconnect(" + device + ")");
Matthew Xiebf246ef2012-03-21 23:15:06 -0700275 if (mService != null && isEnabled() && isValidDevice(device)) {
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800276 try {
Matthew Xiebf246ef2012-03-21 23:15:06 -0700277 return mService.disconnect(device);
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800278 } catch (RemoteException e) {
279 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
280 return false;
Matthew Xiebf246ef2012-03-21 23:15:06 -0700281 }
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700282 }
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800283 if (mService == null) Log.w(TAG, "Proxy not attached to service");
284 return false;
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700285 }
286
287 /**
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800288 * {@inheritDoc}
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700289 */
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800290 public List<BluetoothDevice> getConnectedDevices() {
291 if (DBG) log("getConnectedDevices()");
292 if (mService != null && isEnabled()) {
293 try {
Matthew Xiebf246ef2012-03-21 23:15:06 -0700294 return mService.getConnectedDevices();
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800295 } catch (RemoteException e) {
296 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
297 return new ArrayList<BluetoothDevice>();
Matthew Xiebf246ef2012-03-21 23:15:06 -0700298 }
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700299 }
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800300 if (mService == null) Log.w(TAG, "Proxy not attached to service");
301 return new ArrayList<BluetoothDevice>();
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700302 }
303
304 /**
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800305 * {@inheritDoc}
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700306 */
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800307 public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
308 if (DBG) log("getDevicesMatchingStates()");
309 if (mService != null && isEnabled()) {
310 try {
Matthew Xiebf246ef2012-03-21 23:15:06 -0700311 return mService.getDevicesMatchingConnectionStates(states);
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800312 } catch (RemoteException e) {
313 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
314 return new ArrayList<BluetoothDevice>();
Matthew Xiebf246ef2012-03-21 23:15:06 -0700315 }
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700316 }
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800317 if (mService == null) Log.w(TAG, "Proxy not attached to service");
318 return new ArrayList<BluetoothDevice>();
319 }
320
321 /**
322 * {@inheritDoc}
323 */
324 public int getConnectionState(BluetoothDevice device) {
325 if (DBG) log("getState(" + device + ")");
Matthew Xiebf246ef2012-03-21 23:15:06 -0700326 if (mService != null && isEnabled() && isValidDevice(device)) {
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800327 try {
Matthew Xiebf246ef2012-03-21 23:15:06 -0700328 return mService.getConnectionState(device);
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800329 } catch (RemoteException e) {
330 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
331 return BluetoothProfile.STATE_DISCONNECTED;
Matthew Xiebf246ef2012-03-21 23:15:06 -0700332 }
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800333 }
334 if (mService == null) Log.w(TAG, "Proxy not attached to service");
335 return BluetoothProfile.STATE_DISCONNECTED;
336 }
337
338 /**
Jaikumar Ganeshf8789162011-05-26 13:56:40 -0700339 * Set priority of the profile
340 *
341 * <p> The device should already be paired.
342 * Priority can be one of {@link #PRIORITY_ON} or
343 * {@link #PRIORITY_OFF},
344 *
345 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
346 * permission.
347 *
348 * @param device Paired bluetooth device
349 * @param priority
350 * @return true if priority is set, false on error
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800351 * @hide
352 */
353 public boolean setPriority(BluetoothDevice device, int priority) {
354 if (DBG) log("setPriority(" + device + ", " + priority + ")");
Matthew Xiebf246ef2012-03-21 23:15:06 -0700355 if (mService != null && isEnabled() && isValidDevice(device)) {
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800356 if (priority != BluetoothProfile.PRIORITY_OFF &&
357 priority != BluetoothProfile.PRIORITY_ON) {
358 return false;
359 }
360 try {
Matthew Xiebf246ef2012-03-21 23:15:06 -0700361 return mService.setPriority(device, priority);
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800362 } catch (RemoteException e) {
363 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
364 return false;
Matthew Xiebf246ef2012-03-21 23:15:06 -0700365 }
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800366 }
367 if (mService == null) Log.w(TAG, "Proxy not attached to service");
368 return false;
369 }
370
371 /**
Jaikumar Ganeshf8789162011-05-26 13:56:40 -0700372 * Get the priority of the profile.
373 *
374 * <p> The priority can be any of:
375 * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
376 * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
377 *
378 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
379 *
380 * @param device Bluetooth device
381 * @return priority of the device
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800382 * @hide
383 */
384 public int getPriority(BluetoothDevice device) {
385 if (DBG) log("getPriority(" + device + ")");
Matthew Xiebf246ef2012-03-21 23:15:06 -0700386 if (mService != null && isEnabled() && isValidDevice(device)) {
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800387 try {
Matthew Xiebf246ef2012-03-21 23:15:06 -0700388 return mService.getPriority(device);
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800389 } catch (RemoteException e) {
390 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
391 return BluetoothProfile.PRIORITY_OFF;
Matthew Xiebf246ef2012-03-21 23:15:06 -0700392 }
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800393 }
394 if (mService == null) Log.w(TAG, "Proxy not attached to service");
395 return BluetoothProfile.PRIORITY_OFF;
396 }
397
Matthew Xiebf246ef2012-03-21 23:15:06 -0700398 private ServiceConnection mConnection = new ServiceConnection() {
399 public void onServiceConnected(ComponentName className, IBinder service) {
400 if (DBG) Log.d(TAG, "Proxy object connected");
401 mService = IBluetoothInputDevice.Stub.asInterface(service);
402
403 if (mServiceListener != null) {
404 mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, BluetoothInputDevice.this);
405 }
406 }
407 public void onServiceDisconnected(ComponentName className) {
408 if (DBG) Log.d(TAG, "Proxy object disconnected");
409 mService = null;
410 if (mServiceListener != null) {
411 mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_DEVICE);
412 }
413 }
414 };
415
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800416 private boolean isEnabled() {
417 if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
418 return false;
419 }
420
421 private boolean isValidDevice(BluetoothDevice device) {
422 if (device == null) return false;
423
424 if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
425 return false;
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700426 }
427
Priti Aghera349e62f2012-04-09 12:13:17 -0700428
429 /**
430 * Initiate virtual unplug for a HID input device.
431 *
432 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
433 *
434 * @param device Remote Bluetooth Device
435 * @return false on immediate error,
436 * true otherwise
437 * @hide
438 */
439 public boolean virtualUnplug(BluetoothDevice device) {
440 if (DBG) log("virtualUnplug(" + device + ")");
441 if (mService != null && isEnabled() && isValidDevice(device)) {
442 try {
443 return mService.virtualUnplug(device);
444 } catch (RemoteException e) {
445 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
446 return false;
447 }
448 }
449
450 if (mService == null) Log.w(TAG, "Proxy not attached to service");
451 return false;
452
453 }
454
455 /**
456 * Send Get_Protocol_Mode command to the connected HID input device.
457 *
458 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
459 *
460 * @param device Remote Bluetooth Device
461 * @return false on immediate error,
462 *true otherwise
463 * @hide
464 */
465 public boolean getProtocolMode(BluetoothDevice device) {
466 if (DBG) log("getProtocolMode(" + device + ")");
467 if (mService != null && isEnabled() && isValidDevice(device)) {
468 try {
469 return mService.getProtocolMode(device);
470 } catch (RemoteException e) {
471 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
472 return false;
473 }
474 }
475 if (mService == null) Log.w(TAG, "Proxy not attached to service");
476 return false;
477 }
478
479 /**
480 * Send Set_Protocol_Mode command to the connected HID input device.
481 *
482 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
483 *
484 * @param device Remote Bluetooth Device
485 * @return false on immediate error,
486 * true otherwise
487 * @hide
488 */
489 public boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
490 if (DBG) log("setProtocolMode(" + device + ")");
491 if (mService != null && isEnabled() && isValidDevice(device)) {
492 try {
493 return mService.setProtocolMode(device, protocolMode);
494 } catch (RemoteException e) {
495 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
496 return false;
497 }
498 }
499 if (mService == null) Log.w(TAG, "Proxy not attached to service");
500 return false;
501 }
502
503 /**
504 * Send Get_Report command to the connected HID input device.
505 *
506 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
507 *
508 * @param device Remote Bluetooth Device
509 * @param reportType Report type
510 * @param reportId Report ID
511 * @param bufferSize Report receiving buffer size
512 * @return false on immediate error,
513 * true otherwise
514 * @hide
515 */
516 public boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) {
517 if (DBG) log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId + "bufferSize=" + bufferSize);
518 if (mService != null && isEnabled() && isValidDevice(device)) {
519 try {
520 return mService.getReport(device, reportType, reportId, bufferSize);
521 } catch (RemoteException e) {
522 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
523 return false;
524 }
525 }
526 if (mService == null) Log.w(TAG, "Proxy not attached to service");
527 return false;
528 }
529
530 /**
531 * Send Set_Report command to the connected HID input device.
532 *
533 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
534 *
535 * @param device Remote Bluetooth Device
536 * @param reportType Report type
537 * @param report Report receiving buffer size
538 * @return false on immediate error,
539 * true otherwise
540 * @hide
541 */
542 public boolean setReport(BluetoothDevice device, byte reportType, String report) {
543 if (DBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
544 if (mService != null && isEnabled() && isValidDevice(device)) {
545 try {
546 return mService.setReport(device, reportType, report);
547 } catch (RemoteException e) {
548 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
549 return false;
550 }
551 }
552 if (mService == null) Log.w(TAG, "Proxy not attached to service");
553 return false;
554 }
555
556 /**
557 * Send Send_Data command to the connected HID input device.
558 *
559 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
560 *
561 * @param device Remote Bluetooth Device
562 * @param data Data to send
563 * @return false on immediate error,
564 * true otherwise
565 * @hide
566 */
567 public boolean sendData(BluetoothDevice device, String report) {
568 if (DBG) log("sendData(" + device + "), report=" + report);
569 if (mService != null && isEnabled() && isValidDevice(device)) {
570 try {
571 return mService.sendData(device, report);
572 } catch (RemoteException e) {
573 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
574 return false;
575 }
576 }
577 if (mService == null) Log.w(TAG, "Proxy not attached to service");
578 return false;
579 }
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700580 private static void log(String msg) {
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800581 Log.d(TAG, msg);
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700582 }
583}