Home | History | Annotate | Download | only in btservice
      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 {
    133         classInitNative();
    134     }
    135 
    136     private static AdapterService sAdapterService;
    137 
    138     public static synchronized AdapterService getAdapterService() {
    139         Log.d(TAG, "getAdapterService() - returning " + sAdapterService);
    140         return sAdapterService;
    141     }
    142 
    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 
    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      */
    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      */
    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      */
    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
    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 
    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 
    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 
    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 
    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
    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
    447     public IBinder onBind(Intent intent) {
    448         debugLog("onBind()");
    449         return mBinder;
    450     }
    451 
    452     @Override
    453     public boolean onUnbind(Intent intent) {
    454         debugLog("onUnbind() - calling cleanup");
    455         cleanup();
    456         return super.onUnbind(intent);
    457     }
    458 
    459     @Override
    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 
    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 
    518     void bringDownBle() {
    519         stopGattProfileService();
    520     }
    521 
    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      */
    535     void setBluetoothClassFromConfig() {
    536         int bluetoothClassConfig = retrieveBluetoothClassConfig();
    537         if (bluetoothClassConfig != 0) {
    538             mAdapterProperties.setBluetoothClass(new BluetoothClass(bluetoothClassConfig));
    539         }
    540     }
    541 
    542     private int retrieveBluetoothClassConfig() {
    543         return Settings.Global.getInt(
    544                 getContentResolver(), Settings.Global.BLUETOOTH_CLASS_OF_DEVICE, 0);
    545     }
    546 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    743         AdapterServiceBinder(AdapterService svc) {
    744             mService = svc;
    745         }
    746 
    747         public void cleanup() {
    748             mService = null;
    749         }
    750 
    751         public AdapterService getService() {
    752             if (mService != null && mService.isAvailable()) {
    753                 return mService;
    754             }
    755             return null;
    756         }
    757 
    758         @Override
    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
    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
    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
    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
    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
    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
    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
    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
    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 
    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 
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   1123         public long getSupportedProfiles() {
   1124             AdapterService service = getService();
   1125             if (service == null) {
   1126                 return 0;
   1127             }
   1128             return service.getSupportedProfiles();
   1129         }
   1130 
   1131         @Override
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   1376         public IBluetoothSocketManager getSocketManager() {
   1377             AdapterService service = getService();
   1378             if (service == null) {
   1379                 return null;
   1380             }
   1381             return service.getSocketManager();
   1382         }
   1383 
   1384         @Override
   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
   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
   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
   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
   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
   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
   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
   1462         public boolean isMultiAdvertisementSupported() {
   1463             AdapterService service = getService();
   1464             if (service == null) {
   1465                 return false;
   1466             }
   1467             return service.isMultiAdvertisementSupported();
   1468         }
   1469 
   1470         @Override
   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
   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
   1491         public boolean isLe2MPhySupported() {
   1492             AdapterService service = getService();
   1493             if (service == null) {
   1494                 return false;
   1495             }
   1496             return service.isLe2MPhySupported();
   1497         }
   1498 
   1499         @Override
   1500         public boolean isLeCodedPhySupported() {
   1501             AdapterService service = getService();
   1502             if (service == null) {
   1503                 return false;
   1504             }
   1505             return service.isLeCodedPhySupported();
   1506         }
   1507 
   1508         @Override
   1509         public boolean isLeExtendedAdvertisingSupported() {
   1510             AdapterService service = getService();
   1511             if (service == null) {
   1512                 return false;
   1513             }
   1514             return service.isLeExtendedAdvertisingSupported();
   1515         }
   1516 
   1517         @Override
   1518         public boolean isLePeriodicAdvertisingSupported() {
   1519             AdapterService service = getService();
   1520             if (service == null) {
   1521                 return false;
   1522             }
   1523             return service.isLePeriodicAdvertisingSupported();
   1524         }
   1525 
   1526         @Override
   1527         public int getLeMaximumAdvertisingDataLength() {
   1528             AdapterService service = getService();
   1529             if (service == null) {
   1530                 return 0;
   1531             }
   1532             return service.getLeMaximumAdvertisingDataLength();
   1533         }
   1534 
   1535         @Override
   1536         public boolean isActivityAndEnergyReportingSupported() {
   1537             AdapterService service = getService();
   1538             if (service == null) {
   1539                 return false;
   1540             }
   1541             return service.isActivityAndEnergyReportingSupported();
   1542         }
   1543 
   1544         @Override
   1545         public BluetoothActivityEnergyInfo reportActivityInfo() {
   1546             AdapterService service = getService();
   1547             if (service == null) {
   1548                 return null;
   1549             }
   1550             return service.reportActivityInfo();
   1551         }
   1552 
   1553         @Override
   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
   1561         public void onLeServiceUp() {
   1562             AdapterService service = getService();
   1563             if (service == null) {
   1564                 return;
   1565             }
   1566             service.onLeServiceUp();
   1567         }
   1568 
   1569         @Override
   1570         public void onBrEdrDown() {
   1571             AdapterService service = getService();
   1572             if (service == null) {
   1573                 return;
   1574             }
   1575             service.onBrEdrDown();
   1576         }
   1577 
   1578         @Override
   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 
   1594     public boolean isEnabled() {
   1595         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1596         return mAdapterProperties.getState() == BluetoothAdapter.STATE_ON;
   1597     }
   1598 
   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 
   1607     public boolean enable() {
   1608         return enable(false);
   1609     }
   1610 
   1611     public boolean enableNoAutoConnect() {
   1612         return enable(true);
   1613     }
   1614 
   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 
   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 
   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 
   1647     ParcelUuid[] getUuids() {
   1648         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1649 
   1650         return mAdapterProperties.getUuids();
   1651     }
   1652 
   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 
   1664     boolean setName(String name) {
   1665         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
   1666 
   1667         return mAdapterProperties.setName(name);
   1668     }
   1669 
   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      */
   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 
   1693     int getScanMode() {
   1694         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1695 
   1696         return mAdapterProperties.getScanMode();
   1697     }
   1698 
   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 
   1708     int getDiscoverableTimeout() {
   1709         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1710 
   1711         return mAdapterProperties.getDiscoverableTimeout();
   1712     }
   1713 
   1714     boolean setDiscoverableTimeout(int timeout) {
   1715         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1716 
   1717         return mAdapterProperties.setDiscoverableTimeout(timeout);
   1718     }
   1719 
   1720     boolean startDiscovery() {
   1721         debugLog("startDiscovery");
   1722         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
   1723 
   1724         return startDiscoveryNative();
   1725     }
   1726 
   1727     boolean cancelDiscovery() {
   1728         debugLog("cancelDiscovery");
   1729         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
   1730 
   1731         return cancelDiscoveryNative();
   1732     }
   1733 
   1734     boolean isDiscovering() {
   1735         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1736 
   1737         return mAdapterProperties.isDiscovering();
   1738     }
   1739 
   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      */
   1751     public BluetoothDevice[] getBondedDevices() {
   1752         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1753         return mAdapterProperties.getBondedDevices();
   1754     }
   1755 
   1756     int getAdapterConnectionState() {
   1757         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1758         return mAdapterProperties.getConnectionState();
   1759     }
   1760 
   1761     int getProfileConnectionState(int profile) {
   1762         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1763 
   1764         return mAdapterProperties.getProfileConnectionState(profile);
   1765     }
   1766 
   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 
   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 
   1803     public boolean isQuietModeEnabled() {
   1804         debugLog("isQuetModeEnabled() - Enabled = " + mQuietmode);
   1805         return mQuietmode;
   1806     }
   1807 
   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     boolean cancelBondProcess(BluetoothDevice device) {
   1821         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
   1822         byte[] addr = Utils.getBytesFromAddress(device.getAddress());
   1823 
   1824         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1825         if (deviceProp != null) {
   1826             deviceProp.setBondingInitiatedLocally(false);
   1827         }
   1828 
   1829         return cancelBondNative(addr);
   1830     }
   1831 
   1832     boolean removeBond(BluetoothDevice device) {
   1833         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
   1834         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1835         if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) {
   1836             return false;
   1837         }
   1838         deviceProp.setBondingInitiatedLocally(false);
   1839 
   1840         Message msg = mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND);
   1841         msg.obj = device;
   1842         mBondStateMachine.sendMessage(msg);
   1843         return true;
   1844     }
   1845 
   1846     /**
   1847      * Get the bond state of a particular {@link BluetoothDevice}
   1848      *
   1849      * @param device remote device of interest
   1850      * @return bond state <p>Possible values are
   1851      * {@link BluetoothDevice#BOND_NONE},
   1852      * {@link BluetoothDevice#BOND_BONDING},
   1853      * {@link BluetoothDevice#BOND_BONDED}.
   1854      */
   1855     @VisibleForTesting
   1856     public int getBondState(BluetoothDevice device) {
   1857         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1858         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1859         if (deviceProp == null) {
   1860             return BluetoothDevice.BOND_NONE;
   1861         }
   1862         return deviceProp.getBondState();
   1863     }
   1864 
   1865     boolean isBondingInitiatedLocally(BluetoothDevice device) {
   1866         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1867         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1868         if (deviceProp == null) {
   1869             return false;
   1870         }
   1871         return deviceProp.isBondingInitiatedLocally();
   1872     }
   1873 
   1874     long getSupportedProfiles() {
   1875         return Config.getSupportedProfilesBitMask();
   1876     }
   1877 
   1878     int getConnectionState(BluetoothDevice device) {
   1879         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1880         byte[] addr = Utils.getBytesFromAddress(device.getAddress());
   1881         return getConnectionStateNative(addr);
   1882     }
   1883 
   1884     /**
   1885      * Same as API method {@link BluetoothDevice#getName()}
   1886      *
   1887      * @param device remote device of interest
   1888      * @return remote device name
   1889      */
   1890     public String getRemoteName(BluetoothDevice device) {
   1891         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1892         if (mRemoteDevices == null) {
   1893             return null;
   1894         }
   1895         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1896         if (deviceProp == null) {
   1897             return null;
   1898         }
   1899         return deviceProp.getName();
   1900     }
   1901 
   1902     int getRemoteType(BluetoothDevice device) {
   1903         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1904         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1905         if (deviceProp == null) {
   1906             return BluetoothDevice.DEVICE_TYPE_UNKNOWN;
   1907         }
   1908         return deviceProp.getDeviceType();
   1909     }
   1910 
   1911     String getRemoteAlias(BluetoothDevice device) {
   1912         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1913         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1914         if (deviceProp == null) {
   1915             return null;
   1916         }
   1917         return deviceProp.getAlias();
   1918     }
   1919 
   1920     boolean setRemoteAlias(BluetoothDevice device, String name) {
   1921         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1922         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1923         if (deviceProp == null) {
   1924             return false;
   1925         }
   1926         deviceProp.setAlias(device, name);
   1927         return true;
   1928     }
   1929 
   1930     int getRemoteClass(BluetoothDevice device) {
   1931         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1932         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1933         if (deviceProp == null) {
   1934             return 0;
   1935         }
   1936 
   1937         return deviceProp.getBluetoothClass();
   1938     }
   1939 
   1940     /**
   1941      * Get UUIDs for service supported by a remote device
   1942      *
   1943      * @param device the remote device that we want to get UUIDs from
   1944      * @return
   1945      */
   1946     @VisibleForTesting
   1947     public ParcelUuid[] getRemoteUuids(BluetoothDevice device) {
   1948         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1949         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1950         if (deviceProp == null) {
   1951             return null;
   1952         }
   1953         return deviceProp.getUuids();
   1954     }
   1955 
   1956     boolean fetchRemoteUuids(BluetoothDevice device) {
   1957         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1958         mRemoteDevices.fetchUuids(device);
   1959         return true;
   1960     }
   1961 
   1962     int getBatteryLevel(BluetoothDevice device) {
   1963         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1964         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1965         if (deviceProp == null) {
   1966             return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
   1967         }
   1968         return deviceProp.getBatteryLevel();
   1969     }
   1970 
   1971     boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) {
   1972         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
   1973         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1974         // Only allow setting a pin in bonding state, or bonded state in case of security upgrade.
   1975         if (deviceProp == null || (deviceProp.getBondState() != BluetoothDevice.BOND_BONDING
   1976                 && deviceProp.getBondState() != BluetoothDevice.BOND_BONDED)) {
   1977             return false;
   1978         }
   1979 
   1980         byte[] addr = Utils.getBytesFromAddress(device.getAddress());
   1981         return pinReplyNative(addr, accept, len, pinCode);
   1982     }
   1983 
   1984     boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) {
   1985         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   1986         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   1987         if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) {
   1988             return false;
   1989         }
   1990 
   1991         byte[] addr = Utils.getBytesFromAddress(device.getAddress());
   1992         return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY, accept,
   1993                 Utils.byteArrayToInt(passkey));
   1994     }
   1995 
   1996     boolean setPairingConfirmation(BluetoothDevice device, boolean accept) {
   1997         enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
   1998                 "Need BLUETOOTH PRIVILEGED permission");
   1999         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
   2000         if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) {
   2001             return false;
   2002         }
   2003 
   2004         byte[] addr = Utils.getBytesFromAddress(device.getAddress());
   2005         return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION, accept,
   2006                 0);
   2007     }
   2008 
   2009     int getPhonebookAccessPermission(BluetoothDevice device) {
   2010         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2011         SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE,
   2012                 Context.MODE_PRIVATE);
   2013         if (!pref.contains(device.getAddress())) {
   2014             return BluetoothDevice.ACCESS_UNKNOWN;
   2015         }
   2016         return pref.getBoolean(device.getAddress(), false) ? BluetoothDevice.ACCESS_ALLOWED
   2017                 : BluetoothDevice.ACCESS_REJECTED;
   2018     }
   2019 
   2020     boolean setPhonebookAccessPermission(BluetoothDevice device, int value) {
   2021         enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
   2022                 "Need BLUETOOTH PRIVILEGED permission");
   2023         SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE,
   2024                 Context.MODE_PRIVATE);
   2025         SharedPreferences.Editor editor = pref.edit();
   2026         if (value == BluetoothDevice.ACCESS_UNKNOWN) {
   2027             editor.remove(device.getAddress());
   2028         } else {
   2029             editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED);
   2030         }
   2031         editor.apply();
   2032         return true;
   2033     }
   2034 
   2035     int getMessageAccessPermission(BluetoothDevice device) {
   2036         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2037         SharedPreferences pref = getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE,
   2038                 Context.MODE_PRIVATE);
   2039         if (!pref.contains(device.getAddress())) {
   2040             return BluetoothDevice.ACCESS_UNKNOWN;
   2041         }
   2042         return pref.getBoolean(device.getAddress(), false) ? BluetoothDevice.ACCESS_ALLOWED
   2043                 : BluetoothDevice.ACCESS_REJECTED;
   2044     }
   2045 
   2046     boolean setMessageAccessPermission(BluetoothDevice device, int value) {
   2047         enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
   2048                 "Need BLUETOOTH PRIVILEGED permission");
   2049         SharedPreferences pref = getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE,
   2050                 Context.MODE_PRIVATE);
   2051         SharedPreferences.Editor editor = pref.edit();
   2052         if (value == BluetoothDevice.ACCESS_UNKNOWN) {
   2053             editor.remove(device.getAddress());
   2054         } else {
   2055             editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED);
   2056         }
   2057         editor.apply();
   2058         return true;
   2059     }
   2060 
   2061     int getSimAccessPermission(BluetoothDevice device) {
   2062         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2063         SharedPreferences pref =
   2064                 getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, Context.MODE_PRIVATE);
   2065         if (!pref.contains(device.getAddress())) {
   2066             return BluetoothDevice.ACCESS_UNKNOWN;
   2067         }
   2068         return pref.getBoolean(device.getAddress(), false) ? BluetoothDevice.ACCESS_ALLOWED
   2069                 : BluetoothDevice.ACCESS_REJECTED;
   2070     }
   2071 
   2072     boolean setSimAccessPermission(BluetoothDevice device, int value) {
   2073         enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
   2074                 "Need BLUETOOTH PRIVILEGED permission");
   2075         SharedPreferences pref =
   2076                 getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, Context.MODE_PRIVATE);
   2077         SharedPreferences.Editor editor = pref.edit();
   2078         if (value == BluetoothDevice.ACCESS_UNKNOWN) {
   2079             editor.remove(device.getAddress());
   2080         } else {
   2081             editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED);
   2082         }
   2083         editor.apply();
   2084         return true;
   2085     }
   2086 
   2087     void sendConnectionStateChange(BluetoothDevice device, int profile, int state, int prevState) {
   2088         // TODO(BT) permission check?
   2089         // Since this is a binder call check if Bluetooth is on still
   2090         if (getState() == BluetoothAdapter.STATE_OFF) {
   2091             return;
   2092         }
   2093 
   2094         mAdapterProperties.sendConnectionStateChange(device, profile, state, prevState);
   2095 
   2096     }
   2097 
   2098     IBluetoothSocketManager getSocketManager() {
   2099         android.os.IBinder obj = getSocketManagerNative();
   2100         if (obj == null) {
   2101             return null;
   2102         }
   2103 
   2104         return IBluetoothSocketManager.Stub.asInterface(obj);
   2105     }
   2106 
   2107     boolean factoryReset() {
   2108         enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission");
   2109         return factoryResetNative();
   2110     }
   2111 
   2112     void registerCallback(IBluetoothCallback cb) {
   2113         mCallbacks.register(cb);
   2114     }
   2115 
   2116     void unregisterCallback(IBluetoothCallback cb) {
   2117         mCallbacks.unregister(cb);
   2118     }
   2119 
   2120     public int getNumOfAdvertisementInstancesSupported() {
   2121         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2122         return mAdapterProperties.getNumOfAdvertisementInstancesSupported();
   2123     }
   2124 
   2125     public boolean isMultiAdvertisementSupported() {
   2126         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2127         return getNumOfAdvertisementInstancesSupported() >= MIN_ADVT_INSTANCES_FOR_MA;
   2128     }
   2129 
   2130     public boolean isRpaOffloadSupported() {
   2131         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2132         return mAdapterProperties.isRpaOffloadSupported();
   2133     }
   2134 
   2135     public int getNumOfOffloadedIrkSupported() {
   2136         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2137         return mAdapterProperties.getNumOfOffloadedIrkSupported();
   2138     }
   2139 
   2140     public int getNumOfOffloadedScanFilterSupported() {
   2141         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2142         return mAdapterProperties.getNumOfOffloadedScanFilterSupported();
   2143     }
   2144 
   2145     public int getOffloadedScanResultStorage() {
   2146         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2147         return mAdapterProperties.getOffloadedScanResultStorage();
   2148     }
   2149 
   2150     private boolean isActivityAndEnergyReportingSupported() {
   2151         enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission");
   2152         return mAdapterProperties.isActivityAndEnergyReportingSupported();
   2153     }
   2154 
   2155     public boolean isLe2MPhySupported() {
   2156         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2157         return mAdapterProperties.isLe2MPhySupported();
   2158     }
   2159 
   2160     public boolean isLeCodedPhySupported() {
   2161         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2162         return mAdapterProperties.isLeCodedPhySupported();
   2163     }
   2164 
   2165     public boolean isLeExtendedAdvertisingSupported() {
   2166         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2167         return mAdapterProperties.isLeExtendedAdvertisingSupported();
   2168     }
   2169 
   2170     public boolean isLePeriodicAdvertisingSupported() {
   2171         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2172         return mAdapterProperties.isLePeriodicAdvertisingSupported();
   2173     }
   2174 
   2175     public int getLeMaximumAdvertisingDataLength() {
   2176         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2177         return mAdapterProperties.getLeMaximumAdvertisingDataLength();
   2178     }
   2179 
   2180     /**
   2181      * Get the maximum number of connected audio devices.
   2182      *
   2183      * @return the maximum number of connected audio devices
   2184      */
   2185     public int getMaxConnectedAudioDevices() {
   2186         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2187         return mAdapterProperties.getMaxConnectedAudioDevices();
   2188     }
   2189 
   2190     /**
   2191      * Check whether A2DP offload is enabled.
   2192      *
   2193      * @return true if A2DP offload is enabled
   2194      */
   2195     public boolean isA2dpOffloadEnabled() {
   2196         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2197         return mAdapterProperties.isA2dpOffloadEnabled();
   2198     }
   2199 
   2200     private BluetoothActivityEnergyInfo reportActivityInfo() {
   2201         enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission");
   2202         if (mAdapterProperties.getState() != BluetoothAdapter.STATE_ON
   2203                 || !mAdapterProperties.isActivityAndEnergyReportingSupported()) {
   2204             return null;
   2205         }
   2206 
   2207         // Pull the data. The callback will notify mEnergyInfoLock.
   2208         readEnergyInfo();
   2209 
   2210         synchronized (mEnergyInfoLock) {
   2211             try {
   2212                 mEnergyInfoLock.wait(CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS);
   2213             } catch (InterruptedException e) {
   2214                 // Just continue, the energy data may be stale but we won't miss anything next time
   2215                 // we query.
   2216             }
   2217 
   2218             final BluetoothActivityEnergyInfo info =
   2219                     new BluetoothActivityEnergyInfo(SystemClock.elapsedRealtime(),
   2220                             mStackReportedState, mTxTimeTotalMs, mRxTimeTotalMs, mIdleTimeTotalMs,
   2221                             mEnergyUsedTotalVoltAmpSecMicro);
   2222 
   2223             // Count the number of entries that have byte counts > 0
   2224             int arrayLen = 0;
   2225             for (int i = 0; i < mUidTraffic.size(); i++) {
   2226                 final UidTraffic traffic = mUidTraffic.valueAt(i);
   2227                 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) {
   2228                     arrayLen++;
   2229                 }
   2230             }
   2231 
   2232             // Copy the traffic objects whose byte counts are > 0
   2233             final UidTraffic[] result = arrayLen > 0 ? new UidTraffic[arrayLen] : null;
   2234             int putIdx = 0;
   2235             for (int i = 0; i < mUidTraffic.size(); i++) {
   2236                 final UidTraffic traffic = mUidTraffic.valueAt(i);
   2237                 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) {
   2238                     result[putIdx++] = traffic.clone();
   2239                 }
   2240             }
   2241 
   2242             info.setUidTraffic(result);
   2243 
   2244             return info;
   2245         }
   2246     }
   2247 
   2248     public int getTotalNumOfTrackableAdvertisements() {
   2249         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
   2250         return mAdapterProperties.getTotalNumOfTrackableAdvertisements();
   2251     }
   2252 
   2253     void onLeServiceUp() {
   2254         mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
   2255     }
   2256 
   2257     void onBrEdrDown() {
   2258         mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF);
   2259     }
   2260 
   2261     private static int convertScanModeToHal(int mode) {
   2262         switch (mode) {
   2263             case BluetoothAdapter.SCAN_MODE_NONE:
   2264                 return AbstractionLayer.BT_SCAN_MODE_NONE;
   2265             case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
   2266                 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE;
   2267             case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
   2268                 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
   2269         }
   2270         // errorLog("Incorrect scan mode in convertScanModeToHal");
   2271         return -1;
   2272     }
   2273 
   2274     static int convertScanModeFromHal(int mode) {
   2275         switch (mode) {
   2276             case AbstractionLayer.BT_SCAN_MODE_NONE:
   2277                 return BluetoothAdapter.SCAN_MODE_NONE;
   2278             case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE:
   2279                 return BluetoothAdapter.SCAN_MODE_CONNECTABLE;
   2280             case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
   2281                 return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
   2282         }
   2283         //errorLog("Incorrect scan mode in convertScanModeFromHal");
   2284         return -1;
   2285     }
   2286 
   2287     // This function is called from JNI. It allows native code to set a single wake
   2288     // alarm. If an alarm is already pending and a new request comes in, the alarm
   2289     // will be rescheduled (i.e. the previously set alarm will be cancelled).
   2290     private boolean setWakeAlarm(long delayMillis, boolean shouldWake) {
   2291         synchronized (this) {
   2292             if (mPendingAlarm != null) {
   2293                 mAlarmManager.cancel(mPendingAlarm);
   2294             }
   2295 
   2296             long wakeupTime = SystemClock.elapsedRealtime() + delayMillis;
   2297             int type = shouldWake ? AlarmManager.ELAPSED_REALTIME_WAKEUP
   2298                     : AlarmManager.ELAPSED_REALTIME;
   2299 
   2300             Intent intent = new Intent(ACTION_ALARM_WAKEUP);
   2301             mPendingAlarm =
   2302                     PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
   2303             mAlarmManager.setExact(type, wakeupTime, mPendingAlarm);
   2304             return true;
   2305         }
   2306     }
   2307 
   2308     // This function is called from JNI. It allows native code to acquire a single wake lock.
   2309     // If the wake lock is already held, this function returns success. Although this function
   2310     // only supports acquiring a single wake lock at a time right now, it will eventually be
   2311     // extended to allow acquiring an arbitrary number of wake locks. The current interface
   2312     // takes |lockName| as a parameter in anticipation of that implementation.
   2313     private boolean acquireWakeLock(String lockName) {
   2314         synchronized (this) {
   2315             if (mWakeLock == null) {
   2316                 mWakeLockName = lockName;
   2317                 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName);
   2318             }
   2319 
   2320             if (!mWakeLock.isHeld()) {
   2321                 mWakeLock.acquire();
   2322             }
   2323         }
   2324         return true;
   2325     }
   2326 
   2327     // This function is called from JNI. It allows native code to release a wake lock acquired
   2328     // by |acquireWakeLock|. If the wake lock is not held, this function returns failure.
   2329     // Note that the release() call is also invoked by {@link #cleanup()} so a synchronization is
   2330     // needed here. See the comment for |acquireWakeLock| for an explanation of the interface.
   2331     private boolean releaseWakeLock(String lockName) {
   2332         synchronized (this) {
   2333             if (mWakeLock == null) {
   2334                 errorLog("Repeated wake lock release; aborting release: " + lockName);
   2335                 return false;
   2336             }
   2337 
   2338             if (mWakeLock.isHeld()) {
   2339                 mWakeLock.release();
   2340             }
   2341         }
   2342         return true;
   2343     }
   2344 
   2345     private void energyInfoCallback(int status, int ctrlState, long txTime, long rxTime,
   2346             long idleTime, long energyUsed, UidTraffic[] data) throws RemoteException {
   2347         if (ctrlState >= BluetoothActivityEnergyInfo.BT_STACK_STATE_INVALID
   2348                 && ctrlState <= BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_IDLE) {
   2349             // Energy is product of mA, V and ms. If the chipset doesn't
   2350             // report it, we have to compute it from time
   2351             if (energyUsed == 0) {
   2352                 try {
   2353                     final long txMah = Math.multiplyExact(txTime, getTxCurrentMa());
   2354                     final long rxMah = Math.multiplyExact(rxTime, getRxCurrentMa());
   2355                     final long idleMah = Math.multiplyExact(idleTime, getIdleCurrentMa());
   2356                     energyUsed = (long) (Math.addExact(Math.addExact(txMah, rxMah), idleMah)
   2357                             * getOperatingVolt());
   2358                 } catch (ArithmeticException e) {
   2359                     Slog.wtf(TAG, "overflow in bluetooth energy callback", e);
   2360                     // Energy is already 0 if the exception was thrown.
   2361                 }
   2362             }
   2363 
   2364             synchronized (mEnergyInfoLock) {
   2365                 mStackReportedState = ctrlState;
   2366                 long totalTxTimeMs;
   2367                 long totalRxTimeMs;
   2368                 long totalIdleTimeMs;
   2369                 long totalEnergy;
   2370                 try {
   2371                     totalTxTimeMs = Math.addExact(mTxTimeTotalMs, txTime);
   2372                     totalRxTimeMs = Math.addExact(mRxTimeTotalMs, rxTime);
   2373                     totalIdleTimeMs = Math.addExact(mIdleTimeTotalMs, idleTime);
   2374                     totalEnergy = Math.addExact(mEnergyUsedTotalVoltAmpSecMicro, energyUsed);
   2375                 } catch (ArithmeticException e) {
   2376                     // This could be because we accumulated a lot of time, or we got a very strange
   2377                     // value from the controller (more likely). Discard this data.
   2378                     Slog.wtf(TAG, "overflow in bluetooth energy callback", e);
   2379                     totalTxTimeMs = mTxTimeTotalMs;
   2380                     totalRxTimeMs = mRxTimeTotalMs;
   2381                     totalIdleTimeMs = mIdleTimeTotalMs;
   2382                     totalEnergy = mEnergyUsedTotalVoltAmpSecMicro;
   2383                 }
   2384 
   2385                 mTxTimeTotalMs = totalTxTimeMs;
   2386                 mRxTimeTotalMs = totalRxTimeMs;
   2387                 mIdleTimeTotalMs = totalIdleTimeMs;
   2388                 mEnergyUsedTotalVoltAmpSecMicro = totalEnergy;
   2389 
   2390                 for (UidTraffic traffic : data) {
   2391                     UidTraffic existingTraffic = mUidTraffic.get(traffic.getUid());
   2392                     if (existingTraffic == null) {
   2393                         mUidTraffic.put(traffic.getUid(), traffic);
   2394                     } else {
   2395                         existingTraffic.addRxBytes(traffic.getRxBytes());
   2396                         existingTraffic.addTxBytes(traffic.getTxBytes());
   2397                     }
   2398                 }
   2399                 mEnergyInfoLock.notifyAll();
   2400             }
   2401         }
   2402 
   2403         verboseLog("energyInfoCallback() status = " + status + "txTime = " + txTime + "rxTime = "
   2404                 + rxTime + "idleTime = " + idleTime + "energyUsed = " + energyUsed + "ctrlState = "
   2405                 + ctrlState + "traffic = " + Arrays.toString(data));
   2406     }
   2407 
   2408     private int getIdleCurrentMa() {
   2409         return getResources().getInteger(R.integer.config_bluetooth_idle_cur_ma);
   2410     }
   2411 
   2412     private int getTxCurrentMa() {
   2413         return getResources().getInteger(R.integer.config_bluetooth_tx_cur_ma);
   2414     }
   2415 
   2416     private int getRxCurrentMa() {
   2417         return getResources().getInteger(R.integer.config_bluetooth_rx_cur_ma);
   2418     }
   2419 
   2420     private double getOperatingVolt() {
   2421         return getResources().getInteger(R.integer.config_bluetooth_operating_voltage_mv) / 1000.0;
   2422     }
   2423 
   2424     @Override
   2425     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
   2426         enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
   2427 
   2428         if (args.length == 0) {
   2429             writer.println("Skipping dump in APP SERVICES, see bluetooth_manager section.");
   2430             writer.println("Use --print argument for dumpsys direct from AdapterService.");
   2431             return;
   2432         }
   2433 
   2434         verboseLog("dumpsys arguments, check for protobuf output: " + TextUtils.join(" ", args));
   2435         if (args[0].equals("--proto-bin")) {
   2436             dumpMetrics(fd);
   2437             return;
   2438         }
   2439 
   2440         writer.println();
   2441         mAdapterProperties.dump(fd, writer, args);
   2442         writer.println("mSnoopLogSettingAtEnable = " + mSnoopLogSettingAtEnable);
   2443 
   2444         writer.println();
   2445         mAdapterStateMachine.dump(fd, writer, args);
   2446 
   2447         StringBuilder sb = new StringBuilder();
   2448         for (ProfileService profile : mRegisteredProfiles) {
   2449             profile.dump(sb);
   2450         }
   2451 
   2452         writer.write(sb.toString());
   2453         writer.flush();
   2454 
   2455         dumpNative(fd, args);
   2456     }
   2457 
   2458     private void dumpMetrics(FileDescriptor fd) {
   2459         BluetoothMetricsProto.BluetoothLog.Builder metricsBuilder =
   2460                 BluetoothMetricsProto.BluetoothLog.newBuilder();
   2461         byte[] nativeMetricsBytes = dumpMetricsNative();
   2462         debugLog("dumpMetrics: native metrics size is " + nativeMetricsBytes.length);
   2463         if (nativeMetricsBytes.length > 0) {
   2464             try {
   2465                 metricsBuilder.mergeFrom(nativeMetricsBytes);
   2466             } catch (InvalidProtocolBufferException ex) {
   2467                 Log.w(TAG, "dumpMetrics: problem parsing metrics protobuf, " + ex.getMessage());
   2468                 return;
   2469             }
   2470         }
   2471         metricsBuilder.setNumBondedDevices(getBondedDevices().length);
   2472         MetricsLogger.dumpProto(metricsBuilder);
   2473         for (ProfileService profile : mRegisteredProfiles) {
   2474             profile.dumpProto(metricsBuilder);
   2475         }
   2476         byte[] metricsBytes = Base64.encode(metricsBuilder.build().toByteArray(), Base64.DEFAULT);
   2477         debugLog("dumpMetrics: combined metrics size is " + metricsBytes.length);
   2478         try (FileOutputStream protoOut = new FileOutputStream(fd)) {
   2479             protoOut.write(metricsBytes);
   2480         } catch (IOException e) {
   2481             errorLog("dumpMetrics: error writing combined protobuf to fd, " + e.getMessage());
   2482         }
   2483     }
   2484 
   2485     private void debugLog(String msg) {
   2486         if (DBG) {
   2487             Log.d(TAG, msg);
   2488         }
   2489     }
   2490 
   2491     private void verboseLog(String msg) {
   2492         if (VERBOSE) {
   2493             Log.v(TAG, msg);
   2494         }
   2495     }
   2496 
   2497     private void errorLog(String msg) {
   2498         Log.e(TAG, msg);
   2499     }
   2500 
   2501     private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() {
   2502         @Override
   2503         public void onReceive(Context context, Intent intent) {
   2504             synchronized (AdapterService.this) {
   2505                 mPendingAlarm = null;
   2506                 alarmFiredNative();
   2507             }
   2508         }
   2509     };
   2510 
   2511     private void enableNativeWithGuestFlag() {
   2512         boolean isGuest = UserManager.get(this).isGuestUser();
   2513         if (!enableNative(isGuest)) {
   2514             Log.e(TAG, "enableNative() returned false");
   2515         }
   2516     }
   2517 
   2518     static native void classInitNative();
   2519 
   2520     native boolean initNative();
   2521 
   2522     native void cleanupNative();
   2523 
   2524     /*package*/
   2525     native boolean enableNative(boolean startRestricted);
   2526 
   2527     /*package*/
   2528     native boolean disableNative();
   2529 
   2530     /*package*/
   2531     native boolean setAdapterPropertyNative(int type, byte[] val);
   2532 
   2533     /*package*/
   2534     native boolean getAdapterPropertiesNative();
   2535 
   2536     /*package*/
   2537     native boolean getAdapterPropertyNative(int type);
   2538 
   2539     /*package*/
   2540     native boolean setAdapterPropertyNative(int type);
   2541 
   2542     /*package*/
   2543     native boolean setDevicePropertyNative(byte[] address, int type, byte[] val);
   2544 
   2545     /*package*/
   2546     native boolean getDevicePropertyNative(byte[] address, int type);
   2547 
   2548     /*package*/
   2549     native boolean createBondNative(byte[] address, int transport);
   2550 
   2551     /*package*/
   2552     native boolean createBondOutOfBandNative(byte[] address, int transport, OobData oobData);
   2553 
   2554     /*package*/
   2555     native boolean removeBondNative(byte[] address);
   2556 
   2557     /*package*/
   2558     native boolean cancelBondNative(byte[] address);
   2559 
   2560     /*package*/
   2561     native boolean sdpSearchNative(byte[] address, byte[] uuid);
   2562 
   2563     /*package*/
   2564     native int getConnectionStateNative(byte[] address);
   2565 
   2566     private native boolean startDiscoveryNative();
   2567 
   2568     private native boolean cancelDiscoveryNative();
   2569 
   2570     private native boolean pinReplyNative(byte[] address, boolean accept, int len, byte[] pin);
   2571 
   2572     private native boolean sspReplyNative(byte[] address, int type, boolean accept, int passkey);
   2573 
   2574     /*package*/
   2575     native boolean getRemoteServicesNative(byte[] address);
   2576 
   2577     /*package*/
   2578     native boolean getRemoteMasInstancesNative(byte[] address);
   2579 
   2580     private native int readEnergyInfo();
   2581 
   2582     private native IBinder getSocketManagerNative();
   2583 
   2584     private native void setSystemUiUidNative(int systemUiUid);
   2585 
   2586     private static native void setForegroundUserIdNative(int foregroundUserId);
   2587 
   2588     /*package*/
   2589     native boolean factoryResetNative();
   2590 
   2591     private native void alarmFiredNative();
   2592 
   2593     private native void dumpNative(FileDescriptor fd, String[] arguments);
   2594 
   2595     private native byte[] dumpMetricsNative();
   2596 
   2597     private native void interopDatabaseClearNative();
   2598 
   2599     private native void interopDatabaseAddNative(int feature, byte[] address, int length);
   2600 
   2601     // Returns if this is a mock object. This is currently used in testing so that we may not call
   2602     // System.exit() while finalizing the object. Otherwise GC of mock objects unfortunately ends up
   2603     // calling finalize() which in turn calls System.exit() and the process crashes.
   2604     //
   2605     // Mock this in your testing framework to return true to avoid the mentioned behavior. In
   2606     // production this has no effect.
   2607     public boolean isMock() {
   2608         return false;
   2609     }
   2610 }
   2611