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