BluetoothInputDevice.java revision bf246ef0abb6ea354fe412b139dec1adb4e5791d
1545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh/* 24ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Copyright (C) 2011 The Android Open Source Project 3545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 4545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * Licensed under the Apache License, Version 2.0 (the "License"); 5545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * you may not use this file except in compliance with the License. 6545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * You may obtain a copy of the License at 7545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 8545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * http://www.apache.org/licenses/LICENSE-2.0 9545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 10545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * Unless required by applicable law or agreed to in writing, software 11545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * distributed under the License is distributed on an "AS IS" BASIS, 12545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * See the License for the specific language governing permissions and 14545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * limitations under the License. 15545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 16545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 17545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshpackage android.bluetooth; 18545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 19545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.annotation.SdkConstant; 20545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.annotation.SdkConstant.SdkConstantType; 21bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xieimport android.content.ComponentName; 22545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.content.Context; 23bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xieimport android.content.Intent; 24bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xieimport android.content.ServiceConnection; 25545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.os.IBinder; 26545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.os.RemoteException; 27545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshimport android.util.Log; 28545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 295a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganeshimport java.util.ArrayList; 305a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganeshimport java.util.List; 31545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 324ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 33545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh/** 344ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * This class provides the public APIs to control the Bluetooth Input 354ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Device Profile. 36545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 374ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth 384ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get 394ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * the BluetoothInputDevice proxy object. 40545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * 414ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *<p>Each method is protected with its appropriate permission. 424ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh *@hide 43545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 444ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganeshpublic final class BluetoothInputDevice implements BluetoothProfile { 45545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh private static final String TAG = "BluetoothInputDevice"; 46545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh private static final boolean DBG = false; 47545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 48545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 494ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Intent used to broadcast the change in connection state of the Input 504ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Device profile. 514ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 524ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <p>This intent will have 3 extras: 534ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <ul> 544ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> 554ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li> 564ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> 574ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * </ul> 584ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 594ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 604ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, 614ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. 624ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 634ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 644ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * receive. 65545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 664ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 674ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public static final String ACTION_CONNECTION_STATE_CHANGED = 684ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED"; 69545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 70fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh /** 71fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh * Return codes for the connect and disconnect Bluez / Dbus calls. 724ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 73fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh */ 74fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000; 75fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 764ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 774ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 784ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 79fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001; 80fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 814ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 824ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 834ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 84fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002; 85fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 864ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 874ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 884ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 89fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003; 90fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 914ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 924ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 934ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh */ 94fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh public static final int INPUT_OPERATION_SUCCESS = 5004; 95fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh 96bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie private Context mContext; 974ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private ServiceListener mServiceListener; 984ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private BluetoothAdapter mAdapter; 99bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie private IBluetoothInputDevice mService; 100545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 101545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 102545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh * Create a BluetoothInputDevice proxy object for interacting with the local 1034ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * Bluetooth Service which handles the InputDevice profile 1044ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * 105545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 106bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie /*package*/ BluetoothInputDevice(Context context, ServiceListener l) { 107bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mContext = context; 1084ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh mServiceListener = l; 1094ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh mAdapter = BluetoothAdapter.getDefaultAdapter(); 110bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (!context.bindService(new Intent(IBluetoothInputDevice.class.getName()), 111bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mConnection, 0)) { 112bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie Log.e(TAG, "Could not bind to Bluetooth HID Service"); 113545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 114545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 115545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 1169bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh /*package*/ void close() { 117bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (DBG) log("close()"); 118bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mConnection != null) { 119bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mContext.unbindService(mConnection); 120bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mConnection = null; 121bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 1229bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh mServiceListener = null; 1239bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh } 1249bb275197df8eb999eab4cdd0a2aff83c2bb2ef6Jaikumar Ganesh 1254ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 126f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate connection to a profile of the remote bluetooth device. 127f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 128f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The system supports connection to multiple input devices. 129f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 130f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API returns false in scenarios like the profile on the 131f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * device is already connected or Bluetooth is not turned on. 132f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * When this API returns true, it is guaranteed that 133f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * connection state intent for the profile will be broadcasted with 134f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * the state. Users can get the connection state of the profile 135f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * from this intent. 136f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 137f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 138f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 139f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 140f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 141f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 142f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 1434ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 144545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 1454ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public boolean connect(BluetoothDevice device) { 1464ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("connect(" + device + ")"); 147bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 1484ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 149bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.connect(device); 1504ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 1514ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 1524ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 153bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 154545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 1554ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 1564ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 157545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 158545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 1594ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 160f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Initiate disconnection from a profile 161f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 162f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> This API will return false in scenarios like the profile on the 163f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Bluetooth device is not in connected state etc. When this API returns, 164f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true, it is guaranteed that the connection state change 165f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * intent will be broadcasted with the state. Users can get the 166f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * disconnection state of the profile from this intent. 167f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 168f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> If the disconnection is initiated by a remote device, the state 169f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * will transition from {@link #STATE_CONNECTED} to 170f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the 171f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * host (local) device the state will transition from 172f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to 173f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * state {@link #STATE_DISCONNECTED}. The transition to 174f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #STATE_DISCONNECTING} can be used to distinguish between the 175f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * two scenarios. 176f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 177f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 178f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 179f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 180f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Remote Bluetooth Device 181f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return false on immediate error, 182f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * true otherwise 1834ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 184545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 1854ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public boolean disconnect(BluetoothDevice device) { 1864ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("disconnect(" + device + ")"); 187bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 1884ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 189bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.disconnect(device); 1904ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 1914ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 1924ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 193bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 194545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 1954ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 1964ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 197545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 198545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 1994ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 2004ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@inheritDoc} 201545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 2024ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public List<BluetoothDevice> getConnectedDevices() { 2034ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("getConnectedDevices()"); 2044ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService != null && isEnabled()) { 2054ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 206bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getConnectedDevices(); 2074ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 2084ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 2094ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 210bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 2114ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 2124ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 2134ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 214545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 215545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 2164ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 2174ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@inheritDoc} 218545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 2194ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 2204ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("getDevicesMatchingStates()"); 2214ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService != null && isEnabled()) { 2224ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 223bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getDevicesMatchingConnectionStates(states); 2244ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 2254ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 2264ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 227bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 228545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 2294ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 2304ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return new ArrayList<BluetoothDevice>(); 231545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 232545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 2334ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh /** 2344ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * {@inheritDoc} 235545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 2364ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public int getConnectionState(BluetoothDevice device) { 2374ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("getState(" + device + ")"); 238bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 2394ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 240bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getConnectionState(device); 2414ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 2424ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 2434ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.STATE_DISCONNECTED; 244bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 245545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 2464ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 2474ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.STATE_DISCONNECTED; 248545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 249545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 250545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 251f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Set priority of the profile 252f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 253f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The device should already be paired. 254f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Priority can be one of {@link #PRIORITY_ON} or 255f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_OFF}, 256f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 257f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 258f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * permission. 259f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 260f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Paired bluetooth device 261f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param priority 262f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return true if priority is set, false on error 2634ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 264545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 2654ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public boolean setPriority(BluetoothDevice device, int priority) { 2664ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("setPriority(" + device + ", " + priority + ")"); 267bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 2684ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (priority != BluetoothProfile.PRIORITY_OFF && 2694ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh priority != BluetoothProfile.PRIORITY_ON) { 2704ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 2714ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 2724ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 273bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.setPriority(device, priority); 2744ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 2754ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 2764ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 277bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 278545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 2794ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 2804ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 281545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 282545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 283545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh /** 284f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * Get the priority of the profile. 285f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 286f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p> The priority can be any of: 287f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF}, 288f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED} 289f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 290f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 291f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * 292f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @param device Bluetooth device 293f8789167e903b637b1dbe8f710e7c66c4cfd74fdJaikumar Ganesh * @return priority of the device 2944ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh * @hide 295545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh */ 2964ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh public int getPriority(BluetoothDevice device) { 2974ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (DBG) log("getPriority(" + device + ")"); 298bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mService != null && isEnabled() && isValidDevice(device)) { 2994ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh try { 300bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie return mService.getPriority(device); 3014ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } catch (RemoteException e) { 3024ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 3034ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.PRIORITY_OFF; 304bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 305545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 3064ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mService == null) Log.w(TAG, "Proxy not attached to service"); 3074ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return BluetoothProfile.PRIORITY_OFF; 3084ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 3094ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 310bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie private ServiceConnection mConnection = new ServiceConnection() { 311bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie public void onServiceConnected(ComponentName className, IBinder service) { 312bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (DBG) Log.d(TAG, "Proxy object connected"); 313bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mService = IBluetoothInputDevice.Stub.asInterface(service); 314bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie 315bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mServiceListener != null) { 316bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, BluetoothInputDevice.this); 317bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 318bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 319bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie public void onServiceDisconnected(ComponentName className) { 320bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (DBG) Log.d(TAG, "Proxy object disconnected"); 321bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mService = null; 322bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie if (mServiceListener != null) { 323bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_DEVICE); 324bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 325bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie } 326bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie }; 327bf246ef0abb6ea354fe412b139dec1adb4e5791dMatthew Xie 3284ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private boolean isEnabled() { 3294ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true; 3304ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 3314ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh } 3324ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 3334ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh private boolean isValidDevice(BluetoothDevice device) { 3344ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (device == null) return false; 3354ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh 3364ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; 3374ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh return false; 338545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 339545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh 340545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh private static void log(String msg) { 3414ab0e7746fe74a9e4d75d374f73b7af87420b2f6Jaikumar Ganesh Log.d(TAG, msg); 342545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh } 343545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh} 344