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