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