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 android.text.format.DateUtils.MINUTE_IN_MILLIS;
20 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
21 
22 import static com.android.bluetooth.Utils.addressToBytes;
23 import static com.android.bluetooth.Utils.callerIsSystemOrActiveOrManagedUser;
24 import static com.android.bluetooth.Utils.callerIsSystemOrActiveUser;
25 import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;
26 import static com.android.bluetooth.Utils.enforceCdmAssociation;
27 import static com.android.bluetooth.Utils.enforceDumpPermission;
28 import static com.android.bluetooth.Utils.enforceLocalMacAddressPermission;
29 import static com.android.bluetooth.Utils.hasBluetoothPrivilegedPermission;
30 import static com.android.bluetooth.Utils.isPackageNameAccurate;
31 
32 import android.annotation.NonNull;
33 import android.annotation.RequiresPermission;
34 import android.annotation.SuppressLint;
35 import android.app.ActivityManager;
36 import android.app.AlarmManager;
37 import android.app.AppOpsManager;
38 import android.app.PendingIntent;
39 import android.app.Service;
40 import android.app.admin.DevicePolicyManager;
41 import android.bluetooth.BluetoothA2dp;
42 import android.bluetooth.BluetoothActivityEnergyInfo;
43 import android.bluetooth.BluetoothAdapter;
44 import android.bluetooth.BluetoothAdapter.ActiveDeviceUse;
45 import android.bluetooth.BluetoothClass;
46 import android.bluetooth.BluetoothDevice;
47 import android.bluetooth.BluetoothProfile;
48 import android.bluetooth.BluetoothProtoEnums;
49 import android.bluetooth.BluetoothStatusCodes;
50 import android.bluetooth.BluetoothUuid;
51 import android.bluetooth.BufferConstraints;
52 import android.bluetooth.IBluetooth;
53 import android.bluetooth.IBluetoothCallback;
54 import android.bluetooth.IBluetoothConnectionCallback;
55 import android.bluetooth.IBluetoothMetadataListener;
56 import android.bluetooth.IBluetoothOobDataCallback;
57 import android.bluetooth.IBluetoothSocketManager;
58 import android.bluetooth.OobData;
59 import android.bluetooth.UidTraffic;
60 import android.companion.CompanionDeviceManager;
61 import android.content.Attributable;
62 import android.content.AttributionSource;
63 import android.content.BroadcastReceiver;
64 import android.content.ComponentName;
65 import android.content.Context;
66 import android.content.Intent;
67 import android.content.IntentFilter;
68 import android.content.SharedPreferences;
69 import android.content.pm.PackageManager;
70 import android.os.AsyncTask;
71 import android.os.BatteryStats;
72 import android.os.Binder;
73 import android.os.Bundle;
74 import android.os.BytesMatcher;
75 import android.os.Handler;
76 import android.os.IBinder;
77 import android.os.Looper;
78 import android.os.Message;
79 import android.os.ParcelUuid;
80 import android.os.PowerManager;
81 import android.os.RemoteCallbackList;
82 import android.os.RemoteException;
83 import android.os.ResultReceiver;
84 import android.os.ServiceManager;
85 import android.os.SystemClock;
86 import android.os.SystemProperties;
87 import android.os.UserHandle;
88 import android.os.UserManager;
89 import android.provider.DeviceConfig;
90 import android.provider.Settings;
91 import android.text.TextUtils;
92 import android.util.Base64;
93 import android.util.Log;
94 import android.util.SparseArray;
95 
96 import com.android.bluetooth.BluetoothMetricsProto;
97 import com.android.bluetooth.BluetoothStatsLog;
98 import com.android.bluetooth.Utils;
99 import com.android.bluetooth.a2dp.A2dpService;
100 import com.android.bluetooth.a2dpsink.A2dpSinkService;
101 import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;
102 import com.android.bluetooth.btservice.activityattribution.ActivityAttributionService;
103 import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreService;
104 import com.android.bluetooth.btservice.storage.DatabaseManager;
105 import com.android.bluetooth.btservice.storage.MetadataDatabase;
106 import com.android.bluetooth.gatt.GattService;
107 import com.android.bluetooth.hearingaid.HearingAidService;
108 import com.android.bluetooth.hfp.HeadsetService;
109 import com.android.bluetooth.hfpclient.HeadsetClientService;
110 import com.android.bluetooth.hid.HidDeviceService;
111 import com.android.bluetooth.hid.HidHostService;
112 import com.android.bluetooth.map.BluetoothMapService;
113 import com.android.bluetooth.mapclient.MapClientService;
114 import com.android.bluetooth.pan.PanService;
115 import com.android.bluetooth.pbap.BluetoothPbapService;
116 import com.android.bluetooth.pbapclient.PbapClientService;
117 import com.android.bluetooth.sap.SapService;
118 import com.android.bluetooth.sdp.SdpManager;
119 import com.android.bluetooth.telephony.BluetoothInCallService;
120 import com.android.internal.R;
121 import com.android.internal.annotations.GuardedBy;
122 import com.android.internal.annotations.VisibleForTesting;
123 import com.android.internal.app.IBatteryStats;
124 import com.android.internal.os.BackgroundThread;
125 import com.android.internal.os.BinderCallsStats;
126 import com.android.internal.util.ArrayUtils;
127 
128 import com.google.protobuf.InvalidProtocolBufferException;
129 
130 import libcore.util.SneakyThrow;
131 
132 import java.io.FileDescriptor;
133 import java.io.FileOutputStream;
134 import java.io.IOException;
135 import java.io.PrintWriter;
136 import java.util.ArrayDeque;
137 import java.util.ArrayList;
138 import java.util.Arrays;
139 import java.util.HashMap;
140 import java.util.HashSet;
141 import java.util.List;
142 import java.util.Set;
143 import java.util.function.Predicate;
144 import java.util.regex.Pattern;
145 
146 public class AdapterService extends Service {
147     private static final String TAG = "BluetoothAdapterService";
148     private static final boolean DBG = true;
149     private static final boolean VERBOSE = false;
150     private static final int MIN_ADVT_INSTANCES_FOR_MA = 5;
151     private static final int MIN_OFFLOADED_FILTERS = 10;
152     private static final int MIN_OFFLOADED_SCAN_STORAGE_BYTES = 1024;
153 
154     private final Object mEnergyInfoLock = new Object();
155     private int mStackReportedState;
156     private long mTxTimeTotalMs;
157     private long mRxTimeTotalMs;
158     private long mIdleTimeTotalMs;
159     private long mEnergyUsedTotalVoltAmpSecMicro;
160     private final SparseArray<UidTraffic> mUidTraffic = new SparseArray<>();
161 
162     private final ArrayList<String> mStartedProfiles = new ArrayList<>();
163     private final ArrayList<ProfileService> mRegisteredProfiles = new ArrayList<>();
164     private final ArrayList<ProfileService> mRunningProfiles = new ArrayList<>();
165 
166     public static final String ACTION_LOAD_ADAPTER_PROPERTIES =
167             "com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES";
168     public static final String ACTION_SERVICE_STATE_CHANGED =
169             "com.android.bluetooth.btservice.action.STATE_CHANGED";
170     public static final String EXTRA_ACTION = "action";
171     public static final int PROFILE_CONN_REJECTED = 2;
172 
173     private static final String ACTION_ALARM_WAKEUP =
174             "com.android.bluetooth.btservice.action.ALARM_WAKEUP";
175 
176     static final String BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY = "persist.bluetooth.btsnooplogmode";
177     static final String BLUETOOTH_BTSNOOP_DEFAULT_MODE_PROPERTY =
178             "persist.bluetooth.btsnoopdefaultmode";
179     private String mSnoopLogSettingAtEnable = "empty";
180     private String mDefaultSnoopLogSettingAtEnable = "empty";
181 
182     public static final String BLUETOOTH_PRIVILEGED =
183             android.Manifest.permission.BLUETOOTH_PRIVILEGED;
184     static final String LOCAL_MAC_ADDRESS_PERM = android.Manifest.permission.LOCAL_MAC_ADDRESS;
185     static final String RECEIVE_MAP_PERM = android.Manifest.permission.RECEIVE_BLUETOOTH_MAP;
186 
187     private static final String PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE =
188             "phonebook_access_permission";
189     private static final String MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE =
190             "message_access_permission";
191     private static final String SIM_ACCESS_PERMISSION_PREFERENCE_FILE = "sim_access_permission";
192 
193     private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30;
194 
195     private static final ComponentName BLUETOOTH_INCALLSERVICE_COMPONENT =
196             new ComponentName("com.android.bluetooth",
197                     BluetoothInCallService.class.getCanonicalName());
198 
199     // Report ID definition
200     public enum BqrQualityReportId {
201         QUALITY_REPORT_ID_MONITOR_MODE(0x01),
202         QUALITY_REPORT_ID_APPROACH_LSTO(0x02),
203         QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY(0x03),
204         QUALITY_REPORT_ID_SCO_VOICE_CHOPPY(0x04),
205         QUALITY_REPORT_ID_ROOT_INFLAMMATION(0x05),
206         QUALITY_REPORT_ID_LMP_LL_MESSAGE_TRACE(0x11),
207         QUALITY_REPORT_ID_BT_SCHEDULING_TRACE(0x12),
208         QUALITY_REPORT_ID_CONTROLLER_DBG_INFO(0x13);
209 
210         private final int value;
BqrQualityReportId(int value)211         private BqrQualityReportId(int value) {
212             this.value = value;
213         }
getValue()214         public int getValue() {
215             return value;
216         }
217     };
218 
219     private final ArrayList<DiscoveringPackage> mDiscoveringPackages = new ArrayList<>();
220 
221     static {
classInitNative()222         classInitNative();
223     }
224 
225     private static AdapterService sAdapterService;
226 
getAdapterService()227     public static synchronized AdapterService getAdapterService() {
228         return sAdapterService;
229     }
230 
setAdapterService(AdapterService instance)231     private static synchronized void setAdapterService(AdapterService instance) {
232         Log.d(TAG, "setAdapterService() - trying to set service to " + instance);
233         if (instance == null) {
234             return;
235         }
236         sAdapterService = instance;
237     }
238 
clearAdapterService(AdapterService current)239     private static synchronized void clearAdapterService(AdapterService current) {
240         if (sAdapterService == current) {
241             sAdapterService = null;
242         }
243     }
244 
245     private AdapterProperties mAdapterProperties;
246     private AdapterState mAdapterStateMachine;
247     private BondStateMachine mBondStateMachine;
248     private JniCallbacks mJniCallbacks;
249     private RemoteDevices mRemoteDevices;
250 
251     /* TODO: Consider to remove the search API from this class, if changed to use call-back */
252     private SdpManager mSdpManager = null;
253 
254     private boolean mNativeAvailable;
255     private boolean mCleaningUp;
256     private final HashMap<BluetoothDevice, ArrayList<IBluetoothMetadataListener>>
257             mMetadataListeners = new HashMap<>();
258     private final HashMap<String, Integer> mProfileServicesState = new HashMap<String, Integer>();
259     private Set<IBluetoothConnectionCallback> mBluetoothConnectionCallbacks = new HashSet<>();
260     //Only BluetoothManagerService should be registered
261     private RemoteCallbackList<IBluetoothCallback> mCallbacks;
262     private int mCurrentRequestId;
263     private boolean mQuietmode = false;
264     private HashMap<String, CallerInfo> mBondAttemptCallerInfo = new HashMap<>();
265 
266     private AlarmManager mAlarmManager;
267     private PendingIntent mPendingAlarm;
268     private IBatteryStats mBatteryStats;
269     private PowerManager mPowerManager;
270     private PowerManager.WakeLock mWakeLock;
271     private String mWakeLockName;
272     private UserManager mUserManager;
273     private CompanionDeviceManager mCompanionDeviceManager;
274 
275     private PhonePolicy mPhonePolicy;
276     private ActiveDeviceManager mActiveDeviceManager;
277     private DatabaseManager mDatabaseManager;
278     private SilenceDeviceManager mSilenceDeviceManager;
279     private AppOpsManager mAppOps;
280 
281     private BluetoothSocketManagerBinder mBluetoothSocketManagerBinder;
282 
283     private BluetoothKeystoreService mBluetoothKeystoreService;
284     private A2dpService mA2dpService;
285     private A2dpSinkService mA2dpSinkService;
286     private ActivityAttributionService mActivityAttributionService;
287     private HeadsetService mHeadsetService;
288     private HeadsetClientService mHeadsetClientService;
289     private BluetoothMapService mMapService;
290     private MapClientService mMapClientService;
291     private HidDeviceService mHidDeviceService;
292     private HidHostService mHidHostService;
293     private PanService mPanService;
294     private BluetoothPbapService mPbapService;
295     private PbapClientService mPbapClientService;
296     private HearingAidService mHearingAidService;
297     private SapService mSapService;
298 
299     private BinderCallsStats.SettingsObserver mBinderCallsSettingsObserver;
300 
301     private volatile boolean mTestModeEnabled = false;
302 
303     /**
304      * Register a {@link ProfileService} with AdapterService.
305      *
306      * @param profile the service being added.
307      */
addProfile(ProfileService profile)308     public void addProfile(ProfileService profile) {
309         mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_REGISTERED, profile).sendToTarget();
310     }
311 
312     /**
313      * Unregister a ProfileService with AdapterService.
314      *
315      * @param profile the service being removed.
316      */
removeProfile(ProfileService profile)317     public void removeProfile(ProfileService profile) {
318         mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_UNREGISTERED, profile).sendToTarget();
319     }
320 
321     /**
322      * Notify AdapterService that a ProfileService has started or stopped.
323      *
324      * @param profile the service being removed.
325      * @param state {@link BluetoothAdapter#STATE_ON} or {@link BluetoothAdapter#STATE_OFF}
326      */
onProfileServiceStateChanged(ProfileService profile, int state)327     public void onProfileServiceStateChanged(ProfileService profile, int state) {
328         if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) {
329             throw new IllegalArgumentException(BluetoothAdapter.nameForState(state));
330         }
331         Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
332         m.obj = profile;
333         m.arg1 = state;
334         mHandler.sendMessage(m);
335     }
336 
337     /**
338      * Confirm whether the ProfileService is started expectedly.
339      *
340      * @param string the service simple name.
341      * @return true if the service is started expectedly, false otherwise.
342      */
isStartedProfile(String serviceSampleName)343     public boolean isStartedProfile(String serviceSampleName) {
344         return mStartedProfiles.contains(serviceSampleName);
345     }
346 
347     private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED = 1;
348     private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2;
349     private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3;
350 
351     class AdapterServiceHandler extends Handler {
352         @Override
handleMessage(Message msg)353         public void handleMessage(Message msg) {
354             verboseLog("handleMessage() - Message: " + msg.what);
355 
356             switch (msg.what) {
357                 case MESSAGE_PROFILE_SERVICE_STATE_CHANGED:
358                     verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED");
359                     processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1);
360                     break;
361                 case MESSAGE_PROFILE_SERVICE_REGISTERED:
362                     verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_REGISTERED");
363                     registerProfileService((ProfileService) msg.obj);
364                     break;
365                 case MESSAGE_PROFILE_SERVICE_UNREGISTERED:
366                     verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_UNREGISTERED");
367                     unregisterProfileService((ProfileService) msg.obj);
368                     break;
369             }
370         }
371 
registerProfileService(ProfileService profile)372         private void registerProfileService(ProfileService profile) {
373             if (mRegisteredProfiles.contains(profile)) {
374                 Log.e(TAG, profile.getName() + " already registered.");
375                 return;
376             }
377             mRegisteredProfiles.add(profile);
378         }
379 
unregisterProfileService(ProfileService profile)380         private void unregisterProfileService(ProfileService profile) {
381             if (!mRegisteredProfiles.contains(profile)) {
382                 Log.e(TAG, profile.getName() + " not registered (UNREGISTER).");
383                 return;
384             }
385             mRegisteredProfiles.remove(profile);
386         }
387 
processProfileServiceStateChanged(ProfileService profile, int state)388         private void processProfileServiceStateChanged(ProfileService profile, int state) {
389             switch (state) {
390                 case BluetoothAdapter.STATE_ON:
391                     if (!mRegisteredProfiles.contains(profile)) {
392                         Log.e(TAG, profile.getName() + " not registered (STATE_ON).");
393                         return;
394                     }
395                     if (mRunningProfiles.contains(profile)) {
396                         Log.e(TAG, profile.getName() + " already running.");
397                         return;
398                     }
399                     mRunningProfiles.add(profile);
400                     if (GattService.class.getSimpleName().equals(profile.getName())) {
401                         enableNative();
402                     } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
403                             && mRegisteredProfiles.size() == mRunningProfiles.size()) {
404                         mAdapterProperties.onBluetoothReady();
405                         updateUuids();
406                         setBluetoothClassFromConfig();
407                         initProfileServices();
408                         getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS);
409                         getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS_BLE);
410                         getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_DYNAMIC_AUDIO_BUFFER);
411                         mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
412                     }
413                     break;
414                 case BluetoothAdapter.STATE_OFF:
415                     if (!mRegisteredProfiles.contains(profile)) {
416                         Log.e(TAG, profile.getName() + " not registered (STATE_OFF).");
417                         return;
418                     }
419                     if (!mRunningProfiles.contains(profile)) {
420                         Log.e(TAG, profile.getName() + " not running.");
421                         return;
422                     }
423                     mRunningProfiles.remove(profile);
424                     // If only GATT is left, send BREDR_STOPPED.
425                     if ((mRunningProfiles.size() == 1 && (GattService.class.getSimpleName()
426                             .equals(mRunningProfiles.get(0).getName())))) {
427                         mAdapterStateMachine.sendMessage(AdapterState.BREDR_STOPPED);
428                     } else if (mRunningProfiles.size() == 0) {
429                         disableNative();
430                     }
431                     break;
432                 default:
433                     Log.e(TAG, "Unhandled profile state: " + state);
434             }
435         }
436     }
437 
438     private final AdapterServiceHandler mHandler = new AdapterServiceHandler();
439 
updateInteropDatabase()440     private void updateInteropDatabase() {
441         interopDatabaseClearNative();
442 
443         String interopString = Settings.Global.getString(getContentResolver(),
444                 Settings.Global.BLUETOOTH_INTEROPERABILITY_LIST);
445         if (interopString == null) {
446             return;
447         }
448         Log.d(TAG, "updateInteropDatabase: [" + interopString + "]");
449 
450         String[] entries = interopString.split(";");
451         for (String entry : entries) {
452             String[] tokens = entry.split(",");
453             if (tokens.length != 2) {
454                 continue;
455             }
456 
457             // Get feature
458             int feature = 0;
459             try {
460                 feature = Integer.parseInt(tokens[1]);
461             } catch (NumberFormatException e) {
462                 Log.e(TAG, "updateInteropDatabase: Invalid feature '" + tokens[1] + "'");
463                 continue;
464             }
465 
466             // Get address bytes and length
467             int length = (tokens[0].length() + 1) / 3;
468             if (length < 1 || length > 6) {
469                 Log.e(TAG, "updateInteropDatabase: Malformed address string '" + tokens[0] + "'");
470                 continue;
471             }
472 
473             byte[] addr = new byte[6];
474             int offset = 0;
475             for (int i = 0; i < tokens[0].length(); ) {
476                 if (tokens[0].charAt(i) == ':') {
477                     i += 1;
478                 } else {
479                     try {
480                         addr[offset++] = (byte) Integer.parseInt(tokens[0].substring(i, i + 2), 16);
481                     } catch (NumberFormatException e) {
482                         offset = 0;
483                         break;
484                     }
485                     i += 2;
486                 }
487             }
488 
489             // Check if address was parsed ok, otherwise, move on...
490             if (offset == 0) {
491                 continue;
492             }
493 
494             // Add entry
495             interopDatabaseAddNative(feature, addr, length);
496         }
497     }
498 
499     @Override
onCreate()500     public void onCreate() {
501         super.onCreate();
502         debugLog("onCreate()");
503         mDeviceConfigListener.start();
504         mRemoteDevices = new RemoteDevices(this, Looper.getMainLooper());
505         mRemoteDevices.init();
506         clearDiscoveringPackages();
507         mBinder = new AdapterServiceBinder(this);
508         mAdapterProperties = new AdapterProperties(this);
509         mAdapterStateMachine = AdapterState.make(this);
510         mJniCallbacks = new JniCallbacks(this, mAdapterProperties);
511         mBluetoothKeystoreService = new BluetoothKeystoreService(isCommonCriteriaMode());
512         mBluetoothKeystoreService.start();
513         mActivityAttributionService = new ActivityAttributionService();
514         mActivityAttributionService.start();
515         int configCompareResult = mBluetoothKeystoreService.getCompareResult();
516 
517         // Start tracking Binder latency for the bluetooth process.
518         mBinderCallsSettingsObserver = new BinderCallsStats.SettingsObserver(
519                 getApplicationContext(),
520                 new BinderCallsStats(
521                         new BinderCallsStats.Injector(),
522                         com.android.internal.os.BinderLatencyProto.Dims.BLUETOOTH));
523 
524         // Android TV doesn't show consent dialogs for just works and encryption only le pairing
525         boolean isAtvDevice = getApplicationContext().getPackageManager().hasSystemFeature(
526                 PackageManager.FEATURE_LEANBACK_ONLY);
527         initNative(isGuest(), isCommonCriteriaMode(), configCompareResult, getInitFlags(),
528                 isAtvDevice);
529         mNativeAvailable = true;
530         mCallbacks = new RemoteCallbackList<IBluetoothCallback>();
531         mAppOps = getSystemService(AppOpsManager.class);
532         //Load the name and address
533         getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);
534         getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);
535         getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_CLASS_OF_DEVICE);
536         mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
537         mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
538         mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
539         mBatteryStats = IBatteryStats.Stub.asInterface(
540                 ServiceManager.getService(BatteryStats.SERVICE_NAME));
541         mCompanionDeviceManager = getSystemService(CompanionDeviceManager.class);
542 
543         mBluetoothKeystoreService.initJni();
544 
545         mSdpManager = SdpManager.init(this);
546         registerReceiver(mAlarmBroadcastReceiver, new IntentFilter(ACTION_ALARM_WAKEUP));
547 
548         mDatabaseManager = new DatabaseManager(this);
549         mDatabaseManager.start(MetadataDatabase.createDatabase(this));
550 
551         // Phone policy is specific to phone implementations and hence if a device wants to exclude
552         // it out then it can be disabled by using the flag below.
553         if (getResources().getBoolean(com.android.bluetooth.R.bool.enable_phone_policy)) {
554             Log.i(TAG, "Phone policy enabled");
555             mPhonePolicy = new PhonePolicy(this, new ServiceFactory());
556             mPhonePolicy.start();
557         } else {
558             Log.i(TAG, "Phone policy disabled");
559         }
560 
561         mActiveDeviceManager = new ActiveDeviceManager(this, new ServiceFactory());
562         mActiveDeviceManager.start();
563 
564         mSilenceDeviceManager = new SilenceDeviceManager(this, new ServiceFactory(),
565                 Looper.getMainLooper());
566         mSilenceDeviceManager.start();
567 
568         mBluetoothSocketManagerBinder = new BluetoothSocketManagerBinder(this);
569 
570         setAdapterService(this);
571 
572         invalidateBluetoothCaches();
573 
574         // First call to getSharedPreferences will result in a file read into
575         // memory cache. Call it here asynchronously to avoid potential ANR
576         // in the future
577         new AsyncTask<Void, Void, Void>() {
578             @Override
579             protected Void doInBackground(Void... params) {
580                 getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE,
581                         Context.MODE_PRIVATE);
582                 getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE,
583                         Context.MODE_PRIVATE);
584                 getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, Context.MODE_PRIVATE);
585                 return null;
586             }
587         }.execute();
588 
589         try {
590             int systemUiUid = getApplicationContext()
591                     .createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0)
592                     .getPackageManager()
593                     .getPackageUid("com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY);
594 
595             Utils.setSystemUiUid(systemUiUid);
596         } catch (PackageManager.NameNotFoundException e) {
597             // Some platforms, such as wearables do not have a system ui.
598             Log.w(TAG, "Unable to resolve SystemUI's UID.", e);
599         }
600 
601         IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
602         getApplicationContext().registerReceiverForAllUsers(sUserSwitchedReceiver, filter, null, null);
603         int fuid = ActivityManager.getCurrentUser();
604         Utils.setForegroundUserId(fuid);
605     }
606 
607     @Override
onBind(Intent intent)608     public IBinder onBind(Intent intent) {
609         debugLog("onBind()");
610         return mBinder;
611     }
612 
613     @Override
onUnbind(Intent intent)614     public boolean onUnbind(Intent intent) {
615         debugLog("onUnbind() - calling cleanup");
616         cleanup();
617         return super.onUnbind(intent);
618     }
619 
620     @Override
onDestroy()621     public void onDestroy() {
622         debugLog("onDestroy()");
623         if (!isMock()) {
624             // TODO(b/27859763)
625             Log.i(TAG, "Force exit to cleanup internal state in Bluetooth stack");
626             System.exit(0);
627         }
628     }
629 
630     public static final BroadcastReceiver sUserSwitchedReceiver = new BroadcastReceiver() {
631         @Override
632         public void onReceive(Context context, Intent intent) {
633             if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
634                 int fuid = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
635                 Utils.setForegroundUserId(fuid);
636             }
637         }
638     };
639 
bringUpBle()640     void bringUpBle() {
641         debugLog("bleOnProcessStart()");
642 
643         if (getResources().getBoolean(
644                 R.bool.config_bluetooth_reload_supported_profiles_when_enabled)) {
645             Config.init(getApplicationContext());
646         }
647 
648         // Reset |mRemoteDevices| whenever BLE is turned off then on
649         // This is to replace the fact that |mRemoteDevices| was
650         // reinitialized in previous code.
651         //
652         // TODO(apanicke): The reason is unclear but
653         // I believe it is to clear the variable every time BLE was
654         // turned off then on. The same effect can be achieved by
655         // calling cleanup but this may not be necessary at all
656         // We should figure out why this is needed later
657         mRemoteDevices.reset();
658         mAdapterProperties.init(mRemoteDevices);
659 
660         debugLog("bleOnProcessStart() - Make Bond State Machine");
661         mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);
662 
663         mJniCallbacks.init(mBondStateMachine, mRemoteDevices);
664 
665         try {
666             mBatteryStats.noteResetBleScan();
667         } catch (RemoteException e) {
668             Log.w(TAG, "RemoteException trying to send a reset to BatteryStats");
669         }
670         BluetoothStatsLog.write_non_chained(BluetoothStatsLog.BLE_SCAN_STATE_CHANGED, -1, null,
671                 BluetoothStatsLog.BLE_SCAN_STATE_CHANGED__STATE__RESET, false, false, false);
672 
673         //Start Gatt service
674         setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON);
675     }
676 
bringDownBle()677     void bringDownBle() {
678         stopGattProfileService();
679     }
680 
stateChangeCallback(int status)681     void stateChangeCallback(int status) {
682         if (status == AbstractionLayer.BT_STATE_OFF) {
683             debugLog("stateChangeCallback: disableNative() completed");
684             mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
685         } else if (status == AbstractionLayer.BT_STATE_ON) {
686             mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED);
687         } else {
688             Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback");
689         }
690     }
691 
692     /**
693      * Sets the Bluetooth CoD value of the local adapter if there exists a config value for it.
694      */
setBluetoothClassFromConfig()695     void setBluetoothClassFromConfig() {
696         int bluetoothClassConfig = retrieveBluetoothClassConfig();
697         if (bluetoothClassConfig != 0) {
698             mAdapterProperties.setBluetoothClass(new BluetoothClass(bluetoothClassConfig));
699         }
700     }
701 
retrieveBluetoothClassConfig()702     private int retrieveBluetoothClassConfig() {
703         return Settings.Global.getInt(
704                 getContentResolver(), Settings.Global.BLUETOOTH_CLASS_OF_DEVICE, 0);
705     }
706 
startProfileServices()707     void startProfileServices() {
708         debugLog("startCoreServices()");
709         Class[] supportedProfileServices = Config.getSupportedProfiles();
710         if (supportedProfileServices.length == 1 && GattService.class.getSimpleName()
711                 .equals(supportedProfileServices[0].getSimpleName())) {
712             mAdapterProperties.onBluetoothReady();
713             updateUuids();
714             setBluetoothClassFromConfig();
715             mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
716         } else {
717             setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON);
718         }
719     }
720 
stopProfileServices()721     void stopProfileServices() {
722         // Make sure to stop classic background tasks now
723         cancelDiscoveryNative();
724         mAdapterProperties.setScanMode(AbstractionLayer.BT_SCAN_MODE_NONE);
725 
726         Class[] supportedProfileServices = Config.getSupportedProfiles();
727         if (supportedProfileServices.length == 1 && (mRunningProfiles.size() == 1
728                 && GattService.class.getSimpleName().equals(mRunningProfiles.get(0).getName()))) {
729             debugLog("stopProfileServices() - No profiles services to stop or already stopped.");
730             mAdapterStateMachine.sendMessage(AdapterState.BREDR_STOPPED);
731         } else {
732             setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_OFF);
733         }
734     }
735 
stopGattProfileService()736     private void stopGattProfileService() {
737         mAdapterProperties.onBleDisable();
738         if (mRunningProfiles.size() == 0) {
739             debugLog("stopGattProfileService() - No profiles services to stop.");
740             mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
741         }
742         setProfileServiceState(GattService.class, BluetoothAdapter.STATE_OFF);
743     }
744 
invalidateBluetoothGetStateCache()745     private void invalidateBluetoothGetStateCache() {
746         BluetoothAdapter.invalidateBluetoothGetStateCache();
747     }
748 
updateAdapterState(int prevState, int newState)749     void updateAdapterState(int prevState, int newState) {
750         mAdapterProperties.setState(newState);
751         invalidateBluetoothGetStateCache();
752         if (mCallbacks != null) {
753             int n = mCallbacks.beginBroadcast();
754             debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState(
755                     newState) + " to " + n + " receivers.");
756             for (int i = 0; i < n; i++) {
757                 try {
758                     mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState);
759                 } catch (RemoteException e) {
760                     debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")");
761                 }
762             }
763             mCallbacks.finishBroadcast();
764         }
765 
766         // Turn the Adapter all the way off if we are disabling and the snoop log setting changed.
767         if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON) {
768             mSnoopLogSettingAtEnable =
769                     SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, "empty");
770             mDefaultSnoopLogSettingAtEnable =
771                     Settings.Global.getString(getContentResolver(),
772                             Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE);
773             SystemProperties.set(BLUETOOTH_BTSNOOP_DEFAULT_MODE_PROPERTY,
774                     mDefaultSnoopLogSettingAtEnable);
775         } else if (newState == BluetoothAdapter.STATE_BLE_ON
776                    && prevState != BluetoothAdapter.STATE_OFF) {
777             String snoopLogSetting =
778                     SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, "empty");
779             String snoopDefaultModeSetting =
780                     Settings.Global.getString(getContentResolver(),
781                             Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE);
782 
783             if (!TextUtils.equals(mSnoopLogSettingAtEnable, snoopLogSetting)
784                     || !TextUtils.equals(mDefaultSnoopLogSettingAtEnable,
785                             snoopDefaultModeSetting)) {
786                 mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF);
787             }
788         }
789     }
790 
linkQualityReportCallback( long timestamp, int reportId, int rssi, int snr, int retransmissionCount, int packetsNotReceiveCount, int negativeAcknowledgementCount)791     void linkQualityReportCallback(
792             long timestamp,
793             int reportId,
794             int rssi,
795             int snr,
796             int retransmissionCount,
797             int packetsNotReceiveCount,
798             int negativeAcknowledgementCount) {
799         BluetoothInCallService bluetoothInCallService = BluetoothInCallService.getInstance();
800 
801         if (reportId == BqrQualityReportId.QUALITY_REPORT_ID_SCO_VOICE_CHOPPY.getValue()) {
802             if (bluetoothInCallService == null) {
803                 Log.w(TAG, "No BluetoothInCallService while trying to send BQR."
804                         + " timestamp: " + timestamp + " reportId: " + reportId
805                         + " rssi: " + rssi + " snr: " + snr
806                         + " retransmissionCount: " + retransmissionCount
807                         + " packetsNotReceiveCount: " + packetsNotReceiveCount
808                         + " negativeAcknowledgementCount: " + negativeAcknowledgementCount);
809                 return;
810             }
811             bluetoothInCallService.sendBluetoothCallQualityReport(
812                     timestamp, rssi, snr, retransmissionCount,
813                     packetsNotReceiveCount, negativeAcknowledgementCount);
814         }
815     }
816 
817     /**
818      * Enable/disable BluetoothInCallService
819      *
820      * @param enable to enable/disable BluetoothInCallService.
821      */
enableBluetoothInCallService(boolean enable)822     public void enableBluetoothInCallService(boolean enable) {
823         debugLog("enableBluetoothInCallService() - Enable = " + enable);
824         getPackageManager().setComponentEnabledSetting(
825                 BLUETOOTH_INCALLSERVICE_COMPONENT,
826                 enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
827                         : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
828                 PackageManager.DONT_KILL_APP);
829     }
830 
cleanup()831     void cleanup() {
832         debugLog("cleanup()");
833         if (mCleaningUp) {
834             errorLog("cleanup() - Service already starting to cleanup, ignoring request...");
835             return;
836         }
837 
838         clearAdapterService(this);
839 
840         mCleaningUp = true;
841         invalidateBluetoothCaches();
842 
843         unregisterReceiver(mAlarmBroadcastReceiver);
844 
845         if (mPendingAlarm != null) {
846             mAlarmManager.cancel(mPendingAlarm);
847             mPendingAlarm = null;
848         }
849 
850         // This wake lock release may also be called concurrently by
851         // {@link #releaseWakeLock(String lockName)}, so a synchronization is needed here.
852         synchronized (this) {
853             if (mWakeLock != null) {
854                 if (mWakeLock.isHeld()) {
855                     mWakeLock.release();
856                 }
857                 mWakeLock = null;
858             }
859         }
860 
861         if (mDatabaseManager != null) {
862             mDatabaseManager.cleanup();
863         }
864 
865         if (mAdapterStateMachine != null) {
866             mAdapterStateMachine.doQuit();
867         }
868 
869         if (mBondStateMachine != null) {
870             mBondStateMachine.doQuit();
871         }
872 
873         if (mRemoteDevices != null) {
874             mRemoteDevices.cleanup();
875         }
876 
877         if (mSdpManager != null) {
878             mSdpManager.cleanup();
879             mSdpManager = null;
880         }
881 
882         if (mBluetoothKeystoreService != null) {
883             mBluetoothKeystoreService.cleanup();
884         }
885 
886         if (mActivityAttributionService != null) {
887             mActivityAttributionService.cleanup();
888         }
889 
890         if (mNativeAvailable) {
891             debugLog("cleanup() - Cleaning up adapter native");
892             cleanupNative();
893             mNativeAvailable = false;
894         }
895 
896         if (mAdapterProperties != null) {
897             mAdapterProperties.cleanup();
898         }
899 
900         if (mJniCallbacks != null) {
901             mJniCallbacks.cleanup();
902         }
903 
904         if (mPhonePolicy != null) {
905             mPhonePolicy.cleanup();
906         }
907 
908         if (mSilenceDeviceManager != null) {
909             mSilenceDeviceManager.cleanup();
910         }
911 
912         if (mActiveDeviceManager != null) {
913             mActiveDeviceManager.cleanup();
914         }
915 
916         if (mProfileServicesState != null) {
917             mProfileServicesState.clear();
918         }
919 
920         if (mBluetoothSocketManagerBinder != null) {
921             mBluetoothSocketManagerBinder.cleanUp();
922             mBluetoothSocketManagerBinder = null;
923         }
924 
925         if (mBinder != null) {
926             mBinder.cleanup();
927             mBinder = null;  //Do not remove. Otherwise Binder leak!
928         }
929 
930         if (mCallbacks != null) {
931             mCallbacks.kill();
932         }
933     }
934 
invalidateBluetoothCaches()935     private void invalidateBluetoothCaches() {
936         BluetoothAdapter.invalidateGetProfileConnectionStateCache();
937         BluetoothAdapter.invalidateIsOffloadedFilteringSupportedCache();
938         BluetoothDevice.invalidateBluetoothGetBondStateCache();
939         BluetoothAdapter.invalidateBluetoothGetStateCache();
940         BluetoothAdapter.invalidateGetAdapterConnectionStateCache();
941     }
942 
setProfileServiceState(Class service, int state)943     private void setProfileServiceState(Class service, int state) {
944         if (state == BluetoothAdapter.STATE_ON) {
945             mStartedProfiles.add(service.getSimpleName());
946         } else if (state == BluetoothAdapter.STATE_OFF) {
947             mStartedProfiles.remove(service.getSimpleName());
948         }
949         Intent intent = new Intent(this, service);
950         intent.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED);
951         intent.putExtra(BluetoothAdapter.EXTRA_STATE, state);
952         startService(intent);
953     }
954 
setAllProfileServiceStates(Class[] services, int state)955     private void setAllProfileServiceStates(Class[] services, int state) {
956         for (Class service : services) {
957             if (GattService.class.getSimpleName().equals(service.getSimpleName())) {
958                 continue;
959             }
960             setProfileServiceState(service, state);
961         }
962     }
963 
964     /**
965      * Verifies whether the profile is supported by the local bluetooth adapter by checking a
966      * bitmask of its supported profiles
967      *
968      * @param remoteDeviceUuids is an array of all supported profiles by the remote device
969      * @param localDeviceUuids  is an array of all supported profiles by the local device
970      * @param profile           is the profile we are checking for support
971      * @param device            is the remote device we wish to connect to
972      * @return true if the profile is supported by both the local and remote device, false otherwise
973      */
974     @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
isSupported(ParcelUuid[] localDeviceUuids, ParcelUuid[] remoteDeviceUuids, int profile, BluetoothDevice device)975     private boolean isSupported(ParcelUuid[] localDeviceUuids, ParcelUuid[] remoteDeviceUuids,
976             int profile, BluetoothDevice device) {
977         if (remoteDeviceUuids == null || remoteDeviceUuids.length == 0) {
978             Log.e(TAG, "isSupported: Remote Device Uuids Empty");
979         }
980 
981         if (profile == BluetoothProfile.HEADSET) {
982             return (ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HSP_AG)
983                     && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HSP))
984                     || (ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HFP_AG)
985                     && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HFP));
986         }
987         if (profile == BluetoothProfile.HEADSET_CLIENT) {
988             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HFP_AG)
989                     && ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HFP);
990         }
991         if (profile == BluetoothProfile.A2DP) {
992             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.ADV_AUDIO_DIST)
993                     || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.A2DP_SINK);
994         }
995         if (profile == BluetoothProfile.A2DP_SINK) {
996             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.ADV_AUDIO_DIST)
997                     || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.A2DP_SOURCE);
998         }
999         if (profile == BluetoothProfile.OPP) {
1000             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.OBEX_OBJECT_PUSH);
1001         }
1002         if (profile == BluetoothProfile.HID_HOST) {
1003             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HID)
1004                     || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HOGP);
1005         }
1006         if (profile == BluetoothProfile.HID_DEVICE) {
1007             return mHidDeviceService.getConnectionState(device)
1008                     == BluetoothProfile.STATE_DISCONNECTED;
1009         }
1010         if (profile == BluetoothProfile.PAN) {
1011             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.NAP);
1012         }
1013         if (profile == BluetoothProfile.MAP) {
1014             return mMapService.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED;
1015         }
1016         if (profile == BluetoothProfile.PBAP) {
1017             return mPbapService.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED;
1018         }
1019         if (profile == BluetoothProfile.MAP_CLIENT) {
1020             return true;
1021         }
1022         if (profile == BluetoothProfile.PBAP_CLIENT) {
1023             return ArrayUtils.contains(localDeviceUuids, BluetoothUuid.PBAP_PCE)
1024                     && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.PBAP_PSE);
1025         }
1026         if (profile == BluetoothProfile.HEARING_AID) {
1027             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HEARING_AID);
1028         }
1029         if (profile == BluetoothProfile.SAP) {
1030             return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.SAP);
1031         }
1032 
1033         Log.e(TAG, "isSupported: Unexpected profile passed in to function: " + profile);
1034         return false;
1035     }
1036 
1037     /**
1038      * Checks if any profile is enabled for the given device
1039      *
1040      * @param device is the device for which we are checking if any profiles are enabled
1041      * @return true if any profile is enabled, false otherwise
1042      */
1043     @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
isAnyProfileEnabled(BluetoothDevice device)1044     private boolean isAnyProfileEnabled(BluetoothDevice device) {
1045 
1046         if (mA2dpService != null && mA2dpService.getConnectionPolicy(device)
1047                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1048             return true;
1049         }
1050         if (mA2dpSinkService != null && mA2dpSinkService.getConnectionPolicy(device)
1051                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1052             return true;
1053         }
1054         if (mHeadsetService != null && mHeadsetService.getConnectionPolicy(device)
1055                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1056             return true;
1057         }
1058         if (mHeadsetClientService != null && mHeadsetClientService.getConnectionPolicy(device)
1059                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1060             return true;
1061         }
1062         if (mMapClientService != null && mMapClientService.getConnectionPolicy(device)
1063                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1064             return true;
1065         }
1066         if (mHidHostService != null && mHidHostService.getConnectionPolicy(device)
1067                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1068             return true;
1069         }
1070         if (mPanService != null && mPanService.getConnectionPolicy(device)
1071                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1072             return true;
1073         }
1074         if (mPbapClientService != null && mPbapClientService.getConnectionPolicy(device)
1075                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1076             return true;
1077         }
1078         if (mHearingAidService != null && mHearingAidService.getConnectionPolicy(device)
1079                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1080             return true;
1081         }
1082 
1083         return false;
1084     }
1085 
1086     /**
1087      * Connects only available profiles
1088      * (those with {@link BluetoothProfile.CONNECTION_POLICY_ALLOWED})
1089      *
1090      * @param device is the device with which we are connecting the profiles
1091      * @return true
1092      */
1093     @RequiresPermission(allOf = {
1094             android.Manifest.permission.BLUETOOTH_PRIVILEGED,
1095             android.Manifest.permission.MODIFY_PHONE_STATE,
1096     })
connectEnabledProfiles(BluetoothDevice device)1097     private boolean connectEnabledProfiles(BluetoothDevice device) {
1098         ParcelUuid[] remoteDeviceUuids = getRemoteUuids(device);
1099         ParcelUuid[] localDeviceUuids = mAdapterProperties.getUuids();
1100 
1101         if (mA2dpService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
1102                 BluetoothProfile.A2DP, device) && mA2dpService.getConnectionPolicy(device)
1103                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1104             Log.i(TAG, "connectEnabledProfiles: Connecting A2dp");
1105             mA2dpService.connect(device);
1106         }
1107         if (mA2dpSinkService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
1108                 BluetoothProfile.A2DP_SINK, device) && mA2dpSinkService.getConnectionPolicy(device)
1109                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1110             Log.i(TAG, "connectEnabledProfiles: Connecting A2dp Sink");
1111             mA2dpSinkService.connect(device);
1112         }
1113         if (mHeadsetService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
1114                 BluetoothProfile.HEADSET, device) && mHeadsetService.getConnectionPolicy(device)
1115                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1116             Log.i(TAG, "connectEnabledProfiles: Connecting Headset Profile");
1117             mHeadsetService.connect(device);
1118         }
1119         if (mHeadsetClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
1120                 BluetoothProfile.HEADSET_CLIENT, device)
1121                 && mHeadsetClientService.getConnectionPolicy(device)
1122                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1123             Log.i(TAG, "connectEnabledProfiles: Connecting HFP");
1124             mHeadsetClientService.connect(device);
1125         }
1126         if (mMapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
1127                 BluetoothProfile.MAP_CLIENT, device)
1128                 && mMapClientService.getConnectionPolicy(device)
1129                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1130             Log.i(TAG, "connectEnabledProfiles: Connecting MAP");
1131             mMapClientService.connect(device);
1132         }
1133         if (mHidHostService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
1134                 BluetoothProfile.HID_HOST, device) && mHidHostService.getConnectionPolicy(device)
1135                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1136             Log.i(TAG, "connectEnabledProfiles: Connecting Hid Host Profile");
1137             mHidHostService.connect(device);
1138         }
1139         if (mPanService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
1140                 BluetoothProfile.PAN, device) && mPanService.getConnectionPolicy(device)
1141                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1142             Log.i(TAG, "connectEnabledProfiles: Connecting Pan Profile");
1143             mPanService.connect(device);
1144         }
1145         if (mPbapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
1146                 BluetoothProfile.PBAP_CLIENT, device)
1147                 && mPbapClientService.getConnectionPolicy(device)
1148                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1149             Log.i(TAG, "connectEnabledProfiles: Connecting Pbap");
1150             mPbapClientService.connect(device);
1151         }
1152         if (mHearingAidService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
1153                 BluetoothProfile.HEARING_AID, device)
1154                 && mHearingAidService.getConnectionPolicy(device)
1155                 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
1156             Log.i(TAG, "connectEnabledProfiles: Connecting Hearing Aid Profile");
1157             mHearingAidService.connect(device);
1158         }
1159 
1160         return true;
1161     }
1162 
1163     /**
1164      * Verifies that all bluetooth profile services are running
1165      *
1166      * @return true if all bluetooth profile services running, false otherwise
1167      */
profileServicesRunning()1168     private boolean profileServicesRunning() {
1169         if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
1170                 && mRegisteredProfiles.size() == mRunningProfiles.size()) {
1171             return true;
1172         }
1173 
1174         Log.e(TAG, "profileServicesRunning: One or more supported services not running");
1175         return false;
1176     }
1177 
1178     /**
1179      * Initializes all the profile services fields
1180      */
initProfileServices()1181     private void initProfileServices() {
1182         Log.i(TAG, "initProfileServices: Initializing all bluetooth profile services");
1183         mA2dpService = A2dpService.getA2dpService();
1184         mA2dpSinkService = A2dpSinkService.getA2dpSinkService();
1185         mHeadsetService = HeadsetService.getHeadsetService();
1186         mHeadsetClientService = HeadsetClientService.getHeadsetClientService();
1187         mMapService = BluetoothMapService.getBluetoothMapService();
1188         mMapClientService = MapClientService.getMapClientService();
1189         mHidDeviceService = HidDeviceService.getHidDeviceService();
1190         mHidHostService = HidHostService.getHidHostService();
1191         mPanService = PanService.getPanService();
1192         mPbapService = BluetoothPbapService.getBluetoothPbapService();
1193         mPbapClientService = PbapClientService.getPbapClientService();
1194         mHearingAidService = HearingAidService.getHearingAidService();
1195         mSapService = SapService.getSapService();
1196     }
1197 
isAvailable()1198     private boolean isAvailable() {
1199         return !mCleaningUp;
1200     }
1201 
1202     /**
1203      * Handlers for incoming service calls
1204      */
1205     private AdapterServiceBinder mBinder;
1206 
1207     /**
1208      * The Binder implementation must be declared to be a static class, with
1209      * the AdapterService instance passed in the constructor. Furthermore,
1210      * when the AdapterService shuts down, the reference to the AdapterService
1211      * must be explicitly removed.
1212      *
1213      * Otherwise, a memory leak can occur from repeated starting/stopping the
1214      * service...Please refer to android.os.Binder for further details on
1215      * why an inner instance class should be avoided.
1216      *
1217      */
1218     @VisibleForTesting
1219     public static class AdapterServiceBinder extends IBluetooth.Stub {
1220         private AdapterService mService;
1221 
AdapterServiceBinder(AdapterService svc)1222         AdapterServiceBinder(AdapterService svc) {
1223             mService = svc;
1224             mService.invalidateBluetoothGetStateCache();
1225             BluetoothAdapter.getDefaultAdapter().disableBluetoothGetStateCache();
1226         }
1227 
cleanup()1228         public void cleanup() {
1229             mService = null;
1230         }
1231 
getService()1232         public AdapterService getService() {
1233             if (mService != null && mService.isAvailable()) {
1234                 return mService;
1235             }
1236             return null;
1237         }
1238 
1239         @Override
getState()1240         public int getState() {
1241             // don't check caller, may be called from system UI
1242             AdapterService service = getService();
1243             if (service == null) {
1244                 return BluetoothAdapter.STATE_OFF;
1245             }
1246 
1247             return service.getState();
1248         }
1249 
1250         @Override
enable(boolean quietMode, AttributionSource attributionSource)1251         public boolean enable(boolean quietMode, AttributionSource attributionSource) {
1252             AdapterService service = getService();
1253             if (service == null || !callerIsSystemOrActiveUser(TAG, "enable")
1254                     || !Utils.checkConnectPermissionForDataDelivery(
1255                             service, attributionSource, "AdapterService enable")) {
1256                 return false;
1257             }
1258 
1259             return service.enable(quietMode);
1260         }
1261 
1262         @Override
disable(AttributionSource attributionSource)1263         public boolean disable(AttributionSource attributionSource) {
1264             AdapterService service = getService();
1265             if (service == null || !callerIsSystemOrActiveUser(TAG, "disable")
1266                     || !Utils.checkConnectPermissionForDataDelivery(
1267                             service, attributionSource, "AdapterService disable")) {
1268                 return false;
1269             }
1270 
1271             return service.disable();
1272         }
1273 
1274         @Override
getAddress()1275         public String getAddress() {
1276             return getAddressWithAttribution(Utils.getCallingAttributionSource());
1277         }
1278 
1279         @Override
getAddressWithAttribution(AttributionSource attributionSource)1280         public String getAddressWithAttribution(AttributionSource attributionSource) {
1281             AdapterService service = getService();
1282             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getAddress")
1283                     || !Utils.checkConnectPermissionForDataDelivery(
1284                             service, attributionSource, "AdapterService getAddress")) {
1285                 return null;
1286             }
1287 
1288             enforceLocalMacAddressPermission(service);
1289 
1290             return Utils.getAddressStringFromByte(service.mAdapterProperties.getAddress());
1291         }
1292 
1293         @Override
getUuids(AttributionSource attributionSource)1294         public ParcelUuid[] getUuids(AttributionSource attributionSource) {
1295             AdapterService service = getService();
1296             if (service == null || !callerIsSystemOrActiveUser(TAG, "getUuids")
1297                     || !Utils.checkConnectPermissionForDataDelivery(
1298                             service, attributionSource, "AdapterService getUuids")) {
1299                 return new ParcelUuid[0];
1300             }
1301 
1302             return service.mAdapterProperties.getUuids();
1303         }
1304 
1305         @Override
getName(AttributionSource attributionSource)1306         public String getName(AttributionSource attributionSource) {
1307             AdapterService service = getService();
1308             if (service == null || !callerIsSystemOrActiveUser(TAG, "getName")
1309                     || !Utils.checkConnectPermissionForDataDelivery(
1310                             service, attributionSource, "AdapterService getName")) {
1311                 return null;
1312             }
1313 
1314             return service.getName();
1315         }
1316 
1317         @Override
getNameLengthForAdvertise(AttributionSource attributionSource)1318         public int getNameLengthForAdvertise(AttributionSource attributionSource) {
1319             AdapterService service = getService();
1320             if (service == null || !callerIsSystemOrActiveUser(TAG, "getNameLengthForAdvertise")
1321                     || !Utils.checkAdvertisePermissionForDataDelivery(
1322                             service, attributionSource, TAG)) {
1323                 return -1;
1324             }
1325 
1326             return service.getNameLengthForAdvertise();
1327         }
1328 
1329         @Override
setName(String name, AttributionSource attributionSource)1330         public boolean setName(String name, AttributionSource attributionSource) {
1331             AdapterService service = getService();
1332             if (service == null || !callerIsSystemOrActiveUser(TAG, "setName")
1333                     || !Utils.checkConnectPermissionForDataDelivery(
1334                             service, attributionSource, "AdapterService setName")) {
1335                 return false;
1336             }
1337 
1338             return service.mAdapterProperties.setName(name);
1339         }
1340 
1341         @Override
getBluetoothClass(AttributionSource attributionSource)1342         public BluetoothClass getBluetoothClass(AttributionSource attributionSource) {
1343             AdapterService service = getService();
1344             if (service == null || !callerIsSystemOrActiveUser(TAG, "getBluetoothClass")
1345                     || !Utils.checkConnectPermissionForDataDelivery(
1346                             service, attributionSource, "AdapterSource getBluetoothClass")) {
1347                 return null;
1348             }
1349 
1350             return service.mAdapterProperties.getBluetoothClass();
1351         }
1352 
1353         @Override
setBluetoothClass(BluetoothClass bluetoothClass, AttributionSource source)1354         public boolean setBluetoothClass(BluetoothClass bluetoothClass, AttributionSource source) {
1355             AdapterService service = getService();
1356             if (service == null
1357                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
1358                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
1359                 return false;
1360             }
1361 
1362             enforceBluetoothPrivilegedPermission(service);
1363 
1364             if (!service.mAdapterProperties.setBluetoothClass(bluetoothClass)) {
1365               return false;
1366             }
1367 
1368             return Settings.Global.putInt(
1369                     service.getContentResolver(),
1370                     Settings.Global.BLUETOOTH_CLASS_OF_DEVICE,
1371                     bluetoothClass.getClassOfDevice());
1372         }
1373 
1374         @Override
getIoCapability(AttributionSource attributionSource)1375         public int getIoCapability(AttributionSource attributionSource) {
1376             AdapterService service = getService();
1377             if (service == null || !callerIsSystemOrActiveUser(TAG, "getIoCapability")
1378                     || !Utils.checkConnectPermissionForDataDelivery(
1379                             service, attributionSource, "AdapterService getIoCapability")) {
1380                 return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
1381             }
1382 
1383             return service.mAdapterProperties.getIoCapability();
1384         }
1385 
1386         @Override
setIoCapability(int capability, AttributionSource source)1387         public boolean setIoCapability(int capability, AttributionSource source) {
1388             AdapterService service = getService();
1389             if (service == null
1390                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
1391                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
1392                 return false;
1393             }
1394 
1395             enforceBluetoothPrivilegedPermission(service);
1396 
1397             if (!isValidIoCapability(capability)) {
1398               return false;
1399             }
1400 
1401             return service.mAdapterProperties.setIoCapability(capability);
1402         }
1403 
1404         @Override
getLeIoCapability(AttributionSource attributionSource)1405         public int getLeIoCapability(AttributionSource attributionSource) {
1406             AdapterService service = getService();
1407             if (service == null || !callerIsSystemOrActiveUser(TAG, "getLeIoCapability")
1408                     || !Utils.checkConnectPermissionForDataDelivery(
1409                             service, attributionSource, "AdapterService getLeIoCapability")) {
1410                 return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
1411             }
1412 
1413             return service.mAdapterProperties.getLeIoCapability();
1414         }
1415 
1416         @Override
setLeIoCapability(int capability, AttributionSource source)1417         public boolean setLeIoCapability(int capability, AttributionSource source) {
1418             AdapterService service = getService();
1419             if (service == null
1420                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
1421                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
1422                 return false;
1423             }
1424 
1425             enforceBluetoothPrivilegedPermission(service);
1426 
1427             if (!isValidIoCapability(capability)) {
1428               return false;
1429             }
1430 
1431             return service.mAdapterProperties.setLeIoCapability(capability);
1432         }
1433 
1434         @Override
getScanMode(AttributionSource attributionSource)1435         public int getScanMode(AttributionSource attributionSource) {
1436             AdapterService service = getService();
1437             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getScanMode")
1438                     || !Utils.checkScanPermissionForDataDelivery(
1439                             service, attributionSource, "AdapterService getScanMode")) {
1440                 return BluetoothAdapter.SCAN_MODE_NONE;
1441             }
1442 
1443             return service.mAdapterProperties.getScanMode();
1444         }
1445 
1446         @Override
setScanMode(int mode, int duration, AttributionSource attributionSource)1447         public boolean setScanMode(int mode, int duration, AttributionSource attributionSource) {
1448             AdapterService service = getService();
1449             if (service == null || !callerIsSystemOrActiveUser(TAG, "setScanMode")
1450                     || !Utils.checkScanPermissionForDataDelivery(
1451                             service, attributionSource, "AdapterService setScanMode")) {
1452                 return false;
1453             }
1454 
1455             enforceBluetoothPrivilegedPermission(service);
1456 
1457             service.mAdapterProperties.setDiscoverableTimeout(duration);
1458             return service.mAdapterProperties.setScanMode(convertScanModeToHal(mode));
1459         }
1460 
1461         @Override
getDiscoverableTimeout(AttributionSource attributionSource)1462         public int getDiscoverableTimeout(AttributionSource attributionSource) {
1463             AdapterService service = getService();
1464             if (service == null || !callerIsSystemOrActiveUser(TAG, "getDiscoverableTimeout")
1465                     || !Utils.checkScanPermissionForDataDelivery(
1466                             service, attributionSource, "AdapterService getDiscoverableTimeout")) {
1467                 return 0;
1468             }
1469 
1470             return service.mAdapterProperties.getDiscoverableTimeout();
1471         }
1472 
1473         @Override
setDiscoverableTimeout(int timeout, AttributionSource attributionSource)1474         public boolean setDiscoverableTimeout(int timeout, AttributionSource attributionSource) {
1475             AdapterService service = getService();
1476             if (service == null || !callerIsSystemOrActiveUser(TAG, "setDiscoverableTimeout")
1477                     || !Utils.checkScanPermissionForDataDelivery(
1478                             service, attributionSource, "AdapterService setDiscoverableTimeout")) {
1479                 return false;
1480             }
1481 
1482             enforceBluetoothPrivilegedPermission(service);
1483 
1484             return service.mAdapterProperties.setDiscoverableTimeout(timeout);
1485         }
1486 
1487         @Override
startDiscovery(AttributionSource attributionSource)1488         public boolean startDiscovery(AttributionSource attributionSource) {
1489             AdapterService service = getService();
1490             if (service == null || !callerIsSystemOrActiveUser(TAG, "startDiscovery")) {
1491                 return false;
1492             }
1493 
1494             if (!Utils.checkScanPermissionForDataDelivery(
1495                     service, attributionSource, "Starting discovery.")) {
1496                 return false;
1497             }
1498 
1499             return service.startDiscovery(attributionSource);
1500         }
1501 
1502         @Override
cancelDiscovery(AttributionSource attributionSource)1503         public boolean cancelDiscovery(AttributionSource attributionSource) {
1504             AdapterService service = getService();
1505             if (service == null || !callerIsSystemOrActiveUser(TAG, "cancelDiscovery")
1506                     || !Utils.checkScanPermissionForDataDelivery(
1507                             service, attributionSource, "AdapterService cancelDiscovery")) {
1508                 return false;
1509             }
1510 
1511             service.debugLog("cancelDiscovery");
1512             return service.cancelDiscoveryNative();
1513         }
1514 
1515         @Override
isDiscovering(AttributionSource attributionSource)1516         public boolean isDiscovering(AttributionSource attributionSource) {
1517             AdapterService service = getService();
1518             if (service == null
1519                     || !callerIsSystemOrActiveOrManagedUser(service, TAG, "isDiscovering")
1520                     || !Utils.checkScanPermissionForDataDelivery(
1521                             service, attributionSource, "AdapterService isDiscovering")) {
1522                 return false;
1523             }
1524 
1525             return service.mAdapterProperties.isDiscovering();
1526         }
1527 
1528         @Override
getDiscoveryEndMillis(AttributionSource source)1529         public long getDiscoveryEndMillis(AttributionSource source) {
1530             AdapterService service = getService();
1531             if (service == null
1532                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
1533                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
1534                 return -1;
1535             }
1536 
1537             enforceBluetoothPrivilegedPermission(service);
1538 
1539             return service.mAdapterProperties.discoveryEndMillis();
1540         }
1541 
1542         @Override
getMostRecentlyConnectedDevices( AttributionSource attributionSource)1543         public List<BluetoothDevice> getMostRecentlyConnectedDevices(
1544                 AttributionSource attributionSource) {
1545             // don't check caller, may be called from system UI
1546             AdapterService service = getService();
1547             if (service == null || !Utils.checkConnectPermissionForDataDelivery(
1548                     service, attributionSource, "AdapterService getMostRecentlyConnectedDevices")) {
1549                 return new ArrayList<>();
1550             }
1551 
1552             return service.mDatabaseManager.getMostRecentlyConnectedDevices();
1553         }
1554 
1555         @Override
getBondedDevices(AttributionSource attributionSource)1556         public BluetoothDevice[] getBondedDevices(AttributionSource attributionSource) {
1557             // don't check caller, may be called from system UI
1558             AdapterService service = getService();
1559             if (service == null || !Utils.checkConnectPermissionForDataDelivery(
1560                     service, attributionSource, "AdapterService getBondedDevices")) {
1561                 return new BluetoothDevice[0];
1562             }
1563 
1564             return service.getBondedDevices();
1565         }
1566 
1567         @Override
getAdapterConnectionState()1568         public int getAdapterConnectionState() {
1569             // don't check caller, may be called from system UI
1570             AdapterService service = getService();
1571             if (service == null) {
1572                 return BluetoothAdapter.STATE_DISCONNECTED;
1573             }
1574 
1575             return service.mAdapterProperties.getConnectionState();
1576         }
1577 
1578         /**
1579          * This method has an associated binder cache.  The invalidation
1580          * methods must be changed if the logic behind this method changes.
1581          */
1582         @Override
getProfileConnectionState(int profile)1583         public int getProfileConnectionState(int profile) {
1584             AdapterService service = getService();
1585             if (service == null
1586                     || !callerIsSystemOrActiveOrManagedUser(
1587                             service, TAG, "getProfileConnectionState")) {
1588                 return BluetoothProfile.STATE_DISCONNECTED;
1589             }
1590 
1591             return service.mAdapterProperties.getProfileConnectionState(profile);
1592         }
1593 
1594         @Override
createBond(BluetoothDevice device, int transport, OobData remoteP192Data, OobData remoteP256Data, AttributionSource attributionSource)1595         public boolean createBond(BluetoothDevice device, int transport, OobData remoteP192Data,
1596                 OobData remoteP256Data, AttributionSource attributionSource) {
1597             Attributable.setAttributionSource(device, attributionSource);
1598             AdapterService service = getService();
1599             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBond")
1600                     || !Utils.checkConnectPermissionForDataDelivery(
1601                             service, attributionSource, "AdapterService createBond")) {
1602                 return false;
1603             }
1604 
1605             // This conditional is required to satisfy permission dependencies
1606             // since createBond calls createBondOutOfBand with null value passed as data.
1607             // BluetoothDevice#createBond requires BLUETOOTH_ADMIN only.
1608             service.enforceBluetoothPrivilegedPermissionIfNeeded(remoteP192Data, remoteP256Data);
1609 
1610             return service.createBond(device, transport, remoteP192Data, remoteP256Data,
1611                     attributionSource.getPackageName());
1612         }
1613 
1614         @Override
cancelBondProcess( BluetoothDevice device, AttributionSource attributionSource)1615         public boolean cancelBondProcess(
1616                 BluetoothDevice device, AttributionSource attributionSource) {
1617             Attributable.setAttributionSource(device, attributionSource);
1618             AdapterService service = getService();
1619             if (service == null || !callerIsSystemOrActiveUser(TAG, "cancelBondProcess")
1620                     || !Utils.checkConnectPermissionForDataDelivery(
1621                             service, attributionSource, "AdapterService cancelBondProcess")) {
1622                 return false;
1623             }
1624 
1625             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1626             if (deviceProp != null) {
1627                 deviceProp.setBondingInitiatedLocally(false);
1628             }
1629 
1630             return service.cancelBondNative(addressToBytes(device.getAddress()));
1631         }
1632 
1633         @Override
removeBond(BluetoothDevice device, AttributionSource attributionSource)1634         public boolean removeBond(BluetoothDevice device, AttributionSource attributionSource) {
1635             Attributable.setAttributionSource(device, attributionSource);
1636             AdapterService service = getService();
1637             if (service == null || !callerIsSystemOrActiveUser(TAG, "removeBond")
1638                     || !Utils.checkConnectPermissionForDataDelivery(
1639                             service, attributionSource, "AdapterService removeBond")) {
1640                 return false;
1641             }
1642 
1643             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1644             if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) {
1645                 return false;
1646             }
1647             service.mBondAttemptCallerInfo.remove(device.getAddress());
1648             deviceProp.setBondingInitiatedLocally(false);
1649 
1650             Message msg = service.mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND);
1651             msg.obj = device;
1652             service.mBondStateMachine.sendMessage(msg);
1653             return true;
1654         }
1655 
1656         @Override
getBondState(BluetoothDevice device, AttributionSource attributionSource)1657         public int getBondState(BluetoothDevice device, AttributionSource attributionSource) {
1658             // don't check caller, may be called from system UI
1659             Attributable.setAttributionSource(device, attributionSource);
1660             AdapterService service = getService();
1661             if (service == null || !Utils.checkConnectPermissionForDataDelivery(
1662                     service, attributionSource, "AdapterService getBondState")) {
1663                 return BluetoothDevice.BOND_NONE;
1664             }
1665 
1666             return service.getBondState(device);
1667         }
1668 
1669         @Override
isBondingInitiatedLocally( BluetoothDevice device, AttributionSource attributionSource)1670         public boolean isBondingInitiatedLocally(
1671                 BluetoothDevice device, AttributionSource attributionSource) {
1672             // don't check caller, may be called from system UI
1673             Attributable.setAttributionSource(device, attributionSource);
1674             AdapterService service = getService();
1675             if (service == null || !Utils.checkConnectPermissionForDataDelivery(
1676                     service, attributionSource, "AdapterService isBondingInitiatedLocally")) {
1677                 return false;
1678             }
1679 
1680             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1681             return deviceProp != null && deviceProp.isBondingInitiatedLocally();
1682         }
1683 
1684         @Override
generateLocalOobData(int transport, IBluetoothOobDataCallback callback, AttributionSource source)1685         public void generateLocalOobData(int transport, IBluetoothOobDataCallback callback,
1686                 AttributionSource source) {
1687             AdapterService service = getService();
1688             if (service == null
1689                     || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG)
1690                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
1691                 return;
1692             }
1693             enforceBluetoothPrivilegedPermission(service);
1694             service.generateLocalOobData(transport, callback);
1695         }
1696 
1697         @Override
getSupportedProfiles()1698         public long getSupportedProfiles() {
1699             AdapterService service = getService();
1700             if (service == null) {
1701                 return 0;
1702             }
1703             return Config.getSupportedProfilesBitMask();
1704         }
1705 
1706         @Override
getConnectionState(BluetoothDevice device)1707         public int getConnectionState(BluetoothDevice device) {
1708             return getConnectionStateWithAttribution(device, Utils.getCallingAttributionSource());
1709         }
1710 
1711         @Override
getConnectionStateWithAttribution( BluetoothDevice device, AttributionSource attributionSource)1712         public int getConnectionStateWithAttribution(
1713                 BluetoothDevice device, AttributionSource attributionSource) {
1714             Attributable.setAttributionSource(device, attributionSource);
1715             AdapterService service = getService();
1716             if (service == null || !Utils.checkConnectPermissionForDataDelivery(
1717                     service, attributionSource, "AdapterService getConnectionState")) {
1718                 return 0;
1719             }
1720 
1721             return service.getConnectionState(device);
1722         }
1723 
1724         @Override
canBondWithoutDialog(BluetoothDevice device, AttributionSource source)1725         public boolean canBondWithoutDialog(BluetoothDevice device, AttributionSource source) {
1726             Attributable.setAttributionSource(device, source);
1727             AdapterService service = getService();
1728             if (service == null
1729                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
1730                 return false;
1731             }
1732 
1733             enforceBluetoothPrivilegedPermission(service);
1734 
1735             return service.canBondWithoutDialog(device);
1736         }
1737 
1738         @Override
removeActiveDevice(@ctiveDeviceUse int profiles, AttributionSource source)1739         public boolean removeActiveDevice(@ActiveDeviceUse int profiles,
1740                 AttributionSource source) {
1741             AdapterService service = getService();
1742             if (service == null
1743                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
1744                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
1745                 return false;
1746             }
1747             return service.setActiveDevice(null, profiles);
1748         }
1749 
1750         @Override
setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles, AttributionSource source)1751         public boolean setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles,
1752                 AttributionSource source) {
1753             Attributable.setAttributionSource(device, source);
1754             AdapterService service = getService();
1755             if (service == null
1756                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
1757                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
1758                 return false;
1759             }
1760             return service.setActiveDevice(device, profiles);
1761         }
1762 
1763         @Override
connectAllEnabledProfiles(BluetoothDevice device, AttributionSource source)1764         public boolean connectAllEnabledProfiles(BluetoothDevice device,
1765                 AttributionSource source) {
1766             Attributable.setAttributionSource(device, source);
1767             AdapterService service = getService();
1768             if (service == null
1769                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
1770                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
1771                 return false;
1772             }
1773 
1774             enforceBluetoothPrivilegedPermission(service);
1775 
1776             try {
1777                 return service.connectAllEnabledProfiles(device);
1778             } catch (Exception e) {
1779                 Log.v(TAG, "connectAllEnabledProfiles() failed", e);
1780                 SneakyThrow.sneakyThrow(e);
1781                 throw new RuntimeException(e);
1782             }
1783         }
1784 
1785         @Override
disconnectAllEnabledProfiles(BluetoothDevice device, AttributionSource source)1786         public boolean disconnectAllEnabledProfiles(BluetoothDevice device,
1787                 AttributionSource source) {
1788             Attributable.setAttributionSource(device, source);
1789             AdapterService service = getService();
1790             if (service == null
1791                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
1792                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
1793                 return false;
1794             }
1795 
1796             enforceBluetoothPrivilegedPermission(service);
1797 
1798             try {
1799                 return service.disconnectAllEnabledProfiles(device);
1800             } catch (Exception e) {
1801                 Log.v(TAG, "disconnectAllEnabledProfiles() failed", e);
1802                 SneakyThrow.sneakyThrow(e);
1803                 throw new RuntimeException(e);
1804             }
1805         }
1806 
1807         @Override
getRemoteName(BluetoothDevice device, AttributionSource attributionSource)1808         public String getRemoteName(BluetoothDevice device, AttributionSource attributionSource) {
1809             Attributable.setAttributionSource(device, attributionSource);
1810             AdapterService service = getService();
1811             if (service == null
1812                     || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteName")
1813                     || !Utils.checkConnectPermissionForDataDelivery(
1814                             service, attributionSource, "AdapterService getRemoteName")) {
1815                 return null;
1816             }
1817 
1818             return service.getRemoteName(device);
1819         }
1820 
1821         @Override
getRemoteType(BluetoothDevice device, AttributionSource attributionSource)1822         public int getRemoteType(BluetoothDevice device, AttributionSource attributionSource) {
1823             Attributable.setAttributionSource(device, attributionSource);
1824             AdapterService service = getService();
1825             if (service == null
1826                     || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteType")
1827                     || !Utils.checkConnectPermissionForDataDelivery(
1828                             service, attributionSource, "AdapterService getRemoteType")) {
1829                 return BluetoothDevice.DEVICE_TYPE_UNKNOWN;
1830             }
1831 
1832             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1833             return deviceProp != null ? deviceProp.getDeviceType() : BluetoothDevice.DEVICE_TYPE_UNKNOWN;
1834         }
1835 
1836         @Override
getRemoteAlias(BluetoothDevice device)1837         public String getRemoteAlias(BluetoothDevice device) {
1838             return getRemoteAliasWithAttribution(device, Utils.getCallingAttributionSource());
1839         }
1840 
1841         @Override
getRemoteAliasWithAttribution( BluetoothDevice device, AttributionSource attributionSource)1842         public String getRemoteAliasWithAttribution(
1843                 BluetoothDevice device, AttributionSource attributionSource) {
1844             Attributable.setAttributionSource(device, attributionSource);
1845             AdapterService service = getService();
1846             if (service == null
1847                     || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteAlias")
1848                     || !Utils.checkConnectPermissionForDataDelivery(
1849                             service, attributionSource, "AdapterService getRemoteAlias")) {
1850                 return null;
1851             }
1852 
1853             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1854             return deviceProp != null ? deviceProp.getAlias() : null;
1855         }
1856 
1857         @Override
setRemoteAlias(BluetoothDevice device, String name, AttributionSource attributionSource)1858         public int setRemoteAlias(BluetoothDevice device, String name,
1859                 AttributionSource attributionSource) {
1860             Attributable.setAttributionSource(device, attributionSource);
1861             AdapterService service = getService();
1862             if (service == null) {
1863                 return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
1864             }
1865             if (!callerIsSystemOrActiveUser(TAG, "setRemoteAlias")) {
1866                 return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
1867             }
1868             if (name != null && name.isEmpty()) {
1869                 throw new IllegalArgumentException("alias cannot be the empty string");
1870             }
1871 
1872             if (!hasBluetoothPrivilegedPermission(service)) {
1873                 if (!Utils.checkConnectPermissionForDataDelivery(
1874                         service, attributionSource, "AdapterService setRemoteAlias")) {
1875                     return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
1876                 }
1877                 enforceCdmAssociation(service.mCompanionDeviceManager, service,
1878                         attributionSource.getPackageName(), Binder.getCallingUid(), device);
1879             }
1880 
1881             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1882             if (deviceProp == null) {
1883                 return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED;
1884             }
1885             deviceProp.setAlias(device, name);
1886             return BluetoothStatusCodes.SUCCESS;
1887         }
1888 
1889         @Override
getRemoteClass(BluetoothDevice device, AttributionSource attributionSource)1890         public int getRemoteClass(BluetoothDevice device, AttributionSource attributionSource) {
1891             Attributable.setAttributionSource(device, attributionSource);
1892             AdapterService service = getService();
1893             if (service == null
1894                     || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteClass")
1895                     || !Utils.checkConnectPermissionForDataDelivery(
1896                             service, attributionSource, "AdapterService getRemoteClass")) {
1897                 return 0;
1898             }
1899 
1900             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1901             return deviceProp != null ? deviceProp.getBluetoothClass() : 0;
1902         }
1903 
1904         @Override
getRemoteUuids( BluetoothDevice device, AttributionSource attributionSource)1905         public ParcelUuid[] getRemoteUuids(
1906                 BluetoothDevice device, AttributionSource attributionSource) {
1907             Attributable.setAttributionSource(device, attributionSource);
1908             AdapterService service = getService();
1909             if (service == null
1910                     || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteUuids")
1911                     || !Utils.checkConnectPermissionForDataDelivery(
1912                             service, attributionSource, "AdapterService getRemoteUuids")) {
1913                 return new ParcelUuid[0];
1914             }
1915 
1916             return service.getRemoteUuids(device);
1917         }
1918 
1919         @Override
fetchRemoteUuids(BluetoothDevice device)1920         public boolean fetchRemoteUuids(BluetoothDevice device) {
1921             return fetchRemoteUuidsWithAttribution(device, Utils.getCallingAttributionSource());
1922         }
1923 
1924         @Override
fetchRemoteUuidsWithAttribution( BluetoothDevice device, AttributionSource attributionSource)1925         public boolean fetchRemoteUuidsWithAttribution(
1926                 BluetoothDevice device, AttributionSource attributionSource) {
1927             Attributable.setAttributionSource(device, attributionSource);
1928             AdapterService service = getService();
1929             if (service == null
1930                     || !callerIsSystemOrActiveOrManagedUser(service, TAG, "fetchRemoteUuids")
1931                     || !Utils.checkConnectPermissionForDataDelivery(
1932                             service, attributionSource, "AdapterService fetchRemoteUuids")) {
1933                 return false;
1934             }
1935 
1936             service.mRemoteDevices.fetchUuids(device);
1937             return true;
1938         }
1939 
1940 
1941         @Override
setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode, AttributionSource attributionSource)1942         public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode,
1943                 AttributionSource attributionSource) {
1944             Attributable.setAttributionSource(device, attributionSource);
1945             AdapterService service = getService();
1946             if (service == null || !callerIsSystemOrActiveUser(TAG, "setPin")
1947                     || !Utils.checkConnectPermissionForDataDelivery(
1948                             service, attributionSource, "AdapterService setPin")) {
1949                 return false;
1950             }
1951 
1952             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1953             // Only allow setting a pin in bonding state, or bonded state in case of security
1954             // upgrade.
1955             if (deviceProp == null || !deviceProp.isBondingOrBonded()) {
1956                 return false;
1957             }
1958             if (pinCode.length != len) {
1959                 android.util.EventLog.writeEvent(0x534e4554, "139287605", -1,
1960                         "PIN code length mismatch");
1961                 return false;
1962             }
1963             service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_PIN_REPLIED);
1964             return service.pinReplyNative(addressToBytes(device.getAddress()), accept, len, pinCode);
1965         }
1966 
1967         @Override
setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey, AttributionSource attributionSource)1968         public boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey,
1969                 AttributionSource attributionSource) {
1970             Attributable.setAttributionSource(device, attributionSource);
1971             AdapterService service = getService();
1972             if (service == null || !callerIsSystemOrActiveUser(TAG, "setPasskey")
1973                     || !Utils.checkConnectPermissionForDataDelivery(
1974                             service, attributionSource, "AdapterService setPasskey")) {
1975                 return false;
1976             }
1977 
1978             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
1979             if (deviceProp == null || !deviceProp.isBonding()) {
1980                 return false;
1981             }
1982             if (passkey.length != len) {
1983                 android.util.EventLog.writeEvent(0x534e4554, "139287605", -1,
1984                         "Passkey length mismatch");
1985                 return false;
1986             }
1987             service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REPLIED);
1988             return service.sspReplyNative(
1989                     addressToBytes(device.getAddress()),
1990                     AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY,
1991                     accept,
1992                     Utils.byteArrayToInt(passkey));
1993         }
1994 
1995         @Override
setPairingConfirmation(BluetoothDevice device, boolean accept, AttributionSource source)1996         public boolean setPairingConfirmation(BluetoothDevice device, boolean accept,
1997                 AttributionSource source) {
1998             Attributable.setAttributionSource(device, source);
1999             AdapterService service = getService();
2000             if (service == null
2001                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2002                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2003                 return false;
2004             }
2005 
2006             enforceBluetoothPrivilegedPermission(service);
2007 
2008             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
2009             if (deviceProp == null || !deviceProp.isBonding()) {
2010                 return false;
2011             }
2012             service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REPLIED);
2013             return service.sspReplyNative(
2014                     addressToBytes(device.getAddress()),
2015                     AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION,
2016                     accept,
2017                     0);
2018         }
2019 
2020         @Override
getSilenceMode(BluetoothDevice device, AttributionSource source)2021         public boolean getSilenceMode(BluetoothDevice device, AttributionSource source) {
2022             Attributable.setAttributionSource(device, source);
2023             AdapterService service = getService();
2024             if (service == null
2025                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2026                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2027                 return false;
2028             }
2029 
2030             enforceBluetoothPrivilegedPermission(service);
2031 
2032             return service.mSilenceDeviceManager.getSilenceMode(device);
2033         }
2034 
2035 
2036         @Override
setSilenceMode(BluetoothDevice device, boolean silence, AttributionSource source)2037         public boolean setSilenceMode(BluetoothDevice device, boolean silence,
2038                 AttributionSource source) {
2039             Attributable.setAttributionSource(device, source);
2040             AdapterService service = getService();
2041             if (service == null
2042                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2043                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2044                 return false;
2045             }
2046 
2047             enforceBluetoothPrivilegedPermission(service);
2048 
2049             service.mSilenceDeviceManager.setSilenceMode(device, silence);
2050             return true;
2051         }
2052 
2053         @Override
getPhonebookAccessPermission( BluetoothDevice device, AttributionSource attributionSource)2054         public int getPhonebookAccessPermission(
2055                 BluetoothDevice device, AttributionSource attributionSource) {
2056             Attributable.setAttributionSource(device, attributionSource);
2057             AdapterService service = getService();
2058             if (service == null || !callerIsSystemOrActiveUser(TAG, "getPhonebookAccessPermission")
2059                     || !Utils.checkConnectPermissionForDataDelivery(
2060                     service, attributionSource, "AdapterService getPhonebookAccessPermission")) {
2061                 return BluetoothDevice.ACCESS_UNKNOWN;
2062             }
2063 
2064             return service.getDeviceAccessFromPrefs(device, PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE);
2065         }
2066 
2067         @Override
setPhonebookAccessPermission(BluetoothDevice device, int value, AttributionSource source)2068         public boolean setPhonebookAccessPermission(BluetoothDevice device, int value,
2069                 AttributionSource source) {
2070             Attributable.setAttributionSource(device, source);
2071             AdapterService service = getService();
2072             if (service == null
2073                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2074                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2075                 return false;
2076             }
2077 
2078             enforceBluetoothPrivilegedPermission(service);
2079 
2080             service.setPhonebookAccessPermission(device, value);
2081             return true;
2082         }
2083 
2084         @Override
getMessageAccessPermission( BluetoothDevice device, AttributionSource attributionSource)2085         public int getMessageAccessPermission(
2086                 BluetoothDevice device, AttributionSource attributionSource) {
2087             Attributable.setAttributionSource(device, attributionSource);
2088             AdapterService service = getService();
2089             if (service == null || !callerIsSystemOrActiveUser(TAG, "getMessageAccessPermission")
2090                     || !Utils.checkConnectPermissionForDataDelivery(
2091                     service, attributionSource, "AdapterService getMessageAccessPermission")) {
2092                 return BluetoothDevice.ACCESS_UNKNOWN;
2093             }
2094 
2095             return service.getDeviceAccessFromPrefs(device, MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE);
2096         }
2097 
2098         @Override
setMessageAccessPermission(BluetoothDevice device, int value, AttributionSource source)2099         public boolean setMessageAccessPermission(BluetoothDevice device, int value,
2100                 AttributionSource source) {
2101             Attributable.setAttributionSource(device, source);
2102             AdapterService service = getService();
2103             if (service == null
2104                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2105                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2106                 return false;
2107             }
2108 
2109             enforceBluetoothPrivilegedPermission(service);
2110 
2111             service.setMessageAccessPermission(device, value);
2112             return true;
2113         }
2114 
2115         @Override
getSimAccessPermission( BluetoothDevice device, AttributionSource attributionSource)2116         public int getSimAccessPermission(
2117                 BluetoothDevice device, AttributionSource attributionSource) {
2118             Attributable.setAttributionSource(device, attributionSource);
2119             AdapterService service = getService();
2120             if (service == null || !callerIsSystemOrActiveUser(TAG, "getSimAccessPermission")
2121                     || !Utils.checkConnectPermissionForDataDelivery(
2122                             service, attributionSource, "AdapterService getSimAccessPermission")) {
2123                 return BluetoothDevice.ACCESS_UNKNOWN;
2124             }
2125 
2126             return service.getDeviceAccessFromPrefs(device, SIM_ACCESS_PERMISSION_PREFERENCE_FILE);
2127         }
2128 
2129         @Override
setSimAccessPermission(BluetoothDevice device, int value, AttributionSource source)2130         public boolean setSimAccessPermission(BluetoothDevice device, int value,
2131                 AttributionSource source) {
2132             Attributable.setAttributionSource(device, source);
2133             AdapterService service = getService();
2134             if (service == null
2135                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2136                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2137                 return false;
2138             }
2139 
2140             enforceBluetoothPrivilegedPermission(service);
2141 
2142             service.setSimAccessPermission(device, value);
2143             return true;
2144         }
2145 
2146         @Override
getSocketManager()2147         public IBluetoothSocketManager getSocketManager() {
2148             AdapterService service = getService();
2149             if (service == null) {
2150                 return null;
2151             }
2152 
2153             return IBluetoothSocketManager.Stub.asInterface(service.mBluetoothSocketManagerBinder);
2154         }
2155 
2156         @Override
sdpSearch( BluetoothDevice device, ParcelUuid uuid, AttributionSource attributionSource)2157         public boolean sdpSearch(
2158                 BluetoothDevice device, ParcelUuid uuid, AttributionSource attributionSource) {
2159             Attributable.setAttributionSource(device, attributionSource);
2160             AdapterService service = getService();
2161             if (service == null || !callerIsSystemOrActiveUser(TAG, "sdpSearch")
2162                     || !Utils.checkConnectPermissionForDataDelivery(
2163                             service, attributionSource, "AdapterService sdpSearch")) {
2164                 return false;
2165             }
2166 
2167             if (service.mSdpManager == null) {
2168                 return false;
2169             }
2170             service.mSdpManager.sdpSearch(device, uuid);
2171             return true;
2172         }
2173 
2174         @Override
getBatteryLevel(BluetoothDevice device, AttributionSource attributionSource)2175         public int getBatteryLevel(BluetoothDevice device, AttributionSource attributionSource) {
2176             Attributable.setAttributionSource(device, attributionSource);
2177             AdapterService service = getService();
2178             if (service == null || !callerIsSystemOrActiveUser(TAG, "getBatteryLevel")
2179                     || !Utils.checkConnectPermissionForDataDelivery(
2180                             service, attributionSource, "AdapterService getBatteryLevel")) {
2181                 return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
2182             }
2183 
2184             DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
2185             if (deviceProp == null) {
2186                 return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
2187             }
2188             return deviceProp.getBatteryLevel();
2189         }
2190 
2191         @Override
getMaxConnectedAudioDevices(AttributionSource attributionSource)2192         public int getMaxConnectedAudioDevices(AttributionSource attributionSource) {
2193             // don't check caller, may be called from system UI
2194             AdapterService service = getService();
2195             if (service == null || !Utils.checkConnectPermissionForDataDelivery(
2196                     service, attributionSource, "AdapterService getMaxConnectedAudioDevices")) {
2197                 return AdapterProperties.MAX_CONNECTED_AUDIO_DEVICES_LOWER_BOND;
2198             }
2199 
2200             return service.getMaxConnectedAudioDevices();
2201         }
2202 
2203         //@Override
2204         @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
isA2dpOffloadEnabled(AttributionSource attributionSource)2205         public boolean isA2dpOffloadEnabled(AttributionSource attributionSource) {
2206             // don't check caller, may be called from system UI
2207             AdapterService service = getService();
2208             if (service == null || !Utils.checkConnectPermissionForDataDelivery(
2209                     service, attributionSource, "AdapterService isA2dpOffloadEnabled")) {
2210                 return false;
2211             }
2212 
2213             return service.isA2dpOffloadEnabled();
2214         }
2215 
2216         @Override
factoryReset(AttributionSource source)2217         public boolean factoryReset(AttributionSource source) {
2218             AdapterService service = getService();
2219             if (service == null
2220                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2221                 return false;
2222             }
2223 
2224             enforceBluetoothPrivilegedPermission(service);
2225 
2226             if (service.mDatabaseManager != null) {
2227                 service.mDatabaseManager.factoryReset();
2228             }
2229 
2230             if (service.mBluetoothKeystoreService != null) {
2231                 service.mBluetoothKeystoreService.factoryReset();
2232             }
2233 
2234             return service.factoryResetNative();
2235         }
2236 
2237         @Override
registerBluetoothConnectionCallback(IBluetoothConnectionCallback callback, AttributionSource source)2238         public boolean registerBluetoothConnectionCallback(IBluetoothConnectionCallback callback,
2239                 AttributionSource source) {
2240             AdapterService service = getService();
2241             if (service == null
2242                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2243                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2244                 return false;
2245             }
2246             enforceBluetoothPrivilegedPermission(service);
2247             service.mBluetoothConnectionCallbacks.add(callback);
2248             return true;
2249         }
2250 
2251         @Override
unregisterBluetoothConnectionCallback(IBluetoothConnectionCallback callback, AttributionSource source)2252         public boolean unregisterBluetoothConnectionCallback(IBluetoothConnectionCallback callback,
2253                 AttributionSource source) {
2254             AdapterService service = getService();
2255             if (service == null
2256                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2257                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2258                 return false;
2259             }
2260             enforceBluetoothPrivilegedPermission(service);
2261             return service.mBluetoothConnectionCallbacks.remove(callback);
2262         }
2263 
2264         @Override
registerCallback(IBluetoothCallback callback, AttributionSource source)2265         public void registerCallback(IBluetoothCallback callback, AttributionSource source) {
2266             AdapterService service = getService();
2267             if (service == null
2268                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2269                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2270                 return;
2271             }
2272 
2273             enforceBluetoothPrivilegedPermission(service);
2274 
2275             service.mCallbacks.register(callback);
2276         }
2277 
2278         @Override
unregisterCallback(IBluetoothCallback callback, AttributionSource source)2279         public void unregisterCallback(IBluetoothCallback callback, AttributionSource source) {
2280             AdapterService service = getService();
2281             if (service == null || service.mCallbacks == null
2282                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2283                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2284                 return;
2285             }
2286 
2287             enforceBluetoothPrivilegedPermission(service);
2288 
2289             service.mCallbacks.unregister(callback);
2290         }
2291 
2292         @Override
isMultiAdvertisementSupported()2293         public boolean isMultiAdvertisementSupported() {
2294             AdapterService service = getService();
2295             if (service == null) {
2296                 return false;
2297             }
2298 
2299             int val = service.mAdapterProperties.getNumOfAdvertisementInstancesSupported();
2300             return val >= MIN_ADVT_INSTANCES_FOR_MA;
2301         }
2302 
2303         /**
2304          * This method has an associated binder cache.  The invalidation
2305          * methods must be changed if the logic behind this method changes.
2306          */
2307         @Override
isOffloadedFilteringSupported()2308         public boolean isOffloadedFilteringSupported() {
2309             AdapterService service = getService();
2310             if (service == null) {
2311                 return false;
2312             }
2313 
2314             int val = service.getNumOfOffloadedScanFilterSupported();
2315             return val >= MIN_OFFLOADED_FILTERS;
2316         }
2317 
2318         @Override
isOffloadedScanBatchingSupported()2319         public boolean isOffloadedScanBatchingSupported() {
2320             AdapterService service = getService();
2321             if (service == null) {
2322                 return false;
2323             }
2324 
2325             int val = service.getOffloadedScanResultStorage();
2326             return val >= MIN_OFFLOADED_SCAN_STORAGE_BYTES;
2327         }
2328 
2329         @Override
isLe2MPhySupported()2330         public boolean isLe2MPhySupported() {
2331             AdapterService service = getService();
2332             if (service == null) {
2333                 return false;
2334             }
2335 
2336             return service.isLe2MPhySupported();
2337         }
2338 
2339         @Override
isLeCodedPhySupported()2340         public boolean isLeCodedPhySupported() {
2341             AdapterService service = getService();
2342             if (service == null) {
2343                 return false;
2344             }
2345 
2346             return service.isLeCodedPhySupported();
2347         }
2348 
2349         @Override
isLeExtendedAdvertisingSupported()2350         public boolean isLeExtendedAdvertisingSupported() {
2351             AdapterService service = getService();
2352             if (service == null) {
2353                 return false;
2354             }
2355 
2356             return service.isLeExtendedAdvertisingSupported();
2357         }
2358 
2359         @Override
isLePeriodicAdvertisingSupported()2360         public boolean isLePeriodicAdvertisingSupported() {
2361             AdapterService service = getService();
2362             if (service == null) {
2363                 return false;
2364             }
2365 
2366             return service.isLePeriodicAdvertisingSupported();
2367         }
2368 
2369         @Override
getLeMaximumAdvertisingDataLength()2370         public int getLeMaximumAdvertisingDataLength() {
2371             AdapterService service = getService();
2372             if (service == null) {
2373                 return 0;
2374             }
2375 
2376             return service.getLeMaximumAdvertisingDataLength();
2377         }
2378 
2379         @Override
isActivityAndEnergyReportingSupported()2380         public boolean isActivityAndEnergyReportingSupported() {
2381             AdapterService service = getService();
2382             if (service == null) {
2383                 return false;
2384             }
2385 
2386             return service.mAdapterProperties.isActivityAndEnergyReportingSupported();
2387         }
2388 
2389         @Override
reportActivityInfo(AttributionSource source)2390         public BluetoothActivityEnergyInfo reportActivityInfo(AttributionSource source) {
2391             AdapterService service = getService();
2392             if (service == null
2393                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2394                 return null;
2395             }
2396 
2397             enforceBluetoothPrivilegedPermission(service);
2398 
2399             return service.reportActivityInfo();
2400         }
2401 
2402         @Override
registerMetadataListener(IBluetoothMetadataListener listener, BluetoothDevice device, AttributionSource source)2403         public boolean registerMetadataListener(IBluetoothMetadataListener listener,
2404                 BluetoothDevice device, AttributionSource source) {
2405             Attributable.setAttributionSource(device, source);
2406             AdapterService service = getService();
2407             if (service == null
2408                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2409                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2410                 return false;
2411             }
2412 
2413             enforceBluetoothPrivilegedPermission(service);
2414 
2415             if (service.mMetadataListeners == null) {
2416                 return false;
2417             }
2418             ArrayList<IBluetoothMetadataListener> list = service.mMetadataListeners.get(device);
2419             if (list == null) {
2420                 list = new ArrayList<>();
2421             } else if (list.contains(listener)) {
2422                 // The device is already registered with this listener
2423                 return true;
2424             }
2425             list.add(listener);
2426             service.mMetadataListeners.put(device, list);
2427             return true;
2428         }
2429 
2430         @Override
unregisterMetadataListener(BluetoothDevice device, AttributionSource source)2431         public boolean unregisterMetadataListener(BluetoothDevice device,
2432                 AttributionSource source) {
2433             Attributable.setAttributionSource(device, source);
2434             AdapterService service = getService();
2435             if (service == null
2436                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2437                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2438                 return false;
2439             }
2440 
2441             enforceBluetoothPrivilegedPermission(service);
2442 
2443             if (service.mMetadataListeners == null) {
2444                 return false;
2445             }
2446             if (service.mMetadataListeners.containsKey(device)) {
2447                 service.mMetadataListeners.remove(device);
2448             }
2449             return true;
2450         }
2451 
2452         @Override
setMetadata(BluetoothDevice device, int key, byte[] value, AttributionSource source)2453         public boolean setMetadata(BluetoothDevice device, int key, byte[] value,
2454                 AttributionSource source) {
2455             Attributable.setAttributionSource(device, source);
2456             AdapterService service = getService();
2457             if (service == null
2458                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2459                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2460                 return false;
2461             }
2462 
2463             enforceBluetoothPrivilegedPermission(service);
2464 
2465             if (value.length > BluetoothDevice.METADATA_MAX_LENGTH) {
2466                 return false;
2467             }
2468             return service.mDatabaseManager.setCustomMeta(device, key, value);
2469         }
2470 
2471         @Override
getMetadata(BluetoothDevice device, int key, AttributionSource source)2472         public byte[] getMetadata(BluetoothDevice device, int key,
2473                 AttributionSource source) {
2474             Attributable.setAttributionSource(device, source);
2475             AdapterService service = getService();
2476             if (service == null
2477                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2478                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2479                 return null;
2480             }
2481 
2482             enforceBluetoothPrivilegedPermission(service);
2483 
2484             return service.mDatabaseManager.getCustomMeta(device, key);
2485         }
2486 
2487         @Override
requestActivityInfo(ResultReceiver result, AttributionSource source)2488         public void requestActivityInfo(ResultReceiver result, AttributionSource source) {
2489             Bundle bundle = new Bundle();
2490             bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY,
2491                     reportActivityInfo(source));
2492             result.send(0, bundle);
2493         }
2494 
2495         @Override
onLeServiceUp(AttributionSource source)2496         public void onLeServiceUp(AttributionSource source) {
2497             AdapterService service = getService();
2498             if (service == null
2499                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2500                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2501                 return;
2502             }
2503 
2504             enforceBluetoothPrivilegedPermission(service);
2505 
2506             service.mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
2507         }
2508 
2509         @Override
onBrEdrDown(AttributionSource source)2510         public void onBrEdrDown(AttributionSource source) {
2511             AdapterService service = getService();
2512             if (service == null
2513                     || !Utils.checkCallerIsSystemOrActiveUser(TAG)
2514                     || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
2515                 return;
2516             }
2517 
2518             enforceBluetoothPrivilegedPermission(service);
2519 
2520             service.mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF);
2521         }
2522 
2523         @Override
dump(FileDescriptor fd, String[] args)2524         public void dump(FileDescriptor fd, String[] args) {
2525             PrintWriter writer = new PrintWriter(new FileOutputStream(fd));
2526             AdapterService service = getService();
2527             if (service == null) {
2528                 return;
2529             }
2530 
2531             enforceDumpPermission(service);
2532 
2533             service.dump(fd, writer, args);
2534             writer.close();
2535         }
2536     }
2537 
2538     // ----API Methods--------
2539 
isEnabled()2540     public boolean isEnabled() {
2541         return getState() == BluetoothAdapter.STATE_ON;
2542     }
2543 
getState()2544     public int getState() {
2545         if (mAdapterProperties != null) {
2546             return mAdapterProperties.getState();
2547         }
2548         return BluetoothAdapter.STATE_OFF;
2549     }
2550 
enable(boolean quietMode)2551     public synchronized boolean enable(boolean quietMode) {
2552         // Enforce the user restriction for disallowing Bluetooth if it was set.
2553         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) {
2554             debugLog("enable() called when Bluetooth was disallowed");
2555             return false;
2556         }
2557 
2558         debugLog("enable() - Enable called with quiet mode status =  " + quietMode);
2559         mQuietmode = quietMode;
2560         mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
2561         return true;
2562     }
2563 
disable()2564     boolean disable() {
2565         debugLog("disable() called with mRunningProfiles.size() = " + mRunningProfiles.size());
2566         mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_OFF);
2567         return true;
2568     }
2569 
getName()2570     public String getName() {
2571         return mAdapterProperties.getName();
2572     }
2573 
getNameLengthForAdvertise()2574     public int getNameLengthForAdvertise() {
2575         return mAdapterProperties.getName().length();
2576     }
2577 
isValidIoCapability(int capability)2578     private static boolean isValidIoCapability(int capability) {
2579         if (capability < 0 || capability >= BluetoothAdapter.IO_CAPABILITY_MAX) {
2580             Log.e(TAG, "Invalid IO capability value - " + capability);
2581             return false;
2582         }
2583 
2584         return true;
2585     }
2586 
getDiscoveringPackages()2587     ArrayList<DiscoveringPackage> getDiscoveringPackages() {
2588         return mDiscoveringPackages;
2589     }
2590 
clearDiscoveringPackages()2591     void clearDiscoveringPackages() {
2592         synchronized (mDiscoveringPackages) {
2593             mDiscoveringPackages.clear();
2594         }
2595     }
2596 
startDiscovery(AttributionSource attributionSource)2597     boolean startDiscovery(AttributionSource attributionSource) {
2598         UserHandle callingUser = UserHandle.of(UserHandle.getCallingUserId());
2599         debugLog("startDiscovery");
2600         String callingPackage = attributionSource.getPackageName();
2601         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2602         boolean isQApp = Utils.isQApp(this, callingPackage);
2603         boolean hasDisavowedLocation =
2604                 Utils.hasDisavowedLocationForScan(this, attributionSource, mTestModeEnabled);
2605         String permission = null;
2606         if (Utils.checkCallerHasNetworkSettingsPermission(this)) {
2607             permission = android.Manifest.permission.NETWORK_SETTINGS;
2608         } else if (Utils.checkCallerHasNetworkSetupWizardPermission(this)) {
2609             permission = android.Manifest.permission.NETWORK_SETUP_WIZARD;
2610         } else if (!hasDisavowedLocation) {
2611             if (isQApp) {
2612                 if (!Utils.checkCallerHasFineLocation(this, attributionSource, callingUser)) {
2613                     return false;
2614                 }
2615                 permission = android.Manifest.permission.ACCESS_FINE_LOCATION;
2616             } else {
2617                 if (!Utils.checkCallerHasCoarseLocation(this, attributionSource, callingUser)) {
2618                     return false;
2619                 }
2620                 permission = android.Manifest.permission.ACCESS_COARSE_LOCATION;
2621             }
2622         }
2623 
2624         synchronized (mDiscoveringPackages) {
2625             mDiscoveringPackages.add(
2626                     new DiscoveringPackage(callingPackage, permission, hasDisavowedLocation));
2627         }
2628         return startDiscoveryNative();
2629     }
2630 
2631     /**
2632      * Same as API method {@link BluetoothAdapter#getBondedDevices()}
2633      *
2634      * @return array of bonded {@link BluetoothDevice} or null on error
2635      */
getBondedDevices()2636     public BluetoothDevice[] getBondedDevices() {
2637         return mAdapterProperties.getBondedDevices();
2638     }
2639 
2640     /**
2641      * Get the database manager to access Bluetooth storage
2642      *
2643      * @return {@link DatabaseManager} or null on error
2644      */
2645     @VisibleForTesting
getDatabase()2646     public DatabaseManager getDatabase() {
2647         return mDatabaseManager;
2648     }
2649 
2650     private class CallerInfo {
2651         public String callerPackageName;
2652         public UserHandle user;
2653     }
2654 
createBond(BluetoothDevice device, int transport, OobData remoteP192Data, OobData remoteP256Data, String callingPackage)2655     boolean createBond(BluetoothDevice device, int transport, OobData remoteP192Data,
2656             OobData remoteP256Data, String callingPackage) {
2657         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
2658         if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {
2659             return false;
2660         }
2661 
2662         if (!isPackageNameAccurate(this, callingPackage, Binder.getCallingUid())) {
2663             return false;
2664         }
2665 
2666         CallerInfo createBondCaller = new CallerInfo();
2667         createBondCaller.callerPackageName = callingPackage;
2668         createBondCaller.user = UserHandle.of(UserHandle.getCallingUserId());
2669         mBondAttemptCallerInfo.put(device.getAddress(), createBondCaller);
2670 
2671         mRemoteDevices.setBondingInitiatedLocally(Utils.getByteAddress(device));
2672 
2673         // Pairing is unreliable while scanning, so cancel discovery
2674         // Note, remove this when native stack improves
2675         cancelDiscoveryNative();
2676 
2677         Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
2678         msg.obj = device;
2679         msg.arg1 = transport;
2680 
2681         Bundle remoteOobDatasBundle = new Bundle();
2682         boolean setData = false;
2683         if (remoteP192Data != null) {
2684             remoteOobDatasBundle.putParcelable(BondStateMachine.OOBDATAP192, remoteP192Data);
2685             setData = true;
2686         }
2687         if (remoteP256Data != null) {
2688             remoteOobDatasBundle.putParcelable(BondStateMachine.OOBDATAP256, remoteP256Data);
2689             setData = true;
2690         }
2691         if (setData) {
2692             msg.setData(remoteOobDatasBundle);
2693         }
2694         mBondStateMachine.sendMessage(msg);
2695         return true;
2696     }
2697 
2698     private final ArrayDeque<IBluetoothOobDataCallback> mOobDataCallbackQueue =
2699             new ArrayDeque<>();
2700 
2701     /**
2702      * Fetches the local OOB data to give out to remote.
2703      *
2704      * @param transport - specify data transport.
2705      * @param callback - callback used to receive the requested {@link Oobdata}; null will be
2706      * ignored silently.
2707      *
2708      * @hide
2709      */
generateLocalOobData(int transport, IBluetoothOobDataCallback callback)2710     public synchronized void generateLocalOobData(int transport,
2711             IBluetoothOobDataCallback callback) {
2712         if (callback == null) {
2713             Log.e(TAG, "'callback' argument must not be null!");
2714             return;
2715         }
2716         if (mOobDataCallbackQueue.peek() != null) {
2717             try {
2718                 callback.onError(BluetoothStatusCodes.ERROR_ANOTHER_ACTIVE_OOB_REQUEST);
2719                 return;
2720             } catch (RemoteException e) {
2721                 Log.e(TAG, "Failed to make callback", e);
2722             }
2723         }
2724         mOobDataCallbackQueue.offer(callback);
2725         generateLocalOobDataNative(transport);
2726     }
2727 
notifyOobDataCallback(int transport, OobData oobData)2728     /* package */ synchronized void notifyOobDataCallback(int transport, OobData oobData) {
2729         if (mOobDataCallbackQueue.peek() == null) {
2730             Log.e(TAG, "Failed to make callback, no callback exists");
2731             return;
2732         }
2733         if (oobData == null) {
2734             try {
2735                 mOobDataCallbackQueue.poll().onError(BluetoothStatusCodes.ERROR_UNKNOWN);
2736             } catch (RemoteException e) {
2737                 Log.e(TAG, "Failed to make callback", e);
2738             }
2739         } else {
2740             try {
2741                 mOobDataCallbackQueue.poll().onOobData(transport, oobData);
2742             } catch (RemoteException e) {
2743                 Log.e(TAG, "Failed to make callback", e);
2744             }
2745         }
2746     }
2747 
isQuietModeEnabled()2748     public boolean isQuietModeEnabled() {
2749         debugLog("isQuetModeEnabled() - Enabled = " + mQuietmode);
2750         return mQuietmode;
2751     }
2752 
updateUuids()2753     public void updateUuids() {
2754         debugLog("updateUuids() - Updating UUIDs for bonded devices");
2755         BluetoothDevice[] bondedDevices = getBondedDevices();
2756         if (bondedDevices == null) {
2757             return;
2758         }
2759 
2760         for (BluetoothDevice device : bondedDevices) {
2761             mRemoteDevices.updateUuids(device);
2762         }
2763     }
2764 
2765     /**
2766      * Update device UUID changed to {@link BondStateMachine}
2767      *
2768      * @param device remote device of interest
2769      */
deviceUuidUpdated(BluetoothDevice device)2770     public void deviceUuidUpdated(BluetoothDevice device) {
2771         // Notify BondStateMachine for SDP complete / UUID changed.
2772         Message msg = mBondStateMachine.obtainMessage(BondStateMachine.UUID_UPDATE);
2773         msg.obj = device;
2774         mBondStateMachine.sendMessage(msg);
2775     }
2776 
2777     /**
2778      * Get the bond state of a particular {@link BluetoothDevice}
2779      *
2780      * @param device remote device of interest
2781      * @return bond state <p>Possible values are
2782      * {@link BluetoothDevice#BOND_NONE},
2783      * {@link BluetoothDevice#BOND_BONDING},
2784      * {@link BluetoothDevice#BOND_BONDED}.
2785      */
2786     @VisibleForTesting
getBondState(BluetoothDevice device)2787     public int getBondState(BluetoothDevice device) {
2788         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
2789         if (deviceProp == null) {
2790             return BluetoothDevice.BOND_NONE;
2791         }
2792         return deviceProp.getBondState();
2793     }
2794 
getConnectionState(BluetoothDevice device)2795     int getConnectionState(BluetoothDevice device) {
2796         return getConnectionStateNative(addressToBytes(device.getAddress()));
2797     }
2798 
2799     /**
2800      * Checks whether the device was recently associated with the comapnion app that called
2801      * {@link BluetoothDevice#createBond}. This allows these devices to skip the pairing dialog if
2802      * their pairing variant is {@link BluetoothDevice#PAIRING_VARIANT_CONSENT}.
2803      *
2804      * @param device the bluetooth device that is being bonded
2805      * @return true if it was recently associated and we can bypass the dialog, false otherwise
2806      */
canBondWithoutDialog(BluetoothDevice device)2807     public boolean canBondWithoutDialog(BluetoothDevice device) {
2808         if (mBondAttemptCallerInfo.containsKey(device.getAddress())) {
2809             CallerInfo bondCallerInfo = mBondAttemptCallerInfo.get(device.getAddress());
2810 
2811             return mCompanionDeviceManager.canPairWithoutPrompt(bondCallerInfo.callerPackageName,
2812                     device.getAddress(), bondCallerInfo.user);
2813         }
2814         return false;
2815     }
2816 
2817     /**
2818      * Sets device as the active devices for the profiles passed into the function
2819      *
2820      * @param device is the remote bluetooth device
2821      * @param profiles is a constant that references for which profiles we'll be setting the remote
2822      *                 device as our active device. One of the following:
2823      *                 {@link BluetoothAdapter#ACTIVE_DEVICE_AUDIO},
2824      *                 {@link BluetoothAdapter#ACTIVE_DEVICE_PHONE_CALL}
2825      *                 {@link BluetoothAdapter#ACTIVE_DEVICE_ALL}
2826      * @return false if profiles value is not one of the constants we accept, true otherwise
2827      */
2828     @RequiresPermission(allOf = {
2829             android.Manifest.permission.BLUETOOTH_PRIVILEGED,
2830             android.Manifest.permission.MODIFY_PHONE_STATE,
2831     })
setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles)2832     public boolean setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles) {
2833         enforceCallingOrSelfPermission(
2834                 BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
2835 
2836         boolean setA2dp = false;
2837         boolean setHeadset = false;
2838 
2839         // Determine for which profiles we want to set device as our active device
2840         switch(profiles) {
2841             case BluetoothAdapter.ACTIVE_DEVICE_AUDIO:
2842                 setA2dp = true;
2843                 break;
2844             case BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL:
2845                 setHeadset = true;
2846                 break;
2847             case BluetoothAdapter.ACTIVE_DEVICE_ALL:
2848                 setA2dp = true;
2849                 setHeadset = true;
2850                 break;
2851             default:
2852                 return false;
2853         }
2854 
2855         if (setA2dp && mA2dpService != null && (device == null
2856                 || mA2dpService.getConnectionPolicy(device)
2857                 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
2858             Log.i(TAG, "setActiveDevice: Setting active A2dp device " + device);
2859             mA2dpService.setActiveDevice(device);
2860         }
2861 
2862         if (mHearingAidService != null && (device == null
2863                 || mHearingAidService.getConnectionPolicy(device)
2864                 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
2865             Log.i(TAG, "setActiveDevice: Setting active Hearing Aid " + device);
2866             mHearingAidService.setActiveDevice(device);
2867         }
2868 
2869         if (setHeadset && mHeadsetService != null && (device == null
2870                 || mHeadsetService.getConnectionPolicy(device)
2871                 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
2872             Log.i(TAG, "setActiveDevice: Setting active Headset " + device);
2873             mHeadsetService.setActiveDevice(device);
2874         }
2875 
2876         return true;
2877     }
2878 
2879     /**
2880      * Connects all enabled and supported bluetooth profiles between the local and remote device
2881      *
2882      * @param device is the remote device with which to connect these profiles
2883      * @return true if all profiles successfully connected, false if an error occurred
2884      */
2885     @RequiresPermission(allOf = {
2886             android.Manifest.permission.BLUETOOTH_PRIVILEGED,
2887             android.Manifest.permission.MODIFY_PHONE_STATE,
2888     })
connectAllEnabledProfiles(BluetoothDevice device)2889     public boolean connectAllEnabledProfiles(BluetoothDevice device) {
2890         if (!profileServicesRunning()) {
2891             Log.e(TAG, "connectAllEnabledProfiles: Not all profile services running");
2892             return false;
2893         }
2894 
2895         // Checks if any profiles are enabled and if so, only connect enabled profiles
2896         if (isAnyProfileEnabled(device)) {
2897             return connectEnabledProfiles(device);
2898         }
2899 
2900         int numProfilesConnected = 0;
2901         ParcelUuid[] remoteDeviceUuids = getRemoteUuids(device);
2902         ParcelUuid[] localDeviceUuids = mAdapterProperties.getUuids();
2903 
2904         // All profile toggles disabled, so connects all supported profiles
2905         if (mA2dpService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2906                 BluetoothProfile.A2DP, device)) {
2907             Log.i(TAG, "connectAllEnabledProfiles: Connecting A2dp");
2908             // Set connection policy also connects the profile with CONNECTION_POLICY_ALLOWED
2909             mA2dpService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2910             numProfilesConnected++;
2911         }
2912         if (mA2dpSinkService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2913                 BluetoothProfile.A2DP_SINK, device)) {
2914             Log.i(TAG, "connectAllEnabledProfiles: Connecting A2dp Sink");
2915             mA2dpSinkService.setConnectionPolicy(device,
2916                     BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2917             numProfilesConnected++;
2918         }
2919         if (mHeadsetService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2920                 BluetoothProfile.HEADSET, device)) {
2921             Log.i(TAG, "connectAllEnabledProfiles: Connecting Headset Profile");
2922             mHeadsetService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2923             numProfilesConnected++;
2924         }
2925         if (mHeadsetClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2926                 BluetoothProfile.HEADSET_CLIENT, device)) {
2927             Log.i(TAG, "connectAllEnabledProfiles: Connecting HFP");
2928             mHeadsetClientService.setConnectionPolicy(device,
2929                     BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2930             numProfilesConnected++;
2931         }
2932         if (mMapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2933                 BluetoothProfile.MAP_CLIENT, device)) {
2934             Log.i(TAG, "connectAllEnabledProfiles: Connecting MAP");
2935             mMapClientService.setConnectionPolicy(device,
2936                     BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2937             numProfilesConnected++;
2938         }
2939         if (mHidHostService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2940                 BluetoothProfile.HID_HOST, device)) {
2941             Log.i(TAG, "connectAllEnabledProfiles: Connecting Hid Host Profile");
2942             mHidHostService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2943             numProfilesConnected++;
2944         }
2945         if (mPanService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2946                 BluetoothProfile.PAN, device)) {
2947             Log.i(TAG, "connectAllEnabledProfiles: Connecting Pan Profile");
2948             mPanService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2949             numProfilesConnected++;
2950         }
2951         if (mPbapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2952                 BluetoothProfile.PBAP_CLIENT, device)) {
2953             Log.i(TAG, "connectAllEnabledProfiles: Connecting Pbap");
2954             mPbapClientService.setConnectionPolicy(device,
2955                     BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2956             numProfilesConnected++;
2957         }
2958         if (mHearingAidService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
2959                 BluetoothProfile.HEARING_AID, device)) {
2960             Log.i(TAG, "connectAllEnabledProfiles: Connecting Hearing Aid Profile");
2961             mHearingAidService.setConnectionPolicy(device,
2962                     BluetoothProfile.CONNECTION_POLICY_ALLOWED);
2963             numProfilesConnected++;
2964         }
2965 
2966         Log.i(TAG, "connectAllEnabledProfiles: Number of Profiles Connected: "
2967                 + numProfilesConnected);
2968 
2969         return true;
2970     }
2971 
2972     /**
2973      * Disconnects all enabled and supported bluetooth profiles between the local and remote device
2974      *
2975      * @param device is the remote device with which to disconnect these profiles
2976      * @return true if all profiles successfully disconnected, false if an error occurred
2977      */
2978     @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
disconnectAllEnabledProfiles(BluetoothDevice device)2979     public boolean disconnectAllEnabledProfiles(BluetoothDevice device) {
2980         if (!profileServicesRunning()) {
2981             Log.e(TAG, "disconnectAllEnabledProfiles: Not all profile services bound");
2982             return false;
2983         }
2984 
2985         if (mA2dpService != null && mA2dpService.getConnectionState(device)
2986                 == BluetoothProfile.STATE_CONNECTED) {
2987             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp");
2988             mA2dpService.disconnect(device);
2989         }
2990         if (mA2dpSinkService != null && mA2dpSinkService.getConnectionState(device)
2991                 == BluetoothProfile.STATE_CONNECTED) {
2992             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp Sink");
2993             mA2dpSinkService.disconnect(device);
2994         }
2995         if (mHeadsetService != null && mHeadsetService.getConnectionState(device)
2996                 == BluetoothProfile.STATE_CONNECTED) {
2997             Log.i(TAG,
2998                     "disconnectAllEnabledProfiles: Disconnecting Headset Profile");
2999             mHeadsetService.disconnect(device);
3000         }
3001         if (mHeadsetClientService != null && mHeadsetClientService.getConnectionState(device)
3002                 == BluetoothProfile.STATE_CONNECTED) {
3003             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting HFP");
3004             mHeadsetClientService.disconnect(device);
3005         }
3006         if (mMapClientService != null && mMapClientService.getConnectionState(device)
3007                 == BluetoothProfile.STATE_CONNECTED) {
3008             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting MAP Client");
3009             mMapClientService.disconnect(device);
3010         }
3011         if (mMapService != null && mMapService.getConnectionState(device)
3012                 == BluetoothProfile.STATE_CONNECTED) {
3013             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting MAP");
3014             mMapService.disconnect(device);
3015         }
3016         if (mHidDeviceService != null && mHidDeviceService.getConnectionState(device)
3017                 == BluetoothProfile.STATE_CONNECTED) {
3018             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hid Device Profile");
3019             mHidDeviceService.disconnect(device);
3020         }
3021         if (mHidHostService != null && mHidHostService.getConnectionState(device)
3022                 == BluetoothProfile.STATE_CONNECTED) {
3023             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hid Host Profile");
3024             mHidHostService.disconnect(device);
3025         }
3026         if (mPanService != null && mPanService.getConnectionState(device)
3027                 == BluetoothProfile.STATE_CONNECTED) {
3028             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pan Profile");
3029             mPanService.disconnect(device);
3030         }
3031         if (mPbapClientService != null && mPbapClientService.getConnectionState(device)
3032                 == BluetoothProfile.STATE_CONNECTED) {
3033             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pbap Client");
3034             mPbapClientService.disconnect(device);
3035         }
3036         if (mPbapService != null && mPbapService.getConnectionState(device)
3037                 == BluetoothProfile.STATE_CONNECTED) {
3038             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pbap Server");
3039             mPbapService.disconnect(device);
3040         }
3041         if (mHearingAidService != null && mHearingAidService.getConnectionState(device)
3042                 == BluetoothProfile.STATE_CONNECTED) {
3043             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hearing Aid Profile");
3044             mHearingAidService.disconnect(device);
3045         }
3046         if (mSapService != null && mSapService.getConnectionState(device)
3047                 == BluetoothProfile.STATE_CONNECTED) {
3048             Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Sap Profile");
3049             mSapService.disconnect(device);
3050         }
3051 
3052         return true;
3053     }
3054 
3055     /**
3056      * Same as API method {@link BluetoothDevice#getName()}
3057      *
3058      * @param device remote device of interest
3059      * @return remote device name
3060      */
getRemoteName(BluetoothDevice device)3061     public String getRemoteName(BluetoothDevice device) {
3062         if (mRemoteDevices == null) {
3063             return null;
3064         }
3065         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
3066         if (deviceProp == null) {
3067             return null;
3068         }
3069         return deviceProp.getName();
3070     }
3071 
3072     /**
3073      * Get UUIDs for service supported by a remote device
3074      *
3075      * @param device the remote device that we want to get UUIDs from
3076      * @return
3077      */
3078     @VisibleForTesting
getRemoteUuids(BluetoothDevice device)3079     public ParcelUuid[] getRemoteUuids(BluetoothDevice device) {
3080         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
3081         if (deviceProp == null) {
3082             return null;
3083         }
3084         return deviceProp.getUuids();
3085     }
3086 
getBluetoothConnectionCallbacks()3087     public Set<IBluetoothConnectionCallback> getBluetoothConnectionCallbacks() {
3088         return mBluetoothConnectionCallbacks;
3089     }
3090 
3091     /**
3092      * Converts HCI disconnect reasons to Android disconnect reasons.
3093      * <p>
3094      * The HCI Error Codes used for ACL disconnect reasons propagated up from native code were
3095      * copied from: {@link system/bt/stack/include/hci_error_code.h}.
3096      * <p>
3097      * These error codes are specified and described in Bluetooth Core Spec v5.1, Vol 2, Part D.
3098      *
3099      * @param hciReason is the raw HCI disconnect reason from native.
3100      * @return the Android disconnect reason for apps.
3101      */
3102     static @BluetoothAdapter.BluetoothConnectionCallback.DisconnectReason int
hciToAndroidDisconnectReason(int hciReason)3103             hciToAndroidDisconnectReason(int hciReason) {
3104         switch(hciReason) {
3105             case /*HCI_SUCCESS*/ 0x00:
3106             case /*HCI_ERR_UNSPECIFIED*/ 0x1F:
3107             case /*HCI_ERR_UNDEFINED*/ 0xff:
3108                 return BluetoothStatusCodes.ERROR_UNKNOWN;
3109             case /*HCI_ERR_ILLEGAL_COMMAND*/ 0x01:
3110             case /*HCI_ERR_NO_CONNECTION*/ 0x02:
3111             case /*HCI_ERR_HW_FAILURE*/ 0x03:
3112             case /*HCI_ERR_DIFF_TRANSACTION_COLLISION*/ 0x2A:
3113             case /*HCI_ERR_ROLE_SWITCH_PENDING*/ 0x32:
3114             case /*HCI_ERR_ROLE_SWITCH_FAILED*/ 0x35:
3115                 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL;
3116             case /*HCI_ERR_PAGE_TIMEOUT*/ 0x04:
3117             case /*HCI_ERR_CONNECTION_TOUT*/ 0x08:
3118             case /*HCI_ERR_HOST_TIMEOUT*/ 0x10:
3119             case /*HCI_ERR_LMP_RESPONSE_TIMEOUT*/ 0x22:
3120             case /*HCI_ERR_ADVERTISING_TIMEOUT*/ 0x3C:
3121             case /*HCI_ERR_CONN_FAILED_ESTABLISHMENT*/ 0x3E:
3122                 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_TIMEOUT;
3123             case /*HCI_ERR_AUTH_FAILURE*/ 0x05:
3124             case /*HCI_ERR_KEY_MISSING*/ 0x06:
3125             case /*HCI_ERR_HOST_REJECT_SECURITY*/ 0x0E:
3126             case /*HCI_ERR_REPEATED_ATTEMPTS*/ 0x17:
3127             case /*HCI_ERR_PAIRING_NOT_ALLOWED*/ 0x18:
3128             case /*HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE*/ 0x25:
3129             case /*HCI_ERR_UNIT_KEY_USED*/ 0x26:
3130             case /*HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED*/ 0x29:
3131             case /*HCI_ERR_INSUFFCIENT_SECURITY*/ 0x2F:
3132             case /*HCI_ERR_HOST_BUSY_PAIRING*/ 0x38:
3133                 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SECURITY;
3134             case /*HCI_ERR_MEMORY_FULL*/ 0x07:
3135             case /*HCI_ERR_MAX_NUM_OF_CONNECTIONS*/ 0x09:
3136             case /*HCI_ERR_MAX_NUM_OF_SCOS*/ 0x0A:
3137             case /*HCI_ERR_COMMAND_DISALLOWED*/ 0x0C:
3138             case /*HCI_ERR_HOST_REJECT_RESOURCES*/ 0x0D:
3139             case /*HCI_ERR_LIMIT_REACHED*/ 0x43:
3140                 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_RESOURCE_LIMIT_REACHED;
3141             case /*HCI_ERR_CONNECTION_EXISTS*/ 0x0B:
3142                 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_CONNECTION_ALREADY_EXISTS;
3143             case /*HCI_ERR_HOST_REJECT_DEVICE*/ 0x0F:
3144                 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SYSTEM_POLICY;
3145             case /*HCI_ERR_ILLEGAL_PARAMETER_FMT*/ 0x12:
3146                 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_BAD_PARAMETERS;
3147             case /*HCI_ERR_PEER_USER*/ 0x13:
3148                 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE_REQUEST;
3149             case /*HCI_ERR_CONN_CAUSE_LOCAL_HOST*/ 0x16:
3150                 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL_REQUEST;
3151             case /*HCI_ERR_UNSUPPORTED_REM_FEATURE*/ 0x1A:
3152                 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE;
3153             case /*HCI_ERR_UNACCEPT_CONN_INTERVAL*/ 0x3B:
3154                 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_BAD_PARAMETERS;
3155             default:
3156                 Log.e(TAG, "Invalid HCI disconnect reason: " + hciReason);
3157                 return BluetoothStatusCodes.ERROR_UNKNOWN;
3158         }
3159     }
3160 
logUserBondResponse(BluetoothDevice device, boolean accepted, int event)3161     void logUserBondResponse(BluetoothDevice device, boolean accepted, int event) {
3162         final long token = Binder.clearCallingIdentity();
3163         try {
3164             BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
3165                     obfuscateAddress(device), 0, device.getType(),
3166                     BluetoothDevice.BOND_BONDING,
3167                     event,
3168                     accepted ? 0 : BluetoothDevice.UNBOND_REASON_AUTH_REJECTED);
3169         } finally {
3170             Binder.restoreCallingIdentity(token);
3171         }
3172     }
3173 
getDeviceAccessFromPrefs(BluetoothDevice device, String prefFile)3174     int getDeviceAccessFromPrefs(BluetoothDevice device, String prefFile) {
3175         SharedPreferences prefs = getSharedPreferences(prefFile, Context.MODE_PRIVATE);
3176         if (!prefs.contains(device.getAddress())) {
3177             return BluetoothDevice.ACCESS_UNKNOWN;
3178         }
3179         return prefs.getBoolean(device.getAddress(), false)
3180                 ? BluetoothDevice.ACCESS_ALLOWED
3181                 : BluetoothDevice.ACCESS_REJECTED;
3182     }
3183 
setDeviceAccessFromPrefs(BluetoothDevice device, int value, String prefFile)3184     void setDeviceAccessFromPrefs(BluetoothDevice device, int value, String prefFile) {
3185         SharedPreferences pref = getSharedPreferences(prefFile, Context.MODE_PRIVATE);
3186         SharedPreferences.Editor editor = pref.edit();
3187         if (value == BluetoothDevice.ACCESS_UNKNOWN) {
3188             editor.remove(device.getAddress());
3189         } else {
3190             editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED);
3191         }
3192         editor.apply();
3193     }
3194 
setPhonebookAccessPermission(BluetoothDevice device, int value)3195     public void setPhonebookAccessPermission(BluetoothDevice device, int value) {
3196         setDeviceAccessFromPrefs(device, value, PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE);
3197     }
3198 
setMessageAccessPermission(BluetoothDevice device, int value)3199     public void setMessageAccessPermission(BluetoothDevice device, int value) {
3200         setDeviceAccessFromPrefs(device, value, MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE);
3201     }
3202 
setSimAccessPermission(BluetoothDevice device, int value)3203     public void setSimAccessPermission(BluetoothDevice device, int value) {
3204         setDeviceAccessFromPrefs(device, value, SIM_ACCESS_PERMISSION_PREFERENCE_FILE);
3205     }
3206 
isRpaOffloadSupported()3207     public boolean isRpaOffloadSupported() {
3208         return mAdapterProperties.isRpaOffloadSupported();
3209     }
3210 
getNumOfOffloadedIrkSupported()3211     public int getNumOfOffloadedIrkSupported() {
3212         return mAdapterProperties.getNumOfOffloadedIrkSupported();
3213     }
3214 
getNumOfOffloadedScanFilterSupported()3215     public int getNumOfOffloadedScanFilterSupported() {
3216         return mAdapterProperties.getNumOfOffloadedScanFilterSupported();
3217     }
3218 
getOffloadedScanResultStorage()3219     public int getOffloadedScanResultStorage() {
3220         return mAdapterProperties.getOffloadedScanResultStorage();
3221     }
3222 
isLe2MPhySupported()3223     public boolean isLe2MPhySupported() {
3224         return mAdapterProperties.isLe2MPhySupported();
3225     }
3226 
isLeCodedPhySupported()3227     public boolean isLeCodedPhySupported() {
3228         return mAdapterProperties.isLeCodedPhySupported();
3229     }
3230 
isLeExtendedAdvertisingSupported()3231     public boolean isLeExtendedAdvertisingSupported() {
3232         return mAdapterProperties.isLeExtendedAdvertisingSupported();
3233     }
3234 
isLePeriodicAdvertisingSupported()3235     public boolean isLePeriodicAdvertisingSupported() {
3236         return mAdapterProperties.isLePeriodicAdvertisingSupported();
3237     }
3238 
getLeMaximumAdvertisingDataLength()3239     public int getLeMaximumAdvertisingDataLength() {
3240         return mAdapterProperties.getLeMaximumAdvertisingDataLength();
3241     }
3242 
3243     /**
3244      * Get the maximum number of connected audio devices.
3245      *
3246      * @return the maximum number of connected audio devices
3247      */
getMaxConnectedAudioDevices()3248     public int getMaxConnectedAudioDevices() {
3249         return mAdapterProperties.getMaxConnectedAudioDevices();
3250     }
3251 
3252     /**
3253      * Check whether A2DP offload is enabled.
3254      *
3255      * @return true if A2DP offload is enabled
3256      */
isA2dpOffloadEnabled()3257     public boolean isA2dpOffloadEnabled() {
3258         return mAdapterProperties.isA2dpOffloadEnabled();
3259     }
3260 
reportActivityInfo()3261     private BluetoothActivityEnergyInfo reportActivityInfo() {
3262         if (mAdapterProperties.getState() != BluetoothAdapter.STATE_ON
3263                 || !mAdapterProperties.isActivityAndEnergyReportingSupported()) {
3264             return null;
3265         }
3266 
3267         // Pull the data. The callback will notify mEnergyInfoLock.
3268         readEnergyInfo();
3269 
3270         synchronized (mEnergyInfoLock) {
3271             try {
3272                 mEnergyInfoLock.wait(CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS);
3273             } catch (InterruptedException e) {
3274                 // Just continue, the energy data may be stale but we won't miss anything next time
3275                 // we query.
3276             }
3277 
3278             final BluetoothActivityEnergyInfo info =
3279                     new BluetoothActivityEnergyInfo(SystemClock.elapsedRealtime(),
3280                             mStackReportedState, mTxTimeTotalMs, mRxTimeTotalMs, mIdleTimeTotalMs,
3281                             mEnergyUsedTotalVoltAmpSecMicro);
3282 
3283             // Count the number of entries that have byte counts > 0
3284             int arrayLen = 0;
3285             for (int i = 0; i < mUidTraffic.size(); i++) {
3286                 final UidTraffic traffic = mUidTraffic.valueAt(i);
3287                 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) {
3288                     arrayLen++;
3289                 }
3290             }
3291 
3292             // Copy the traffic objects whose byte counts are > 0
3293             final UidTraffic[] result = arrayLen > 0 ? new UidTraffic[arrayLen] : null;
3294             int putIdx = 0;
3295             for (int i = 0; i < mUidTraffic.size(); i++) {
3296                 final UidTraffic traffic = mUidTraffic.valueAt(i);
3297                 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) {
3298                     result[putIdx++] = traffic.clone();
3299                 }
3300             }
3301 
3302             info.setUidTraffic(result);
3303 
3304             return info;
3305         }
3306     }
3307 
getTotalNumOfTrackableAdvertisements()3308     public int getTotalNumOfTrackableAdvertisements() {
3309         return mAdapterProperties.getTotalNumOfTrackableAdvertisements();
3310     }
3311 
convertScanModeToHal(int mode)3312     private static int convertScanModeToHal(int mode) {
3313         switch (mode) {
3314             case BluetoothAdapter.SCAN_MODE_NONE:
3315                 return AbstractionLayer.BT_SCAN_MODE_NONE;
3316             case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
3317                 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE;
3318             case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
3319                 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
3320         }
3321         // errorLog("Incorrect scan mode in convertScanModeToHal");
3322         return -1;
3323     }
3324 
convertScanModeFromHal(int mode)3325     static int convertScanModeFromHal(int mode) {
3326         switch (mode) {
3327             case AbstractionLayer.BT_SCAN_MODE_NONE:
3328                 return BluetoothAdapter.SCAN_MODE_NONE;
3329             case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE:
3330                 return BluetoothAdapter.SCAN_MODE_CONNECTABLE;
3331             case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
3332                 return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
3333         }
3334         //errorLog("Incorrect scan mode in convertScanModeFromHal");
3335         return -1;
3336     }
3337 
3338     // This function is called from JNI. It allows native code to set a single wake
3339     // alarm. If an alarm is already pending and a new request comes in, the alarm
3340     // will be rescheduled (i.e. the previously set alarm will be cancelled).
setWakeAlarm(long delayMillis, boolean shouldWake)3341     private boolean setWakeAlarm(long delayMillis, boolean shouldWake) {
3342         synchronized (this) {
3343             if (mPendingAlarm != null) {
3344                 mAlarmManager.cancel(mPendingAlarm);
3345             }
3346 
3347             long wakeupTime = SystemClock.elapsedRealtime() + delayMillis;
3348             int type = shouldWake ? AlarmManager.ELAPSED_REALTIME_WAKEUP
3349                     : AlarmManager.ELAPSED_REALTIME;
3350 
3351             Intent intent = new Intent(ACTION_ALARM_WAKEUP);
3352             // TODO(b/171825892) Please replace FLAG_MUTABLE_UNAUDITED below
3353             // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
3354             mPendingAlarm =
3355                     PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT
3356                             | PendingIntent.FLAG_IMMUTABLE);
3357             mAlarmManager.setExact(type, wakeupTime, mPendingAlarm);
3358             return true;
3359         }
3360     }
3361 
3362     // This function is called from JNI. It allows native code to acquire a single wake lock.
3363     // If the wake lock is already held, this function returns success. Although this function
3364     // only supports acquiring a single wake lock at a time right now, it will eventually be
3365     // extended to allow acquiring an arbitrary number of wake locks. The current interface
3366     // takes |lockName| as a parameter in anticipation of that implementation.
acquireWakeLock(String lockName)3367     private boolean acquireWakeLock(String lockName) {
3368         synchronized (this) {
3369             if (mWakeLock == null) {
3370                 mWakeLockName = lockName;
3371                 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName);
3372             }
3373 
3374             if (!mWakeLock.isHeld()) {
3375                 mWakeLock.acquire();
3376             }
3377         }
3378         return true;
3379     }
3380 
3381     // This function is called from JNI. It allows native code to release a wake lock acquired
3382     // by |acquireWakeLock|. If the wake lock is not held, this function returns failure.
3383     // Note that the release() call is also invoked by {@link #cleanup()} so a synchronization is
3384     // needed here. See the comment for |acquireWakeLock| for an explanation of the interface.
releaseWakeLock(String lockName)3385     private boolean releaseWakeLock(String lockName) {
3386         synchronized (this) {
3387             if (mWakeLock == null) {
3388                 errorLog("Repeated wake lock release; aborting release: " + lockName);
3389                 return false;
3390             }
3391 
3392             if (mWakeLock.isHeld()) {
3393                 mWakeLock.release();
3394             }
3395         }
3396         return true;
3397     }
3398 
energyInfoCallback(int status, int ctrlState, long txTime, long rxTime, long idleTime, long energyUsed, UidTraffic[] data)3399     private void energyInfoCallback(int status, int ctrlState, long txTime, long rxTime,
3400             long idleTime, long energyUsed, UidTraffic[] data) throws RemoteException {
3401         if (ctrlState >= BluetoothActivityEnergyInfo.BT_STACK_STATE_INVALID
3402                 && ctrlState <= BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_IDLE) {
3403             // Energy is product of mA, V and ms. If the chipset doesn't
3404             // report it, we have to compute it from time
3405             if (energyUsed == 0) {
3406                 try {
3407                     final long txMah = Math.multiplyExact(txTime, getTxCurrentMa());
3408                     final long rxMah = Math.multiplyExact(rxTime, getRxCurrentMa());
3409                     final long idleMah = Math.multiplyExact(idleTime, getIdleCurrentMa());
3410                     energyUsed = (long) (Math.addExact(Math.addExact(txMah, rxMah), idleMah)
3411                             * getOperatingVolt());
3412                 } catch (ArithmeticException e) {
3413                     Log.wtf(TAG, "overflow in bluetooth energy callback", e);
3414                     // Energy is already 0 if the exception was thrown.
3415                 }
3416             }
3417 
3418             synchronized (mEnergyInfoLock) {
3419                 mStackReportedState = ctrlState;
3420                 long totalTxTimeMs;
3421                 long totalRxTimeMs;
3422                 long totalIdleTimeMs;
3423                 long totalEnergy;
3424                 try {
3425                     totalTxTimeMs = Math.addExact(mTxTimeTotalMs, txTime);
3426                     totalRxTimeMs = Math.addExact(mRxTimeTotalMs, rxTime);
3427                     totalIdleTimeMs = Math.addExact(mIdleTimeTotalMs, idleTime);
3428                     totalEnergy = Math.addExact(mEnergyUsedTotalVoltAmpSecMicro, energyUsed);
3429                 } catch (ArithmeticException e) {
3430                     // This could be because we accumulated a lot of time, or we got a very strange
3431                     // value from the controller (more likely). Discard this data.
3432                     Log.wtf(TAG, "overflow in bluetooth energy callback", e);
3433                     totalTxTimeMs = mTxTimeTotalMs;
3434                     totalRxTimeMs = mRxTimeTotalMs;
3435                     totalIdleTimeMs = mIdleTimeTotalMs;
3436                     totalEnergy = mEnergyUsedTotalVoltAmpSecMicro;
3437                 }
3438 
3439                 mTxTimeTotalMs = totalTxTimeMs;
3440                 mRxTimeTotalMs = totalRxTimeMs;
3441                 mIdleTimeTotalMs = totalIdleTimeMs;
3442                 mEnergyUsedTotalVoltAmpSecMicro = totalEnergy;
3443 
3444                 for (UidTraffic traffic : data) {
3445                     UidTraffic existingTraffic = mUidTraffic.get(traffic.getUid());
3446                     if (existingTraffic == null) {
3447                         mUidTraffic.put(traffic.getUid(), traffic);
3448                     } else {
3449                         existingTraffic.addRxBytes(traffic.getRxBytes());
3450                         existingTraffic.addTxBytes(traffic.getTxBytes());
3451                     }
3452                 }
3453                 mEnergyInfoLock.notifyAll();
3454             }
3455         }
3456 
3457         verboseLog("energyInfoCallback() status = " + status + "txTime = " + txTime + "rxTime = "
3458                 + rxTime + "idleTime = " + idleTime + "energyUsed = " + energyUsed + "ctrlState = "
3459                 + ctrlState + "traffic = " + Arrays.toString(data));
3460     }
3461 
3462     /**
3463      * Update metadata change to registered listeners
3464      */
3465     @VisibleForTesting
metadataChanged(String address, int key, byte[] value)3466     public void metadataChanged(String address, int key, byte[] value) {
3467         BluetoothDevice device = mRemoteDevices.getDevice(Utils.getBytesFromAddress(address));
3468         if (mMetadataListeners.containsKey(device)) {
3469             ArrayList<IBluetoothMetadataListener> list = mMetadataListeners.get(device);
3470             for (IBluetoothMetadataListener listener : list) {
3471                 try {
3472                     listener.onMetadataChanged(device, key, value);
3473                 } catch (RemoteException e) {
3474                     Log.w(TAG, "RemoteException when onMetadataChanged");
3475                 }
3476             }
3477         }
3478     }
3479 
getIdleCurrentMa()3480     private int getIdleCurrentMa() {
3481         return getResources().getInteger(R.integer.config_bluetooth_idle_cur_ma);
3482     }
3483 
getTxCurrentMa()3484     private int getTxCurrentMa() {
3485         return getResources().getInteger(R.integer.config_bluetooth_tx_cur_ma);
3486     }
3487 
getRxCurrentMa()3488     private int getRxCurrentMa() {
3489         return getResources().getInteger(R.integer.config_bluetooth_rx_cur_ma);
3490     }
3491 
getOperatingVolt()3492     private double getOperatingVolt() {
3493         return getResources().getInteger(R.integer.config_bluetooth_operating_voltage_mv) / 1000.0;
3494     }
3495 
3496     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)3497     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
3498         if (args.length == 0) {
3499             writer.println("Skipping dump in APP SERVICES, see bluetooth_manager section.");
3500             writer.println("Use --print argument for dumpsys direct from AdapterService.");
3501             return;
3502         }
3503 
3504         if ("set-test-mode".equals(args[0])) {
3505             final boolean testModeEnabled = "enabled".equalsIgnoreCase(args[1]);
3506             for (ProfileService profile : mRunningProfiles) {
3507                 profile.setTestModeEnabled(testModeEnabled);
3508             }
3509             mTestModeEnabled = testModeEnabled;
3510             return;
3511         }
3512 
3513         verboseLog("dumpsys arguments, check for protobuf output: " + TextUtils.join(" ", args));
3514         if (args[0].equals("--proto-bin")) {
3515             dumpMetrics(fd);
3516             return;
3517         }
3518 
3519         writer.println();
3520         mAdapterProperties.dump(fd, writer, args);
3521         writer.println("mSnoopLogSettingAtEnable = " + mSnoopLogSettingAtEnable);
3522         writer.println("mDefaultSnoopLogSettingAtEnable = " + mDefaultSnoopLogSettingAtEnable);
3523 
3524         writer.println();
3525         mAdapterStateMachine.dump(fd, writer, args);
3526 
3527         StringBuilder sb = new StringBuilder();
3528         for (ProfileService profile : mRegisteredProfiles) {
3529             profile.dump(sb);
3530         }
3531         mSilenceDeviceManager.dump(fd, writer, args);
3532         mDatabaseManager.dump(writer);
3533 
3534         writer.write(sb.toString());
3535         writer.flush();
3536 
3537         dumpNative(fd, args);
3538     }
3539 
dumpMetrics(FileDescriptor fd)3540     private void dumpMetrics(FileDescriptor fd) {
3541         BluetoothMetricsProto.BluetoothLog.Builder metricsBuilder =
3542                 BluetoothMetricsProto.BluetoothLog.newBuilder();
3543         byte[] nativeMetricsBytes = dumpMetricsNative();
3544         debugLog("dumpMetrics: native metrics size is " + nativeMetricsBytes.length);
3545         if (nativeMetricsBytes.length > 0) {
3546             try {
3547                 metricsBuilder.mergeFrom(nativeMetricsBytes);
3548             } catch (InvalidProtocolBufferException ex) {
3549                 Log.w(TAG, "dumpMetrics: problem parsing metrics protobuf, " + ex.getMessage());
3550                 return;
3551             }
3552         }
3553         metricsBuilder.setNumBondedDevices(getBondedDevices().length);
3554         MetricsLogger.dumpProto(metricsBuilder);
3555         for (ProfileService profile : mRegisteredProfiles) {
3556             profile.dumpProto(metricsBuilder);
3557         }
3558         byte[] metricsBytes = Base64.encode(metricsBuilder.build().toByteArray(), Base64.DEFAULT);
3559         debugLog("dumpMetrics: combined metrics size is " + metricsBytes.length);
3560         try (FileOutputStream protoOut = new FileOutputStream(fd)) {
3561             protoOut.write(metricsBytes);
3562         } catch (IOException e) {
3563             errorLog("dumpMetrics: error writing combined protobuf to fd, " + e.getMessage());
3564         }
3565     }
3566 
debugLog(String msg)3567     private void debugLog(String msg) {
3568         if (DBG) {
3569             Log.d(TAG, msg);
3570         }
3571     }
3572 
verboseLog(String msg)3573     private void verboseLog(String msg) {
3574         if (VERBOSE) {
3575             Log.v(TAG, msg);
3576         }
3577     }
3578 
errorLog(String msg)3579     private void errorLog(String msg) {
3580         Log.e(TAG, msg);
3581     }
3582 
3583     private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() {
3584         @Override
3585         public void onReceive(Context context, Intent intent) {
3586             synchronized (AdapterService.this) {
3587                 mPendingAlarm = null;
3588                 alarmFiredNative();
3589             }
3590         }
3591     };
3592 
isGuest()3593     private boolean isGuest() {
3594         return UserManager.get(this).isGuestUser();
3595     }
3596 
isCommonCriteriaMode()3597     private boolean isCommonCriteriaMode() {
3598         return ((DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE))
3599                 .isCommonCriteriaModeEnabled(null);
3600     }
3601 
3602     @SuppressLint("AndroidFrameworkRequiresPermission")
enforceBluetoothPrivilegedPermissionIfNeeded(OobData remoteP192Data, OobData remoteP256Data)3603     private void enforceBluetoothPrivilegedPermissionIfNeeded(OobData remoteP192Data,
3604             OobData remoteP256Data) {
3605         if (remoteP192Data != null || remoteP256Data != null) {
3606             enforceBluetoothPrivilegedPermission(this);
3607         }
3608     }
3609 
3610     // Boolean flags
3611     private static final String GD_CORE_FLAG = "INIT_gd_core";
3612     private static final String GD_ADVERTISING_FLAG = "INIT_gd_advertising";
3613     private static final String GD_SCANNING_FLAG = "INIT_gd_scanning";
3614     private static final String GD_HCI_FLAG = "INIT_gd_hci";
3615     private static final String GD_CONTROLLER_FLAG = "INIT_gd_controller";
3616     private static final String GD_ACL_FLAG = "INIT_gd_acl";
3617     private static final String GD_L2CAP_FLAG = "INIT_gd_l2cap";
3618     private static final String GD_RUST_FLAG = "INIT_gd_rust";
3619     private static final String GD_LINK_POLICY_FLAG = "INIT_gd_link_policy";
3620 
3621     /**
3622      * Logging flags logic (only applies to DEBUG and VERBOSE levels):
3623      * if LOG_TAG in LOGGING_DEBUG_DISABLED_FOR_TAGS_FLAG:
3624      *   DO NOT LOG
3625      * else if LOG_TAG in LOGGING_DEBUG_ENABLED_FOR_TAGS_FLAG:
3626      *   DO LOG
3627      * else if LOGGING_DEBUG_ENABLED_FOR_ALL_FLAG:
3628      *   DO LOG
3629      * else:
3630      *   DO NOT LOG
3631      */
3632     private static final String LOGGING_DEBUG_ENABLED_FOR_ALL_FLAG =
3633             "INIT_logging_debug_enabled_for_all";
3634     // String flags
3635     // Comma separated tags
3636     private static final String LOGGING_DEBUG_ENABLED_FOR_TAGS_FLAG =
3637             "INIT_logging_debug_enabled_for_tags";
3638     private static final String LOGGING_DEBUG_DISABLED_FOR_TAGS_FLAG =
3639             "INIT_logging_debug_disabled_for_tags";
3640     private static final String BTAA_HCI_LOG_FLAG = "INIT_btaa_hci";
3641 
getInitFlags()3642     private String[] getInitFlags() {
3643         ArrayList<String> initFlags = new ArrayList<>();
3644         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_CORE_FLAG, false)) {
3645             initFlags.add(String.format("%s=%s", GD_CORE_FLAG, "true"));
3646         }
3647         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_ADVERTISING_FLAG, false)) {
3648             initFlags.add(String.format("%s=%s", GD_ADVERTISING_FLAG, "true"));
3649         }
3650         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_SCANNING_FLAG,
3651                 Config.isGdEnabledUpToScanningLayer())) {
3652             initFlags.add(String.format("%s=%s", GD_SCANNING_FLAG, "true"));
3653         }
3654         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_HCI_FLAG, false)) {
3655             initFlags.add(String.format("%s=%s", GD_HCI_FLAG, "true"));
3656         }
3657         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_CONTROLLER_FLAG, false)) {
3658             initFlags.add(String.format("%s=%s", GD_CONTROLLER_FLAG, "true"));
3659         }
3660         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_ACL_FLAG, false)) {
3661             initFlags.add(String.format("%s=%s", GD_ACL_FLAG, "true"));
3662         }
3663         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_L2CAP_FLAG, false)) {
3664             initFlags.add(String.format("%s=%s", GD_L2CAP_FLAG, "true"));
3665         }
3666         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_RUST_FLAG, false)) {
3667             initFlags.add(String.format("%s=%s", GD_RUST_FLAG, "true"));
3668         }
3669         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_LINK_POLICY_FLAG, false)) {
3670             initFlags.add(String.format("%s=%s", GD_LINK_POLICY_FLAG, "true"));
3671         }
3672         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH,
3673                 LOGGING_DEBUG_ENABLED_FOR_ALL_FLAG, false)) {
3674             initFlags.add(String.format("%s=%s", LOGGING_DEBUG_ENABLED_FOR_ALL_FLAG, "true"));
3675             mIsVerboseLoggingEnabledForAll = true;
3676         }
3677         String debugLoggingEnabledTags = DeviceConfig.getString(DeviceConfig.NAMESPACE_BLUETOOTH,
3678                 LOGGING_DEBUG_ENABLED_FOR_TAGS_FLAG, "");
3679         if (!debugLoggingEnabledTags.isEmpty()) {
3680             initFlags.add(String.format("%s=%s", LOGGING_DEBUG_ENABLED_FOR_TAGS_FLAG,
3681                     debugLoggingEnabledTags));
3682         }
3683         String debugLoggingDisabledTags = DeviceConfig.getString(DeviceConfig.NAMESPACE_BLUETOOTH,
3684                 LOGGING_DEBUG_DISABLED_FOR_TAGS_FLAG, "");
3685         if (!debugLoggingDisabledTags.isEmpty()) {
3686             initFlags.add(String.format("%s=%s", LOGGING_DEBUG_DISABLED_FOR_TAGS_FLAG,
3687                     debugLoggingDisabledTags));
3688         }
3689         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, BTAA_HCI_LOG_FLAG, false)) {
3690             initFlags.add(String.format("%s=%s", BTAA_HCI_LOG_FLAG, "true"));
3691         }
3692         return initFlags.toArray(new String[0]);
3693     }
3694 
3695     private boolean mIsVerboseLoggingEnabledForAll = false;
3696 
getIsVerboseLoggingEnabledForAll()3697     public boolean getIsVerboseLoggingEnabledForAll() {
3698         return mIsVerboseLoggingEnabledForAll;
3699     }
3700 
3701     private final Object mDeviceConfigLock = new Object();
3702 
3703     /**
3704      * Predicate that can be applied to names to determine if a device is
3705      * well-known to be used for physical location.
3706      */
3707     @GuardedBy("mDeviceConfigLock")
3708     private Predicate<String> mLocationDenylistName = (v) -> false;
3709 
3710     /**
3711      * Predicate that can be applied to MAC addresses to determine if a device
3712      * is well-known to be used for physical location.
3713      */
3714     @GuardedBy("mDeviceConfigLock")
3715     private Predicate<byte[]> mLocationDenylistMac = (v) -> false;
3716 
3717     /**
3718      * Predicate that can be applied to Advertising Data payloads to determine
3719      * if a device is well-known to be used for physical location.
3720      */
3721     @GuardedBy("mDeviceConfigLock")
3722     private Predicate<byte[]> mLocationDenylistAdvertisingData = (v) -> false;
3723 
3724     @GuardedBy("mDeviceConfigLock")
3725     private int mScanQuotaCount = DeviceConfigListener.DEFAULT_SCAN_QUOTA_COUNT;
3726     @GuardedBy("mDeviceConfigLock")
3727     private long mScanQuotaWindowMillis = DeviceConfigListener.DEFAULT_SCAN_QUOTA_WINDOW_MILLIS;
3728     @GuardedBy("mDeviceConfigLock")
3729     private long mScanTimeoutMillis = DeviceConfigListener.DEFAULT_SCAN_TIMEOUT_MILLIS;
3730 
getLocationDenylistName()3731     public @NonNull Predicate<String> getLocationDenylistName() {
3732         synchronized (mDeviceConfigLock) {
3733             return mLocationDenylistName;
3734         }
3735     }
3736 
getLocationDenylistMac()3737     public @NonNull Predicate<byte[]> getLocationDenylistMac() {
3738         synchronized (mDeviceConfigLock) {
3739             return mLocationDenylistMac;
3740         }
3741     }
3742 
getLocationDenylistAdvertisingData()3743     public @NonNull Predicate<byte[]> getLocationDenylistAdvertisingData() {
3744         synchronized (mDeviceConfigLock) {
3745             return mLocationDenylistAdvertisingData;
3746         }
3747     }
3748 
getScanQuotaCount()3749     public int getScanQuotaCount() {
3750         synchronized (mDeviceConfigLock) {
3751             return mScanQuotaCount;
3752         }
3753     }
3754 
getScanQuotaWindowMillis()3755     public long getScanQuotaWindowMillis() {
3756         synchronized (mDeviceConfigLock) {
3757             return mScanQuotaWindowMillis;
3758         }
3759     }
3760 
getScanTimeoutMillis()3761     public long getScanTimeoutMillis() {
3762         synchronized (mDeviceConfigLock) {
3763             return mScanTimeoutMillis;
3764         }
3765     }
3766 
3767     private final DeviceConfigListener mDeviceConfigListener = new DeviceConfigListener();
3768 
3769     private class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener {
3770         private static final String LOCATION_DENYLIST_NAME =
3771                 "location_denylist_name";
3772         private static final String LOCATION_DENYLIST_MAC =
3773                 "location_denylist_mac";
3774         private static final String LOCATION_DENYLIST_ADVERTISING_DATA =
3775                 "location_denylist_advertising_data";
3776         private static final String SCAN_QUOTA_COUNT =
3777                 "scan_quota_count";
3778         private static final String SCAN_QUOTA_WINDOW_MILLIS =
3779                 "scan_quota_window_millis";
3780         private static final String SCAN_TIMEOUT_MILLIS =
3781                 "scan_timeout_millis";
3782 
3783         /**
3784          * Default denylist which matches Eddystone and iBeacon payloads.
3785          */
3786         private static final String DEFAULT_LOCATION_DENYLIST_ADVERTISING_DATA =
3787                 "⊆0016AAFE/00FFFFFF,⊆00FF4C0002/00FFFFFFFF";
3788 
3789         private static final int DEFAULT_SCAN_QUOTA_COUNT = 5;
3790         private static final long DEFAULT_SCAN_QUOTA_WINDOW_MILLIS = 30 * SECOND_IN_MILLIS;
3791         private static final long DEFAULT_SCAN_TIMEOUT_MILLIS = 30 * MINUTE_IN_MILLIS;
3792 
start()3793         public void start() {
3794             DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BLUETOOTH,
3795                     BackgroundThread.getExecutor(), this);
3796             onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BLUETOOTH));
3797         }
3798 
3799         @Override
onPropertiesChanged(DeviceConfig.Properties properties)3800         public void onPropertiesChanged(DeviceConfig.Properties properties) {
3801             synchronized (mDeviceConfigLock) {
3802                 final String name = properties.getString(LOCATION_DENYLIST_NAME, null);
3803                 mLocationDenylistName = !TextUtils.isEmpty(name)
3804                         ? Pattern.compile(name).asPredicate()
3805                         : (v) -> false;
3806                 mLocationDenylistMac = BytesMatcher
3807                         .decode(properties.getString(LOCATION_DENYLIST_MAC, null));
3808                 mLocationDenylistAdvertisingData = BytesMatcher
3809                         .decode(properties.getString(LOCATION_DENYLIST_ADVERTISING_DATA,
3810                                 DEFAULT_LOCATION_DENYLIST_ADVERTISING_DATA));
3811                 mScanQuotaCount = properties.getInt(SCAN_QUOTA_COUNT,
3812                         DEFAULT_SCAN_QUOTA_COUNT);
3813                 mScanQuotaWindowMillis = properties.getLong(SCAN_QUOTA_WINDOW_MILLIS,
3814                         DEFAULT_SCAN_QUOTA_WINDOW_MILLIS);
3815                 mScanTimeoutMillis = properties.getLong(SCAN_TIMEOUT_MILLIS,
3816                         DEFAULT_SCAN_TIMEOUT_MILLIS);
3817             }
3818         }
3819     }
3820 
3821     /**
3822      *  Obfuscate Bluetooth MAC address into a PII free ID string
3823      *
3824      *  @param device Bluetooth device whose MAC address will be obfuscated
3825      *  @return a byte array that is unique to this MAC address on this device,
3826      *          or empty byte array when either device is null or obfuscateAddressNative fails
3827      */
obfuscateAddress(BluetoothDevice device)3828     public byte[] obfuscateAddress(BluetoothDevice device) {
3829         if (device == null) {
3830             return new byte[0];
3831         }
3832         return obfuscateAddressNative(Utils.getByteAddress(device));
3833     }
3834 
3835     /**
3836      * Get dynamic audio buffer size supported type
3837      *
3838      * @return support <p>Possible values are
3839      * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_NONE},
3840      * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD},
3841      * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING}.
3842      */
getDynamicBufferSupport()3843     public int getDynamicBufferSupport() {
3844         return mAdapterProperties.getDynamicBufferSupport();
3845     }
3846 
3847     /**
3848      * Get dynamic audio buffer size
3849      *
3850      * @return BufferConstraints
3851      */
getBufferConstraints()3852     public BufferConstraints getBufferConstraints() {
3853         return mAdapterProperties.getBufferConstraints();
3854     }
3855 
3856     /**
3857      * Set dynamic audio buffer size
3858      *
3859      * @param codec Audio codec
3860      * @param value buffer millis
3861      * @return true if the settings is successful, false otherwise
3862      */
setBufferLengthMillis(int codec, int value)3863     public boolean setBufferLengthMillis(int codec, int value) {
3864         return mAdapterProperties.setBufferLengthMillis(codec, value);
3865     }
3866 
3867     /**
3868      *  Get an incremental id of Bluetooth metrics and log
3869      *
3870      *  @param device Bluetooth device
3871      *  @return int of id for Bluetooth metrics and logging, 0 if the device is invalid
3872      */
getMetricId(BluetoothDevice device)3873     public int getMetricId(BluetoothDevice device) {
3874         if (device == null) {
3875             return 0;
3876         }
3877         return getMetricIdNative(Utils.getByteAddress(device));
3878     }
3879 
classInitNative()3880     static native void classInitNative();
3881 
initNative(boolean startRestricted, boolean isCommonCriteriaMode, int configCompareResult, String[] initFlags, boolean isAtvDevice)3882     native boolean initNative(boolean startRestricted, boolean isCommonCriteriaMode,
3883             int configCompareResult, String[] initFlags, boolean isAtvDevice);
3884 
cleanupNative()3885     native void cleanupNative();
3886 
3887     /*package*/
enableNative()3888     native boolean enableNative();
3889 
3890     /*package*/
disableNative()3891     native boolean disableNative();
3892 
3893     /*package*/
setAdapterPropertyNative(int type, byte[] val)3894     native boolean setAdapterPropertyNative(int type, byte[] val);
3895 
3896     /*package*/
getAdapterPropertiesNative()3897     native boolean getAdapterPropertiesNative();
3898 
3899     /*package*/
getAdapterPropertyNative(int type)3900     native boolean getAdapterPropertyNative(int type);
3901 
3902     /*package*/
setAdapterPropertyNative(int type)3903     native boolean setAdapterPropertyNative(int type);
3904 
3905     /*package*/
setDevicePropertyNative(byte[] address, int type, byte[] val)3906     native boolean setDevicePropertyNative(byte[] address, int type, byte[] val);
3907 
3908     /*package*/
getDevicePropertyNative(byte[] address, int type)3909     native boolean getDevicePropertyNative(byte[] address, int type);
3910 
3911     /*package*/
createBondNative(byte[] address, int transport)3912     public native boolean createBondNative(byte[] address, int transport);
3913 
3914     /*package*/
createBondOutOfBandNative(byte[] address, int transport, OobData p192Data, OobData p256Data)3915     native boolean createBondOutOfBandNative(byte[] address, int transport,
3916             OobData p192Data, OobData p256Data);
3917 
3918     /*package*/
removeBondNative(byte[] address)3919     public native boolean removeBondNative(byte[] address);
3920 
3921     /*package*/
cancelBondNative(byte[] address)3922     native boolean cancelBondNative(byte[] address);
3923 
3924     /*package*/
generateLocalOobDataNative(int transport)3925     native void generateLocalOobDataNative(int transport);
3926 
3927     /*package*/
sdpSearchNative(byte[] address, byte[] uuid)3928     native boolean sdpSearchNative(byte[] address, byte[] uuid);
3929 
3930     /*package*/
getConnectionStateNative(byte[] address)3931     native int getConnectionStateNative(byte[] address);
3932 
startDiscoveryNative()3933     private native boolean startDiscoveryNative();
3934 
cancelDiscoveryNative()3935     private native boolean cancelDiscoveryNative();
3936 
pinReplyNative(byte[] address, boolean accept, int len, byte[] pin)3937     private native boolean pinReplyNative(byte[] address, boolean accept, int len, byte[] pin);
3938 
sspReplyNative(byte[] address, int type, boolean accept, int passkey)3939     private native boolean sspReplyNative(byte[] address, int type, boolean accept, int passkey);
3940 
3941     /*package*/
getRemoteServicesNative(byte[] address)3942     native boolean getRemoteServicesNative(byte[] address);
3943 
3944     /*package*/
getRemoteMasInstancesNative(byte[] address)3945     native boolean getRemoteMasInstancesNative(byte[] address);
3946 
readEnergyInfo()3947     private native int readEnergyInfo();
3948 
3949     /*package*/
factoryResetNative()3950     native boolean factoryResetNative();
3951 
alarmFiredNative()3952     private native void alarmFiredNative();
3953 
dumpNative(FileDescriptor fd, String[] arguments)3954     private native void dumpNative(FileDescriptor fd, String[] arguments);
3955 
dumpMetricsNative()3956     private native byte[] dumpMetricsNative();
3957 
interopDatabaseClearNative()3958     private native void interopDatabaseClearNative();
3959 
interopDatabaseAddNative(int feature, byte[] address, int length)3960     private native void interopDatabaseAddNative(int feature, byte[] address, int length);
3961 
obfuscateAddressNative(byte[] address)3962     private native byte[] obfuscateAddressNative(byte[] address);
3963 
setBufferLengthMillisNative(int codec, int value)3964     native boolean setBufferLengthMillisNative(int codec, int value);
3965 
getMetricIdNative(byte[] address)3966     private native int getMetricIdNative(byte[] address);
3967 
connectSocketNative( byte[] address, int type, byte[] uuid, int port, int flag, int callingUid)3968     /*package*/ native int connectSocketNative(
3969             byte[] address, int type, byte[] uuid, int port, int flag, int callingUid);
3970 
createSocketChannelNative( int type, String serviceName, byte[] uuid, int port, int flag, int callingUid)3971     /*package*/ native int createSocketChannelNative(
3972             int type, String serviceName, byte[] uuid, int port, int flag, int callingUid);
3973 
requestMaximumTxDataLengthNative(byte[] address)3974     /*package*/ native void requestMaximumTxDataLengthNative(byte[] address);
3975 
3976     // Returns if this is a mock object. This is currently used in testing so that we may not call
3977     // System.exit() while finalizing the object. Otherwise GC of mock objects unfortunately ends up
3978     // calling finalize() which in turn calls System.exit() and the process crashes.
3979     //
3980     // Mock this in your testing framework to return true to avoid the mentioned behavior. In
3981     // production this has no effect.
isMock()3982     public boolean isMock() {
3983         return false;
3984     }
3985 }
3986