AdapterService.java revision df3304a333d8c385f9d5cb0e691fb72d940ec273
1/* 2 * Copyright (C) 2012 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 17/** 18 * @hide 19 */ 20 21package com.android.bluetooth.btservice; 22 23import android.app.AlarmManager; 24import android.app.Application; 25import android.app.PendingIntent; 26import android.app.Service; 27import android.bluetooth.BluetoothAdapter; 28import android.bluetooth.BluetoothDevice; 29import android.bluetooth.BluetoothProfile; 30import android.bluetooth.BluetoothUuid; 31import android.bluetooth.IBluetooth; 32import android.bluetooth.IBluetoothCallback; 33import android.bluetooth.IBluetoothManager; 34import android.bluetooth.IBluetoothManagerCallback; 35import android.bluetooth.BluetoothActivityEnergyInfo; 36import android.content.BroadcastReceiver; 37import android.content.ContentResolver; 38import android.content.Context; 39import android.content.Intent; 40import android.content.IntentFilter; 41import android.content.SharedPreferences; 42import android.os.Binder; 43import android.os.Bundle; 44import android.os.Handler; 45import android.os.IBinder; 46import android.os.Message; 47import android.os.ParcelFileDescriptor; 48import android.os.ParcelUuid; 49import android.os.PowerManager; 50import android.os.Process; 51import android.os.RemoteCallbackList; 52import android.os.RemoteException; 53import android.os.SystemClock; 54import android.provider.Settings; 55import android.util.EventLog; 56import android.util.Log; 57import android.util.Pair; 58 59import com.android.bluetooth.a2dp.A2dpService; 60import com.android.bluetooth.hid.HidService; 61import com.android.bluetooth.hfp.HeadsetService; 62import com.android.bluetooth.hdp.HealthService; 63import com.android.bluetooth.pan.PanService; 64import com.android.bluetooth.sdp.SdpManager; 65import com.android.internal.R; 66import com.android.bluetooth.Utils; 67import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; 68 69import java.io.FileDescriptor; 70import java.io.FileWriter; 71import java.io.IOException; 72import java.util.ArrayList; 73import java.util.HashMap; 74import java.util.Set; 75import java.util.Map; 76import java.util.Iterator; 77import java.util.Map.Entry; 78import java.util.List; 79 80import android.content.pm.PackageManager; 81import android.os.ServiceManager; 82 83public class AdapterService extends Service { 84 private static final String TAG = "BluetoothAdapterService"; 85 private static final boolean DBG = false; 86 private static final boolean TRACE_REF = false; 87 private static final int MIN_ADVT_INSTANCES_FOR_MA = 5; 88 private static final int MIN_OFFLOADED_FILTERS = 10; 89 private static final int MIN_OFFLOADED_SCAN_STORAGE_BYTES = 1024; 90 //For Debugging only 91 private static int sRefCount=0; 92 93 private int mStackReportedState; 94 private int mTxTimeTotalMs; 95 private int mRxTimeTotalMs; 96 private int mIdleTimeTotalMs; 97 private int mEnergyUsedTotalVoltAmpSecMicro; 98 99 private final ArrayList<ProfileService> mProfiles = new ArrayList<ProfileService>(); 100 101 public static final String ACTION_LOAD_ADAPTER_PROPERTIES = 102 "com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES"; 103 public static final String ACTION_SERVICE_STATE_CHANGED = 104 "com.android.bluetooth.btservice.action.STATE_CHANGED"; 105 public static final String EXTRA_ACTION="action"; 106 public static final int PROFILE_CONN_CONNECTED = 1; 107 public static final int PROFILE_CONN_REJECTED = 2; 108 109 private static final String ACTION_ALARM_WAKEUP = 110 "com.android.bluetooth.btservice.action.ALARM_WAKEUP"; 111 112 public static final String BLUETOOTH_ADMIN_PERM = 113 android.Manifest.permission.BLUETOOTH_ADMIN; 114 public static final String BLUETOOTH_PRIVILEGED = 115 android.Manifest.permission.BLUETOOTH_PRIVILEGED; 116 static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; 117 static final String RECEIVE_MAP_PERM = android.Manifest.permission.RECEIVE_BLUETOOTH_MAP; 118 119 private static final String PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE = 120 "phonebook_access_permission"; 121 private static final String MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE = 122 "message_access_permission"; 123 private static final String SIM_ACCESS_PERMISSION_PREFERENCE_FILE = 124 "sim_access_permission"; 125 126 private static final int ADAPTER_SERVICE_TYPE=Service.START_STICKY; 127 128 static { 129 classInitNative(); 130 } 131 132 private static AdapterService sAdapterService; 133 public static synchronized AdapterService getAdapterService(){ 134 if (sAdapterService != null && !sAdapterService.mCleaningUp) { 135 Log.d(TAG, "getAdapterService() - returning " + sAdapterService); 136 return sAdapterService; 137 } 138 if (DBG) { 139 if (sAdapterService == null) { 140 Log.d(TAG, "getAdapterService() - Service not available"); 141 } else if (sAdapterService.mCleaningUp) { 142 Log.d(TAG,"getAdapterService() - Service is cleaning up"); 143 } 144 } 145 return null; 146 } 147 148 private static synchronized void setAdapterService(AdapterService instance) { 149 if (instance != null && !instance.mCleaningUp) { 150 if (DBG) Log.d(TAG, "setAdapterService() - set to: " + sAdapterService); 151 sAdapterService = instance; 152 } else { 153 if (DBG) { 154 if (sAdapterService == null) { 155 Log.d(TAG, "setAdapterService() - Service not available"); 156 } else if (sAdapterService.mCleaningUp) { 157 Log.d(TAG,"setAdapterService() - Service is cleaning up"); 158 } 159 } 160 } 161 } 162 163 private static synchronized void clearAdapterService() { 164 sAdapterService = null; 165 } 166 167 private AdapterProperties mAdapterProperties; 168 private AdapterState mAdapterStateMachine; 169 private BondStateMachine mBondStateMachine; 170 private JniCallbacks mJniCallbacks; 171 private RemoteDevices mRemoteDevices; 172 173 /* TODO: Consider to remove the search API from this class, if changed to use call-back */ 174 private SdpManager mSdpManager = null; 175 176 private boolean mProfilesStarted; 177 private boolean mNativeAvailable; 178 private boolean mCleaningUp; 179 private HashMap<String,Integer> mProfileServicesState = new HashMap<String,Integer>(); 180 //Only BluetoothManagerService should be registered 181 private RemoteCallbackList<IBluetoothCallback> mCallbacks; 182 private int mCurrentRequestId; 183 private boolean mQuietmode = false; 184 185 private AlarmManager mAlarmManager; 186 private PendingIntent mPendingAlarm; 187 private PowerManager mPowerManager; 188 private PowerManager.WakeLock mWakeLock; 189 private String mWakeLockName; 190 191 public AdapterService() { 192 super(); 193 if (TRACE_REF) { 194 synchronized (AdapterService.class) { 195 sRefCount++; 196 debugLog("AdapterService() - REFCOUNT: CREATED. INSTANCE_COUNT" + sRefCount); 197 } 198 } 199 } 200 201 public void onProfileConnectionStateChanged(BluetoothDevice device, int profileId, int newState, int prevState) { 202 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED); 203 m.obj = device; 204 m.arg1 = profileId; 205 m.arg2 = newState; 206 Bundle b = new Bundle(1); 207 b.putInt("prevState", prevState); 208 m.setData(b); 209 mHandler.sendMessage(m); 210 } 211 212 public void initProfilePriorities(BluetoothDevice device, ParcelUuid[] mUuids) { 213 if(mUuids == null) return; 214 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES); 215 m.obj = device; 216 m.arg1 = mUuids.length; 217 Bundle b = new Bundle(1); 218 for(int i=0; i<mUuids.length; i++) { 219 b.putParcelable("uuids" + i, mUuids[i]); 220 } 221 m.setData(b); 222 mHandler.sendMessage(m); 223 } 224 225 private void processInitProfilePriorities (BluetoothDevice device, ParcelUuid[] uuids){ 226 HidService hidService = HidService.getHidService(); 227 A2dpService a2dpService = A2dpService.getA2dpService(); 228 HeadsetService headsetService = HeadsetService.getHeadsetService(); 229 230 // Set profile priorities only for the profiles discovered on the remote device. 231 // This avoids needless auto-connect attempts to profiles non-existent on the remote device 232 if ((hidService != null) && 233 (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hid) || 234 BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hogp)) && 235 (hidService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ 236 hidService.setPriority(device,BluetoothProfile.PRIORITY_ON); 237 } 238 239 // If we do not have a stored priority for A2DP then default to on. 240 if ((a2dpService != null) && 241 (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink) || 242 BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AdvAudioDist)) && 243 (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ 244 a2dpService.setPriority(device,BluetoothProfile.PRIORITY_ON); 245 } 246 247 if ((headsetService != null) && 248 ((BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP) || 249 BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree)) && 250 (headsetService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED))){ 251 headsetService.setPriority(device,BluetoothProfile.PRIORITY_ON); 252 } 253 } 254 255 private void processProfileStateChanged(BluetoothDevice device, int profileId, int newState, int prevState) { 256 if (((profileId == BluetoothProfile.A2DP) ||(profileId == BluetoothProfile.HEADSET)) && 257 (newState == BluetoothProfile.STATE_CONNECTED)){ 258 debugLog( "Profile connected. Schedule missing profile connection if any"); 259 connectOtherProfile(device, PROFILE_CONN_CONNECTED); 260 setProfileAutoConnectionPriority(device, profileId); 261 } 262 IBluetooth.Stub binder = mBinder; 263 if (binder != null) { 264 try { 265 binder.sendConnectionStateChange(device, profileId, newState,prevState); 266 } catch (RemoteException re) { 267 errorLog("" + re); 268 } 269 } 270 } 271 272 public void addProfile(ProfileService profile) { 273 synchronized (mProfiles) { 274 mProfiles.add(profile); 275 } 276 } 277 278 public void removeProfile(ProfileService profile) { 279 synchronized (mProfiles) { 280 mProfiles.remove(profile); 281 } 282 } 283 284 public void onProfileServiceStateChanged(String serviceName, int state) { 285 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 286 m.obj=serviceName; 287 m.arg1 = state; 288 mHandler.sendMessage(m); 289 } 290 291 private void processProfileServiceStateChanged(String serviceName, int state) { 292 boolean doUpdate=false; 293 boolean isBleTurningOn; 294 boolean isBleTurningOff; 295 boolean isTurningOn; 296 boolean isTurningOff; 297 298 synchronized (mProfileServicesState) { 299 Integer prevState = mProfileServicesState.get(serviceName); 300 if (prevState != null && prevState != state) { 301 mProfileServicesState.put(serviceName,state); 302 doUpdate=true; 303 } 304 } 305 debugLog("onProfileServiceStateChange() serviceName=" + serviceName 306 + ", state=" + state +", doUpdate=" + doUpdate); 307 308 if (!doUpdate) { 309 return; 310 } 311 312 synchronized (mAdapterStateMachine) { 313 isTurningOff = mAdapterStateMachine.isTurningOff(); 314 isTurningOn = mAdapterStateMachine.isTurningOn(); 315 isBleTurningOn = mAdapterStateMachine.isBleTurningOn(); 316 isBleTurningOff = mAdapterStateMachine.isBleTurningOff(); 317 } 318 319 debugLog("processProfileServiceStateChanged() - serviceName=" + serviceName + 320 " isTurningOn=" + isTurningOn + " isTurningOff=" + isTurningOff + 321 " isBleTurningOn=" + isBleTurningOn + " isBleTurningOff=" + isBleTurningOff); 322 323 if (isBleTurningOn) { 324 if (serviceName.equals("com.android.bluetooth.gatt.GattService")) { 325 debugLog("GattService is started"); 326 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BLE_STARTED)); 327 return; 328 } 329 330 } else if(isBleTurningOff) { 331 if (serviceName.equals("com.android.bluetooth.gatt.GattService")) { 332 debugLog("GattService stopped"); 333 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BLE_STOPPED)); 334 return; 335 } 336 337 } else if (isTurningOff) { 338 //On to BLE_ON 339 //Process stop or disable pending 340 //Check if all services are stopped if so, do cleanup 341 synchronized (mProfileServicesState) { 342 Iterator<Map.Entry<String,Integer>> i = mProfileServicesState.entrySet().iterator(); 343 while (i.hasNext()) { 344 Map.Entry<String,Integer> entry = i.next(); 345 debugLog("Service: " + entry.getKey()); 346 if (entry.getKey().equals("com.android.bluetooth.gatt.GattService")) { 347 debugLog("Skip GATT service - already started before"); 348 continue; 349 } 350 if (BluetoothAdapter.STATE_OFF != entry.getValue()) { 351 debugLog("onProfileServiceStateChange() - Profile still running: " 352 + entry.getKey()); 353 return; 354 } 355 } 356 } 357 debugLog("onProfileServiceStateChange() - All profile services stopped..."); 358 //Send message to state machine 359 mProfilesStarted=false; 360 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BREDR_STOPPED)); 361 362 } else if (isTurningOn) { 363 //Process start pending 364 //Check if all services are started if so, update state 365 synchronized (mProfileServicesState) { 366 Iterator<Map.Entry<String,Integer>> i = mProfileServicesState.entrySet().iterator(); 367 while (i.hasNext()) { 368 Map.Entry<String,Integer> entry = i.next(); 369 debugLog("Service: " + entry.getKey()); 370 if (entry.getKey().equals("com.android.bluetooth.gatt.GattService")) { 371 debugLog("Skip GATT service - already started before"); 372 continue; 373 } 374 if (BluetoothAdapter.STATE_ON != entry.getValue()) { 375 debugLog("onProfileServiceStateChange() - Profile still not running:" 376 + entry.getKey()); 377 return; 378 } 379 } 380 } 381 debugLog("onProfileServiceStateChange() - All profile services started."); 382 mProfilesStarted=true; 383 //Send message to state machine 384 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BREDR_STARTED)); 385 } 386 } 387 388 @Override 389 public void onCreate() { 390 super.onCreate(); 391 debugLog("onCreate()"); 392 mBinder = new AdapterServiceBinder(this); 393 mAdapterProperties = new AdapterProperties(this); 394 mAdapterStateMachine = AdapterState.make(this, mAdapterProperties); 395 mJniCallbacks = new JniCallbacks(mAdapterStateMachine, mAdapterProperties); 396 initNative(); 397 mNativeAvailable=true; 398 mCallbacks = new RemoteCallbackList<IBluetoothCallback>(); 399 //Load the name and address 400 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR); 401 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME); 402 mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 403 mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); 404 405 mSdpManager = SdpManager.init(this); 406 registerReceiver(mAlarmBroadcastReceiver, new IntentFilter(ACTION_ALARM_WAKEUP)); 407 408 409 410 } 411 412 @Override 413 public IBinder onBind(Intent intent) { 414 debugLog("onBind()"); 415 return mBinder; 416 } 417 public boolean onUnbind(Intent intent) { 418 debugLog("onUnbind() - calling cleanup"); 419 cleanup(); 420 return super.onUnbind(intent); 421 } 422 423 public void onDestroy() { 424 debugLog("onDestroy()"); 425 } 426 427 void BleOnProcessStart() { 428 debugLog("BleOnProcessStart()"); 429 Class[] supportedProfileServices = Config.getSupportedProfiles(); 430 //Initialize data objects 431 for (int i=0; i < supportedProfileServices.length;i++) { 432 mProfileServicesState.put(supportedProfileServices[i].getName(),BluetoothAdapter.STATE_OFF); 433 } 434 mRemoteDevices = new RemoteDevices(this); 435 mAdapterProperties.init(mRemoteDevices); 436 437 debugLog("BleOnProcessStart() - Make Bond State Machine"); 438 mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices); 439 440 mJniCallbacks.init(mBondStateMachine,mRemoteDevices); 441 442 //FIXME: Set static instance here??? 443 setAdapterService(this); 444 445 //Start Gatt service 446 setGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON); 447 } 448 449 void startCoreServices() 450 { 451 debugLog("startCoreServices()"); 452 Class[] supportedProfileServices = Config.getSupportedProfiles(); 453 454 //Start profile services 455 if (!mProfilesStarted && supportedProfileServices.length >0) { 456 //Startup all profile services 457 setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON); 458 }else { 459 debugLog("startCoreProfiles(): Profile Services alreay started"); 460 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BREDR_STARTED)); 461 } 462 } 463 464 void startBluetoothDisable() { 465 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BEGIN_DISABLE)); 466 } 467 468 boolean stopProfileServices() { 469 Class[] supportedProfileServices = Config.getSupportedProfiles(); 470 if (mProfilesStarted && supportedProfileServices.length>0) { 471 setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_OFF); 472 return true; 473 } 474 debugLog("stopProfileServices() - No profiles services to stop or already stopped."); 475 return false; 476 } 477 478 boolean stopGattProfileService() { 479 //TODO: can optimize this instead of looping around all supported profiles 480 debugLog("stopGattProfileService()"); 481 Class[] supportedProfileServices = Config.getSupportedProfiles(); 482 483 setGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_OFF); 484 return true; 485 } 486 487 488 void updateAdapterState(int prevState, int newState){ 489 if (mCallbacks !=null) { 490 int n=mCallbacks.beginBroadcast(); 491 debugLog("updateAdapterState() - Broadcasting state to " + n + " receivers."); 492 for (int i=0; i <n;i++) { 493 try { 494 mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState,newState); 495 } catch (RemoteException e) { 496 debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")"); 497 } 498 } 499 mCallbacks.finishBroadcast(); 500 } 501 } 502 503 void cleanup () { 504 debugLog("cleanup()"); 505 if (mCleaningUp) { 506 errorLog("cleanup() - Service already starting to cleanup, ignoring request..."); 507 return; 508 } 509 510 mCleaningUp = true; 511 512 unregisterReceiver(mAlarmBroadcastReceiver); 513 514 if (mPendingAlarm != null) { 515 mAlarmManager.cancel(mPendingAlarm); 516 mPendingAlarm = null; 517 } 518 519 // This wake lock release may also be called concurrently by 520 // {@link #releaseWakeLock(String lockName)}, so a synchronization is needed here. 521 synchronized (this) { 522 if (mWakeLock != null) { 523 mWakeLock.release(); 524 mWakeLock = null; 525 } 526 } 527 528 if (mAdapterStateMachine != null) { 529 mAdapterStateMachine.doQuit(); 530 mAdapterStateMachine.cleanup(); 531 } 532 533 if (mBondStateMachine != null) { 534 mBondStateMachine.doQuit(); 535 mBondStateMachine.cleanup(); 536 } 537 538 if (mRemoteDevices != null) { 539 mRemoteDevices.cleanup(); 540 } 541 542 if(mSdpManager != null) { 543 mSdpManager.cleanup(); 544 mSdpManager = null; 545 } 546 547 if (mNativeAvailable) { 548 debugLog("cleanup() - Cleaning up adapter native"); 549 cleanupNative(); 550 mNativeAvailable=false; 551 } 552 553 if (mAdapterProperties != null) { 554 mAdapterProperties.cleanup(); 555 } 556 557 if (mJniCallbacks != null) { 558 mJniCallbacks.cleanup(); 559 } 560 561 if (mProfileServicesState != null) { 562 mProfileServicesState.clear(); 563 } 564 565 clearAdapterService(); 566 567 if (mBinder != null) { 568 mBinder.cleanup(); 569 mBinder = null; //Do not remove. Otherwise Binder leak! 570 } 571 572 if (mCallbacks !=null) { 573 mCallbacks.kill(); 574 } 575 576 System.exit(0); 577 } 578 579 private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED =1; 580 private static final int MESSAGE_PROFILE_CONNECTION_STATE_CHANGED=20; 581 private static final int MESSAGE_CONNECT_OTHER_PROFILES = 30; 582 private static final int MESSAGE_PROFILE_INIT_PRIORITIES=40; 583 private static final int CONNECT_OTHER_PROFILES_TIMEOUT= 6000; 584 585 private final Handler mHandler = new Handler() { 586 @Override 587 public void handleMessage(Message msg) { 588 debugLog("handleMessage() - Message: " + msg.what); 589 590 switch (msg.what) { 591 case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: { 592 debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED"); 593 processProfileServiceStateChanged((String) msg.obj, msg.arg1); 594 } 595 break; 596 case MESSAGE_PROFILE_CONNECTION_STATE_CHANGED: { 597 debugLog( "handleMessage() - MESSAGE_PROFILE_CONNECTION_STATE_CHANGED"); 598 processProfileStateChanged((BluetoothDevice) msg.obj, msg.arg1,msg.arg2, msg.getData().getInt("prevState",BluetoothAdapter.ERROR)); 599 } 600 break; 601 case MESSAGE_PROFILE_INIT_PRIORITIES: { 602 debugLog( "handleMessage() - MESSAGE_PROFILE_INIT_PRIORITIES"); 603 ParcelUuid[] mUuids = new ParcelUuid[msg.arg1]; 604 for(int i=0; i<mUuids.length; i++) { 605 mUuids[i] = msg.getData().getParcelable("uuids" + i); 606 } 607 processInitProfilePriorities((BluetoothDevice) msg.obj, 608 mUuids); 609 } 610 break; 611 case MESSAGE_CONNECT_OTHER_PROFILES: { 612 debugLog( "handleMessage() - MESSAGE_CONNECT_OTHER_PROFILES"); 613 processConnectOtherProfiles((BluetoothDevice) msg.obj,msg.arg1); 614 } 615 break; 616 } 617 } 618 }; 619 620 @SuppressWarnings("rawtypes") 621 private void setGattProfileServiceState(Class[] services, int state) { 622 if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) { 623 Log.w(TAG,"setGattProfileServiceState(): invalid state...Leaving..."); 624 return; 625 } 626 627 int expectedCurrentState= BluetoothAdapter.STATE_OFF; 628 int pendingState = BluetoothAdapter.STATE_TURNING_ON; 629 630 if (state == BluetoothAdapter.STATE_OFF) { 631 expectedCurrentState= BluetoothAdapter.STATE_ON; 632 pendingState = BluetoothAdapter.STATE_TURNING_OFF; 633 } 634 635 for (int i=0; i <services.length;i++) { 636 String serviceName = services[i].getName(); 637 String simpleName = services[i].getSimpleName(); 638 639 if (simpleName.equals("GattService")) { 640 Integer serviceState = mProfileServicesState.get(serviceName); 641 642 if(serviceState != null && serviceState != expectedCurrentState) { 643 debugLog("setProfileServiceState() - Unable to " 644 + (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" ) 645 + " service " + serviceName 646 + ". Invalid state: " + serviceState); 647 continue; 648 } 649 debugLog("setProfileServiceState() - " 650 + (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting") 651 + " service " + serviceName); 652 653 mProfileServicesState.put(serviceName,pendingState); 654 Intent intent = new Intent(this,services[i]); 655 intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED); 656 intent.putExtra(BluetoothAdapter.EXTRA_STATE,state); 657 startService(intent); 658 return; 659 } 660 } 661 } 662 663 664 @SuppressWarnings("rawtypes") 665 private void setProfileServiceState(Class[] services, int state) { 666 if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) { 667 debugLog("setProfileServiceState() - Invalid state, leaving..."); 668 return; 669 } 670 671 int expectedCurrentState= BluetoothAdapter.STATE_OFF; 672 int pendingState = BluetoothAdapter.STATE_TURNING_ON; 673 if (state == BluetoothAdapter.STATE_OFF) { 674 expectedCurrentState= BluetoothAdapter.STATE_ON; 675 pendingState = BluetoothAdapter.STATE_TURNING_OFF; 676 } 677 678 for (int i=0; i <services.length;i++) { 679 String serviceName = services[i].getName(); 680 String simpleName = services[i].getSimpleName(); 681 682 if (simpleName.equals("GattService")) continue; 683 684 Integer serviceState = mProfileServicesState.get(serviceName); 685 if(serviceState != null && serviceState != expectedCurrentState) { 686 debugLog("setProfileServiceState() - Unable to " 687 + (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" ) 688 + " service " + serviceName 689 + ". Invalid state: " + serviceState); 690 continue; 691 } 692 693 debugLog("setProfileServiceState() - " 694 + (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting") 695 + " service " + serviceName); 696 697 mProfileServicesState.put(serviceName,pendingState); 698 Intent intent = new Intent(this,services[i]); 699 intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED); 700 intent.putExtra(BluetoothAdapter.EXTRA_STATE,state); 701 startService(intent); 702 } 703 } 704 705 private boolean isAvailable() { 706 return !mCleaningUp; 707 } 708 709 /** 710 * Handlers for incoming service calls 711 */ 712 private AdapterServiceBinder mBinder; 713 714 /** 715 * The Binder implementation must be declared to be a static class, with 716 * the AdapterService instance passed in the constructor. Furthermore, 717 * when the AdapterService shuts down, the reference to the AdapterService 718 * must be explicitly removed. 719 * 720 * Otherwise, a memory leak can occur from repeated starting/stopping the 721 * service...Please refer to android.os.Binder for further details on 722 * why an inner instance class should be avoided. 723 * 724 */ 725 private static class AdapterServiceBinder extends IBluetooth.Stub { 726 private AdapterService mService; 727 728 public AdapterServiceBinder(AdapterService svc) { 729 mService = svc; 730 } 731 public boolean cleanup() { 732 mService = null; 733 return true; 734 } 735 736 public AdapterService getService() { 737 if (mService != null && mService.isAvailable()) { 738 return mService; 739 } 740 return null; 741 } 742 public boolean isEnabled() { 743 // don't check caller, may be called from system UI 744 AdapterService service = getService(); 745 if (service == null) return false; 746 return service.isEnabled(); 747 } 748 749 public int getState() { 750 // don't check caller, may be called from system UI 751 AdapterService service = getService(); 752 if (service == null) return BluetoothAdapter.STATE_OFF; 753 return service.getState(); 754 } 755 756 public boolean enable() { 757 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 758 (!Utils.checkCaller())) { 759 Log.w(TAG, "enable() - Not allowed for non-active user and non system user"); 760 return false; 761 } 762 AdapterService service = getService(); 763 if (service == null) return false; 764 return service.enable(); 765 } 766 767 public boolean enableNoAutoConnect() { 768 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 769 (!Utils.checkCaller())) { 770 Log.w(TAG, "enableNoAuto() - Not allowed for non-active user and non system user"); 771 return false; 772 } 773 774 AdapterService service = getService(); 775 if (service == null) return false; 776 return service.enableNoAutoConnect(); 777 } 778 779 public boolean disable() { 780 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 781 (!Utils.checkCaller())) { 782 Log.w(TAG, "disable() - Not allowed for non-active user and non system user"); 783 return false; 784 } 785 786 AdapterService service = getService(); 787 if (service == null) return false; 788 return service.disable(); 789 } 790 791 public String getAddress() { 792 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 793 (!Utils.checkCallerAllowManagedProfiles(mService))) { 794 Log.w(TAG, "getAddress() - Not allowed for non-active user and non system user"); 795 return null; 796 } 797 798 AdapterService service = getService(); 799 if (service == null) return null; 800 return service.getAddress(); 801 } 802 803 public ParcelUuid[] getUuids() { 804 if (!Utils.checkCaller()) { 805 Log.w(TAG, "getUuids() - Not allowed for non-active user"); 806 return new ParcelUuid[0]; 807 } 808 809 AdapterService service = getService(); 810 if (service == null) return new ParcelUuid[0]; 811 return service.getUuids(); 812 } 813 814 public String getName() { 815 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 816 (!Utils.checkCaller())) { 817 Log.w(TAG, "getName() - Not allowed for non-active user and non system user"); 818 return null; 819 } 820 821 AdapterService service = getService(); 822 if (service == null) return null; 823 return service.getName(); 824 } 825 826 public boolean setName(String name) { 827 if (!Utils.checkCaller()) { 828 Log.w(TAG, "setName() - Not allowed for non-active user"); 829 return false; 830 } 831 832 AdapterService service = getService(); 833 if (service == null) return false; 834 return service.setName(name); 835 } 836 837 public int getScanMode() { 838 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 839 Log.w(TAG, "getScanMode() - Not allowed for non-active user"); 840 return BluetoothAdapter.SCAN_MODE_NONE; 841 } 842 843 AdapterService service = getService(); 844 if (service == null) return BluetoothAdapter.SCAN_MODE_NONE; 845 return service.getScanMode(); 846 } 847 848 public boolean setScanMode(int mode, int duration) { 849 if (!Utils.checkCaller()) { 850 Log.w(TAG, "setScanMode() - Not allowed for non-active user"); 851 return false; 852 } 853 854 AdapterService service = getService(); 855 if (service == null) return false; 856 return service.setScanMode(mode,duration); 857 } 858 859 public int getDiscoverableTimeout() { 860 if (!Utils.checkCaller()) { 861 Log.w(TAG, "getDiscoverableTimeout() - Not allowed for non-active user"); 862 return 0; 863 } 864 865 AdapterService service = getService(); 866 if (service == null) return 0; 867 return service.getDiscoverableTimeout(); 868 } 869 870 public boolean setDiscoverableTimeout(int timeout) { 871 if (!Utils.checkCaller()) { 872 Log.w(TAG, "setDiscoverableTimeout() - Not allowed for non-active user"); 873 return false; 874 } 875 876 AdapterService service = getService(); 877 if (service == null) return false; 878 return service.setDiscoverableTimeout(timeout); 879 } 880 881 public boolean startDiscovery() { 882 if (!Utils.checkCaller()) { 883 Log.w(TAG, "startDiscovery() - Not allowed for non-active user"); 884 return false; 885 } 886 887 AdapterService service = getService(); 888 if (service == null) return false; 889 return service.startDiscovery(); 890 } 891 892 public boolean cancelDiscovery() { 893 if (!Utils.checkCaller()) { 894 Log.w(TAG, "cancelDiscovery() - Not allowed for non-active user"); 895 return false; 896 } 897 898 AdapterService service = getService(); 899 if (service == null) return false; 900 return service.cancelDiscovery(); 901 } 902 public boolean isDiscovering() { 903 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 904 Log.w(TAG, "isDiscovering() - Not allowed for non-active user"); 905 return false; 906 } 907 908 AdapterService service = getService(); 909 if (service == null) return false; 910 return service.isDiscovering(); 911 } 912 913 public BluetoothDevice[] getBondedDevices() { 914 // don't check caller, may be called from system UI 915 AdapterService service = getService(); 916 if (service == null) return new BluetoothDevice[0]; 917 return service.getBondedDevices(); 918 } 919 920 public int getAdapterConnectionState() { 921 // don't check caller, may be called from system UI 922 AdapterService service = getService(); 923 if (service == null) return BluetoothAdapter.STATE_DISCONNECTED; 924 return service.getAdapterConnectionState(); 925 } 926 927 public int getProfileConnectionState(int profile) { 928 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 929 Log.w(TAG, "getProfileConnectionState- Not allowed for non-active user"); 930 return BluetoothProfile.STATE_DISCONNECTED; 931 } 932 933 AdapterService service = getService(); 934 if (service == null) return BluetoothProfile.STATE_DISCONNECTED; 935 return service.getProfileConnectionState(profile); 936 } 937 938 public boolean createBond(BluetoothDevice device, int transport) { 939 if (!Utils.checkCaller()) { 940 Log.w(TAG, "createBond() - Not allowed for non-active user"); 941 return false; 942 } 943 944 AdapterService service = getService(); 945 if (service == null) return false; 946 return service.createBond(device, transport); 947 } 948 949 public boolean cancelBondProcess(BluetoothDevice device) { 950 if (!Utils.checkCaller()) { 951 Log.w(TAG, "cancelBondProcess() - Not allowed for non-active user"); 952 return false; 953 } 954 955 AdapterService service = getService(); 956 if (service == null) return false; 957 return service.cancelBondProcess(device); 958 } 959 960 public boolean removeBond(BluetoothDevice device) { 961 if (!Utils.checkCaller()) { 962 Log.w(TAG, "removeBond() - Not allowed for non-active user"); 963 return false; 964 } 965 966 AdapterService service = getService(); 967 if (service == null) return false; 968 return service.removeBond(device); 969 } 970 971 public int getBondState(BluetoothDevice device) { 972 // don't check caller, may be called from system UI 973 AdapterService service = getService(); 974 if (service == null) return BluetoothDevice.BOND_NONE; 975 return service.getBondState(device); 976 } 977 978 public int getConnectionState(BluetoothDevice device) { 979 AdapterService service = getService(); 980 if (service == null) return 0; 981 return service.getConnectionState(device); 982 } 983 984 public String getRemoteName(BluetoothDevice device) { 985 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 986 Log.w(TAG, "getRemoteName() - Not allowed for non-active user"); 987 return null; 988 } 989 990 AdapterService service = getService(); 991 if (service == null) return null; 992 return service.getRemoteName(device); 993 } 994 995 public int getRemoteType(BluetoothDevice device) { 996 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 997 Log.w(TAG, "getRemoteType() - Not allowed for non-active user"); 998 return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 999 } 1000 1001 AdapterService service = getService(); 1002 if (service == null) return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1003 return service.getRemoteType(device); 1004 } 1005 1006 public String getRemoteAlias(BluetoothDevice device) { 1007 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1008 Log.w(TAG, "getRemoteAlias() - Not allowed for non-active user"); 1009 return null; 1010 } 1011 1012 AdapterService service = getService(); 1013 if (service == null) return null; 1014 return service.getRemoteAlias(device); 1015 } 1016 1017 public boolean setRemoteAlias(BluetoothDevice device, String name) { 1018 if (!Utils.checkCaller()) { 1019 Log.w(TAG, "setRemoteAlias() - Not allowed for non-active user"); 1020 return false; 1021 } 1022 1023 AdapterService service = getService(); 1024 if (service == null) return false; 1025 return service.setRemoteAlias(device, name); 1026 } 1027 1028 public int getRemoteClass(BluetoothDevice device) { 1029 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1030 Log.w(TAG, "getRemoteClass() - Not allowed for non-active user"); 1031 return 0; 1032 } 1033 1034 AdapterService service = getService(); 1035 if (service == null) return 0; 1036 return service.getRemoteClass(device); 1037 } 1038 1039 public ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 1040 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1041 Log.w(TAG, "getRemoteUuids() - Not allowed for non-active user"); 1042 return new ParcelUuid[0]; 1043 } 1044 1045 AdapterService service = getService(); 1046 if (service == null) return new ParcelUuid[0]; 1047 return service.getRemoteUuids(device); 1048 } 1049 1050 public boolean fetchRemoteUuids(BluetoothDevice device) { 1051 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1052 Log.w(TAG, "fetchRemoteUuids() - Not allowed for non-active user"); 1053 return false; 1054 } 1055 1056 AdapterService service = getService(); 1057 if (service == null) return false; 1058 return service.fetchRemoteUuids(device); 1059 } 1060 1061 1062 1063 public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { 1064 if (!Utils.checkCaller()) { 1065 Log.w(TAG, "setPin() - Not allowed for non-active user"); 1066 return false; 1067 } 1068 1069 AdapterService service = getService(); 1070 if (service == null) return false; 1071 return service.setPin(device, accept, len, pinCode); 1072 } 1073 1074 public boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) { 1075 if (!Utils.checkCaller()) { 1076 Log.w(TAG, "setPasskey() - Not allowed for non-active user"); 1077 return false; 1078 } 1079 1080 AdapterService service = getService(); 1081 if (service == null) return false; 1082 return service.setPasskey(device, accept, len, passkey); 1083 } 1084 1085 public boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { 1086 if (!Utils.checkCaller()) { 1087 Log.w(TAG, "setPairingConfirmation() - Not allowed for non-active user"); 1088 return false; 1089 } 1090 1091 AdapterService service = getService(); 1092 if (service == null) return false; 1093 return service.setPairingConfirmation(device, accept); 1094 } 1095 1096 public int getPhonebookAccessPermission(BluetoothDevice device) { 1097 if (!Utils.checkCaller()) { 1098 Log.w(TAG, "getPhonebookAccessPermission() - Not allowed for non-active user"); 1099 return BluetoothDevice.ACCESS_UNKNOWN; 1100 } 1101 1102 AdapterService service = getService(); 1103 if (service == null) return BluetoothDevice.ACCESS_UNKNOWN; 1104 return service.getPhonebookAccessPermission(device); 1105 } 1106 1107 public boolean setPhonebookAccessPermission(BluetoothDevice device, int value) { 1108 if (!Utils.checkCaller()) { 1109 Log.w(TAG, "setPhonebookAccessPermission() - Not allowed for non-active user"); 1110 return false; 1111 } 1112 1113 AdapterService service = getService(); 1114 if (service == null) return false; 1115 return service.setPhonebookAccessPermission(device, value); 1116 } 1117 1118 public int getMessageAccessPermission(BluetoothDevice device) { 1119 if (!Utils.checkCaller()) { 1120 Log.w(TAG, "getMessageAccessPermission() - Not allowed for non-active user"); 1121 return BluetoothDevice.ACCESS_UNKNOWN; 1122 } 1123 1124 AdapterService service = getService(); 1125 if (service == null) return BluetoothDevice.ACCESS_UNKNOWN; 1126 return service.getMessageAccessPermission(device); 1127 } 1128 1129 public boolean setMessageAccessPermission(BluetoothDevice device, int value) { 1130 if (!Utils.checkCaller()) { 1131 Log.w(TAG, "setMessageAccessPermission() - Not allowed for non-active user"); 1132 return false; 1133 } 1134 1135 AdapterService service = getService(); 1136 if (service == null) return false; 1137 return service.setMessageAccessPermission(device, value); 1138 } 1139 1140 public int getSimAccessPermission(BluetoothDevice device) { 1141 if (!Utils.checkCaller()) { 1142 Log.w(TAG, "getSimAccessPermission() - Not allowed for non-active user"); 1143 return BluetoothDevice.ACCESS_UNKNOWN; 1144 } 1145 1146 AdapterService service = getService(); 1147 if (service == null) return BluetoothDevice.ACCESS_UNKNOWN; 1148 return service.getSimAccessPermission(device); 1149 } 1150 1151 public boolean setSimAccessPermission(BluetoothDevice device, int value) { 1152 if (!Utils.checkCaller()) { 1153 Log.w(TAG, "setSimAccessPermission() - Not allowed for non-active user"); 1154 return false; 1155 } 1156 1157 AdapterService service = getService(); 1158 if (service == null) return false; 1159 return service.setSimAccessPermission(device, value); 1160 } 1161 1162 public void sendConnectionStateChange(BluetoothDevice 1163 device, int profile, int state, int prevState) { 1164 AdapterService service = getService(); 1165 if (service == null) return; 1166 service.sendConnectionStateChange(device, profile, state, prevState); 1167 } 1168 1169 public ParcelFileDescriptor connectSocket(BluetoothDevice device, int type, 1170 ParcelUuid uuid, int port, int flag) { 1171 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1172 Log.w(TAG, "connectSocket() - Not allowed for non-active user"); 1173 return null; 1174 } 1175 1176 AdapterService service = getService(); 1177 if (service == null) return null; 1178 return service.connectSocket(device, type, uuid, port, flag); 1179 } 1180 1181 public ParcelFileDescriptor createSocketChannel(int type, String serviceName, 1182 ParcelUuid uuid, int port, int flag) { 1183 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1184 Log.w(TAG, "createSocketChannel() - Not allowed for non-active user"); 1185 return null; 1186 } 1187 1188 AdapterService service = getService(); 1189 if (service == null) return null; 1190 return service.createSocketChannel(type, serviceName, uuid, port, flag); 1191 } 1192 public boolean sdpSearch(BluetoothDevice device, ParcelUuid uuid) { 1193 if (!Utils.checkCaller()) { 1194 Log.w(TAG,"sdpSea(): not allowed for non-active user"); 1195 return false; 1196 } 1197 1198 AdapterService service = getService(); 1199 if (service == null) return false; 1200 return service.sdpSearch(device,uuid); 1201 } 1202 1203 public boolean configHciSnoopLog(boolean enable) { 1204 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 1205 EventLog.writeEvent(0x534e4554 /* SNET */, "Bluetooth", Binder.getCallingUid(), 1206 "configHciSnoopLog() - Not allowed for non-active user b/18643224"); 1207 return false; 1208 } 1209 1210 AdapterService service = getService(); 1211 if (service == null) return false; 1212 return service.configHciSnoopLog(enable); 1213 } 1214 1215 public boolean factoryReset() { 1216 AdapterService service = getService(); 1217 if (service == null) return false; 1218 service.disable(); 1219 return service.factoryReset(); 1220 1221 } 1222 1223 public void registerCallback(IBluetoothCallback cb) { 1224 AdapterService service = getService(); 1225 if (service == null) return ; 1226 service.registerCallback(cb); 1227 } 1228 1229 public void unregisterCallback(IBluetoothCallback cb) { 1230 AdapterService service = getService(); 1231 if (service == null) return ; 1232 service.unregisterCallback(cb); 1233 } 1234 1235 public boolean isMultiAdvertisementSupported() { 1236 AdapterService service = getService(); 1237 if (service == null) return false; 1238 return service.isMultiAdvertisementSupported(); 1239 } 1240 1241 public boolean isPeripheralModeSupported() { 1242 AdapterService service = getService(); 1243 if (service == null) return false; 1244 return service.isPeripheralModeSupported(); 1245 } 1246 1247 public boolean isOffloadedFilteringSupported() { 1248 AdapterService service = getService(); 1249 if (service == null) return false; 1250 int val = service.getNumOfOffloadedScanFilterSupported(); 1251 return (val >= MIN_OFFLOADED_FILTERS); 1252 } 1253 1254 public boolean isOffloadedScanBatchingSupported() { 1255 AdapterService service = getService(); 1256 if (service == null) return false; 1257 int val = service.getOffloadedScanResultStorage(); 1258 return (val >= MIN_OFFLOADED_SCAN_STORAGE_BYTES); 1259 } 1260 1261 public boolean isActivityAndEnergyReportingSupported() { 1262 AdapterService service = getService(); 1263 if (service == null) return false; 1264 return service.isActivityAndEnergyReportingSupported(); 1265 } 1266 1267 public void getActivityEnergyInfoFromController() { 1268 AdapterService service = getService(); 1269 if (service == null) return; 1270 service.getActivityEnergyInfoFromController(); 1271 } 1272 1273 public BluetoothActivityEnergyInfo reportActivityInfo() { 1274 AdapterService service = getService(); 1275 if (service == null) return null; 1276 return service.reportActivityInfo(); 1277 } 1278 1279 public void dump(ParcelFileDescriptor fd) { 1280 AdapterService service = getService(); 1281 if (service == null) return; 1282 service.dump(fd.getFileDescriptor()); 1283 } 1284 1285 public void onLeServiceUp(){ 1286 AdapterService service = getService(); 1287 if (service == null) return; 1288 service.onLeServiceUp(); 1289 } 1290 1291 public void onBrEdrDown(){ 1292 AdapterService service = getService(); 1293 if (service == null) return; 1294 service.onBrEdrDown(); 1295 } 1296 }; 1297 1298 // ----API Methods-------- 1299 1300 boolean isEnabled() { 1301 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1302 return mAdapterProperties.getState() == BluetoothAdapter.STATE_ON; 1303 } 1304 1305 int getState() { 1306 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1307 if (mAdapterProperties != null) return mAdapterProperties.getState(); 1308 return BluetoothAdapter.STATE_OFF; 1309 } 1310 1311 boolean enable() { 1312 return enable (false); 1313 } 1314 1315 public boolean enableNoAutoConnect() { 1316 return enable (true); 1317 } 1318 1319 public synchronized boolean enable(boolean quietMode) { 1320 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1321 1322 debugLog("enable() - Enable called with quiet mode status = " + mQuietmode); 1323 mQuietmode = quietMode; 1324 Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON); 1325 mAdapterStateMachine.sendMessage(m); 1326 return true; 1327 } 1328 1329 boolean disable() { 1330 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1331 1332 debugLog("disable() called..."); 1333 Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_OFF); 1334 mAdapterStateMachine.sendMessage(m); 1335 return true; 1336 } 1337 1338 String getAddress() { 1339 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1340 1341 String addrString = null; 1342 byte[] address = mAdapterProperties.getAddress(); 1343 return Utils.getAddressStringFromByte(address); 1344 } 1345 1346 ParcelUuid[] getUuids() { 1347 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1348 1349 return mAdapterProperties.getUuids(); 1350 } 1351 1352 String getName() { 1353 enforceCallingOrSelfPermission(BLUETOOTH_PERM, 1354 "Need BLUETOOTH permission"); 1355 1356 try { 1357 return mAdapterProperties.getName(); 1358 } catch (Throwable t) { 1359 debugLog("getName() - Unexpected exception (" + t + ")"); 1360 } 1361 return null; 1362 } 1363 1364 boolean setName(String name) { 1365 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1366 "Need BLUETOOTH ADMIN permission"); 1367 1368 return mAdapterProperties.setName(name); 1369 } 1370 1371 int getScanMode() { 1372 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1373 1374 return mAdapterProperties.getScanMode(); 1375 } 1376 1377 boolean setScanMode(int mode, int duration) { 1378 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1379 1380 setDiscoverableTimeout(duration); 1381 1382 int newMode = convertScanModeToHal(mode); 1383 return mAdapterProperties.setScanMode(newMode); 1384 } 1385 1386 int getDiscoverableTimeout() { 1387 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1388 1389 return mAdapterProperties.getDiscoverableTimeout(); 1390 } 1391 1392 boolean setDiscoverableTimeout(int timeout) { 1393 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1394 1395 return mAdapterProperties.setDiscoverableTimeout(timeout); 1396 } 1397 1398 boolean startDiscovery() { 1399 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1400 "Need BLUETOOTH ADMIN permission"); 1401 1402 return startDiscoveryNative(); 1403 } 1404 1405 boolean cancelDiscovery() { 1406 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1407 "Need BLUETOOTH ADMIN permission"); 1408 1409 return cancelDiscoveryNative(); 1410 } 1411 1412 boolean isDiscovering() { 1413 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1414 1415 return mAdapterProperties.isDiscovering(); 1416 } 1417 1418 BluetoothDevice[] getBondedDevices() { 1419 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1420 return mAdapterProperties.getBondedDevices(); 1421 } 1422 1423 int getAdapterConnectionState() { 1424 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1425 return mAdapterProperties.getConnectionState(); 1426 } 1427 1428 int getProfileConnectionState(int profile) { 1429 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1430 1431 return mAdapterProperties.getProfileConnectionState(profile); 1432 } 1433 boolean sdpSearch(BluetoothDevice device,ParcelUuid uuid) { 1434 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1435 if(mSdpManager != null) { 1436 mSdpManager.sdpSearch(device,uuid); 1437 return true; 1438 } else { 1439 return false; 1440 } 1441 } 1442 1443 1444 boolean createBond(BluetoothDevice device, int transport) { 1445 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1446 "Need BLUETOOTH ADMIN permission"); 1447 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1448 if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) { 1449 return false; 1450 } 1451 1452 // Pairing is unreliable while scanning, so cancel discovery 1453 // Note, remove this when native stack improves 1454 cancelDiscoveryNative(); 1455 1456 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND); 1457 msg.obj = device; 1458 msg.arg1 = transport; 1459 mBondStateMachine.sendMessage(msg); 1460 return true; 1461 } 1462 1463 public boolean isQuietModeEnabled() { 1464 debugLog("isQuetModeEnabled() - Enabled = " + mQuietmode); 1465 return mQuietmode; 1466 } 1467 1468 public void autoConnect(){ 1469 if (getState() != BluetoothAdapter.STATE_ON){ 1470 errorLog("autoConnect() - BT is not ON. Exiting autoConnect"); 1471 return; 1472 } 1473 if (isQuietModeEnabled() == false) { 1474 debugLog( "autoConnect() - Initiate auto connection on BT on..."); 1475 autoConnectHeadset(); 1476 autoConnectA2dp(); 1477 } 1478 else { 1479 debugLog( "autoConnect() - BT is in quiet mode. Not initiating auto connections"); 1480 } 1481 } 1482 1483 private void autoConnectHeadset(){ 1484 HeadsetService hsService = HeadsetService.getHeadsetService(); 1485 1486 BluetoothDevice bondedDevices[] = getBondedDevices(); 1487 if ((bondedDevices == null) ||(hsService == null)) { 1488 return; 1489 } 1490 for (BluetoothDevice device : bondedDevices) { 1491 if (hsService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT ){ 1492 debugLog("autoConnectHeadset() - Connecting HFP with " + device.toString()); 1493 hsService.connect(device); 1494 } 1495 } 1496 } 1497 1498 private void autoConnectA2dp(){ 1499 A2dpService a2dpSservice = A2dpService.getA2dpService(); 1500 BluetoothDevice bondedDevices[] = getBondedDevices(); 1501 if ((bondedDevices == null) ||(a2dpSservice == null)) { 1502 return; 1503 } 1504 for (BluetoothDevice device : bondedDevices) { 1505 if (a2dpSservice.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT ){ 1506 debugLog("autoConnectA2dp() - Connecting A2DP with " + device.toString()); 1507 a2dpSservice.connect(device); 1508 } 1509 } 1510 } 1511 1512 public void connectOtherProfile(BluetoothDevice device, int firstProfileStatus){ 1513 if ((mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES) == false) && 1514 (isQuietModeEnabled()== false)){ 1515 Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES); 1516 m.obj = device; 1517 m.arg1 = (int)firstProfileStatus; 1518 mHandler.sendMessageDelayed(m,CONNECT_OTHER_PROFILES_TIMEOUT); 1519 } 1520 } 1521 1522 private void processConnectOtherProfiles (BluetoothDevice device, int firstProfileStatus){ 1523 if (getState()!= BluetoothAdapter.STATE_ON){ 1524 return; 1525 } 1526 HeadsetService hsService = HeadsetService.getHeadsetService(); 1527 A2dpService a2dpService = A2dpService.getA2dpService(); 1528 1529 // if any of the profile service is null, second profile connection not required 1530 if ((hsService == null) ||(a2dpService == null )){ 1531 return; 1532 } 1533 List<BluetoothDevice> a2dpConnDevList= a2dpService.getConnectedDevices(); 1534 List<BluetoothDevice> hfConnDevList= hsService.getConnectedDevices(); 1535 // Check if the device is in disconnected state and if so return 1536 // We ned to connect other profile only if one of the profile is still in connected state 1537 // This is required to avoide a race condition in which profiles would 1538 // automaticlly connect if the disconnection is initiated within 6 seconds of connection 1539 //First profile connection being rejected is an exception 1540 if((hfConnDevList.isEmpty() && a2dpConnDevList.isEmpty())&& 1541 (PROFILE_CONN_CONNECTED == firstProfileStatus)){ 1542 return; 1543 } 1544 if((hfConnDevList.isEmpty()) && 1545 (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)){ 1546 hsService.connect(device); 1547 } 1548 else if((a2dpConnDevList.isEmpty()) && 1549 (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)){ 1550 a2dpService.connect(device); 1551 } 1552 } 1553 1554 private void adjustOtherHeadsetPriorities(HeadsetService hsService, 1555 List<BluetoothDevice> connectedDeviceList) { 1556 for (BluetoothDevice device : getBondedDevices()) { 1557 if (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT && 1558 !connectedDeviceList.contains(device)) { 1559 hsService.setPriority(device, BluetoothProfile.PRIORITY_ON); 1560 } 1561 } 1562 } 1563 1564 private void adjustOtherSinkPriorities(A2dpService a2dpService, 1565 BluetoothDevice connectedDevice) { 1566 for (BluetoothDevice device : getBondedDevices()) { 1567 if (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT && 1568 !device.equals(connectedDevice)) { 1569 a2dpService.setPriority(device, BluetoothProfile.PRIORITY_ON); 1570 } 1571 } 1572 } 1573 1574 void setProfileAutoConnectionPriority (BluetoothDevice device, int profileId){ 1575 if (profileId == BluetoothProfile.HEADSET) { 1576 HeadsetService hsService = HeadsetService.getHeadsetService(); 1577 List<BluetoothDevice> deviceList = hsService.getConnectedDevices(); 1578 if ((hsService != null) && 1579 (BluetoothProfile.PRIORITY_AUTO_CONNECT != hsService.getPriority(device))){ 1580 adjustOtherHeadsetPriorities(hsService, deviceList); 1581 hsService.setPriority(device,BluetoothProfile.PRIORITY_AUTO_CONNECT); 1582 } 1583 } 1584 else if (profileId == BluetoothProfile.A2DP) { 1585 A2dpService a2dpService = A2dpService.getA2dpService(); 1586 if ((a2dpService != null) && 1587 (BluetoothProfile.PRIORITY_AUTO_CONNECT != a2dpService.getPriority(device))){ 1588 adjustOtherSinkPriorities(a2dpService, device); 1589 a2dpService.setPriority(device,BluetoothProfile.PRIORITY_AUTO_CONNECT); 1590 } 1591 } 1592 } 1593 1594 boolean cancelBondProcess(BluetoothDevice device) { 1595 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1596 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1597 return cancelBondNative(addr); 1598 } 1599 1600 boolean removeBond(BluetoothDevice device) { 1601 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1602 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1603 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) { 1604 return false; 1605 } 1606 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND); 1607 msg.obj = device; 1608 mBondStateMachine.sendMessage(msg); 1609 return true; 1610 } 1611 1612 int getBondState(BluetoothDevice device) { 1613 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1614 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1615 if (deviceProp == null) { 1616 return BluetoothDevice.BOND_NONE; 1617 } 1618 return deviceProp.getBondState(); 1619 } 1620 1621 int getConnectionState(BluetoothDevice device) { 1622 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1623 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1624 return getConnectionStateNative(addr); 1625 } 1626 1627 String getRemoteName(BluetoothDevice device) { 1628 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1629 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1630 if (deviceProp == null) return null; 1631 return deviceProp.getName(); 1632 } 1633 1634 int getRemoteType(BluetoothDevice device) { 1635 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1636 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1637 if (deviceProp == null) return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1638 return deviceProp.getDeviceType(); 1639 } 1640 1641 String getRemoteAlias(BluetoothDevice device) { 1642 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1643 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1644 if (deviceProp == null) return null; 1645 return deviceProp.getAlias(); 1646 } 1647 1648 boolean setRemoteAlias(BluetoothDevice device, String name) { 1649 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1650 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1651 if (deviceProp == null) return false; 1652 deviceProp.setAlias(device, name); 1653 return true; 1654 } 1655 1656 int getRemoteClass(BluetoothDevice device) { 1657 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1658 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1659 if (deviceProp == null) return 0; 1660 1661 return deviceProp.getBluetoothClass(); 1662 } 1663 1664 ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 1665 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1666 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1667 if (deviceProp == null) return null; 1668 return deviceProp.getUuids(); 1669 } 1670 1671 boolean fetchRemoteUuids(BluetoothDevice device) { 1672 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1673 mRemoteDevices.fetchUuids(device); 1674 return true; 1675 } 1676 1677 1678 boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { 1679 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1680 "Need BLUETOOTH ADMIN permission"); 1681 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1682 // Only allow setting a pin in bonding state, or bonded state in case of security upgrade. 1683 if (deviceProp == null || 1684 (deviceProp.getBondState() != BluetoothDevice.BOND_BONDING && 1685 deviceProp.getBondState() != BluetoothDevice.BOND_BONDED)) { 1686 return false; 1687 } 1688 1689 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1690 return pinReplyNative(addr, accept, len, pinCode); 1691 } 1692 1693 boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) { 1694 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1695 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1696 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1697 return false; 1698 } 1699 1700 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1701 return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY, accept, 1702 Utils.byteArrayToInt(passkey)); 1703 } 1704 1705 boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { 1706 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 1707 "Need BLUETOOTH PRIVILEGED permission"); 1708 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1709 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1710 return false; 1711 } 1712 1713 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1714 return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION, 1715 accept, 0); 1716 } 1717 1718 int getPhonebookAccessPermission(BluetoothDevice device) { 1719 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1720 SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE, 1721 Context.MODE_PRIVATE); 1722 if (!pref.contains(device.getAddress())) { 1723 return BluetoothDevice.ACCESS_UNKNOWN; 1724 } 1725 return pref.getBoolean(device.getAddress(), false) 1726 ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED; 1727 } 1728 1729 boolean setPhonebookAccessPermission(BluetoothDevice device, int value) { 1730 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 1731 "Need BLUETOOTH PRIVILEGED permission"); 1732 SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE, 1733 Context.MODE_PRIVATE); 1734 SharedPreferences.Editor editor = pref.edit(); 1735 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 1736 editor.remove(device.getAddress()); 1737 } else { 1738 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 1739 } 1740 return editor.commit(); 1741 } 1742 1743 int getMessageAccessPermission(BluetoothDevice device) { 1744 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1745 SharedPreferences pref = getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE, 1746 Context.MODE_PRIVATE); 1747 if (!pref.contains(device.getAddress())) { 1748 return BluetoothDevice.ACCESS_UNKNOWN; 1749 } 1750 return pref.getBoolean(device.getAddress(), false) 1751 ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED; 1752 } 1753 1754 boolean setMessageAccessPermission(BluetoothDevice device, int value) { 1755 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 1756 "Need BLUETOOTH PRIVILEGED permission"); 1757 SharedPreferences pref = getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE, 1758 Context.MODE_PRIVATE); 1759 SharedPreferences.Editor editor = pref.edit(); 1760 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 1761 editor.remove(device.getAddress()); 1762 } else { 1763 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 1764 } 1765 return editor.commit(); 1766 } 1767 1768 int getSimAccessPermission(BluetoothDevice device) { 1769 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1770 SharedPreferences pref = getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, 1771 Context.MODE_PRIVATE); 1772 if (!pref.contains(device.getAddress())) { 1773 return BluetoothDevice.ACCESS_UNKNOWN; 1774 } 1775 return pref.getBoolean(device.getAddress(), false) 1776 ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED; 1777 } 1778 1779 boolean setSimAccessPermission(BluetoothDevice device, int value) { 1780 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 1781 "Need BLUETOOTH PRIVILEGED permission"); 1782 SharedPreferences pref = getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, 1783 Context.MODE_PRIVATE); 1784 SharedPreferences.Editor editor = pref.edit(); 1785 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 1786 editor.remove(device.getAddress()); 1787 } else { 1788 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 1789 } 1790 return editor.commit(); 1791 } 1792 1793 void sendConnectionStateChange(BluetoothDevice 1794 device, int profile, int state, int prevState) { 1795 // TODO(BT) permission check? 1796 // Since this is a binder call check if Bluetooth is on still 1797 if (getState() == BluetoothAdapter.STATE_OFF) return; 1798 1799 mAdapterProperties.sendConnectionStateChange(device, profile, state, prevState); 1800 1801 } 1802 1803 ParcelFileDescriptor connectSocket(BluetoothDevice device, int type, 1804 ParcelUuid uuid, int port, int flag) { 1805 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1806 int fd = connectSocketNative(Utils.getBytesFromAddress(device.getAddress()), 1807 type, Utils.uuidToByteArray(uuid), port, flag); 1808 if (fd < 0) { 1809 errorLog("Failed to connect socket"); 1810 return null; 1811 } 1812 return ParcelFileDescriptor.adoptFd(fd); 1813 } 1814 1815 ParcelFileDescriptor createSocketChannel(int type, String serviceName, 1816 ParcelUuid uuid, int port, int flag) { 1817 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1818 int fd = createSocketChannelNative(type, serviceName, 1819 Utils.uuidToByteArray(uuid), port, flag); 1820 if (fd < 0) { 1821 errorLog("Failed to create socket channel"); 1822 return null; 1823 } 1824 return ParcelFileDescriptor.adoptFd(fd); 1825 } 1826 1827 boolean configHciSnoopLog(boolean enable) { 1828 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1829 return configHciSnoopLogNative(enable); 1830 } 1831 1832 boolean factoryReset() { 1833 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 1834 return factoryResetNative(); 1835 } 1836 1837 void registerCallback(IBluetoothCallback cb) { 1838 mCallbacks.register(cb); 1839 } 1840 1841 void unregisterCallback(IBluetoothCallback cb) { 1842 mCallbacks.unregister(cb); 1843 } 1844 1845 public int getNumOfAdvertisementInstancesSupported() { 1846 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1847 return mAdapterProperties.getNumOfAdvertisementInstancesSupported(); 1848 } 1849 1850 public boolean isMultiAdvertisementSupported() { 1851 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1852 return getNumOfAdvertisementInstancesSupported() >= MIN_ADVT_INSTANCES_FOR_MA; 1853 } 1854 1855 public boolean isRpaOffloadSupported() { 1856 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1857 return mAdapterProperties.isRpaOffloadSupported(); 1858 } 1859 1860 public int getNumOfOffloadedIrkSupported() { 1861 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1862 return mAdapterProperties.getNumOfOffloadedIrkSupported(); 1863 } 1864 1865 public int getNumOfOffloadedScanFilterSupported() { 1866 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1867 return mAdapterProperties.getNumOfOffloadedScanFilterSupported(); 1868 } 1869 1870 public boolean isPeripheralModeSupported() { 1871 return getResources().getBoolean(R.bool.config_bluetooth_le_peripheral_mode_supported); 1872 } 1873 1874 public int getOffloadedScanResultStorage() { 1875 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1876 return mAdapterProperties.getOffloadedScanResultStorage(); 1877 } 1878 1879 private boolean isActivityAndEnergyReportingSupported() { 1880 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 1881 return mAdapterProperties.isActivityAndEnergyReportingSupported(); 1882 } 1883 1884 private void getActivityEnergyInfoFromController() { 1885 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 1886 if (isActivityAndEnergyReportingSupported()) { 1887 readEnergyInfo(); 1888 } 1889 } 1890 1891 private BluetoothActivityEnergyInfo reportActivityInfo() { 1892 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 1893 BluetoothActivityEnergyInfo info = 1894 new BluetoothActivityEnergyInfo(SystemClock.elapsedRealtime(), mStackReportedState, 1895 mTxTimeTotalMs, mRxTimeTotalMs, mIdleTimeTotalMs, mEnergyUsedTotalVoltAmpSecMicro); 1896 // Read on clear values; a record of data is created with 1897 // timstamp and new samples are collected until read again 1898 mStackReportedState = 0; 1899 mTxTimeTotalMs = 0; 1900 mRxTimeTotalMs = 0; 1901 mIdleTimeTotalMs = 0; 1902 mEnergyUsedTotalVoltAmpSecMicro = 0; 1903 return info; 1904 } 1905 1906 public int getTotalNumOfTrackableAdvertisements() { 1907 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1908 return mAdapterProperties.getTotalNumOfTrackableAdvertisements(); 1909 } 1910 1911 public void onLeServiceUp() { 1912 Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON); 1913 mAdapterStateMachine.sendMessage(m); 1914 } 1915 1916 public void onBrEdrDown() { 1917 Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_OFF); 1918 mAdapterStateMachine.sendMessage(m); 1919 } 1920 1921 private static int convertScanModeToHal(int mode) { 1922 switch (mode) { 1923 case BluetoothAdapter.SCAN_MODE_NONE: 1924 return AbstractionLayer.BT_SCAN_MODE_NONE; 1925 case BluetoothAdapter.SCAN_MODE_CONNECTABLE: 1926 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE; 1927 case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: 1928 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE; 1929 } 1930 // errorLog("Incorrect scan mode in convertScanModeToHal"); 1931 return -1; 1932 } 1933 1934 static int convertScanModeFromHal(int mode) { 1935 switch (mode) { 1936 case AbstractionLayer.BT_SCAN_MODE_NONE: 1937 return BluetoothAdapter.SCAN_MODE_NONE; 1938 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE: 1939 return BluetoothAdapter.SCAN_MODE_CONNECTABLE; 1940 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE: 1941 return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE; 1942 } 1943 //errorLog("Incorrect scan mode in convertScanModeFromHal"); 1944 return -1; 1945 } 1946 1947 // This function is called from JNI. It allows native code to set a single wake 1948 // alarm. If an alarm is already pending and a new request comes in, the alarm 1949 // will be rescheduled (i.e. the previously set alarm will be cancelled). 1950 private boolean setWakeAlarm(long delayMillis, boolean shouldWake) { 1951 synchronized (this) { 1952 if (mPendingAlarm != null) { 1953 mAlarmManager.cancel(mPendingAlarm); 1954 } 1955 1956 long wakeupTime = SystemClock.elapsedRealtime() + delayMillis; 1957 int type = shouldWake 1958 ? AlarmManager.ELAPSED_REALTIME_WAKEUP 1959 : AlarmManager.ELAPSED_REALTIME; 1960 1961 Intent intent = new Intent(ACTION_ALARM_WAKEUP); 1962 mPendingAlarm = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); 1963 mAlarmManager.setExact(type, wakeupTime, mPendingAlarm); 1964 return true; 1965 } 1966 } 1967 1968 // This function is called from JNI. It allows native code to acquire a single wake lock. 1969 // If the wake lock is already held, this function returns success. Although this function 1970 // only supports acquiring a single wake lock at a time right now, it will eventually be 1971 // extended to allow acquiring an arbitrary number of wake locks. The current interface 1972 // takes |lockName| as a parameter in anticipation of that implementation. 1973 private boolean acquireWakeLock(String lockName) { 1974 if (mWakeLock != null) { 1975 if (!lockName.equals(mWakeLockName)) { 1976 errorLog("Multiple wake lock acquisition attempted; aborting: " + lockName); 1977 return false; 1978 } 1979 1980 // We're already holding the desired wake lock so return success. 1981 if (mWakeLock.isHeld()) { 1982 return true; 1983 } 1984 } 1985 1986 mWakeLockName = lockName; 1987 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName); 1988 mWakeLock.acquire(); 1989 return true; 1990 } 1991 1992 // This function is called from JNI. It allows native code to release a wake lock acquired 1993 // by |acquireWakeLock|. If the wake lock is not held, this function returns failure. 1994 // Note that the release() call is also invoked by {@link #cleanup()} so a synchronization is 1995 // needed here. See the comment for |acquireWakeLock| for an explanation of the interface. 1996 private boolean releaseWakeLock(String lockName) { 1997 synchronized (this) { 1998 if (mWakeLock == null) { 1999 errorLog("Repeated wake lock release; aborting release: " + lockName); 2000 return false; 2001 } 2002 2003 mWakeLock.release(); 2004 mWakeLock = null; 2005 mWakeLockName = null; 2006 } 2007 return true; 2008 } 2009 2010 private void energyInfoCallback (int status, int ctrl_state, 2011 long tx_time, long rx_time, long idle_time, long energy_used) 2012 throws RemoteException { 2013 if (ctrl_state >= BluetoothActivityEnergyInfo.BT_STACK_STATE_INVALID && 2014 ctrl_state <= BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_IDLE) { 2015 mStackReportedState = ctrl_state; 2016 mTxTimeTotalMs += tx_time; 2017 mRxTimeTotalMs += rx_time; 2018 mIdleTimeTotalMs += idle_time; 2019 // Energy is product of mA, V and ms. If the chipset doesn't 2020 // report it, we have to compute it from time 2021 if (energy_used == 0) { 2022 energy_used = (long)((mTxTimeTotalMs * getTxCurrentMa() 2023 + mRxTimeTotalMs * getRxCurrentMa() 2024 + mIdleTimeTotalMs * getIdleCurrentMa()) * getOperatingVolt()); 2025 } 2026 mEnergyUsedTotalVoltAmpSecMicro += energy_used; 2027 } 2028 2029 debugLog("energyInfoCallback() status = " + status + 2030 "tx_time = " + tx_time + "rx_time = " + rx_time + 2031 "idle_time = " + idle_time + "energy_used = " + energy_used + 2032 "ctrl_state = " + ctrl_state); 2033 } 2034 2035 private int getIdleCurrentMa() { 2036 return getResources().getInteger(R.integer.config_bluetooth_idle_cur_ma); 2037 } 2038 2039 private int getTxCurrentMa() { 2040 return getResources().getInteger(R.integer.config_bluetooth_tx_cur_ma); 2041 } 2042 2043 private int getRxCurrentMa() { 2044 return getResources().getInteger(R.integer.config_bluetooth_rx_cur_ma); 2045 } 2046 2047 private double getOperatingVolt() { 2048 return getResources().getInteger(R.integer.config_bluetooth_operating_voltage_mv) / 1000.0; 2049 } 2050 2051 private void dump(FileDescriptor fd) { 2052 // Collect profile information 2053 StringBuilder sb = new StringBuilder(); 2054 synchronized (mProfiles) { 2055 for (ProfileService profile : mProfiles) { 2056 profile.dump(sb); 2057 } 2058 } 2059 2060 // Dump Java based profiles first 2061 FileWriter fw = null; 2062 try { 2063 fw = new FileWriter(fd); 2064 fw.write(sb.toString()); 2065 } catch (IOException ex) { 2066 errorLog("IOException writing profile status!"); 2067 } finally { 2068 if (fw != null) { 2069 try { 2070 fw.close(); 2071 } catch (IOException ex) { 2072 debugLog("IOException closing a file after writing the profile status"); 2073 } 2074 } 2075 } 2076 2077 // Add native logs 2078 dumpNative(fd); 2079 } 2080 2081 private void debugLog(String msg) { 2082 if (DBG) Log.d(TAG, msg); 2083 } 2084 2085 private void errorLog(String msg) { 2086 Log.e(TAG, msg); 2087 } 2088 2089 private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() { 2090 @Override 2091 public void onReceive(Context context, Intent intent) { 2092 synchronized (AdapterService.this) { 2093 mPendingAlarm = null; 2094 alarmFiredNative(); 2095 } 2096 } 2097 }; 2098 2099 private native static void classInitNative(); 2100 private native boolean initNative(); 2101 private native void cleanupNative(); 2102 /*package*/ native boolean enableNative(boolean startRestricted); 2103 /*package*/ native boolean disableNative(); 2104 /*package*/ native boolean setAdapterPropertyNative(int type, byte[] val); 2105 /*package*/ native boolean getAdapterPropertiesNative(); 2106 /*package*/ native boolean getAdapterPropertyNative(int type); 2107 /*package*/ native boolean setAdapterPropertyNative(int type); 2108 /*package*/ native boolean 2109 setDevicePropertyNative(byte[] address, int type, byte[] val); 2110 /*package*/ native boolean getDevicePropertyNative(byte[] address, int type); 2111 2112 /*package*/ native boolean createBondNative(byte[] address, int transport); 2113 /*package*/ native boolean removeBondNative(byte[] address); 2114 /*package*/ native boolean cancelBondNative(byte[] address); 2115 /*package*/ native boolean sdpSearchNative(byte[] address, byte[] uuid); 2116 2117 /*package*/ native int getConnectionStateNative(byte[] address); 2118 2119 private native boolean startDiscoveryNative(); 2120 private native boolean cancelDiscoveryNative(); 2121 2122 private native boolean pinReplyNative(byte[] address, boolean accept, int len, byte[] pin); 2123 private native boolean sspReplyNative(byte[] address, int type, boolean 2124 accept, int passkey); 2125 2126 /*package*/ native boolean getRemoteServicesNative(byte[] address); 2127 /*package*/ native boolean getRemoteMasInstancesNative(byte[] address); 2128 2129 private native int readEnergyInfo(); 2130 // TODO(BT) move this to ../btsock dir 2131 private native int connectSocketNative(byte[] address, int type, 2132 byte[] uuid, int port, int flag); 2133 private native int createSocketChannelNative(int type, String serviceName, 2134 byte[] uuid, int port, int flag); 2135 2136 /*package*/ native boolean configHciSnoopLogNative(boolean enable); 2137 /*package*/ native boolean factoryResetNative(); 2138 2139 private native void alarmFiredNative(); 2140 private native void dumpNative(FileDescriptor fd); 2141 2142 protected void finalize() { 2143 cleanup(); 2144 if (TRACE_REF) { 2145 synchronized (AdapterService.class) { 2146 sRefCount--; 2147 debugLog("finalize() - REFCOUNT: FINALIZED. INSTANCE_COUNT= " + sRefCount); 2148 } 2149 } 2150 } 2151} 2152