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