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