BluetoothPan.java revision e4caddbb7a3b39fd6a1ccf107c7dbf09bc8978e8
1/* 2 * Copyright (C) 2008 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.ArrayList; 28import java.util.List; 29 30 31/** 32 * This class provides the APIs to control the Bluetooth Pan 33 * Profile. 34 * 35 *<p>BluetoothPan is a proxy object for controlling the Bluetooth 36 * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get 37 * the BluetoothPan proxy object. 38 * 39 *<p>Each method is protected with its appropriate permission. 40 *@hide 41 */ 42public final class BluetoothPan implements BluetoothProfile { 43 private static final String TAG = "BluetoothPan"; 44 private static final boolean DBG = false; 45 46 /** 47 * Intent used to broadcast the change in connection state of the Pan 48 * profile. 49 * 50 * <p>This intent will have 4 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 * <li> {@link #EXTRA_LOCAL_ROLE} - Which local role the remote device is 56 * bound to. </li> 57 * </ul> 58 * 59 * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of 60 * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, 61 * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. 62 * 63 * <p> {@link #EXTRA_LOCAL_ROLE} can be one of {@link #LOCAL_NAP_ROLE} or 64 * {@link #LOCAL_PANU_ROLE} 65 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to 66 * receive. 67 */ 68 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 69 public static final String ACTION_CONNECTION_STATE_CHANGED = 70 "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED"; 71 72 /** 73 * Extra for {@link #ACTION_CONNECTION_STATE_CHANGED} intent 74 * The local role of the PAN profile that the remote device is bound to. 75 * It can be one of {@link #LOCAL_NAP_ROLE} or {@link #LOCAL_PANU_ROLE}. 76 */ 77 public static final String EXTRA_LOCAL_ROLE = "android.bluetooth.pan.extra.LOCAL_ROLE"; 78 79 /** 80 * The local device is acting as a Network Access Point. 81 */ 82 public static final int LOCAL_NAP_ROLE = 1; 83 84 /** 85 * The local device is acting as a PAN User. 86 */ 87 public static final int LOCAL_PANU_ROLE = 2; 88 89 /** 90 * Return codes for the connect and disconnect Bluez / Dbus calls. 91 * @hide 92 */ 93 public static final int PAN_DISCONNECT_FAILED_NOT_CONNECTED = 1000; 94 95 /** 96 * @hide 97 */ 98 public static final int PAN_CONNECT_FAILED_ALREADY_CONNECTED = 1001; 99 100 /** 101 * @hide 102 */ 103 public static final int PAN_CONNECT_FAILED_ATTEMPT_FAILED = 1002; 104 105 /** 106 * @hide 107 */ 108 public static final int PAN_OPERATION_GENERIC_FAILURE = 1003; 109 110 /** 111 * @hide 112 */ 113 public static final int PAN_OPERATION_SUCCESS = 1004; 114 115 private ServiceListener mServiceListener; 116 private BluetoothAdapter mAdapter; 117 private IBluetooth mService; 118 119 /** 120 * Create a BluetoothPan proxy object for interacting with the local 121 * Bluetooth Service which handles the Pan profile 122 * 123 */ 124 /*package*/ BluetoothPan(Context mContext, ServiceListener l) { 125 IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE); 126 mServiceListener = l; 127 mAdapter = BluetoothAdapter.getDefaultAdapter(); 128 if (b != null) { 129 mService = IBluetooth.Stub.asInterface(b); 130 if (mServiceListener != null) { 131 mServiceListener.onServiceConnected(BluetoothProfile.PAN, this); 132 } 133 } else { 134 Log.w(TAG, "Bluetooth Service not available!"); 135 136 // Instead of throwing an exception which prevents people from going 137 // into Wireless settings in the emulator. Let it crash later when it is actually used. 138 mService = null; 139 } 140 } 141 142 /*package*/ void close() { 143 mServiceListener = null; 144 } 145 146 /** 147 * Initiate connection to a profile of the remote bluetooth device. 148 * 149 * <p> This API returns false in scenarios like the profile on the 150 * device is already connected or Bluetooth is not turned on. 151 * When this API returns true, it is guaranteed that 152 * connection state intent for the profile will be broadcasted with 153 * the state. Users can get the connection state of the profile 154 * from this intent. 155 * 156 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 157 * permission. 158 * 159 * @param device Remote Bluetooth Device 160 * @return false on immediate error, 161 * true otherwise 162 * @hide 163 */ 164 public boolean connect(BluetoothDevice device) { 165 if (DBG) log("connect(" + device + ")"); 166 if (mService != null && isEnabled() && 167 isValidDevice(device)) { 168 //TODO(BT 169 /* 170 try { 171 return mService.connectPanDevice(device); 172 } catch (RemoteException e) { 173 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 174 return false; 175 }*/ 176 } 177 if (mService == null) Log.w(TAG, "Proxy not attached to service"); 178 return false; 179 } 180 181 /** 182 * Initiate disconnection from a profile 183 * 184 * <p> This API will return false in scenarios like the profile on the 185 * Bluetooth device is not in connected state etc. When this API returns, 186 * true, it is guaranteed that the connection state change 187 * intent will be broadcasted with the state. Users can get the 188 * disconnection state of the profile from this intent. 189 * 190 * <p> If the disconnection is initiated by a remote device, the state 191 * will transition from {@link #STATE_CONNECTED} to 192 * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the 193 * host (local) device the state will transition from 194 * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to 195 * state {@link #STATE_DISCONNECTED}. The transition to 196 * {@link #STATE_DISCONNECTING} can be used to distinguish between the 197 * two scenarios. 198 * 199 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 200 * permission. 201 * 202 * @param device Remote Bluetooth Device 203 * @return false on immediate error, 204 * true otherwise 205 * @hide 206 */ 207 public boolean disconnect(BluetoothDevice device) { 208 if (DBG) log("disconnect(" + device + ")"); 209 if (mService != null && isEnabled() && 210 isValidDevice(device)) { 211 //TODO(BT 212 /* 213 try { 214 return mService.disconnectPanDevice(device); 215 } catch (RemoteException e) { 216 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 217 return false; 218 }*/ 219 } 220 if (mService == null) Log.w(TAG, "Proxy not attached to service"); 221 return false; 222 } 223 224 /** 225 * {@inheritDoc} 226 */ 227 public List<BluetoothDevice> getConnectedDevices() { 228 if (DBG) log("getConnectedDevices()"); 229 if (mService != null && isEnabled()) { 230 //TODO(BT 231 /* 232 try { 233 return mService.getConnectedPanDevices(); 234 } catch (RemoteException e) { 235 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 236 return new ArrayList<BluetoothDevice>(); 237 }*/ 238 } 239 if (mService == null) Log.w(TAG, "Proxy not attached to service"); 240 return new ArrayList<BluetoothDevice>(); 241 } 242 243 /** 244 * {@inheritDoc} 245 */ 246 public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 247 if (DBG) log("getDevicesMatchingStates()"); 248 if (mService != null && isEnabled()) { 249 //TODO(BT 250 /* 251 try { 252 return mService.getPanDevicesMatchingConnectionStates(states); 253 } catch (RemoteException e) { 254 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 255 return new ArrayList<BluetoothDevice>(); 256 }*/ 257 } 258 if (mService == null) Log.w(TAG, "Proxy not attached to service"); 259 return new ArrayList<BluetoothDevice>(); 260 } 261 262 /** 263 * {@inheritDoc} 264 */ 265 public int getConnectionState(BluetoothDevice device) { 266 if (DBG) log("getState(" + device + ")"); 267 if (mService != null && isEnabled() 268 && isValidDevice(device)) { 269 //TODO(BT 270 /* 271 try { 272 return mService.getPanDeviceConnectionState(device); 273 } catch (RemoteException e) { 274 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 275 return BluetoothProfile.STATE_DISCONNECTED; 276 }*/ 277 } 278 if (mService == null) Log.w(TAG, "Proxy not attached to service"); 279 return BluetoothProfile.STATE_DISCONNECTED; 280 } 281 282 public void setBluetoothTethering(boolean value) { 283 if (DBG) log("setBluetoothTethering(" + value + ")"); 284 //TODO(BT 285 /* 286 try { 287 mService.setBluetoothTethering(value); 288 } catch (RemoteException e) { 289 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 290 }*/ 291 } 292 293 public boolean isTetheringOn() { 294 if (DBG) log("isTetheringOn()"); 295 //TODO(BT 296 /* 297 try { 298 return mService.isTetheringOn(); 299 } catch (RemoteException e) { 300 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); 301 return false; 302 }*/ 303 return false; 304 } 305 306 private boolean isEnabled() { 307 if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true; 308 return false; 309 } 310 311 private boolean isValidDevice(BluetoothDevice device) { 312 if (device == null) return false; 313 314 if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; 315 return false; 316 } 317 318 private static void log(String msg) { 319 Log.d(TAG, msg); 320 } 321} 322