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 package com.android.bluetooth.btservice;
18 
19 import static com.android.bluetooth.Utils.addressToBytes;
20 import static com.android.bluetooth.Utils.callerIsSystemOrActiveOrManagedUser;
21 import static com.android.bluetooth.Utils.callerIsSystemOrActiveUser;
22 import static com.android.bluetooth.Utils.enforceBluetoothAdminPermission;
23 import static com.android.bluetooth.Utils.enforceBluetoothPermission;
24 import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;
25 import static com.android.bluetooth.Utils.enforceDumpPermission;
26 import static com.android.bluetooth.Utils.enforceLocalMacAddressPermission;
27 
28 import android.annotation.Nullable;
29 import android.app.ActivityManager;
30 import android.app.AlarmManager;
31 import android.app.AppOpsManager;
32 import android.app.PendingIntent;
33 import android.app.PropertyInvalidatedCache;
34 import android.app.Service;
35 import android.app.admin.DevicePolicyManager;
36 import android.bluetooth.BluetoothActivityEnergyInfo;
37 import android.bluetooth.BluetoothAdapter;
38 import android.bluetooth.BluetoothAdapter.ActiveDeviceUse;
39 import android.bluetooth.BluetoothClass;
40 import android.bluetooth.BluetoothDevice;
41 import android.bluetooth.BluetoothProfile;
42 import android.bluetooth.BluetoothProtoEnums;
43 import android.bluetooth.BluetoothUuid;
44 import android.bluetooth.IBluetooth;
45 import android.bluetooth.IBluetoothCallback;
46 import android.bluetooth.IBluetoothMetadataListener;
47 import android.bluetooth.IBluetoothSocketManager;
48 import android.bluetooth.OobData;
49 import android.bluetooth.UidTraffic;
50 import android.content.BroadcastReceiver;
51 import android.content.Context;
52 import android.content.Intent;
53 import android.content.IntentFilter;
54 import android.content.SharedPreferences;
55 import android.content.pm.PackageManager;
56 import android.os.AsyncTask;
57 import android.os.BatteryStats;
58 import android.os.Binder;
59 import android.os.Bundle;
60 import android.os.Handler;
61 import android.os.IBinder;
62 import android.os.Looper;
63 import android.os.Message;
64 import android.os.ParcelUuid;
65 import android.os.PowerManager;
66 import android.os.RemoteCallbackList;
67 import android.os.RemoteException;
68 import android.os.ResultReceiver;
69 import android.os.ServiceManager;
70 import android.os.SystemClock;
71 import android.os.SystemProperties;
72 import android.os.UserHandle;
73 import android.os.UserManager;
74 import android.provider.Settings;
75 import android.text.TextUtils;
76 import android.util.Base64;
77 import android.util.Log;
78 import android.util.SparseArray;
79 
80 import com.android.bluetooth.BluetoothMetricsProto;
81 import com.android.bluetooth.BluetoothStatsLog;
82 import com.android.bluetooth.Utils;
83 import com.android.bluetooth.a2dp.A2dpService;
84 import com.android.bluetooth.a2dpsink.A2dpSinkService;
85 import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;
86 import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreService;
87 import com.android.bluetooth.btservice.storage.DatabaseManager;
88 import com.android.bluetooth.btservice.storage.MetadataDatabase;
89 import com.android.bluetooth.gatt.GattService;
90 import com.android.bluetooth.hearingaid.HearingAidService;
91 import com.android.bluetooth.hfp.HeadsetService;
92 import com.android.bluetooth.hfpclient.HeadsetClientService;
93 import com.android.bluetooth.hid.HidDeviceService;
94 import com.android.bluetooth.hid.HidHostService;
95 import com.android.bluetooth.map.BluetoothMapService;
96 import com.android.bluetooth.mapclient.MapClientService;
97 import com.android.bluetooth.pan.PanService;
98 import com.android.bluetooth.pbap.BluetoothPbapService;
99 import com.android.bluetooth.pbapclient.PbapClientService;
100 import com.android.bluetooth.sap.SapService;
101 import com.android.bluetooth.sdp.SdpManager;
102 import com.android.internal.R;
103 import com.android.internal.annotations.VisibleForTesting;
104 import com.android.internal.app.IBatteryStats;
105 import com.android.internal.util.ArrayUtils;
106 
107 import com.google.protobuf.InvalidProtocolBufferException;
108 
109 import java.io.FileDescriptor;
110 import java.io.FileOutputStream;
111 import java.io.IOException;
112 import java.io.PrintWriter;
113 import java.util.ArrayList;
114 import java.util.Arrays;
115 import java.util.HashMap;
116 import java.util.List;
117 
118 public class AdapterService extends Service {
119     private static final String TAG = "BluetoothAdapterService";
120     private static final boolean DBG = true;
121     private static final boolean VERBOSE = false;
122     private static final int MIN_ADVT_INSTANCES_FOR_MA = 5;
123     private static final int MIN_OFFLOADED_FILTERS = 10;
124     private static final int MIN_OFFLOADED_SCAN_STORAGE_BYTES = 1024;
125 
126     private final Object mEnergyInfoLock = new Object();
127     private int mStackReportedState;
128     private long mTxTimeTotalMs;
129     private long mRxTimeTotalMs;
130     private long mIdleTimeTotalMs;
131     private long mEnergyUsedTotalVoltAmpSecMicro;
132     private final SparseArray<UidTraffic> mUidTraffic = new SparseArray<>();
133 
134     private final ArrayList<ProfileService> mRegisteredProfiles = new ArrayList<>();
135     private final ArrayList<ProfileService> mRunningProfiles = new ArrayList<>();
136 
137     public static final String ACTION_LOAD_ADAPTER_PROPERTIES =
138             "com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES";
139     public static final String ACTION_SERVICE_STATE_CHANGED =
140             "com.android.bluetooth.btservice.action.STATE_CHANGED";
141     public static final String EXTRA_ACTION = "action";
142     public static final int PROFILE_CONN_REJECTED = 2;
143 
144     private static final String ACTION_ALARM_WAKEUP =
145             "com.android.bluetooth.btservice.action.ALARM_WAKEUP";
146 
147     static final String BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY = "persist.bluetooth.btsnooplogmode";
148     static final String BLUETOOTH_BTSNOOP_DEFAULT_MODE_PROPERTY =
149             "persist.bluetooth.btsnoopdefaultmode";
150     private String mSnoopLogSettingAtEnable = "empty";
151     private String mDefaultSnoopLogSettingAtEnable = "empty";
152 
153     public static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
154     public static final String BLUETOOTH_PRIVILEGED =
155             android.Manifest.permission.BLUETOOTH_PRIVILEGED;
156     static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
157     static final String LOCAL_MAC_ADDRESS_PERM = android.Manifest.permission.LOCAL_MAC_ADDRESS;
158     static final String RECEIVE_MAP_PERM = android.Manifest.permission.RECEIVE_BLUETOOTH_MAP;
159 
160     private static final String PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE =
161             "phonebook_access_permission";
162     private static final String MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE =
163             "message_access_permission";
164     private static final String SIM_ACCESS_PERMISSION_PREFERENCE_FILE = "sim_access_permission";
165 
166     private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30;
167 
168     private final ArrayList<DiscoveringPackage> mDiscoveringPackages = new ArrayList<>();
169 
170     static {
classInitNative()171         classInitNative();
172     }
173 
174     private static AdapterService sAdapterService;
175 
getAdapterService()176     public static synchronized AdapterService getAdapterService() {
177         Log.d(TAG, "getAdapterService() - returning " + sAdapterService);
178         return sAdapterService;
179     }
180 
setAdapterService(AdapterService instance)181     private static synchronized void setAdapterService(AdapterService instance) {
182         Log.d(TAG, "setAdapterService() - trying to set service to " + instance);
183         if (instance == null) {
184             return;
185         }
186         sAdapterService = instance;
187     }
188 
clearAdapterService(AdapterService current)189     private static synchronized void clearAdapterService(AdapterService current) {
190         if (sAdapterService == current) {
191             sAdapterService = null;
192         }
193     }
194 
195     private AdapterProperties mAdapterProperties;
196     private AdapterState mAdapterStateMachine;
197     private BondStateMachine mBondStateMachine;
198     private JniCallbacks mJniCallbacks;
199     private RemoteDevices mRemoteDevices;
200 
201     /* TODO: Consider to remove the search API from this class, if changed to use call-back */
202     private SdpManager mSdpManager = null;
203 
204     private boolean mNativeAvailable;
205     private boolean mCleaningUp;
206     private final HashMap<BluetoothDevice, ArrayList<IBluetoothMetadataListener>>
207             mMetadataListeners = new HashMap<>();
208     private final HashMap<String, Integer> mProfileServicesState = new HashMap<String, Integer>();
209     //Only BluetoothManagerService should be registered
210     private RemoteCallbackList<IBluetoothCallback> mCallbacks;
211     private int mCurrentRequestId;
212     private boolean mQuietmode = false;
213 
214     private AlarmManager mAlarmManager;
215     private PendingIntent mPendingAlarm;
216     private IBatteryStats mBatteryStats;
217     private PowerManager mPowerManager;
218     private PowerManager.WakeLock mWakeLock;
219     private String mWakeLockName;
220     private UserManager mUserManager;
221 
222     private PhonePolicy mPhonePolicy;
223     private ActiveDeviceManager mActiveDeviceManager;
224     private DatabaseManager mDatabaseManager;
225     private SilenceDeviceManager mSilenceDeviceManager;
226     private AppOpsManager mAppOps;
227 
228     private BluetoothSocketManagerBinder mBluetoothSocketManagerBinder;
229 
230     private BluetoothKeystoreService mBluetoothKeystoreService;
231     private A2dpService mA2dpService;
232     private A2dpSinkService mA2dpSinkService;
233     private HeadsetService mHeadsetService;
234     private HeadsetClientService mHeadsetClientService;
235     private BluetoothMapService mMapService;
236     private MapClientService mMapClientService;
237     private HidDeviceService mHidDeviceService;
238     private HidHostService mHidHostService;
239     private PanService mPanService;
240     private BluetoothPbapService mPbapService;
241     private PbapClientService mPbapClientService;
242     private HearingAidService mHearingAidService;
243     private SapService mSapService;
244 
245     /**
246      * Register a {@link ProfileService} with AdapterService.
247      *
248      * @param profile the service being added.
249      */
addProfile(ProfileService profile)250     public void addProfile(ProfileService profile) {
251         mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_REGISTERED, profile).sendToTarget();
252     }
253 
254     /**
255      * Unregister a ProfileService with AdapterService.
256      *
257      * @param profile the service being removed.
258      */
removeProfile(ProfileService profile)259     public void removeProfile(ProfileService profile) {
260         mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_UNREGISTERED, profile).sendToTarget();
261     }
262 
263     /**
264      * Notify AdapterService that a ProfileService has started or stopped.
265      *
266      * @param profile the service being removed.
267      * @param state {@link BluetoothAdapter#STATE_ON} or {@link BluetoothAdapter#STATE_OFF}
268      */
onProfileServiceStateChanged(ProfileService profile, int state)269     public void onProfileServiceStateChanged(ProfileService profile, int state) {
270         if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) {
271             throw new IllegalArgumentException(BluetoothAdapter.nameForState(state));
272         }
273         Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
274         m.obj = profile;
275         m.arg1 = state;
276         mHandler.sendMessage(m);
277     }
278 
279     private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED = 1;
280     private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2;
281     private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3;
282 
283     class AdapterServiceHandler extends Handler {
284         @Override
handleMessage(Message msg)285         public void handleMessage(Message msg) {
286             verboseLog("handleMessage() - Message: " + msg.what);
287 
288             switch (msg.what) {
289                 case MESSAGE_PROFILE_SERVICE_STATE_CHANGED:
290                     verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED");
291                     processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1);
292                     break;
293                 case MESSAGE_PROFILE_SERVICE_REGISTERED:
294                     verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_REGISTERED");
295                     registerProfileService((ProfileService) msg.obj);
296                     break;
297                 case MESSAGE_PROFILE_SERVICE_UNREGISTERED:
298                     verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_UNREGISTERED");
299                     unregisterProfileService((ProfileService) msg.obj);
300                     break;
301             }
302         }
303 
registerProfileService(ProfileService profile)304         private void registerProfileService(ProfileService profile) {
305             if (mRegisteredProfiles.contains(profile)) {
306                 Log.e(TAG, profile.getName() + " already registered.");
307                 return;
308             }
309             mRegisteredProfiles.add(profile);
310         }
311 
unregisterProfileService(ProfileService profile)312         private void unregisterProfileService(ProfileService profile) {
313             if (!mRegisteredProfiles.contains(profile)) {
314                 Log.e(TAG, profile.getName() + " not registered (UNREGISTER).");
315                 return;
316             }
317             mRegisteredProfiles.remove(profile);
318         }
319 
processProfileServiceStateChanged(ProfileService profile, int state)320         private void processProfileServiceStateChanged(ProfileService profile, int state) {
321             switch (state) {
322                 case BluetoothAdapter.STATE_ON:
323                     if (!mRegisteredProfiles.contains(profile)) {
324                         Log.e(TAG, profile.getName() + " not registered (STATE_ON).");
325                         return;
326                     }
327                     if (mRunningProfiles.contains(profile)) {
328                         Log.e(TAG, profile.getName() + " already running.");
329                         return;
330                     }
331                     mRunningProfiles.add(profile);
332                     if (GattService.class.getSimpleName().equals(profile.getName())) {
333                         enableNative();
334                     } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
335                             && mRegisteredProfiles.size() == mRunningProfiles.size()) {
336                         mAdapterProperties.onBluetoothReady();
337                         updateUuids();
338                         setBluetoothClassFromConfig();
339                         initProfileServices();
340                         getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS);
341                         getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS_BLE);
342                         mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
343                     }
344                     break;
345                 case BluetoothAdapter.STATE_OFF:
346                     if (!mRegisteredProfiles.contains(profile)) {
347                         Log.e(TAG, profile.getName() + " not registered (STATE_OFF).");
348                         return;
349                     }
350                     if (!mRunningProfiles.contains(profile)) {
351                         Log.e(TAG, profile.getName() + " not running.");
352                         return;
353                     }
354                     mRunningProfiles.remove(profile);
355                     // If only GATT is left, send BREDR_STOPPED.
356                     if ((mRunningProfiles.size() == 1 && (GattService.class.getSimpleName()
357                             .equals(mRunningProfiles.get(0).getName())))) {
358                         mAdapterStateMachine.sendMessage(AdapterState.BREDR_STOPPED);
359                     } else if (mRunningProfiles.size() == 0) {
360                         disableNative();
361                     }
362                     break;
363                 default:
364                     Log.e(TAG, "Unhandled profile state: " + state);
365             }
366         }
367     }
368 
369     private final AdapterServiceHandler mHandler = new AdapterServiceHandler();
370 
updateInteropDatabase()371     private void updateInteropDatabase() {
372         interopDatabaseClearNative();
373 
374         String interopString = Settings.Global.getString(getContentResolver(),
375                 Settings.Global.BLUETOOTH_INTEROPERABILITY_LIST);
376         if (interopString == null) {
377             return;
378         }
379         Log.d(TAG, "updateInteropDatabase: [" + interopString + "]");
380 
381         String[] entries = interopString.split(";");
382         for (String entry : entries) {
383             String[] tokens = entry.split(",");
384             if (tokens.length != 2) {
385                 continue;
386             }
387 
388             // Get feature
389             int feature = 0;
390             try {
391                 feature = Integer.parseInt(tokens[1]);
392             } catch (NumberFormatException e) {
393                 Log.e(TAG, "updateInteropDatabase: Invalid feature '" + tokens[1] + "'");
394                 continue;
395             }
396 
397             // Get address bytes and length
398             int length = (tokens[0].length() + 1) / 3;
399             if (length < 1 || length > 6) {
400                 Log.e(TAG, "updateInteropDatabase: Malformed address string '" + tokens[0] + "'");
401                 continue;
402             }
403 
404             byte[] addr = new byte[6];
405             int offset = 0;
406             for (int i = 0; i < tokens[0].length(); ) {
407                 if (tokens[0].charAt(i) == ':') {
408                     i += 1;
409                 } else {
410                     try {
411                         addr[offset++] = (byte) Integer.parseInt(tokens[0].substring(i, i + 2), 16);
412                     } catch (NumberFormatException e) {
413                         offset = 0;
414                         break;
415                     }
416                     i += 2;
417                 }
418             }
419 
420             // Check if address was parsed ok, otherwise, move on...
421             if (offset == 0) {
422                 continue;
423             }
424 
425             // Add entry
426             interopDatabaseAddNative(feature, addr, length);
427         }
428     }
429 
430     @Override
onCreate()431     public void onCreate() {
432         super.onCreate();
433         debugLog("onCreate()");
434         mRemoteDevices = new RemoteDevices(this, Looper.getMainLooper());
435         mRemoteDevices.init();
436         clearDiscoveringPackages();
437         mBinder = new AdapterServiceBinder(this);
438         mAdapterProperties = new AdapterProperties(this);
439         mAdapterStateMachine = AdapterState.make(this);
440         mJniCallbacks = new JniCallbacks(this, mAdapterProperties);
441         mBluetoothKeystoreService = new BluetoothKeystoreService(isNiapMode());
442         mBluetoothKeystoreService.start();
443         int configCompareResult = mBluetoothKeystoreService.getCompareResult();
444         initNative(isGuest(), isNiapMode(), configCompareResult);
445         mNativeAvailable = true;
446         mCallbacks = new RemoteCallbackList<IBluetoothCallback>();
447         mAppOps = getSystemService(AppOpsManager.class);
448         //Load the name and address
449         getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);
450         getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);
451         getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_CLASS_OF_DEVICE);
452         mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
453         mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
454         mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
455         mBatteryStats = IBatteryStats.Stub.asInterface(
456                 ServiceManager.getService(BatteryStats.SERVICE_NAME));
457 
458         mBluetoothKeystoreService.initJni();
459 
460         mSdpManager = SdpManager.init(this);
461         registerReceiver(mAlarmBroadcastReceiver, new IntentFilter(ACTION_ALARM_WAKEUP));
462 
463         // Phone policy is specific to phone implementations and hence if a device wants to exclude
464         // it out then it can be disabled by using the flag below.
465         if (getResources().getBoolean(com.android.bluetooth.R.bool.enable_phone_policy)) {
466             Log.i(TAG, "Phone policy enabled");
467             mPhonePolicy = new PhonePolicy(this, new ServiceFactory());
468             mPhonePolicy.start();
469         } else {
470             Log.i(TAG, "Phone policy disabled");
471         }
472 
473         mActiveDeviceManager = new ActiveDeviceManager(this, new ServiceFactory());
474         mActiveDeviceManager.start();
475 
476         mDatabaseManager = new DatabaseManager(this);
477         mDatabaseManager.start(MetadataDatabase.createDatabase(this));
478 
479         mSilenceDeviceManager = new SilenceDeviceManager(this, new ServiceFactory(),
480                 Looper.getMainLooper());
481         mSilenceDeviceManager.start();
482 
483         mBluetoothSocketManagerBinder = new BluetoothSocketManagerBinder(this);
484 
485         setAdapterService(this);
486 
487         invalidateBluetoothCaches();
488 
489         // First call to getSharedPreferences will result in a file read into
490         // memory cache. Call it here asynchronously to avoid potential ANR
491         // in the future
492         new AsyncTask<Void, Void, Void>() {
493             @Override
494             protected Void doInBackground(Void... params) {
495                 getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE,
496                         Context.MODE_PRIVATE);
497                 getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE,
498                         Context.MODE_PRIVATE);
499                 getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, Context.MODE_PRIVATE);
500                 return null;
501             }
502         }.execute();
503 
504         try {
505             int systemUiUid = getApplicationContext().getPackageManager().getPackageUid(
506                     "com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY);
507 
508             Utils.setSystemUiUid(systemUiUid);
509         } catch (PackageManager.NameNotFoundException e) {
510             // Some platforms, such as wearables do not have a system ui.
511             Log.w(TAG, "Unable to resolve SystemUI's UID.", e);
512         }
513 
514         IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
515         getApplicationContext().registerReceiverForAllUsers(sUserSwitchedReceiver, filter, null, null);
516         int fuid = ActivityManager.getCurrentUser();
517         Utils.setForegroundUserId(fuid);
518     }
519 
520     @Override
onBind(Intent intent)521     public IBinder onBind(Intent intent) {
522         debugLog("onBind()");
523         return mBinder;
524     }
525 
526     @Override
onUnbind(Intent intent)527     public boolean onUnbind(Intent intent) {
528         debugLog("onUnbind() - calling cleanup");
529         cleanup();
530         return super.onUnbind(intent);
531     }
532 
533     @Override
onDestroy()534     public void onDestroy() {
535         debugLog("onDestroy()");
536         if (!isMock()) {
537             // TODO(b/27859763)
538             Log.i(TAG, "Force exit to cleanup internal state in Bluetooth stack");
539             System.exit(0);
540         }
541     }
542 
543     public static final BroadcastReceiver sUserSwitchedReceiver = new BroadcastReceiver() {
544         @Override
545         public void onReceive(Context context, Intent intent) {
546             if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
547                 int fuid = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
548                 Utils.setForegroundUserId(fuid);
549             }
550         }
551     };
552 
bringUpBle()553     void bringUpBle() {
554         debugLog("bleOnProcessStart()");
555 
556         if (getResources().getBoolean(
557                 R.bool.config_bluetooth_reload_supported_profiles_when_enabled)) {
558             Config.init(getApplicationContext());
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.reset();
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             Log.w(TAG, "RemoteException trying to send a reset to BatteryStats");
582         }
583         BluetoothStatsLog.write_non_chained(BluetoothStatsLog.BLE_SCAN_STATE_CHANGED, -1, null,
584                 BluetoothStatsLog.BLE_SCAN_STATE_CHANGED__STATE__RESET, false, false, false);
585 
586         //Start Gatt service
587         setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON);
588     }
589 
bringDownBle()590     void bringDownBle() {
591         stopGattProfileService();
592     }
593 
stateChangeCallback(int status)594     void stateChangeCallback(int status) {
595         if (status == AbstractionLayer.BT_STATE_OFF) {
596             debugLog("stateChangeCallback: disableNative() completed");
597             mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
598         } else if (status == AbstractionLayer.BT_STATE_ON) {
599             mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED);
600         } else {
601             Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback");
602         }
603     }
604 
605     /**
606      * Sets the Bluetooth CoD value of the local adapter if there exists a config value for it.
607      */
setBluetoothClassFromConfig()608     void setBluetoothClassFromConfig() {
609         int bluetoothClassConfig = retrieveBluetoothClassConfig();
610         if (bluetoothClassConfig != 0) {
611             mAdapterProperties.setBluetoothClass(new BluetoothClass(bluetoothClassConfig));
612         }
613     }
614 
retrieveBluetoothClassConfig()615     private int retrieveBluetoothClassConfig() {
616         return Settings.Global.getInt(
617                 getContentResolver(), Settings.Global.BLUETOOTH_CLASS_OF_DEVICE, 0);
618     }
619 
startProfileServices()620     void startProfileServices() {
621         debugLog("startCoreServices()");
622         Class[] supportedProfileServices = Config.getSupportedProfiles();
623         if (supportedProfileServices.length == 1 && GattService.class.getSimpleName()
624                 .equals(supportedProfileServices[0].getSimpleName())) {
625             mAdapterProperties.onBluetoothReady();
626             updateUuids();
627             setBluetoothClassFromConfig();
628             mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
629         } else {
630             setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON);
631         }
632     }
633 
stopProfileServices()634     void stopProfileServices() {
635         // Make sure to stop classic background tasks now
636         cancelDiscoveryNative();
637         mAdapterProperties.setScanMode(AbstractionLayer.BT_SCAN_MODE_NONE);
638 
639         Class[] supportedProfileServices = Config.getSupportedProfiles();
640         if (supportedProfileServices.length == 1 && (mRunningProfiles.size() == 1
641                 && GattService.class.getSimpleName().equals(mRunningProfiles.get(0).getName()))) {
642             debugLog("stopProfileServices() - No profiles services to stop or already stopped.");
643             mAdapterStateMachine.sendMessage(AdapterState.BREDR_STOPPED);
644         } else {
645             setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_OFF);
646         }
647     }
648 
stopGattProfileService()649     private void stopGattProfileService() {
650         mAdapterProperties.onBleDisable();
651         if (mRunningProfiles.size() == 0) {
652             debugLog("stopGattProfileService() - No profiles services to stop.");
653             mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
654         }
655         setProfileServiceState(GattService.class, BluetoothAdapter.STATE_OFF);
656     }
657 
invalidateBluetoothGetStateCache()658     private void invalidateBluetoothGetStateCache() {
659         BluetoothAdapter.invalidateBluetoothGetStateCache();
660     }
661 
updateAdapterState(int prevState, int newState)662     void updateAdapterState(int prevState, int newState) {
663         mAdapterProperties.setState(newState);
664         invalidateBluetoothGetStateCache();
665         if (mCallbacks != null) {
666             int n = mCallbacks.beginBroadcast();
667             debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState(
668                     newState) + " to " + n + " receivers.");
669             for (int i = 0; i < n; i++) {
670                 try {
671                     mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState);
672                 } catch (RemoteException e) {
673                     debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")");
674                 }
675             }
676             mCallbacks.finishBroadcast();
677         }
678 
679         // Turn the Adapter all the way off if we are disabling and the snoop log setting changed.
680         if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON) {
681             mSnoopLogSettingAtEnable =
682                     SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, "empty");
683             mDefaultSnoopLogSettingAtEnable =
684                     Settings.Global.getString(getContentResolver(),
685                             Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE);
686             SystemProperties.set(BLUETOOTH_BTSNOOP_DEFAULT_MODE_PROPERTY,
687                     mDefaultSnoopLogSettingAtEnable);
688         } else if (newState == BluetoothAdapter.STATE_BLE_ON
689                    && prevState != BluetoothAdapter.STATE_OFF) {
690             String snoopLogSetting =
691                     SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, "empty");
692             String snoopDefaultModeSetting =
693                     Settings.Global.getString(getContentResolver(),
694                             Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE);
695 
696             if (!TextUtils.equals(mSnoopLogSettingAtEnable, snoopLogSetting)
697                     || !TextUtils.equals(mDefaultSnoopLogSettingAtEnable,
698                             snoopDefaultModeSetting)) {
699                 mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF);
700             }
701         }
702     }
703 
cleanup()704     void cleanup() {
705         debugLog("cleanup()");
706         if (mCleaningUp) {
707             errorLog("cleanup() - Service already starting to cleanup, ignoring request...");
708             return;
709         }
710 
711         clearAdapterService(this);
712 
713         mCleaningUp = true;
714         invalidateBluetoothCaches();
715 
716         unregisterReceiver(mAlarmBroadcastReceiver);
717 
718         if (mPendingAlarm != null) {
719             mAlarmManager.cancel(mPendingAlarm);
720             mPendingAlarm = null;
721         }
722 
723         // This wake lock release may also be called concurrently by
724         // {@link #releaseWakeLock(String lockName)}, so a synchronization is needed here.
725         synchronized (this) {
726             if (mWakeLock != null) {
727                 if (mWakeLock.isHeld()) {
728                     mWakeLock.release();
729                 }
730                 mWakeLock = null;
731             }
732         }
733 
734         if (mDatabaseManager != null) {
735             mDatabaseManager.cleanup();
736         }
737 
738         if (mAdapterStateMachine != null) {
739             mAdapterStateMachine.doQuit();
740         }
741 
742         if (mBondStateMachine != null) {
743             mBondStateMachine.doQuit();
744         }
745 
746         if (mRemoteDevices != null) {
747             mRemoteDevices.cleanup();
748         }
749 
750         if (mSdpManager != null) {
751             mSdpManager.cleanup();
752             mSdpManager = null;
753         }
754 
755         if (mBluetoothKeystoreService != null) {
756             mBluetoothKeystoreService.cleanup();
757         }
758 
759         if (mNativeAvailable) {
760             debugLog("cleanup() - Cleaning up adapter native");
761             cleanupNative();
762             mNativeAvailable = false;
763         }
764 
765         if (mAdapterProperties != null) {
766             mAdapterProperties.cleanup();
767         }
768 
769         if (mJniCallbacks != null) {
770             mJniCallbacks.cleanup();
771         }
772 
773         if (mPhonePolicy != null) {
774             mPhonePolicy.cleanup();
775         }
776 
777         if (mSilenceDeviceManager != null) {
778             mSilenceDeviceManager.cleanup();
779         }
780 
781         if (mActiveDeviceManager != null) {
782             mActiveDeviceManager.cleanup();
783         }
784 
785         if (mProfileServicesState != null) {
786             mProfileServicesState.clear();
787         }
788 
789         if (mBluetoothSocketManagerBinder != null) {
790             mBluetoothSocketManagerBinder.cleanUp();
791             mBluetoothSocketManagerBinder = null;
792         }
793 
794         if (mBinder != null) {
795             mBinder.cleanup();
796             mBinder = null;  //Do not remove. Otherwise Binder leak!
797         }
798 
799         if (mCallbacks != null) {
800             mCallbacks.kill();
801         }
802     }
803 
invalidateBluetoothCaches()804     private void invalidateBluetoothCaches() {
805         BluetoothAdapter.invalidateGetProfileConnectionStateCache();
806         BluetoothAdapter.invalidateIsOffloadedFilteringSupportedCache();
807         BluetoothDevice.invalidateBluetoothGetBondStateCache();
808         BluetoothAdapter.invalidateBluetoothGetStateCache();
809     }
810 
setProfileServiceState(Class service, int state)811     private void setProfileServiceState(Class service, int state) {
812         Intent intent = new Intent(this, service);
813         intent.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED);
814         intent.putExtra(BluetoothAdapter.EXTRA_STATE, state);
815         startService(intent);
816     }
817 
setAllProfileServiceStates(Class[] services, int state)818     private void setAllProfileServiceStates(Class[] services, int state) {
819         for (Class service : services) {
820             if (GattService.class.getSimpleName().equals(service.getSimpleName())) {
821                 continue;
822             }
823             setProfileServiceState(service, state);
824         }
825     }
826 
827     /**
828      * Verifies whether the profile is supported by the local bluetooth adapter by checking a
829      * bitmask of its supported profiles
830      *
831      * @param remoteDeviceUuids is an array of all supported profiles by the remote device
832      * @param localDeviceUuids  is an array of all supported profiles by the local device
833      * @param profile           is the profile we are checking for support
834      * @param device            is the remote device we wish to connect to
835      * @return true if the profile is supported by both the local and remote device, false otherwise
836      */
isSupported(ParcelUuid[] localDeviceUuids, ParcelUuid[] remoteDeviceUuids, int profile, BluetoothDevice device)837     private boolean isSupported(ParcelUuid[] localDeviceUuids, ParcelUuid[] remoteDeviceUuids,
838             int profile, BluetoothDevice device) {
839         if (remoteDeviceUuids == null || remoteDeviceUuids.length == 0) {
840             Log.e(TAG, "isSupported: Remote Device Uuids Empty");
841         }
842 
843         if (profile == BluetoothProfile.HEADSET) {
844             return (ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HSP_AG)
845                     && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HSP))
846                     || (ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HFP_AG)
847                     && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HFP));
848         }
849         if (profile == BluetoothProfile.HEADSET_CLIENT) {
850             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HFP_AG)
851                     && ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HFP);
852         }
853         if (profile == BluetoothProfile.A2DP) {
854             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.ADV_AUDIO_DIST)
855                     || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.A2DP_SINK);
856         }
857         if (profile == BluetoothProfile.A2DP_SINK) {
858             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.ADV_AUDIO_DIST)
859                     || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.A2DP_SOURCE);
860         }
861         if (profile == BluetoothProfile.OPP) {
862             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.OBEX_OBJECT_PUSH);
863         }
864         if (profile == BluetoothProfile.HID_HOST) {
865             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HID)
866                     || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HOGP);
867         }
868         if (profile == BluetoothProfile.HID_DEVICE) {
869             return mHidDeviceService.getConnectionState(device)
870                     == BluetoothProfile.STATE_DISCONNECTED;
871         }
872         if (profile == BluetoothProfile.PAN) {
873             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.NAP);
874         }
875         if (profile == BluetoothProfile.MAP) {
876             return mMapService.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED;
877         }
878         if (profile == BluetoothProfile.PBAP) {
879             return mPbapService.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED;
880         }
881         if (profile == BluetoothProfile.MAP_CLIENT) {
882             return true;
883         }
884         if (profile == BluetoothProfile.PBAP_CLIENT) {
885             return ArrayUtils.contains(localDeviceUuids, BluetoothUuid.PBAP_PCE)
886                     && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.PBAP_PSE);
887         }
888         if (profile == BluetoothProfile.HEARING_AID) {
889             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HEARING_AID);
890         }
891         if (profile == BluetoothProfile.SAP) {
892             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.SAP);
893         }
894 
895         Log.e(TAG, "isSupported: Unexpected profile passed in to function: " + profile);
896         return false;
897     }
898 
899     /**
900      * Checks if any profile is enabled for the given device
901      *
902      * @param device is the device for which we are checking if any profiles are enabled
903      * @return true if any profile is enabled, false otherwise
904      */
isAnyProfileEnabled(BluetoothDevice device)905     private boolean isAnyProfileEnabled(BluetoothDevice device) {
906 
907         if (mA2dpService != null && mA2dpService.getConnectionPolicy(device)
908                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
909             return true;
910         }
911         if (mA2dpSinkService != null && mA2dpSinkService.getConnectionPolicy(device)
912                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
913             return true;
914         }
915         if (mHeadsetService != null && mHeadsetService.getConnectionPolicy(device)
916                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
917             return true;
918         }
919         if (mHeadsetClientService != null && mHeadsetClientService.getConnectionPolicy(device)
920                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
921             return true;
922         }
923         if (mMapClientService != null && mMapClientService.getConnectionPolicy(device)
924                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
925             return true;
926         }
927         if (mHidHostService != null && mHidHostService.getConnectionPolicy(device)
928                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
929             return true;
930         }
931         if (mPanService != null && mPanService.getConnectionPolicy(device)
932                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
933             return true;
934         }
935         if (mPbapClientService != null && mPbapClientService.getConnectionPolicy(device)
936                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
937             return true;
938         }
939         if (mHearingAidService != null && mHearingAidService.getConnectionPolicy(device)
940                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
941             return true;
942         }
943 
944         return false;
945     }
946 
947     /**
948      * Connects only available profiles
949      * (those with {@link BluetoothProfile.CONNECTION_POLICY_ALLOWED})
950      *
951      * @param device is the device with which we are connecting the profiles
952      * @return true
953      */
connectEnabledProfiles(BluetoothDevice device)954     private boolean connectEnabledProfiles(BluetoothDevice device) {
955         ParcelUuid[] remoteDeviceUuids = getRemoteUuids(device);
956         ParcelUuid[] localDeviceUuids = mAdapterProperties.getUuids();
957 
958         if (mA2dpService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
959                 BluetoothProfile.A2DP, device) && mA2dpService.getConnectionPolicy(device)
960                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
961             Log.i(TAG, "connectEnabledProfiles: Connecting A2dp");
962             mA2dpService.connect(device);
963         }
964         if (mA2dpSinkService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
965                 BluetoothProfile.A2DP_SINK, device) && mA2dpSinkService.getConnectionPolicy(device)
966                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
967             Log.i(TAG, "connectEnabledProfiles: Connecting A2dp Sink");
968             mA2dpSinkService.connect(device);
969         }
970         if (mHeadsetService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
971                 BluetoothProfile.HEADSET, device) && mHeadsetService.getConnectionPolicy(device)
972                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
973             Log.i(TAG, "connectEnabledProfiles: Connecting Headset Profile");
974             mHeadsetService.connect(device);
975         }
976         if (mHeadsetClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
977                 BluetoothProfile.HEADSET_CLIENT, device)
978                 && mHeadsetClientService.getConnectionPolicy(device)
979                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
980             Log.i(TAG, "connectEnabledProfiles: Connecting HFP");
981             mHeadsetClientService.connect(device);
982         }
983         if (mMapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
984                 BluetoothProfile.MAP_CLIENT, device)
985                 && mMapClientService.getConnectionPolicy(device)
986                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
987             Log.i(TAG, "connectEnabledProfiles: Connecting MAP");
988             mMapClientService.connect(device);
989         }
990         if (mHidHostService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
991                 BluetoothProfile.HID_HOST, device) && mHidHostService.getConnectionPolicy(device)
992                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
993             Log.i(TAG, "connectEnabledProfiles: Connecting Hid Host Profile");
994             mHidHostService.connect(device);
995         }
996         if (mPanService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
997                 BluetoothProfile.PAN, device) && mPanService.getConnectionPolicy(device)
998                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
999             Log.i(TAG, "connectEnabledProfiles: Connecting Pan Profile");
1000             mPanService.connect(device);
1001         }
1002         if (mPbapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
1003                 BluetoothProfile.PBAP_CLIENT, device)
1004                 && mPbapClientService.getConnectionPolicy(device)
1005                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1006             Log.i(TAG, "connectEnabledProfiles: Connecting Pbap");
1007             mPbapClientService.connect(device);
1008         }
1009         if (mHearingAidService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
1010                 BluetoothProfile.HEARING_AID, device)
1011                 && mHearingAidService.getConnectionPolicy(device)
1012                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1013             Log.i(TAG, "connectEnabledProfiles: Connecting Hearing Aid Profile");
1014             mHearingAidService.connect(device);
1015         }
1016 
1017         return true;
1018     }
1019 
1020     /**
1021      * Verifies that all bluetooth profile services are running
1022      *
1023      * @return true if all bluetooth profile services running, false otherwise
1024      */
profileServicesRunning()1025     private boolean profileServicesRunning() {
1026         if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
1027                 && mRegisteredProfiles.size() == mRunningProfiles.size()) {
1028             return true;
1029         }
1030 
1031         Log.e(TAG, "profileServicesRunning: One or more supported services not running");
1032         return false;
1033     }
1034 
1035     /**
1036      * Initializes all the profile services fields
1037      */
initProfileServices()1038     private void initProfileServices() {
1039         Log.i(TAG, "initProfileServices: Initializing all bluetooth profile services");
1040         mA2dpService = A2dpService.getA2dpService();
1041         mA2dpSinkService = A2dpSinkService.getA2dpSinkService();
1042         mHeadsetService = HeadsetService.getHeadsetService();
1043         mHeadsetClientService = HeadsetClientService.getHeadsetClientService();
1044         mMapService = BluetoothMapService.getBluetoothMapService();
1045         mMapClientService = MapClientService.getMapClientService();
1046         mHidDeviceService = HidDeviceService.getHidDeviceService();
1047         mHidHostService = HidHostService.getHidHostService();
1048         mPanService = PanService.getPanService();
1049         mPbapService = BluetoothPbapService.getBluetoothPbapService();
1050         mPbapClientService = PbapClientService.getPbapClientService();
1051         mHearingAidService = HearingAidService.getHearingAidService();
1052         mSapService = SapService.getSapService();
1053     }
1054 
isAvailable()1055     private boolean isAvailable() {
1056         return !mCleaningUp;
1057     }
1058 
1059     /**
1060      * Handlers for incoming service calls
1061      */
1062     private AdapterServiceBinder mBinder;
1063 
1064     /**
1065      * The Binder implementation must be declared to be a static class, with
1066      * the AdapterService instance passed in the constructor. Furthermore,
1067      * when the AdapterService shuts down, the reference to the AdapterService
1068      * must be explicitly removed.
1069      *
1070      * Otherwise, a memory leak can occur from repeated starting/stopping the
1071      * service...Please refer to android.os.Binder for further details on
1072      * why an inner instance class should be avoided.
1073      *
1074      */
1075     @VisibleForTesting
1076     public static class AdapterServiceBinder extends IBluetooth.Stub {
1077         private AdapterService mService;
1078 
AdapterServiceBinder(AdapterService svc)1079         AdapterServiceBinder(AdapterService svc) {
1080             mService = svc;
1081             mService.invalidateBluetoothGetStateCache();
1082             BluetoothAdapter.getDefaultAdapter().disableBluetoothGetStateCache();
1083         }
1084 
cleanup()1085         public void cleanup() {
1086             mService = null;
1087         }
1088 
getService()1089         public AdapterService getService() {
1090             if (mService != null && mService.isAvailable()) {
1091                 return mService;
1092             }
1093             return null;
1094         }
1095 
1096         @Override
getState()1097         public int getState() {
1098             // don't check caller, may be called from system UI
1099             AdapterService service = getService();
1100             if (service == null) {
1101                 return BluetoothAdapter.STATE_OFF;
1102             }
1103 
1104             enforceBluetoothPermission(service);
1105 
1106             return service.getState();
1107         }
1108 
1109         @Override
enable(boolean quietMode)1110         public boolean enable(boolean quietMode) {
1111             AdapterService service = getService();
1112             if (service == null || !callerIsSystemOrActiveUser(TAG, "enable")) {
1113                 return false;
1114             }
1115 
1116             enforceBluetoothAdminPermission(service);
1117 
1118             return service.enable(quietMode);
1119         }
1120 
1121         @Override
disable()1122         public boolean disable() {
1123             AdapterService service = getService();
1124             if (service == null || !callerIsSystemOrActiveUser(TAG, "disable")) {
1125                 return false;
1126             }
1127 
1128             enforceBluetoothAdminPermission(service);
1129 
1130             return service.disable();
1131         }
1132 
1133         @Override
getAddress()1134         public String getAddress() {
1135             AdapterService service = getService();
1136             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getAddress")) {
1137                 return null;
1138             }
1139 
1140             enforceBluetoothPermission(service);
1141             enforceLocalMacAddressPermission(service);
1142 
1143             return Utils.getAddressStringFromByte(service.mAdapterProperties.getAddress());
1144         }
1145 
1146         @Override
getUuids()1147         public ParcelUuid[] getUuids() {
1148             AdapterService service = getService();
1149             if (service == null || !callerIsSystemOrActiveUser(TAG, "getUuids")) {
1150                 return new ParcelUuid[0];
1151             }
1152 
1153             enforceBluetoothPermission(service);
1154 
1155             return service.mAdapterProperties.getUuids();
1156         }
1157 
1158         @Override
getName()1159         public String getName() {
1160             AdapterService service = getService();
1161             if (service == null || !callerIsSystemOrActiveUser(TAG, "getName")) {
1162                 return null;
1163             }
1164 
1165             enforceBluetoothPermission(service);
1166 
1167             return service.getName();
1168         }
1169 
1170         @Override
setName(String name)1171         public boolean setName(String name) {
1172             AdapterService service = getService();
1173             if (service == null || !callerIsSystemOrActiveUser(TAG, "setName")) {
1174                 return false;
1175             }
1176 
1177             enforceBluetoothAdminPermission(service);
1178 
1179             return service.mAdapterProperties.setName(name);
1180         }
1181 
1182         @Override
getBluetoothClass()1183         public BluetoothClass getBluetoothClass() {
1184             AdapterService service = getService();
1185             if (service == null || !callerIsSystemOrActiveUser(TAG, "getBluetoothClass")) {
1186                 return null;
1187             }
1188 
1189             enforceBluetoothAdminPermission(service);
1190 
1191             return service.mAdapterProperties.getBluetoothClass();
1192         }
1193 
1194         @Override
setBluetoothClass(BluetoothClass bluetoothClass)1195         public boolean setBluetoothClass(BluetoothClass bluetoothClass) {
1196             AdapterService service = getService();
1197             if (service == null || !callerIsSystemOrActiveUser(TAG, "setBluetoothClass")) {
1198                 return false;
1199             }
1200 
1201             enforceBluetoothPrivilegedPermission(service);
1202 
1203             if (!service.mAdapterProperties.setBluetoothClass(bluetoothClass)) {
1204               return false;
1205             }
1206 
1207             return Settings.Global.putInt(
1208                     service.getContentResolver(),
1209                     Settings.Global.BLUETOOTH_CLASS_OF_DEVICE,
1210                     bluetoothClass.getClassOfDevice());
1211         }
1212 
1213         @Override
getIoCapability()1214         public int getIoCapability() {
1215             AdapterService service = getService();
1216             if (service == null || !callerIsSystemOrActiveUser(TAG, "getIoCapability")) {
1217                 return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
1218             }
1219 
1220             enforceBluetoothAdminPermission(service);
1221 
1222             return service.mAdapterProperties.getIoCapability();
1223         }
1224 
1225         @Override
setIoCapability(int capability)1226         public boolean setIoCapability(int capability) {
1227             AdapterService service = getService();
1228             if (service == null || !callerIsSystemOrActiveUser(TAG, "setIoCapability")) {
1229                 return false;
1230             }
1231 
1232             enforceBluetoothPrivilegedPermission(service);
1233 
1234             if (!isValidIoCapability(capability)) {
1235               return false;
1236             }
1237 
1238             return service.mAdapterProperties.setIoCapability(capability);
1239         }
1240 
1241         @Override
getLeIoCapability()1242         public int getLeIoCapability() {
1243             AdapterService service = getService();
1244             if (service == null || !callerIsSystemOrActiveUser(TAG, "getLeIoCapability")) {
1245                 return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
1246             }
1247 
1248             enforceBluetoothAdminPermission(service);
1249 
1250             return service.mAdapterProperties.getLeIoCapability();
1251         }
1252 
1253         @Override
setLeIoCapability(int capability)1254         public boolean setLeIoCapability(int capability) {
1255             AdapterService service = getService();
1256             if (service == null || !callerIsSystemOrActiveUser(TAG, "setLeIoCapability")) {
1257                 return false;
1258             }
1259 
1260             enforceBluetoothPrivilegedPermission(service);
1261 
1262             if (!isValidIoCapability(capability)) {
1263               return false;
1264             }
1265 
1266             return service.mAdapterProperties.setLeIoCapability(capability);
1267         }
1268 
1269         @Override
getScanMode()1270         public int getScanMode() {
1271             AdapterService service = getService();
1272             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getScanMode")) {
1273                 return BluetoothAdapter.SCAN_MODE_NONE;
1274             }
1275 
1276             enforceBluetoothPermission(service);
1277 
1278             return service.mAdapterProperties.getScanMode();
1279         }
1280 
1281         @Override
setScanMode(int mode, int duration)1282         public boolean setScanMode(int mode, int duration) {
1283             AdapterService service = getService();
1284             if (service == null || !callerIsSystemOrActiveUser(TAG, "setScanMode")) {
1285                 return false;
1286             }
1287 
1288             enforceBluetoothPermission(service);
1289 
1290             service.mAdapterProperties.setDiscoverableTimeout(duration);
1291             return service.mAdapterProperties.setScanMode(convertScanModeToHal(mode));
1292         }
1293 
1294         @Override
getDiscoverableTimeout()1295         public int getDiscoverableTimeout() {
1296             AdapterService service = getService();
1297             if (service == null || !callerIsSystemOrActiveUser(TAG, "getDiscoverableTimeout")) {
1298                 return 0;
1299             }
1300 
1301             enforceBluetoothPermission(service);
1302 
1303             return service.mAdapterProperties.getDiscoverableTimeout();
1304         }
1305 
1306         @Override
setDiscoverableTimeout(int timeout)1307         public boolean setDiscoverableTimeout(int timeout) {
1308             AdapterService service = getService();
1309             if (service == null || !callerIsSystemOrActiveUser(TAG, "setDiscoverableTimeout")) {
1310                 return false;
1311             }
1312 
1313             enforceBluetoothPermission(service);
1314 
1315             return service.mAdapterProperties.setDiscoverableTimeout(timeout);
1316         }
1317 
1318         @Override
startDiscovery(String callingPackage, String callingFeatureId)1319         public boolean startDiscovery(String callingPackage, String callingFeatureId) {
1320             AdapterService service = getService();
1321             if (service == null || !callerIsSystemOrActiveUser(TAG, "startDiscovery")) {
1322                 return false;
1323             }
1324 
1325             enforceBluetoothAdminPermission(service);
1326 
1327             return service.startDiscovery(callingPackage, callingFeatureId);
1328         }
1329 
1330         @Override
cancelDiscovery()1331         public boolean cancelDiscovery() {
1332             AdapterService service = getService();
1333             if (service == null || !callerIsSystemOrActiveUser(TAG, "cancelDiscovery")) {
1334                 return false;
1335             }
1336 
1337             enforceBluetoothAdminPermission(service);
1338 
1339             service.debugLog("cancelDiscovery");
1340             return service.cancelDiscoveryNative();
1341         }
1342 
1343         @Override
isDiscovering()1344         public boolean isDiscovering() {
1345             AdapterService service = getService();
1346             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "isDiscovering")) {
1347                 return false;
1348             }
1349 
1350             enforceBluetoothPermission(service);
1351 
1352             return service.mAdapterProperties.isDiscovering();
1353         }
1354 
1355         @Override
getDiscoveryEndMillis()1356         public long getDiscoveryEndMillis() {
1357             AdapterService service = getService();
1358             if (service == null || !callerIsSystemOrActiveUser(TAG, "getDiscoveryEndMillis")) {
1359                 return -1;
1360             }
1361 
1362             enforceBluetoothPrivilegedPermission(service);
1363 
1364             return service.mAdapterProperties.discoveryEndMillis();
1365         }
1366 
1367         @Override
getMostRecentlyConnectedDevices()1368         public List<BluetoothDevice> getMostRecentlyConnectedDevices() {
1369             // don't check caller, may be called from system UI
1370             AdapterService service = getService();
1371             if (service == null) {
1372                 return new ArrayList<>();
1373             }
1374 
1375             enforceBluetoothAdminPermission(service);
1376 
1377             return service.mDatabaseManager.getMostRecentlyConnectedDevices();
1378         }
1379 
1380         @Override
getBondedDevices()1381         public BluetoothDevice[] getBondedDevices() {
1382             // don't check caller, may be called from system UI
1383             AdapterService service = getService();
1384             if (service == null) {
1385                 return new BluetoothDevice[0];
1386             }
1387 
1388             enforceBluetoothPermission(service);
1389 
1390             return service.getBondedDevices();
1391         }
1392 
1393         @Override
getAdapterConnectionState()1394         public int getAdapterConnectionState() {
1395             // don't check caller, may be called from system UI
1396             AdapterService service = getService();
1397             if (service == null) {
1398                 return BluetoothAdapter.STATE_DISCONNECTED;
1399             }
1400 
1401             enforceBluetoothPermission(service);
1402 
1403             return service.mAdapterProperties.getConnectionState();
1404         }
1405 
1406         /**
1407          * This method has an associated binder cache.  The invalidation
1408          * methods must be changed if the logic behind this method changes.
1409          */
1410         @Override
getProfileConnectionState(int profile)1411         public int getProfileConnectionState(int profile) {
1412             AdapterService service = getService();
1413             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getProfileConnectionState")) {
1414                 return BluetoothProfile.STATE_DISCONNECTED;
1415             }
1416 
1417             enforceBluetoothPermission(service);
1418 
1419             return service.mAdapterProperties.getProfileConnectionState(profile);
1420         }
1421 
1422         @Override
createBond(BluetoothDevice device, int transport, OobData oobData)1423         public boolean createBond(BluetoothDevice device, int transport, OobData oobData) {
1424             AdapterService service = getService();
1425             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBond")) {
1426                 return false;
1427             }
1428 
1429             enforceBluetoothAdminPermission(service);
1430 
1431             return service.createBond(device, transport, oobData);
1432         }
1433 
1434         @Override
cancelBondProcess(BluetoothDevice device)1435         public boolean cancelBondProcess(BluetoothDevice device) {
1436             AdapterService service = getService();
1437             if (service == null || !callerIsSystemOrActiveUser(TAG, "cancelBondProcess")) {
1438                 return false;
1439             }
1440 
1441             enforceBluetoothAdminPermission(service);
1442 
1443             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1444             if (deviceProp != null) {
1445                 deviceProp.setBondingInitiatedLocally(false);
1446             }
1447 
1448             return service.cancelBondNative(addressToBytes(device.getAddress()));
1449         }
1450 
1451         @Override
removeBond(BluetoothDevice device)1452         public boolean removeBond(BluetoothDevice device) {
1453             AdapterService service = getService();
1454             if (service == null || !callerIsSystemOrActiveUser(TAG, "removeBond")) {
1455                 return false;
1456             }
1457 
1458             enforceBluetoothAdminPermission(service);
1459 
1460             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1461             if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) {
1462                 return false;
1463             }
1464             deviceProp.setBondingInitiatedLocally(false);
1465 
1466             Message msg = service.mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND);
1467             msg.obj = device;
1468             service.mBondStateMachine.sendMessage(msg);
1469             return true;
1470         }
1471 
1472         @Override
getBondState(BluetoothDevice device)1473         public int getBondState(BluetoothDevice device) {
1474             // don't check caller, may be called from system UI
1475             AdapterService service = getService();
1476             if (service == null) {
1477                 return BluetoothDevice.BOND_NONE;
1478             }
1479 
1480             enforceBluetoothPermission(service);
1481 
1482             return service.getBondState(device);
1483         }
1484 
1485         @Override
isBondingInitiatedLocally(BluetoothDevice device)1486         public boolean isBondingInitiatedLocally(BluetoothDevice device) {
1487             // don't check caller, may be called from system UI
1488             AdapterService service = getService();
1489             if (service == null) {
1490                 return false;
1491             }
1492 
1493             enforceBluetoothPermission(service);
1494 
1495             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1496             return deviceProp != null && deviceProp.isBondingInitiatedLocally();
1497         }
1498 
1499         @Override
getSupportedProfiles()1500         public long getSupportedProfiles() {
1501             AdapterService service = getService();
1502             if (service == null) {
1503                 return 0;
1504             }
1505             return Config.getSupportedProfilesBitMask();
1506         }
1507 
1508         @Override
getConnectionState(BluetoothDevice device)1509         public int getConnectionState(BluetoothDevice device) {
1510             AdapterService service = getService();
1511             if (service == null) {
1512                 return 0;
1513             }
1514 
1515             enforceBluetoothPermission(service);
1516 
1517             return service.getConnectionState(device);
1518         }
1519 
1520         @Override
removeActiveDevice(@ctiveDeviceUse int profiles)1521         public boolean removeActiveDevice(@ActiveDeviceUse int profiles) {
1522             if (!Utils.checkCaller()) {
1523                 Log.w(TAG, "removeActiveDevice() - Not allowed for non-active user");
1524                 return false;
1525             }
1526 
1527             AdapterService service = getService();
1528             if (service == null) {
1529                 return false;
1530             }
1531             return service.setActiveDevice(null, profiles);
1532         }
1533 
1534         @Override
setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles)1535         public boolean setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles) {
1536             if (!Utils.checkCaller()) {
1537                 Log.w(TAG, "setActiveDevice() - Not allowed for non-active user");
1538                 return false;
1539             }
1540 
1541             AdapterService service = getService();
1542             if (service == null) {
1543                 return false;
1544             }
1545             return service.setActiveDevice(device, profiles);
1546         }
1547 
1548         @Override
connectAllEnabledProfiles(BluetoothDevice device)1549         public boolean connectAllEnabledProfiles(BluetoothDevice device) {
1550             AdapterService service = getService();
1551             if (service == null || !callerIsSystemOrActiveUser(TAG, "connectAllEnabledProfiles")) {
1552                 return false;
1553             }
1554 
1555             enforceBluetoothPrivilegedPermission(service);
1556 
1557             return service.connectAllEnabledProfiles(device);
1558         }
1559 
1560         @Override
disconnectAllEnabledProfiles(BluetoothDevice device)1561         public boolean disconnectAllEnabledProfiles(BluetoothDevice device) {
1562             AdapterService service = getService();
1563             if (service == null | !callerIsSystemOrActiveUser(TAG, "disconnectAllEnabledProfiles")) {
1564                 return false;
1565             }
1566 
1567             enforceBluetoothPrivilegedPermission(service);
1568 
1569             return service.disconnectAllEnabledProfiles(device);
1570         }
1571 
1572         @Override
getRemoteName(BluetoothDevice device)1573         public String getRemoteName(BluetoothDevice device) {
1574             AdapterService service = getService();
1575             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteName")) {
1576                 return null;
1577             }
1578 
1579             enforceBluetoothPermission(service);
1580 
1581             return service.getRemoteName(device);
1582         }
1583 
1584         @Override
getRemoteType(BluetoothDevice device)1585         public int getRemoteType(BluetoothDevice device) {
1586             AdapterService service = getService();
1587             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteType")) {
1588                 return BluetoothDevice.DEVICE_TYPE_UNKNOWN;
1589             }
1590 
1591             enforceBluetoothPermission(service);
1592 
1593             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1594             return deviceProp != null ? deviceProp.getDeviceType() : BluetoothDevice.DEVICE_TYPE_UNKNOWN;
1595         }
1596 
1597         @Override
getRemoteAlias(BluetoothDevice device)1598         public String getRemoteAlias(BluetoothDevice device) {
1599             AdapterService service = getService();
1600             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteAlias")) {
1601                 return null;
1602             }
1603 
1604             enforceBluetoothPermission(service);
1605 
1606             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1607             return deviceProp != null ? deviceProp.getAlias() : null;
1608         }
1609 
1610         @Override
setRemoteAlias(BluetoothDevice device, String name)1611         public boolean setRemoteAlias(BluetoothDevice device, String name) {
1612             AdapterService service = getService();
1613             if (service == null || !callerIsSystemOrActiveUser(TAG, "setRemoteAlias")) {
1614                 return false;
1615             }
1616 
1617             enforceBluetoothPermission(service);
1618 
1619             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1620             if (deviceProp == null) {
1621                 return false;
1622             }
1623             deviceProp.setAlias(device, name);
1624             return true;
1625         }
1626 
1627         @Override
getRemoteClass(BluetoothDevice device)1628         public int getRemoteClass(BluetoothDevice device) {
1629             AdapterService service = getService();
1630             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteClass")) {
1631                 return 0;
1632             }
1633 
1634             enforceBluetoothPermission(service);
1635 
1636             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1637             return deviceProp != null ? deviceProp.getBluetoothClass() : 0;
1638         }
1639 
1640         @Override
getRemoteUuids(BluetoothDevice device)1641         public ParcelUuid[] getRemoteUuids(BluetoothDevice device) {
1642             AdapterService service = getService();
1643             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteUuids")) {
1644                 return new ParcelUuid[0];
1645             }
1646 
1647             enforceBluetoothPermission(service);
1648 
1649             return service.getRemoteUuids(device);
1650         }
1651 
1652         @Override
fetchRemoteUuids(BluetoothDevice device)1653         public boolean fetchRemoteUuids(BluetoothDevice device) {
1654             AdapterService service = getService();
1655             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "fetchRemoteUuids")) {
1656                 return false;
1657             }
1658 
1659             enforceBluetoothPermission(service);
1660 
1661             service.mRemoteDevices.fetchUuids(device);
1662             return true;
1663         }
1664 
1665 
1666         @Override
setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode)1667         public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) {
1668             AdapterService service = getService();
1669             if (service == null || !callerIsSystemOrActiveUser(TAG, "setPin")) {
1670                 return false;
1671             }
1672 
1673             enforceBluetoothAdminPermission(service);
1674 
1675             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1676             // Only allow setting a pin in bonding state, or bonded state in case of security upgrade.
1677             if (deviceProp == null || !deviceProp.isBondingOrBonded()) {
1678                 return false;
1679             }
1680             if (pinCode.length != len) {
1681                 android.util.EventLog.writeEvent(0x534e4554, "139287605", -1,
1682                         "PIN code length mismatch");
1683                 return false;
1684             }
1685             service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_PIN_REPLIED);
1686             return service.pinReplyNative(addressToBytes(device.getAddress()), accept, len, pinCode);
1687         }
1688 
1689         @Override
setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey)1690         public boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) {
1691             AdapterService service = getService();
1692             if (service == null || !callerIsSystemOrActiveUser(TAG, "setPasskey")) {
1693                 return false;
1694             }
1695 
1696             enforceBluetoothPermission(service);
1697 
1698             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1699             if (deviceProp == null || !deviceProp.isBonding()) {
1700                 return false;
1701             }
1702             if (passkey.length != len) {
1703                 android.util.EventLog.writeEvent(0x534e4554, "139287605", -1,
1704                         "Passkey length mismatch");
1705                 return false;
1706             }
1707             service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REPLIED);
1708             return service.sspReplyNative(
1709                     addressToBytes(device.getAddress()),
1710                     AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY,
1711                     accept,
1712                     Utils.byteArrayToInt(passkey));
1713         }
1714 
1715         @Override
setPairingConfirmation(BluetoothDevice device, boolean accept)1716         public boolean setPairingConfirmation(BluetoothDevice device, boolean accept) {
1717             AdapterService service = getService();
1718             if (service == null || !callerIsSystemOrActiveUser(TAG, "setPairingConfirmation")) {
1719                 return false;
1720             }
1721 
1722             enforceBluetoothPrivilegedPermission(service);
1723 
1724             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1725             if (deviceProp == null || !deviceProp.isBonding()) {
1726                 return false;
1727             }
1728             service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REPLIED);
1729             return service.sspReplyNative(
1730                     addressToBytes(device.getAddress()),
1731                     AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION,
1732                     accept,
1733                     0);
1734         }
1735 
1736         @Override
getSilenceMode(BluetoothDevice device)1737         public boolean getSilenceMode(BluetoothDevice device) {
1738             AdapterService service = getService();
1739             if (service == null || !callerIsSystemOrActiveUser(TAG, "getSilenceMode")) {
1740                 return false;
1741             }
1742 
1743             enforceBluetoothPrivilegedPermission(service);
1744 
1745             return service.mSilenceDeviceManager.getSilenceMode(device);
1746         }
1747 
1748 
1749         @Override
setSilenceMode(BluetoothDevice device, boolean silence)1750         public boolean setSilenceMode(BluetoothDevice device, boolean silence) {
1751             AdapterService service = getService();
1752             if (service == null || !callerIsSystemOrActiveUser(TAG, "setSilenceMode")) {
1753                 return false;
1754             }
1755 
1756             enforceBluetoothPrivilegedPermission(service);
1757 
1758             service.mSilenceDeviceManager.setSilenceMode(device, silence);
1759             return true;
1760         }
1761 
1762         @Override
getPhonebookAccessPermission(BluetoothDevice device)1763         public int getPhonebookAccessPermission(BluetoothDevice device) {
1764             AdapterService service = getService();
1765             if (service == null || !callerIsSystemOrActiveUser(TAG, "getPhonebookAccessPermission")) {
1766                 return BluetoothDevice.ACCESS_UNKNOWN;
1767             }
1768 
1769             enforceBluetoothPermission(service);
1770 
1771             return service.getDeviceAccessFromPrefs(device, PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE);
1772         }
1773 
1774         @Override
setPhonebookAccessPermission(BluetoothDevice device, int value)1775         public boolean setPhonebookAccessPermission(BluetoothDevice device, int value) {
1776             AdapterService service = getService();
1777             if (service == null || !callerIsSystemOrActiveUser(TAG, "setPhonebookAccessPermission")) {
1778                 return false;
1779             }
1780 
1781             enforceBluetoothPrivilegedPermission(service);
1782 
1783             service.setPhonebookAccessPermission(device, value);
1784             return true;
1785         }
1786 
1787         @Override
getMessageAccessPermission(BluetoothDevice device)1788         public int getMessageAccessPermission(BluetoothDevice device) {
1789             AdapterService service = getService();
1790             if (service == null || !callerIsSystemOrActiveUser(TAG, "getMessageAccessPermission")) {
1791                 return BluetoothDevice.ACCESS_UNKNOWN;
1792             }
1793 
1794             enforceBluetoothPermission(service);
1795 
1796             return service.getDeviceAccessFromPrefs(device, MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE);
1797         }
1798 
1799         @Override
setMessageAccessPermission(BluetoothDevice device, int value)1800         public boolean setMessageAccessPermission(BluetoothDevice device, int value) {
1801             AdapterService service = getService();
1802             if (service == null || !callerIsSystemOrActiveUser(TAG, "setMessageAccessPermission")) {
1803                 return false;
1804             }
1805 
1806             enforceBluetoothPrivilegedPermission(service);
1807 
1808             service.setMessageAccessPermission(device, value);
1809             return true;
1810         }
1811 
1812         @Override
getSimAccessPermission(BluetoothDevice device)1813         public int getSimAccessPermission(BluetoothDevice device) {
1814             AdapterService service = getService();
1815             if (service == null || !callerIsSystemOrActiveUser(TAG, "getSimAccessPermission")) {
1816                 return BluetoothDevice.ACCESS_UNKNOWN;
1817             }
1818 
1819             enforceBluetoothPermission(service);
1820 
1821             return service.getDeviceAccessFromPrefs(device, SIM_ACCESS_PERMISSION_PREFERENCE_FILE);
1822         }
1823 
1824         @Override
setSimAccessPermission(BluetoothDevice device, int value)1825         public boolean setSimAccessPermission(BluetoothDevice device, int value) {
1826             AdapterService service = getService();
1827             if (service == null || !callerIsSystemOrActiveUser(TAG, "setSimAccessPermission")) {
1828                 return false;
1829             }
1830 
1831             enforceBluetoothPrivilegedPermission(service);
1832 
1833             service.setSimAccessPermission(device, value);
1834             return true;
1835         }
1836 
1837         @Override
getSocketManager()1838         public IBluetoothSocketManager getSocketManager() {
1839             AdapterService service = getService();
1840             if (service == null) {
1841                 return null;
1842             }
1843 
1844             return IBluetoothSocketManager.Stub.asInterface(service.mBluetoothSocketManagerBinder);
1845         }
1846 
1847         @Override
sdpSearch(BluetoothDevice device, ParcelUuid uuid)1848         public boolean sdpSearch(BluetoothDevice device, ParcelUuid uuid) {
1849             AdapterService service = getService();
1850             if (service == null || !callerIsSystemOrActiveUser(TAG, "sdpSearch")) {
1851                 return false;
1852             }
1853 
1854             enforceBluetoothPermission(service);
1855 
1856             if (service.mSdpManager == null) {
1857                 return false;
1858             }
1859             service.mSdpManager.sdpSearch(device, uuid);
1860             return true;
1861         }
1862 
1863         @Override
getBatteryLevel(BluetoothDevice device)1864         public int getBatteryLevel(BluetoothDevice device) {
1865             AdapterService service = getService();
1866             if (service == null || !callerIsSystemOrActiveUser(TAG, "getBatteryLevel")) {
1867                 return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
1868             }
1869 
1870             enforceBluetoothPermission(service);
1871 
1872             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1873             if (deviceProp == null) {
1874                 return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
1875             }
1876             return deviceProp.getBatteryLevel();
1877         }
1878 
1879         @Override
getMaxConnectedAudioDevices()1880         public int getMaxConnectedAudioDevices() {
1881             // don't check caller, may be called from system UI
1882             AdapterService service = getService();
1883             if (service == null) {
1884                 return AdapterProperties.MAX_CONNECTED_AUDIO_DEVICES_LOWER_BOND;
1885             }
1886 
1887             enforceBluetoothPermission(service);
1888 
1889             return service.getMaxConnectedAudioDevices();
1890         }
1891 
1892         //@Override
isA2dpOffloadEnabled()1893         public boolean isA2dpOffloadEnabled() {
1894             // don't check caller, may be called from system UI
1895             AdapterService service = getService();
1896             if (service == null) {
1897                 return false;
1898             }
1899 
1900             enforceBluetoothPermission(service);
1901 
1902             return service.isA2dpOffloadEnabled();
1903         }
1904 
1905         @Override
factoryReset()1906         public boolean factoryReset() {
1907             AdapterService service = getService();
1908             if (service == null) {
1909                 return false;
1910             }
1911 
1912             enforceBluetoothPrivilegedPermission(service);
1913 
1914             if (service.mDatabaseManager != null) {
1915                 service.mDatabaseManager.factoryReset();
1916             }
1917 
1918             if (service.mBluetoothKeystoreService != null) {
1919                 service.mBluetoothKeystoreService.factoryReset();
1920             }
1921 
1922             return service.factoryResetNative();
1923         }
1924 
1925         @Override
registerCallback(IBluetoothCallback callback)1926         public void registerCallback(IBluetoothCallback callback) {
1927             AdapterService service = getService();
1928             if (service == null || !callerIsSystemOrActiveUser(TAG, "registerCallback")) {
1929                 return;
1930             }
1931 
1932             enforceBluetoothPrivilegedPermission(service);
1933 
1934             service.mCallbacks.register(callback);
1935         }
1936 
1937         @Override
unregisterCallback(IBluetoothCallback callback)1938         public void unregisterCallback(IBluetoothCallback callback) {
1939             AdapterService service = getService();
1940             if (service == null || service.mCallbacks == null
1941                     || !callerIsSystemOrActiveUser(TAG, "unregisterCallback")) {
1942                 return;
1943             }
1944 
1945             enforceBluetoothPrivilegedPermission(service);
1946 
1947             service.mCallbacks.unregister(callback);
1948         }
1949 
1950         @Override
isMultiAdvertisementSupported()1951         public boolean isMultiAdvertisementSupported() {
1952             AdapterService service = getService();
1953             if (service == null) {
1954                 return false;
1955             }
1956 
1957             enforceBluetoothPermission(service);
1958 
1959             int val = service.mAdapterProperties.getNumOfAdvertisementInstancesSupported();
1960             return val >= MIN_ADVT_INSTANCES_FOR_MA;
1961         }
1962 
1963         /**
1964          * This method has an associated binder cache.  The invalidation
1965          * methods must be changed if the logic behind this method changes.
1966          */
1967         @Override
isOffloadedFilteringSupported()1968         public boolean isOffloadedFilteringSupported() {
1969             AdapterService service = getService();
1970             if (service == null) {
1971                 return false;
1972             }
1973 
1974             enforceBluetoothPermission(service);
1975 
1976             int val = service.getNumOfOffloadedScanFilterSupported();
1977             return val >= MIN_OFFLOADED_FILTERS;
1978         }
1979 
1980         @Override
isOffloadedScanBatchingSupported()1981         public boolean isOffloadedScanBatchingSupported() {
1982             AdapterService service = getService();
1983             if (service == null) {
1984                 return false;
1985             }
1986 
1987             enforceBluetoothPermission(service);
1988 
1989             int val = service.getOffloadedScanResultStorage();
1990             return val >= MIN_OFFLOADED_SCAN_STORAGE_BYTES;
1991         }
1992 
1993         @Override
isLe2MPhySupported()1994         public boolean isLe2MPhySupported() {
1995             AdapterService service = getService();
1996             if (service == null) {
1997                 return false;
1998             }
1999 
2000             enforceBluetoothPermission(service);
2001 
2002             return service.isLe2MPhySupported();
2003         }
2004 
2005         @Override
isLeCodedPhySupported()2006         public boolean isLeCodedPhySupported() {
2007             AdapterService service = getService();
2008             if (service == null) {
2009                 return false;
2010             }
2011 
2012             enforceBluetoothPermission(service);
2013 
2014             return service.isLeCodedPhySupported();
2015         }
2016 
2017         @Override
isLeExtendedAdvertisingSupported()2018         public boolean isLeExtendedAdvertisingSupported() {
2019             AdapterService service = getService();
2020             if (service == null) {
2021                 return false;
2022             }
2023 
2024             enforceBluetoothPermission(service);
2025 
2026             return service.isLeExtendedAdvertisingSupported();
2027         }
2028 
2029         @Override
isLePeriodicAdvertisingSupported()2030         public boolean isLePeriodicAdvertisingSupported() {
2031             AdapterService service = getService();
2032             if (service == null) {
2033                 return false;
2034             }
2035 
2036             enforceBluetoothPermission(service);
2037 
2038             return service.isLePeriodicAdvertisingSupported();
2039         }
2040 
2041         @Override
getLeMaximumAdvertisingDataLength()2042         public int getLeMaximumAdvertisingDataLength() {
2043             AdapterService service = getService();
2044             if (service == null) {
2045                 return 0;
2046             }
2047 
2048             enforceBluetoothPermission(service);
2049 
2050             return service.getLeMaximumAdvertisingDataLength();
2051         }
2052 
2053         @Override
isActivityAndEnergyReportingSupported()2054         public boolean isActivityAndEnergyReportingSupported() {
2055             AdapterService service = getService();
2056             if (service == null) {
2057                 return false;
2058             }
2059 
2060             enforceBluetoothPrivilegedPermission(service);
2061 
2062             return service.mAdapterProperties.isActivityAndEnergyReportingSupported();
2063         }
2064 
2065         @Override
reportActivityInfo()2066         public BluetoothActivityEnergyInfo reportActivityInfo() {
2067             AdapterService service = getService();
2068             if (service == null) {
2069                 return null;
2070             }
2071 
2072             enforceBluetoothPrivilegedPermission(service);
2073 
2074             return service.reportActivityInfo();
2075         }
2076 
2077         @Override
registerMetadataListener(IBluetoothMetadataListener listener, BluetoothDevice device)2078         public boolean registerMetadataListener(IBluetoothMetadataListener listener,
2079                 BluetoothDevice device) {
2080             AdapterService service = getService();
2081             if (service == null || !callerIsSystemOrActiveUser(TAG, "registerMetadataListener")) {
2082                 return false;
2083             }
2084 
2085             enforceBluetoothPrivilegedPermission(service);
2086 
2087             if (service.mMetadataListeners == null) {
2088                 return false;
2089             }
2090             ArrayList<IBluetoothMetadataListener> list = service.mMetadataListeners.get(device);
2091             if (list == null) {
2092                 list = new ArrayList<>();
2093             } else if (list.contains(listener)) {
2094                 // The device is already registered with this listener
2095                 return true;
2096             }
2097             list.add(listener);
2098             service.mMetadataListeners.put(device, list);
2099             return true;
2100         }
2101 
2102         @Override
unregisterMetadataListener(BluetoothDevice device)2103         public boolean unregisterMetadataListener(BluetoothDevice device) {
2104             AdapterService service = getService();
2105             if (service == null
2106                     || !callerIsSystemOrActiveUser(TAG, "unregisterMetadataListener")) {
2107                 return false;
2108             }
2109 
2110             enforceBluetoothPrivilegedPermission(service);
2111 
2112             if (service.mMetadataListeners == null) {
2113                 return false;
2114             }
2115             if (service.mMetadataListeners.containsKey(device)) {
2116                 service.mMetadataListeners.remove(device);
2117             }
2118             return true;
2119         }
2120 
2121         @Override
setMetadata(BluetoothDevice device, int key, byte[] value)2122         public boolean setMetadata(BluetoothDevice device, int key, byte[] value) {
2123             AdapterService service = getService();
2124             if (service == null || !callerIsSystemOrActiveUser(TAG, "setMetadata")) {
2125                 return false;
2126             }
2127 
2128             enforceBluetoothPrivilegedPermission(service);
2129 
2130             if (value.length > BluetoothDevice.METADATA_MAX_LENGTH) {
2131                 return false;
2132             }
2133             return service.mDatabaseManager.setCustomMeta(device, key, value);
2134         }
2135 
2136         @Override
getMetadata(BluetoothDevice device, int key)2137         public byte[] getMetadata(BluetoothDevice device, int key) {
2138             AdapterService service = getService();
2139             if (service == null || !callerIsSystemOrActiveUser(TAG, "getMetadata")) {
2140                 return null;
2141             }
2142 
2143             enforceBluetoothPrivilegedPermission(service);
2144 
2145             return service.mDatabaseManager.getCustomMeta(device, key);
2146         }
2147 
2148         @Override
requestActivityInfo(ResultReceiver result)2149         public void requestActivityInfo(ResultReceiver result) {
2150             Bundle bundle = new Bundle();
2151             bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, reportActivityInfo());
2152             result.send(0, bundle);
2153         }
2154 
2155         @Override
onLeServiceUp()2156         public void onLeServiceUp() {
2157             AdapterService service = getService();
2158             if (service == null || !callerIsSystemOrActiveUser(TAG, "onLeServiceUp")) {
2159                 return;
2160             }
2161 
2162             enforceBluetoothPrivilegedPermission(service);
2163 
2164             service.mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
2165         }
2166 
2167         @Override
onBrEdrDown()2168         public void onBrEdrDown() {
2169             AdapterService service = getService();
2170             if (service == null || !callerIsSystemOrActiveUser(TAG, "onBrEdrDown")) {
2171                 return;
2172             }
2173 
2174             enforceBluetoothPrivilegedPermission(service);
2175 
2176             service.mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF);
2177         }
2178 
2179         @Override
dump(FileDescriptor fd, String[] args)2180         public void dump(FileDescriptor fd, String[] args) {
2181             PrintWriter writer = new PrintWriter(new FileOutputStream(fd));
2182             AdapterService service = getService();
2183             if (service == null) {
2184                 return;
2185             }
2186 
2187             enforceDumpPermission(service);
2188 
2189             service.dump(fd, writer, args);
2190             writer.close();
2191         }
2192     }
2193 
2194     // ----API Methods--------
2195 
getState()2196     public int getState() {
2197         if (mAdapterProperties != null) {
2198             return mAdapterProperties.getState();
2199         }
2200         return BluetoothAdapter.STATE_OFF;
2201     }
2202 
enable(boolean quietMode)2203     public synchronized boolean enable(boolean quietMode) {
2204         // Enforce the user restriction for disallowing Bluetooth if it was set.
2205         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) {
2206             debugLog("enable() called when Bluetooth was disallowed");
2207             return false;
2208         }
2209 
2210         debugLog("enable() - Enable called with quiet mode status =  " + quietMode);
2211         mQuietmode = quietMode;
2212         mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
2213         return true;
2214     }
2215 
disable()2216     boolean disable() {
2217         debugLog("disable() called with mRunningProfiles.size() = " + mRunningProfiles.size());
2218         mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_OFF);
2219         return true;
2220     }
2221 
getName()2222     public String getName() {
2223         return mAdapterProperties.getName();
2224     }
2225 
isValidIoCapability(int capability)2226     private static boolean isValidIoCapability(int capability) {
2227         if (capability < 0 || capability >= BluetoothAdapter.IO_CAPABILITY_MAX) {
2228             Log.e(TAG, "Invalid IO capability value - " + capability);
2229             return false;
2230         }
2231 
2232         return true;
2233     }
2234 
getDiscoveringPackages()2235     ArrayList<DiscoveringPackage> getDiscoveringPackages() {
2236         return mDiscoveringPackages;
2237     }
2238 
clearDiscoveringPackages()2239     void clearDiscoveringPackages() {
2240         synchronized (mDiscoveringPackages) {
2241             mDiscoveringPackages.clear();
2242         }
2243     }
2244 
startDiscovery(String callingPackage, @Nullable String callingFeatureId)2245     boolean startDiscovery(String callingPackage, @Nullable String callingFeatureId) {
2246         UserHandle callingUser = UserHandle.of(UserHandle.getCallingUserId());
2247         debugLog("startDiscovery");
2248         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2249         boolean isQApp = Utils.isQApp(this, callingPackage);
2250         String permission = null;
2251         if (Utils.checkCallerHasNetworkSettingsPermission(this)) {
2252             permission = android.Manifest.permission.NETWORK_SETTINGS;
2253         } else if (Utils.checkCallerHasNetworkSetupWizardPermission(this)) {
2254             permission = android.Manifest.permission.NETWORK_SETUP_WIZARD;
2255         } else if (isQApp) {
2256             if (!Utils.checkCallerHasFineLocation(this, mAppOps, callingPackage, callingFeatureId,
2257                     callingUser)) {
2258                 return false;
2259             }
2260             permission = android.Manifest.permission.ACCESS_FINE_LOCATION;
2261         } else {
2262             if (!Utils.checkCallerHasCoarseLocation(this, mAppOps, callingPackage, callingFeatureId,
2263                     callingUser)) {
2264                 return false;
2265             }
2266             permission = android.Manifest.permission.ACCESS_COARSE_LOCATION;
2267         }
2268 
2269         synchronized (mDiscoveringPackages) {
2270             mDiscoveringPackages.add(new DiscoveringPackage(callingPackage, permission));
2271         }
2272         return startDiscoveryNative();
2273     }
2274 
2275     /**
2276      * Same as API method {@link BluetoothAdapter#getBondedDevices()}
2277      *
2278      * @return array of bonded {@link BluetoothDevice} or null on error
2279      */
getBondedDevices()2280     public BluetoothDevice[] getBondedDevices() {
2281         return mAdapterProperties.getBondedDevices();
2282     }
2283 
2284     /**
2285      * Get the database manager to access Bluetooth storage
2286      *
2287      * @return {@link DatabaseManager} or null on error
2288      */
2289     @VisibleForTesting
getDatabase()2290     public DatabaseManager getDatabase() {
2291         return mDatabaseManager;
2292     }
2293 
createBond(BluetoothDevice device, int transport, OobData oobData)2294     boolean createBond(BluetoothDevice device, int transport, OobData oobData) {
2295         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
2296         if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {
2297             return false;
2298         }
2299 
2300         mRemoteDevices.setBondingInitiatedLocally(Utils.getByteAddress(device));
2301 
2302         // Pairing is unreliable while scanning, so cancel discovery
2303         // Note, remove this when native stack improves
2304         cancelDiscoveryNative();
2305 
2306         Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
2307         msg.obj = device;
2308         msg.arg1 = transport;
2309 
2310         if (oobData != null) {
2311             Bundle oobDataBundle = new Bundle();
2312             oobDataBundle.putParcelable(BondStateMachine.OOBDATA, oobData);
2313             msg.setData(oobDataBundle);
2314         }
2315         mBondStateMachine.sendMessage(msg);
2316         return true;
2317     }
2318 
isQuietModeEnabled()2319     public boolean isQuietModeEnabled() {
2320         debugLog("isQuetModeEnabled() - Enabled = " + mQuietmode);
2321         return mQuietmode;
2322     }
2323 
updateUuids()2324     public void updateUuids() {
2325         debugLog("updateUuids() - Updating UUIDs for bonded devices");
2326         BluetoothDevice[] bondedDevices = getBondedDevices();
2327         if (bondedDevices == null) {
2328             return;
2329         }
2330 
2331         for (BluetoothDevice device : bondedDevices) {
2332             mRemoteDevices.updateUuids(device);
2333         }
2334     }
2335 
2336     /**
2337      * Update device UUID changed to {@link BondStateMachine}
2338      *
2339      * @param device remote device of interest
2340      */
deviceUuidUpdated(BluetoothDevice device)2341     public void deviceUuidUpdated(BluetoothDevice device) {
2342         // Notify BondStateMachine for SDP complete / UUID changed.
2343         Message msg = mBondStateMachine.obtainMessage(BondStateMachine.UUID_UPDATE);
2344         msg.obj = device;
2345         mBondStateMachine.sendMessage(msg);
2346     }
2347 
2348     /**
2349      * Get the bond state of a particular {@link BluetoothDevice}
2350      *
2351      * @param device remote device of interest
2352      * @return bond state <p>Possible values are
2353      * {@link BluetoothDevice#BOND_NONE},
2354      * {@link BluetoothDevice#BOND_BONDING},
2355      * {@link BluetoothDevice#BOND_BONDED}.
2356      */
2357     @VisibleForTesting
getBondState(BluetoothDevice device)2358     public int getBondState(BluetoothDevice device) {
2359         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
2360         if (deviceProp == null) {
2361             return BluetoothDevice.BOND_NONE;
2362         }
2363         return deviceProp.getBondState();
2364     }
2365 
getConnectionState(BluetoothDevice device)2366     int getConnectionState(BluetoothDevice device) {
2367         return getConnectionStateNative(addressToBytes(device.getAddress()));
2368     }
2369 
2370     /**
2371      * Sets device as the active devices for the profiles passed into the function
2372      *
2373      * @param device is the remote bluetooth device
2374      * @param profiles is a constant that references for which profiles we'll be setting the remote
2375      *                 device as our active device. One of the following:
2376      *                 {@link BluetoothAdapter#ACTIVE_DEVICE_AUDIO},
2377      *                 {@link BluetoothAdapter#ACTIVE_DEVICE_PHONE_CALL}
2378      *                 {@link BluetoothAdapter#ACTIVE_DEVICE_ALL}
2379      * @return false if profiles value is not one of the constants we accept, true otherwise
2380      */
setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles)2381     public boolean setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles) {
2382         enforceCallingOrSelfPermission(
2383                 BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
2384 
2385         boolean setA2dp = false;
2386         boolean setHeadset = false;
2387 
2388         // Determine for which profiles we want to set device as our active device
2389         switch(profiles) {
2390             case BluetoothAdapter.ACTIVE_DEVICE_AUDIO:
2391                 setA2dp = true;
2392                 break;
2393             case BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL:
2394                 setHeadset = true;
2395                 break;
2396             case BluetoothAdapter.ACTIVE_DEVICE_ALL:
2397                 setA2dp = true;
2398                 setHeadset = true;
2399                 break;
2400             default:
2401                 return false;
2402         }
2403 
2404         if (setA2dp && mA2dpService != null && (device == null
2405                 || mA2dpService.getConnectionPolicy(device)
2406                 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
2407             Log.i(TAG, "setActiveDevice: Setting active A2dp device " + device);
2408             mA2dpService.setActiveDevice(device);
2409         }
2410 
2411         if (mHearingAidService != null && (device == null
2412                 || mHearingAidService.getConnectionPolicy(device)
2413                 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
2414             Log.i(TAG, "setActiveDevice: Setting active Hearing Aid " + device);
2415             mHearingAidService.setActiveDevice(device);
2416         }
2417 
2418         if (setHeadset && mHeadsetService != null && (device == null
2419                 || mHeadsetService.getConnectionPolicy(device)
2420                 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
2421             Log.i(TAG, "setActiveDevice: Setting active Headset " + device);
2422             mHeadsetService.setActiveDevice(device);
2423         }
2424 
2425         return true;
2426     }
2427 
2428     /**
2429      * Connects all enabled and supported bluetooth profiles between the local and remote device
2430      *
2431      * @param device is the remote device with which to connect these profiles
2432      * @return true if all profiles successfully connected, false if an error occurred
2433      */
connectAllEnabledProfiles(BluetoothDevice device)2434     public boolean connectAllEnabledProfiles(BluetoothDevice device) {
2435         if (!profileServicesRunning()) {
2436             Log.e(TAG, "connectAllEnabledProfiles: Not all profile services running");
2437             return false;
2438         }
2439 
2440         // Checks if any profiles are enabled and if so, only connect enabled profiles
2441         if (isAnyProfileEnabled(device)) {
2442             return connectEnabledProfiles(device);
2443         }
2444 
2445         int numProfilesConnected = 0;
2446         ParcelUuid[] remoteDeviceUuids = getRemoteUuids(device);
2447         ParcelUuid[] localDeviceUuids = mAdapterProperties.getUuids();
2448 
2449         // All profile toggles disabled, so connects all supported profiles
2450         if (mA2dpService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2451                 BluetoothProfile.A2DP, device)) {
2452             Log.i(TAG, "connectAllEnabledProfiles: Connecting A2dp");
2453             // Set connection policy also connects the profile with CONNECTION_POLICY_ALLOWED
2454             mA2dpService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2455             numProfilesConnected++;
2456         }
2457         if (mA2dpSinkService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2458                 BluetoothProfile.A2DP_SINK, device)) {
2459             Log.i(TAG, "connectAllEnabledProfiles: Connecting A2dp Sink");
2460             mA2dpSinkService.setConnectionPolicy(device,
2461                     BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2462             numProfilesConnected++;
2463         }
2464         if (mHeadsetService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2465                 BluetoothProfile.HEADSET, device)) {
2466             Log.i(TAG, "connectAllEnabledProfiles: Connecting Headset Profile");
2467             mHeadsetService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2468             numProfilesConnected++;
2469         }
2470         if (mHeadsetClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2471                 BluetoothProfile.HEADSET_CLIENT, device)) {
2472             Log.i(TAG, "connectAllEnabledProfiles: Connecting HFP");
2473             mHeadsetClientService.setConnectionPolicy(device,
2474                     BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2475             numProfilesConnected++;
2476         }
2477         if (mMapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2478                 BluetoothProfile.MAP_CLIENT, device)) {
2479             Log.i(TAG, "connectAllEnabledProfiles: Connecting MAP");
2480             mMapClientService.setConnectionPolicy(device,
2481                     BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2482             numProfilesConnected++;
2483         }
2484         if (mHidHostService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2485                 BluetoothProfile.HID_HOST, device)) {
2486             Log.i(TAG, "connectAllEnabledProfiles: Connecting Hid Host Profile");
2487             mHidHostService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2488             numProfilesConnected++;
2489         }
2490         if (mPanService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2491                 BluetoothProfile.PAN, device)) {
2492             Log.i(TAG, "connectAllEnabledProfiles: Connecting Pan Profile");
2493             mPanService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2494             numProfilesConnected++;
2495         }
2496         if (mPbapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2497                 BluetoothProfile.PBAP_CLIENT, device)) {
2498             Log.i(TAG, "connectAllEnabledProfiles: Connecting Pbap");
2499             mPbapClientService.setConnectionPolicy(device,
2500                     BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2501             numProfilesConnected++;
2502         }
2503         if (mHearingAidService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2504                 BluetoothProfile.HEARING_AID, device)) {
2505             Log.i(TAG, "connectAllEnabledProfiles: Connecting Hearing Aid Profile");
2506             mHearingAidService.setConnectionPolicy(device,
2507                     BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2508             numProfilesConnected++;
2509         }
2510 
2511         Log.i(TAG, "connectAllEnabledProfiles: Number of Profiles Connected: "
2512                 + numProfilesConnected);
2513 
2514         return true;
2515     }
2516 
2517     /**
2518      * Disconnects all enabled and supported bluetooth profiles between the local and remote device
2519      *
2520      * @param device is the remote device with which to disconnect these profiles
2521      * @return true if all profiles successfully disconnected, false if an error occurred
2522      */
disconnectAllEnabledProfiles(BluetoothDevice device)2523     public boolean disconnectAllEnabledProfiles(BluetoothDevice device) {
2524         if (!profileServicesRunning()) {
2525             Log.e(TAG, "disconnectAllEnabledProfiles: Not all profile services bound");
2526             return false;
2527         }
2528 
2529         if (mA2dpService != null && mA2dpService.getConnectionState(device)
2530                 == BluetoothProfile.STATE_CONNECTED) {
2531             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp");
2532             mA2dpService.disconnect(device);
2533         }
2534         if (mA2dpSinkService != null && mA2dpSinkService.getConnectionState(device)
2535                 == BluetoothProfile.STATE_CONNECTED) {
2536             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp Sink");
2537             mA2dpSinkService.disconnect(device);
2538         }
2539         if (mHeadsetService != null && mHeadsetService.getConnectionState(device)
2540                 == BluetoothProfile.STATE_CONNECTED) {
2541             Log.i(TAG,
2542                     "disconnectAllEnabledProfiles: Disconnecting Headset Profile");
2543             mHeadsetService.disconnect(device);
2544         }
2545         if (mHeadsetClientService != null && mHeadsetClientService.getConnectionState(device)
2546                 == BluetoothProfile.STATE_CONNECTED) {
2547             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting HFP");
2548             mHeadsetClientService.disconnect(device);
2549         }
2550         if (mMapClientService != null && mMapClientService.getConnectionState(device)
2551                 == BluetoothProfile.STATE_CONNECTED) {
2552             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting MAP Client");
2553             mMapClientService.disconnect(device);
2554         }
2555         if (mMapService != null && mMapService.getConnectionState(device)
2556                 == BluetoothProfile.STATE_CONNECTED) {
2557             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting MAP");
2558             mMapService.disconnect(device);
2559         }
2560         if (mHidDeviceService != null && mHidDeviceService.getConnectionState(device)
2561                 == BluetoothProfile.STATE_CONNECTED) {
2562             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hid Device Profile");
2563             mHidDeviceService.disconnect(device);
2564         }
2565         if (mHidHostService != null && mHidHostService.getConnectionState(device)
2566                 == BluetoothProfile.STATE_CONNECTED) {
2567             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hid Host Profile");
2568             mHidHostService.disconnect(device);
2569         }
2570         if (mPanService != null && mPanService.getConnectionState(device)
2571                 == BluetoothProfile.STATE_CONNECTED) {
2572             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pan Profile");
2573             mPanService.disconnect(device);
2574         }
2575         if (mPbapClientService != null && mPbapClientService.getConnectionState(device)
2576                 == BluetoothProfile.STATE_CONNECTED) {
2577             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pbap Client");
2578             mPbapClientService.disconnect(device);
2579         }
2580         if (mPbapService != null && mPbapService.getConnectionState(device)
2581                 == BluetoothProfile.STATE_CONNECTED) {
2582             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pbap Server");
2583             mPbapService.disconnect(device);
2584         }
2585         if (mHearingAidService != null && mHearingAidService.getConnectionState(device)
2586                 == BluetoothProfile.STATE_CONNECTED) {
2587             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hearing Aid Profile");
2588             mHearingAidService.disconnect(device);
2589         }
2590 
2591         return true;
2592     }
2593 
2594     /**
2595      * Same as API method {@link BluetoothDevice#getName()}
2596      *
2597      * @param device remote device of interest
2598      * @return remote device name
2599      */
getRemoteName(BluetoothDevice device)2600     public String getRemoteName(BluetoothDevice device) {
2601         if (mRemoteDevices == null) {
2602             return null;
2603         }
2604         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
2605         if (deviceProp == null) {
2606             return null;
2607         }
2608         return deviceProp.getName();
2609     }
2610 
2611     /**
2612      * Get UUIDs for service supported by a remote device
2613      *
2614      * @param device the remote device that we want to get UUIDs from
2615      * @return
2616      */
2617     @VisibleForTesting
getRemoteUuids(BluetoothDevice device)2618     public ParcelUuid[] getRemoteUuids(BluetoothDevice device) {
2619         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
2620         if (deviceProp == null) {
2621             return null;
2622         }
2623         return deviceProp.getUuids();
2624     }
2625 
logUserBondResponse(BluetoothDevice device, boolean accepted, int event)2626     void logUserBondResponse(BluetoothDevice device, boolean accepted, int event) {
2627         BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
2628                 obfuscateAddress(device), 0, device.getType(),
2629                 BluetoothDevice.BOND_BONDING,
2630                 event,
2631                 accepted ? 0 : BluetoothDevice.UNBOND_REASON_AUTH_REJECTED);
2632     }
2633 
getDeviceAccessFromPrefs(BluetoothDevice device, String prefFile)2634     int getDeviceAccessFromPrefs(BluetoothDevice device, String prefFile) {
2635         SharedPreferences prefs = getSharedPreferences(prefFile, Context.MODE_PRIVATE);
2636         if (!prefs.contains(device.getAddress())) {
2637             return BluetoothDevice.ACCESS_UNKNOWN;
2638         }
2639         return prefs.getBoolean(device.getAddress(), false)
2640                 ? BluetoothDevice.ACCESS_ALLOWED
2641                 : BluetoothDevice.ACCESS_REJECTED;
2642     }
2643 
setDeviceAccessFromPrefs(BluetoothDevice device, int value, String prefFile)2644     void setDeviceAccessFromPrefs(BluetoothDevice device, int value, String prefFile) {
2645         SharedPreferences pref = getSharedPreferences(prefFile, Context.MODE_PRIVATE);
2646         SharedPreferences.Editor editor = pref.edit();
2647         if (value == BluetoothDevice.ACCESS_UNKNOWN) {
2648             editor.remove(device.getAddress());
2649         } else {
2650             editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED);
2651         }
2652         editor.apply();
2653     }
2654 
setPhonebookAccessPermission(BluetoothDevice device, int value)2655     void setPhonebookAccessPermission(BluetoothDevice device, int value) {
2656         setDeviceAccessFromPrefs(device, value, PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE);
2657     }
2658 
setMessageAccessPermission(BluetoothDevice device, int value)2659     void setMessageAccessPermission(BluetoothDevice device, int value) {
2660         setDeviceAccessFromPrefs(device, value, MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE);
2661     }
2662 
setSimAccessPermission(BluetoothDevice device, int value)2663     void setSimAccessPermission(BluetoothDevice device, int value) {
2664         setDeviceAccessFromPrefs(device, value, SIM_ACCESS_PERMISSION_PREFERENCE_FILE);
2665     }
2666 
isRpaOffloadSupported()2667     public boolean isRpaOffloadSupported() {
2668         enforceBluetoothPermission(this);
2669         return mAdapterProperties.isRpaOffloadSupported();
2670     }
2671 
getNumOfOffloadedIrkSupported()2672     public int getNumOfOffloadedIrkSupported() {
2673         enforceBluetoothPermission(this);
2674         return mAdapterProperties.getNumOfOffloadedIrkSupported();
2675     }
2676 
getNumOfOffloadedScanFilterSupported()2677     public int getNumOfOffloadedScanFilterSupported() {
2678         return mAdapterProperties.getNumOfOffloadedScanFilterSupported();
2679     }
2680 
getOffloadedScanResultStorage()2681     public int getOffloadedScanResultStorage() {
2682         return mAdapterProperties.getOffloadedScanResultStorage();
2683     }
2684 
isLe2MPhySupported()2685     public boolean isLe2MPhySupported() {
2686         return mAdapterProperties.isLe2MPhySupported();
2687     }
2688 
isLeCodedPhySupported()2689     public boolean isLeCodedPhySupported() {
2690         return mAdapterProperties.isLeCodedPhySupported();
2691     }
2692 
isLeExtendedAdvertisingSupported()2693     public boolean isLeExtendedAdvertisingSupported() {
2694         return mAdapterProperties.isLeExtendedAdvertisingSupported();
2695     }
2696 
isLePeriodicAdvertisingSupported()2697     public boolean isLePeriodicAdvertisingSupported() {
2698         return mAdapterProperties.isLePeriodicAdvertisingSupported();
2699     }
2700 
getLeMaximumAdvertisingDataLength()2701     public int getLeMaximumAdvertisingDataLength() {
2702         return mAdapterProperties.getLeMaximumAdvertisingDataLength();
2703     }
2704 
2705     /**
2706      * Get the maximum number of connected audio devices.
2707      *
2708      * @return the maximum number of connected audio devices
2709      */
getMaxConnectedAudioDevices()2710     public int getMaxConnectedAudioDevices() {
2711         return mAdapterProperties.getMaxConnectedAudioDevices();
2712     }
2713 
2714     /**
2715      * Check whether A2DP offload is enabled.
2716      *
2717      * @return true if A2DP offload is enabled
2718      */
isA2dpOffloadEnabled()2719     public boolean isA2dpOffloadEnabled() {
2720         return mAdapterProperties.isA2dpOffloadEnabled();
2721     }
2722 
reportActivityInfo()2723     private BluetoothActivityEnergyInfo reportActivityInfo() {
2724         if (mAdapterProperties.getState() != BluetoothAdapter.STATE_ON
2725                 || !mAdapterProperties.isActivityAndEnergyReportingSupported()) {
2726             return null;
2727         }
2728 
2729         // Pull the data. The callback will notify mEnergyInfoLock.
2730         readEnergyInfo();
2731 
2732         synchronized (mEnergyInfoLock) {
2733             try {
2734                 mEnergyInfoLock.wait(CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS);
2735             } catch (InterruptedException e) {
2736                 // Just continue, the energy data may be stale but we won't miss anything next time
2737                 // we query.
2738             }
2739 
2740             final BluetoothActivityEnergyInfo info =
2741                     new BluetoothActivityEnergyInfo(SystemClock.elapsedRealtime(),
2742                             mStackReportedState, mTxTimeTotalMs, mRxTimeTotalMs, mIdleTimeTotalMs,
2743                             mEnergyUsedTotalVoltAmpSecMicro);
2744 
2745             // Count the number of entries that have byte counts > 0
2746             int arrayLen = 0;
2747             for (int i = 0; i < mUidTraffic.size(); i++) {
2748                 final UidTraffic traffic = mUidTraffic.valueAt(i);
2749                 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) {
2750                     arrayLen++;
2751                 }
2752             }
2753 
2754             // Copy the traffic objects whose byte counts are > 0
2755             final UidTraffic[] result = arrayLen > 0 ? new UidTraffic[arrayLen] : null;
2756             int putIdx = 0;
2757             for (int i = 0; i < mUidTraffic.size(); i++) {
2758                 final UidTraffic traffic = mUidTraffic.valueAt(i);
2759                 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) {
2760                     result[putIdx++] = traffic.clone();
2761                 }
2762             }
2763 
2764             info.setUidTraffic(result);
2765 
2766             return info;
2767         }
2768     }
2769 
getTotalNumOfTrackableAdvertisements()2770     public int getTotalNumOfTrackableAdvertisements() {
2771         enforceBluetoothPermission(this);
2772         return mAdapterProperties.getTotalNumOfTrackableAdvertisements();
2773     }
2774 
convertScanModeToHal(int mode)2775     private static int convertScanModeToHal(int mode) {
2776         switch (mode) {
2777             case BluetoothAdapter.SCAN_MODE_NONE:
2778                 return AbstractionLayer.BT_SCAN_MODE_NONE;
2779             case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
2780                 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE;
2781             case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
2782                 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
2783         }
2784         // errorLog("Incorrect scan mode in convertScanModeToHal");
2785         return -1;
2786     }
2787 
convertScanModeFromHal(int mode)2788     static int convertScanModeFromHal(int mode) {
2789         switch (mode) {
2790             case AbstractionLayer.BT_SCAN_MODE_NONE:
2791                 return BluetoothAdapter.SCAN_MODE_NONE;
2792             case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE:
2793                 return BluetoothAdapter.SCAN_MODE_CONNECTABLE;
2794             case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
2795                 return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
2796         }
2797         //errorLog("Incorrect scan mode in convertScanModeFromHal");
2798         return -1;
2799     }
2800 
2801     // This function is called from JNI. It allows native code to set a single wake
2802     // alarm. If an alarm is already pending and a new request comes in, the alarm
2803     // will be rescheduled (i.e. the previously set alarm will be cancelled).
setWakeAlarm(long delayMillis, boolean shouldWake)2804     private boolean setWakeAlarm(long delayMillis, boolean shouldWake) {
2805         synchronized (this) {
2806             if (mPendingAlarm != null) {
2807                 mAlarmManager.cancel(mPendingAlarm);
2808             }
2809 
2810             long wakeupTime = SystemClock.elapsedRealtime() + delayMillis;
2811             int type = shouldWake ? AlarmManager.ELAPSED_REALTIME_WAKEUP
2812                     : AlarmManager.ELAPSED_REALTIME;
2813 
2814             Intent intent = new Intent(ACTION_ALARM_WAKEUP);
2815             mPendingAlarm =
2816                     PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
2817             mAlarmManager.setExact(type, wakeupTime, mPendingAlarm);
2818             return true;
2819         }
2820     }
2821 
2822     // This function is called from JNI. It allows native code to acquire a single wake lock.
2823     // If the wake lock is already held, this function returns success. Although this function
2824     // only supports acquiring a single wake lock at a time right now, it will eventually be
2825     // extended to allow acquiring an arbitrary number of wake locks. The current interface
2826     // takes |lockName| as a parameter in anticipation of that implementation.
acquireWakeLock(String lockName)2827     private boolean acquireWakeLock(String lockName) {
2828         synchronized (this) {
2829             if (mWakeLock == null) {
2830                 mWakeLockName = lockName;
2831                 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName);
2832             }
2833 
2834             if (!mWakeLock.isHeld()) {
2835                 mWakeLock.acquire();
2836             }
2837         }
2838         return true;
2839     }
2840 
2841     // This function is called from JNI. It allows native code to release a wake lock acquired
2842     // by |acquireWakeLock|. If the wake lock is not held, this function returns failure.
2843     // Note that the release() call is also invoked by {@link #cleanup()} so a synchronization is
2844     // needed here. See the comment for |acquireWakeLock| for an explanation of the interface.
releaseWakeLock(String lockName)2845     private boolean releaseWakeLock(String lockName) {
2846         synchronized (this) {
2847             if (mWakeLock == null) {
2848                 errorLog("Repeated wake lock release; aborting release: " + lockName);
2849                 return false;
2850             }
2851 
2852             if (mWakeLock.isHeld()) {
2853                 mWakeLock.release();
2854             }
2855         }
2856         return true;
2857     }
2858 
energyInfoCallback(int status, int ctrlState, long txTime, long rxTime, long idleTime, long energyUsed, UidTraffic[] data)2859     private void energyInfoCallback(int status, int ctrlState, long txTime, long rxTime,
2860             long idleTime, long energyUsed, UidTraffic[] data) throws RemoteException {
2861         if (ctrlState >= BluetoothActivityEnergyInfo.BT_STACK_STATE_INVALID
2862                 && ctrlState <= BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_IDLE) {
2863             // Energy is product of mA, V and ms. If the chipset doesn't
2864             // report it, we have to compute it from time
2865             if (energyUsed == 0) {
2866                 try {
2867                     final long txMah = Math.multiplyExact(txTime, getTxCurrentMa());
2868                     final long rxMah = Math.multiplyExact(rxTime, getRxCurrentMa());
2869                     final long idleMah = Math.multiplyExact(idleTime, getIdleCurrentMa());
2870                     energyUsed = (long) (Math.addExact(Math.addExact(txMah, rxMah), idleMah)
2871                             * getOperatingVolt());
2872                 } catch (ArithmeticException e) {
2873                     Log.wtf(TAG, "overflow in bluetooth energy callback", e);
2874                     // Energy is already 0 if the exception was thrown.
2875                 }
2876             }
2877 
2878             synchronized (mEnergyInfoLock) {
2879                 mStackReportedState = ctrlState;
2880                 long totalTxTimeMs;
2881                 long totalRxTimeMs;
2882                 long totalIdleTimeMs;
2883                 long totalEnergy;
2884                 try {
2885                     totalTxTimeMs = Math.addExact(mTxTimeTotalMs, txTime);
2886                     totalRxTimeMs = Math.addExact(mRxTimeTotalMs, rxTime);
2887                     totalIdleTimeMs = Math.addExact(mIdleTimeTotalMs, idleTime);
2888                     totalEnergy = Math.addExact(mEnergyUsedTotalVoltAmpSecMicro, energyUsed);
2889                 } catch (ArithmeticException e) {
2890                     // This could be because we accumulated a lot of time, or we got a very strange
2891                     // value from the controller (more likely). Discard this data.
2892                     Log.wtf(TAG, "overflow in bluetooth energy callback", e);
2893                     totalTxTimeMs = mTxTimeTotalMs;
2894                     totalRxTimeMs = mRxTimeTotalMs;
2895                     totalIdleTimeMs = mIdleTimeTotalMs;
2896                     totalEnergy = mEnergyUsedTotalVoltAmpSecMicro;
2897                 }
2898 
2899                 mTxTimeTotalMs = totalTxTimeMs;
2900                 mRxTimeTotalMs = totalRxTimeMs;
2901                 mIdleTimeTotalMs = totalIdleTimeMs;
2902                 mEnergyUsedTotalVoltAmpSecMicro = totalEnergy;
2903 
2904                 for (UidTraffic traffic : data) {
2905                     UidTraffic existingTraffic = mUidTraffic.get(traffic.getUid());
2906                     if (existingTraffic == null) {
2907                         mUidTraffic.put(traffic.getUid(), traffic);
2908                     } else {
2909                         existingTraffic.addRxBytes(traffic.getRxBytes());
2910                         existingTraffic.addTxBytes(traffic.getTxBytes());
2911                     }
2912                 }
2913                 mEnergyInfoLock.notifyAll();
2914             }
2915         }
2916 
2917         verboseLog("energyInfoCallback() status = " + status + "txTime = " + txTime + "rxTime = "
2918                 + rxTime + "idleTime = " + idleTime + "energyUsed = " + energyUsed + "ctrlState = "
2919                 + ctrlState + "traffic = " + Arrays.toString(data));
2920     }
2921 
2922     /**
2923      * Update metadata change to registered listeners
2924      */
2925     @VisibleForTesting
metadataChanged(String address, int key, byte[] value)2926     public void metadataChanged(String address, int key, byte[] value) {
2927         BluetoothDevice device = mRemoteDevices.getDevice(Utils.getBytesFromAddress(address));
2928         if (mMetadataListeners.containsKey(device)) {
2929             ArrayList<IBluetoothMetadataListener> list = mMetadataListeners.get(device);
2930             for (IBluetoothMetadataListener listener : list) {
2931                 try {
2932                     listener.onMetadataChanged(device, key, value);
2933                 } catch (RemoteException e) {
2934                     Log.w(TAG, "RemoteException when onMetadataChanged");
2935                 }
2936             }
2937         }
2938     }
2939 
getIdleCurrentMa()2940     private int getIdleCurrentMa() {
2941         return getResources().getInteger(R.integer.config_bluetooth_idle_cur_ma);
2942     }
2943 
getTxCurrentMa()2944     private int getTxCurrentMa() {
2945         return getResources().getInteger(R.integer.config_bluetooth_tx_cur_ma);
2946     }
2947 
getRxCurrentMa()2948     private int getRxCurrentMa() {
2949         return getResources().getInteger(R.integer.config_bluetooth_rx_cur_ma);
2950     }
2951 
getOperatingVolt()2952     private double getOperatingVolt() {
2953         return getResources().getInteger(R.integer.config_bluetooth_operating_voltage_mv) / 1000.0;
2954     }
2955 
2956     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)2957     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
2958         if (args.length == 0) {
2959             writer.println("Skipping dump in APP SERVICES, see bluetooth_manager section.");
2960             writer.println("Use --print argument for dumpsys direct from AdapterService.");
2961             return;
2962         }
2963 
2964         verboseLog("dumpsys arguments, check for protobuf output: " + TextUtils.join(" ", args));
2965         if (args[0].equals("--proto-bin")) {
2966             dumpMetrics(fd);
2967             return;
2968         }
2969 
2970         writer.println();
2971         mAdapterProperties.dump(fd, writer, args);
2972         writer.println("mSnoopLogSettingAtEnable = " + mSnoopLogSettingAtEnable);
2973         writer.println("mDefaultSnoopLogSettingAtEnable = " + mDefaultSnoopLogSettingAtEnable);
2974 
2975         writer.println();
2976         mAdapterStateMachine.dump(fd, writer, args);
2977 
2978         StringBuilder sb = new StringBuilder();
2979         for (ProfileService profile : mRegisteredProfiles) {
2980             profile.dump(sb);
2981         }
2982         mSilenceDeviceManager.dump(fd, writer, args);
2983         mDatabaseManager.dump(writer);
2984 
2985         writer.write(sb.toString());
2986         writer.flush();
2987 
2988         dumpNative(fd, args);
2989     }
2990 
dumpMetrics(FileDescriptor fd)2991     private void dumpMetrics(FileDescriptor fd) {
2992         BluetoothMetricsProto.BluetoothLog.Builder metricsBuilder =
2993                 BluetoothMetricsProto.BluetoothLog.newBuilder();
2994         byte[] nativeMetricsBytes = dumpMetricsNative();
2995         debugLog("dumpMetrics: native metrics size is " + nativeMetricsBytes.length);
2996         if (nativeMetricsBytes.length > 0) {
2997             try {
2998                 metricsBuilder.mergeFrom(nativeMetricsBytes);
2999             } catch (InvalidProtocolBufferException ex) {
3000                 Log.w(TAG, "dumpMetrics: problem parsing metrics protobuf, " + ex.getMessage());
3001                 return;
3002             }
3003         }
3004         metricsBuilder.setNumBondedDevices(getBondedDevices().length);
3005         MetricsLogger.dumpProto(metricsBuilder);
3006         for (ProfileService profile : mRegisteredProfiles) {
3007             profile.dumpProto(metricsBuilder);
3008         }
3009         byte[] metricsBytes = Base64.encode(metricsBuilder.build().toByteArray(), Base64.DEFAULT);
3010         debugLog("dumpMetrics: combined metrics size is " + metricsBytes.length);
3011         try (FileOutputStream protoOut = new FileOutputStream(fd)) {
3012             protoOut.write(metricsBytes);
3013         } catch (IOException e) {
3014             errorLog("dumpMetrics: error writing combined protobuf to fd, " + e.getMessage());
3015         }
3016     }
3017 
debugLog(String msg)3018     private void debugLog(String msg) {
3019         if (DBG) {
3020             Log.d(TAG, msg);
3021         }
3022     }
3023 
verboseLog(String msg)3024     private void verboseLog(String msg) {
3025         if (VERBOSE) {
3026             Log.v(TAG, msg);
3027         }
3028     }
3029 
errorLog(String msg)3030     private void errorLog(String msg) {
3031         Log.e(TAG, msg);
3032     }
3033 
3034     private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() {
3035         @Override
3036         public void onReceive(Context context, Intent intent) {
3037             synchronized (AdapterService.this) {
3038                 mPendingAlarm = null;
3039                 alarmFiredNative();
3040             }
3041         }
3042     };
3043 
isGuest()3044     private boolean isGuest() {
3045         return UserManager.get(this).isGuestUser();
3046     }
3047 
isNiapMode()3048     private boolean isNiapMode() {
3049         return ((DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE))
3050                 .isCommonCriteriaModeEnabled(null);
3051     }
3052 
3053     /**
3054      *  Obfuscate Bluetooth MAC address into a PII free ID string
3055      *
3056      *  @param device Bluetooth device whose MAC address will be obfuscated
3057      *  @return a byte array that is unique to this MAC address on this device,
3058      *          or empty byte array when either device is null or obfuscateAddressNative fails
3059      */
obfuscateAddress(BluetoothDevice device)3060     public byte[] obfuscateAddress(BluetoothDevice device) {
3061         if (device == null) {
3062             return new byte[0];
3063         }
3064         return obfuscateAddressNative(Utils.getByteAddress(device));
3065     }
3066 
3067     /**
3068      *  Get an incremental id of Bluetooth metrics and log
3069      *
3070      *  @param device Bluetooth device
3071      *  @return int of id for Bluetooth metrics and logging, 0 if the device is invalid
3072      */
getMetricId(BluetoothDevice device)3073     public int getMetricId(BluetoothDevice device) {
3074         if (device == null) {
3075             return 0;
3076         }
3077         return getMetricIdNative(Utils.getByteAddress(device));
3078     }
3079 
classInitNative()3080     static native void classInitNative();
3081 
initNative(boolean startRestricted, boolean isNiapMode, int configCompareResult)3082     native boolean initNative(boolean startRestricted, boolean isNiapMode,
3083             int configCompareResult);
3084 
cleanupNative()3085     native void cleanupNative();
3086 
3087     /*package*/
enableNative()3088     native boolean enableNative();
3089 
3090     /*package*/
disableNative()3091     native boolean disableNative();
3092 
3093     /*package*/
setAdapterPropertyNative(int type, byte[] val)3094     native boolean setAdapterPropertyNative(int type, byte[] val);
3095 
3096     /*package*/
getAdapterPropertiesNative()3097     native boolean getAdapterPropertiesNative();
3098 
3099     /*package*/
getAdapterPropertyNative(int type)3100     native boolean getAdapterPropertyNative(int type);
3101 
3102     /*package*/
setAdapterPropertyNative(int type)3103     native boolean setAdapterPropertyNative(int type);
3104 
3105     /*package*/
setDevicePropertyNative(byte[] address, int type, byte[] val)3106     native boolean setDevicePropertyNative(byte[] address, int type, byte[] val);
3107 
3108     /*package*/
getDevicePropertyNative(byte[] address, int type)3109     native boolean getDevicePropertyNative(byte[] address, int type);
3110 
3111     /*package*/
createBondNative(byte[] address, int transport)3112     native boolean createBondNative(byte[] address, int transport);
3113 
3114     /*package*/
createBondOutOfBandNative(byte[] address, int transport, OobData oobData)3115     native boolean createBondOutOfBandNative(byte[] address, int transport, OobData oobData);
3116 
3117     /*package*/
removeBondNative(byte[] address)3118     native boolean removeBondNative(byte[] address);
3119 
3120     /*package*/
cancelBondNative(byte[] address)3121     native boolean cancelBondNative(byte[] address);
3122 
3123     /*package*/
sdpSearchNative(byte[] address, byte[] uuid)3124     native boolean sdpSearchNative(byte[] address, byte[] uuid);
3125 
3126     /*package*/
getConnectionStateNative(byte[] address)3127     native int getConnectionStateNative(byte[] address);
3128 
startDiscoveryNative()3129     private native boolean startDiscoveryNative();
3130 
cancelDiscoveryNative()3131     private native boolean cancelDiscoveryNative();
3132 
pinReplyNative(byte[] address, boolean accept, int len, byte[] pin)3133     private native boolean pinReplyNative(byte[] address, boolean accept, int len, byte[] pin);
3134 
sspReplyNative(byte[] address, int type, boolean accept, int passkey)3135     private native boolean sspReplyNative(byte[] address, int type, boolean accept, int passkey);
3136 
3137     /*package*/
getRemoteServicesNative(byte[] address)3138     native boolean getRemoteServicesNative(byte[] address);
3139 
3140     /*package*/
getRemoteMasInstancesNative(byte[] address)3141     native boolean getRemoteMasInstancesNative(byte[] address);
3142 
readEnergyInfo()3143     private native int readEnergyInfo();
3144 
3145     /*package*/
factoryResetNative()3146     native boolean factoryResetNative();
3147 
alarmFiredNative()3148     private native void alarmFiredNative();
3149 
dumpNative(FileDescriptor fd, String[] arguments)3150     private native void dumpNative(FileDescriptor fd, String[] arguments);
3151 
dumpMetricsNative()3152     private native byte[] dumpMetricsNative();
3153 
interopDatabaseClearNative()3154     private native void interopDatabaseClearNative();
3155 
interopDatabaseAddNative(int feature, byte[] address, int length)3156     private native void interopDatabaseAddNative(int feature, byte[] address, int length);
3157 
obfuscateAddressNative(byte[] address)3158     private native byte[] obfuscateAddressNative(byte[] address);
3159 
getMetricIdNative(byte[] address)3160     private native int getMetricIdNative(byte[] address);
3161 
connectSocketNative( byte[] address, int type, byte[] uuid, int port, int flag, int callingUid)3162     /*package*/ native int connectSocketNative(
3163             byte[] address, int type, byte[] uuid, int port, int flag, int callingUid);
3164 
createSocketChannelNative( int type, String serviceName, byte[] uuid, int port, int flag, int callingUid)3165     /*package*/ native int createSocketChannelNative(
3166             int type, String serviceName, byte[] uuid, int port, int flag, int callingUid);
3167 
requestMaximumTxDataLengthNative(byte[] address)3168     /*package*/ native void requestMaximumTxDataLengthNative(byte[] address);
3169 
3170     // Returns if this is a mock object. This is currently used in testing so that we may not call
3171     // System.exit() while finalizing the object. Otherwise GC of mock objects unfortunately ends up
3172     // calling finalize() which in turn calls System.exit() and the process crashes.
3173     //
3174     // Mock this in your testing framework to return true to avoid the mentioned behavior. In
3175     // production this has no effect.
isMock()3176     public boolean isMock() {
3177         return false;
3178     }
3179 }
3180