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