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