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