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