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