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