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