blob: df212a82d4e674f40ea2beb127f2c5e6d06b5c84 [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;
21import android.content.Context;
22import android.os.IBinder;
23import android.os.RemoteException;
24import android.os.ServiceManager;
25import android.util.Log;
26
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070027import java.util.ArrayList;
28import java.util.List;
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070029
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080030
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070031/**
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080032 * This class provides the public APIs to control the Bluetooth Input
33 * Device Profile.
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070034 *
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080035 *<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth
36 * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
37 * the BluetoothInputDevice proxy object.
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070038 *
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080039 *<p>Each method is protected with its appropriate permission.
40 *@hide
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070041 */
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080042public final class BluetoothInputDevice implements BluetoothProfile {
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070043 private static final String TAG = "BluetoothInputDevice";
44 private static final boolean DBG = false;
45
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080046 /**
47 * Intent used to broadcast the change in connection state of the Input
48 * Device profile.
49 *
50 * <p>This intent will have 3 extras:
51 * <ul>
52 * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
53 * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
54 * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
55 * </ul>
56 *
57 * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
58 * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
59 * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
60 *
61 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
62 * receive.
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070063 */
64 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080065 public static final String ACTION_CONNECTION_STATE_CHANGED =
66 "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070067
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -080068 /**
69 * Return codes for the connect and disconnect Bluez / Dbus calls.
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080070 * @hide
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -080071 */
72 public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
73
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080074 /**
75 * @hide
76 */
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -080077 public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
78
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080079 /**
80 * @hide
81 */
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -080082 public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
83
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080084 /**
85 * @hide
86 */
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -080087 public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
88
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080089 /**
90 * @hide
91 */
Jaikumar Ganeshfbe807d2011-01-19 13:59:32 -080092 public static final int INPUT_OPERATION_SUCCESS = 5004;
93
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -080094 private ServiceListener mServiceListener;
95 private BluetoothAdapter mAdapter;
96 private IBluetooth mService;
Jaikumar Ganesh545e6702010-06-04 10:23:03 -070097
98 /**
99 * Create a BluetoothInputDevice proxy object for interacting with the local
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800100 * Bluetooth Service which handles the InputDevice profile
101 *
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700102 */
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800103 /*package*/ BluetoothInputDevice(Context mContext, ServiceListener l) {
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700104 IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800105 mServiceListener = l;
106 mAdapter = BluetoothAdapter.getDefaultAdapter();
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700107 if (b != null) {
108 mService = IBluetooth.Stub.asInterface(b);
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800109 if (mServiceListener != null) {
110 mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, this);
111 }
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700112 } else {
113 Log.w(TAG, "Bluetooth Service not available!");
114
115 // Instead of throwing an exception which prevents people from going
116 // into Wireless settings in the emulator. Let it crash later when it is actually used.
117 mService = null;
118 }
119 }
120
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800121 /**
122 * {@inheritDoc}
123 * @hide
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700124 */
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800125 public boolean connect(BluetoothDevice device) {
126 if (DBG) log("connect(" + device + ")");
127 if (mService != null && isEnabled() &&
128 isValidDevice(device)) {
129 try {
130 return mService.connectInputDevice(device);
131 } catch (RemoteException e) {
132 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
133 return false;
134 }
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700135 }
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800136 if (mService == null) Log.w(TAG, "Proxy not attached to service");
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700137 return false;
138 }
139
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800140 /**
141 * {@inheritDoc}
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700142 * @hide
143 */
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800144 public boolean disconnect(BluetoothDevice device) {
145 if (DBG) log("disconnect(" + device + ")");
146 if (mService != null && isEnabled() &&
147 isValidDevice(device)) {
148 try {
149 return mService.disconnectInputDevice(device);
150 } catch (RemoteException e) {
151 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
152 return false;
153 }
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700154 }
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800155 if (mService == null) Log.w(TAG, "Proxy not attached to service");
156 return false;
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700157 }
158
159 /**
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800160 * {@inheritDoc}
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700161 */
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800162 public List<BluetoothDevice> getConnectedDevices() {
163 if (DBG) log("getConnectedDevices()");
164 if (mService != null && isEnabled()) {
165 try {
166 return mService.getConnectedInputDevices();
167 } catch (RemoteException e) {
168 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
169 return new ArrayList<BluetoothDevice>();
170 }
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700171 }
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800172 if (mService == null) Log.w(TAG, "Proxy not attached to service");
173 return new ArrayList<BluetoothDevice>();
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700174 }
175
176 /**
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800177 * {@inheritDoc}
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700178 */
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800179 public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
180 if (DBG) log("getDevicesMatchingStates()");
181 if (mService != null && isEnabled()) {
182 try {
183 return mService.getInputDevicesMatchingConnectionStates(states);
184 } catch (RemoteException e) {
185 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
186 return new ArrayList<BluetoothDevice>();
187 }
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700188 }
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800189 if (mService == null) Log.w(TAG, "Proxy not attached to service");
190 return new ArrayList<BluetoothDevice>();
191 }
192
193 /**
194 * {@inheritDoc}
195 */
196 public int getConnectionState(BluetoothDevice device) {
197 if (DBG) log("getState(" + device + ")");
198 if (mService != null && isEnabled()
199 && isValidDevice(device)) {
200 try {
201 return mService.getInputDeviceConnectionState(device);
202 } catch (RemoteException e) {
203 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
204 return BluetoothProfile.STATE_DISCONNECTED;
205 }
206 }
207 if (mService == null) Log.w(TAG, "Proxy not attached to service");
208 return BluetoothProfile.STATE_DISCONNECTED;
209 }
210
211 /**
212 * {@inheritDoc}
213 * @hide
214 */
215 public boolean setPriority(BluetoothDevice device, int priority) {
216 if (DBG) log("setPriority(" + device + ", " + priority + ")");
217 if (mService != null && isEnabled()
218 && isValidDevice(device)) {
219 if (priority != BluetoothProfile.PRIORITY_OFF &&
220 priority != BluetoothProfile.PRIORITY_ON) {
221 return false;
222 }
223 try {
224 return mService.setInputDevicePriority(device, priority);
225 } catch (RemoteException e) {
226 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
227 return false;
228 }
229 }
230 if (mService == null) Log.w(TAG, "Proxy not attached to service");
231 return false;
232 }
233
234 /**
235 * {@inheritDoc}
236 * @hide
237 */
238 public int getPriority(BluetoothDevice device) {
239 if (DBG) log("getPriority(" + device + ")");
240 if (mService != null && isEnabled()
241 && isValidDevice(device)) {
242 try {
243 return mService.getInputDevicePriority(device);
244 } catch (RemoteException e) {
245 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
246 return BluetoothProfile.PRIORITY_OFF;
247 }
248 }
249 if (mService == null) Log.w(TAG, "Proxy not attached to service");
250 return BluetoothProfile.PRIORITY_OFF;
251 }
252
253 private boolean isEnabled() {
254 if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
255 return false;
256 }
257
258 private boolean isValidDevice(BluetoothDevice device) {
259 if (device == null) return false;
260
261 if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
262 return false;
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700263 }
264
265 private static void log(String msg) {
Jaikumar Ganesh4ab0e772011-02-18 14:52:32 -0800266 Log.d(TAG, msg);
Jaikumar Ganesh545e6702010-06-04 10:23:03 -0700267 }
268}