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