diff options
| author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-18 17:39:46 -0700 | 
|---|---|---|
| committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-18 17:39:46 -0700 | 
| commit | 105925376f8d0f6b318c9938c7b83ef7fef094da (patch) | |
| tree | 3b19ee2bd8704cb9c6a0da7e42dec6759183de6d /core/java/android/server | |
| parent | ba87e3e6c985e7175152993b5efcc7dd2f0e1c93 (diff) | |
| download | frameworks_base-105925376f8d0f6b318c9938c7b83ef7fef094da.zip frameworks_base-105925376f8d0f6b318c9938c7b83ef7fef094da.tar.gz frameworks_base-105925376f8d0f6b318c9938c7b83ef7fef094da.tar.bz2 | |
auto import from //branches/cupcake_rel/...@140373
Diffstat (limited to 'core/java/android/server')
| -rw-r--r-- | core/java/android/server/BluetoothA2dpService.java | 33 | ||||
| -rw-r--r-- | core/java/android/server/BluetoothDeviceService.java | 288 | ||||
| -rw-r--r-- | core/java/android/server/BluetoothEventLoop.java | 18 | 
3 files changed, 214 insertions, 125 deletions
| diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java index 3aa4078..3c50707 100644 --- a/core/java/android/server/BluetoothA2dpService.java +++ b/core/java/android/server/BluetoothA2dpService.java @@ -63,6 +63,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {      private final IntentFilter mIntentFilter;      private HashMap<String, SinkState> mAudioDevices;      private final AudioManager mAudioManager; +    private final BluetoothDevice mBluetooth;      private class SinkState {          public String address; @@ -75,9 +76,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {          mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); -        BluetoothDevice device = -                (BluetoothDevice)mContext.getSystemService(Context.BLUETOOTH_SERVICE); -        if (device == null) { +        mBluetooth = (BluetoothDevice) mContext.getSystemService(Context.BLUETOOTH_SERVICE); +        if (mBluetooth == null) {              throw new RuntimeException("Platform does not support Bluetooth");          } @@ -85,13 +85,12 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {              throw new RuntimeException("Could not init BluetoothA2dpService");          } -        mIntentFilter = new IntentFilter(BluetoothIntent.ENABLED_ACTION); -        mIntentFilter.addAction(BluetoothIntent.DISABLED_ACTION); +        mIntentFilter = new IntentFilter(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);          mIntentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);          mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);          mContext.registerReceiver(mReceiver, mIntentFilter); -        if (device.isEnabled()) { +        if (mBluetooth.isEnabled()) {              onBluetoothEnable();          }      } @@ -110,10 +109,17 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {          public void onReceive(Context context, Intent intent) {              String action = intent.getAction();              String address = intent.getStringExtra(BluetoothIntent.ADDRESS); -            if (action.equals(BluetoothIntent.ENABLED_ACTION)) { -                onBluetoothEnable(); -            } else if (action.equals(BluetoothIntent.DISABLED_ACTION)) { -                onBluetoothDisable(); +            if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) { +                int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE, +                                               BluetoothError.ERROR); +                switch (state) { +                case BluetoothDevice.BLUETOOTH_STATE_ON: +                    onBluetoothEnable(); +                    break; +                case BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF: +                    onBluetoothDisable(); +                    break; +                }              } else if (action.equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)) {                  int bondState = intent.getIntExtra(BluetoothIntent.BOND_STATE,                                                     BluetoothError.ERROR); @@ -145,9 +151,10 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {              switch (msg.what) {              case MESSAGE_CONNECT_TO:                  String address = (String)msg.obj; -                // check device is still preferred, and nothing is currently -                // connected -                if (getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF && +                // check bluetooth is still on, device is still preferred, and +                // nothing is currently connected +                if (mBluetooth.isEnabled() && +                        getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF &&                          lookupSinksMatchingStates(new int[] {                              BluetoothA2dp.STATE_CONNECTING,                              BluetoothA2dp.STATE_CONNECTED, diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java index 9e9ba62..b7e3846 100644 --- a/core/java/android/server/BluetoothDeviceService.java +++ b/core/java/android/server/BluetoothDeviceService.java @@ -37,8 +37,10 @@ import android.content.Intent;  import android.content.IntentFilter;  import android.os.Binder;  import android.os.Handler; +import android.os.IBinder;  import android.os.Message;  import android.os.RemoteException; +import android.os.ServiceManager;  import android.os.SystemService;  import android.provider.Settings;  import android.util.Log; @@ -51,6 +53,8 @@ import java.util.Arrays;  import java.util.HashMap;  import java.util.Map; +import com.android.internal.app.IBatteryStats; +  public class BluetoothDeviceService extends IBluetoothDevice.Stub {      private static final String TAG = "BluetoothDeviceService";      private static final boolean DBG = true; @@ -60,14 +64,18 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {      private IntentFilter mIntentFilter;      private boolean mIsAirplaneSensitive;      private final BondState mBondState = new BondState();  // local cache of bondings -    private volatile boolean mIsEnabled;  // local cache of isEnabledNative() +    private int mBluetoothState;      private boolean mIsDiscovering; +    private final IBatteryStats mBatteryStats;      private final Context mContext;      private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;      private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; +    private static final int MESSAGE_REGISTER_SDP_RECORDS = 1; +    private static final int MESSAGE_FINISH_DISABLE = 2; +      static {          classInitNative();      } @@ -75,6 +83,12 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {      public BluetoothDeviceService(Context context) {          mContext = context; + +        // Need to do this in place of: +        // mBatteryStats = BatteryStatsService.getService(); +        // Since we can not import BatteryStatsService from here. This class really needs to be +        // moved to java/services/com/android/server/ +        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));      }      /** Must be called after construction, and before any other method. @@ -87,7 +101,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {              disableNative();          } -        mIsEnabled = false; +        setBluetoothState(BluetoothDevice.BLUETOOTH_STATE_OFF);          mIsDiscovering = false;          mEventLoop = new BluetoothEventLoop(mContext, this);          registerForAirplaneMode(); @@ -109,10 +123,16 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {      public boolean isEnabled() {          mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); -        return mIsEnabled; +        return mBluetoothState == BluetoothDevice.BLUETOOTH_STATE_ON;      }      private native int isEnabledNative(); +    public int getBluetoothState() { +        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); +        return mBluetoothState; +    } + +      /**       * Bring down bluetooth and disable BT in settings. Returns true on success.       */ @@ -124,17 +144,36 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {       * Bring down bluetooth. Returns true on success.       *       * @param saveSetting If true, disable BT in settings -     *       */      public synchronized boolean disable(boolean saveSetting) {          mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,                                                  "Need BLUETOOTH_ADMIN permission"); +        switch (mBluetoothState) { +        case BluetoothDevice.BLUETOOTH_STATE_OFF: +            return true; +        case BluetoothDevice.BLUETOOTH_STATE_ON: +            break; +        default: +            return false; +        }          if (mEnableThread != null && mEnableThread.isAlive()) {              return false;          } -        if (!mIsEnabled) { -            return true; +        setBluetoothState(BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF); + +        // Allow 3 seconds for profiles to gracefully disconnect +        // TODO: Introduce a callback mechanism so that each profile can notify +        // BluetoothDeviceService when it is done shutting down +        mHandler.sendMessageDelayed( +                mHandler.obtainMessage(MESSAGE_FINISH_DISABLE, saveSetting ? 1 : 0, 0), 3000); +        return true; +    } + + +    private synchronized void finishDisable(boolean saveSetting) { +        if (mBluetoothState != BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF) { +            return;          }          mEventLoop.stop();          disableNative(); @@ -163,38 +202,37 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {          intent.putExtra(BluetoothIntent.SCAN_MODE, BluetoothDevice.SCAN_MODE_NONE);          mContext.sendBroadcast(intent, BLUETOOTH_PERM); -        mIsEnabled = false; +        mIsDiscovering = false; +          if (saveSetting) {              persistBluetoothOnSetting(false);          } -        mIsDiscovering = false; -        intent = new Intent(BluetoothIntent.DISABLED_ACTION); -        mContext.sendBroadcast(intent, BLUETOOTH_PERM); -        return true; + +        setBluetoothState(BluetoothDevice.BLUETOOTH_STATE_OFF); + +        // Log bluetooth off to battery stats. +        long ident = Binder.clearCallingIdentity(); +        try { +            mBatteryStats.noteBluetoothOff(); +        } catch (RemoteException e) { +        } finally { +            Binder.restoreCallingIdentity(ident); +        }      } -    /** -     * Bring up bluetooth, asynchronously, and enable BT in settings. -     * This turns on/off the underlying hardware. -     * -     * @return True on success (so far), guaranteeing the callback with be -     * notified when complete. -     */ -    public boolean enable(IBluetoothDeviceCallback callback) { -        return enable(callback, true); +    /** Bring up BT and persist BT on in settings */ +    public boolean enable() { +        return enable(true);      }      /**       * Enable this Bluetooth device, asynchronously.       * This turns on/off the underlying hardware.       * -     * @param saveSetting If true, enable BT in settings -     * -     * @return True on success (so far), guaranteeing the callback with be -     * notified when complete. +     * @param saveSetting If true, persist the new state of BT in settings +     * @return True on success (so far)       */ -    public synchronized boolean enable(IBluetoothDeviceCallback callback, -            boolean saveSetting) { +    public synchronized boolean enable(boolean saveSetting) {          mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,                                                  "Need BLUETOOTH_ADMIN permission"); @@ -202,28 +240,49 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {          if (mIsAirplaneSensitive && isAirplaneModeOn()) {              return false;          } -        if (mIsEnabled) { +        if (mBluetoothState != BluetoothDevice.BLUETOOTH_STATE_OFF) {              return false;          }          if (mEnableThread != null && mEnableThread.isAlive()) {              return false;          } -        mEnableThread = new EnableThread(callback, saveSetting); +        setBluetoothState(BluetoothDevice.BLUETOOTH_STATE_TURNING_ON); +        mEnableThread = new EnableThread(saveSetting);          mEnableThread.start();          return true;      } -    private static final int REGISTER_SDP_RECORDS = 1; +    private synchronized void setBluetoothState(int state) { +        if (state == mBluetoothState) { +            return; +        } + +        if (DBG) log("Bluetooth state " + mBluetoothState + " -> " + state); + +        Intent intent = new Intent(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION); +        intent.putExtra(BluetoothIntent.BLUETOOTH_PREVIOUS_STATE, mBluetoothState); +        intent.putExtra(BluetoothIntent.BLUETOOTH_STATE, state); +        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + +        mBluetoothState = state; + +        mContext.sendBroadcast(intent, BLUETOOTH_PERM); +    } +      private final Handler mHandler = new Handler() {          @Override          public void handleMessage(Message msg) {              switch (msg.what) { -            case REGISTER_SDP_RECORDS: +            case MESSAGE_REGISTER_SDP_RECORDS:                  //TODO: Don't assume HSP/HFP is running, don't use sdptool,                  if (isEnabled()) {                      SystemService.start("hsag");                      SystemService.start("hfag");                  } +                break; +            case MESSAGE_FINISH_DISABLE: +                finishDisable(msg.arg1 != 0); +                break;              }          }      }; @@ -231,10 +290,8 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {      private EnableThread mEnableThread;      private class EnableThread extends Thread { -        private final IBluetoothDeviceCallback mEnableCallback;          private final boolean mSaveSetting; -        public EnableThread(IBluetoothDeviceCallback callback, boolean saveSetting) { -            mEnableCallback = callback; +        public EnableThread(boolean saveSetting) {              mSaveSetting = saveSetting;          }          public void run() { @@ -244,7 +301,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {                  boolean running = false;                  while ((retryCount-- > 0) && !running) {                      mEventLoop.start(); -                    // it may take a momement for the other thread to do its  +                    // it may take a momement for the other thread to do its                      // thing.  Check periodically for a while.                      int pollCount = 5;                      while ((pollCount-- > 0) && !running) { @@ -264,36 +321,37 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {                  }              } -            if (mEnableCallback != null) { -                try { -                    mEnableCallback.onEnableResult(res ? -                                                   BluetoothDevice.RESULT_SUCCESS : -                                                   BluetoothDevice.RESULT_FAILURE); -                } catch (RemoteException e) {} -            }              if (res) { -                mIsEnabled = true;                  if (mSaveSetting) {                      persistBluetoothOnSetting(true);                  }                  mIsDiscovering = false;                  mBondState.loadBondState(); -                mHandler.sendMessageDelayed(mHandler.obtainMessage(REGISTER_SDP_RECORDS), 3000); +                mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS), +                                            3000); -                // Update mode -                mEventLoop.onModeChanged(getModeNative()); +                // Log bluetooth on to battery stats. +                long ident = Binder.clearCallingIdentity(); +                try { +                    mBatteryStats.noteBluetoothOn(); +                } catch (RemoteException e) { +                } finally { +                    Binder.restoreCallingIdentity(ident); +                }              } -            Intent intent = null; + +            mEnableThread = null; + +            setBluetoothState(res ? +                              BluetoothDevice.BLUETOOTH_STATE_ON : +                              BluetoothDevice.BLUETOOTH_STATE_OFF); +              if (res) { -                intent = new Intent(BluetoothIntent.ENABLED_ACTION); -            } else { -                intent = new Intent(BluetoothIntent.DISABLED_ACTION); +                // Update mode +                mEventLoop.onModeChanged(getModeNative());              } -            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); -            mContext.sendBroadcast(intent, BLUETOOTH_PERM); -            mEnableThread = null;          }      } @@ -320,18 +378,24 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {          private final HashMap<String, Integer> mState = new HashMap<String, Integer>();          private final HashMap<String, Integer> mPinAttempt = new HashMap<String, Integer>();          private final ArrayList<String> mAutoPairingFailures = new ArrayList<String>(); -        // List of all the vendor_id prefix of Bluetooth addresses for which -        // auto pairing is not attempted +        // List of all the vendor_id prefix of Bluetooth addresses for +        // which auto pairing is not attempted. +        // The following companies are included in the list below: +        // ALPS (lexus), Murata (Prius 2007, Nokia 616), TEMIC SDS (Porsche, Audi), +        // Parrot, Zhongshan General K-mate Electronics, Great Well +        // Electronics, Flaircomm Electronics, Jatty Electronics, Delphi, +        // Clarion, Novero, Denso (Lexus, Toyota), Johnson Controls (Acura),          private final ArrayList<String>  mAutoPairingBlacklisted =                  new ArrayList<String>(Arrays.asList( -                        "00:02:C7", "00:16:FE", "00:19:C1", "00:1B:FB", "00:1E:3D", //ALPS -                        "00:21:4F", "00:23:06", "00:24:33", "00:A0:79", // ALPS -                        "00:0E:6D", "00:13:E0", "00:21:E8", "00:60:57",// Murata for Prius 2007 -                        "00:0E:9F" // TEMIC SDS  for Porsche +                        "00:02:C7", "00:16:FE", "00:19:C1", "00:1B:FB", "00:1E:3D", "00:21:4F", +                        "00:23:06", "00:24:33", "00:A0:79", "00:0E:6D", "00:13:E0", "00:21:E8", +                        "00:60:57", "00:0E:9F", "00:12:1C", "00:18:91", "00:18:96", "00:13:04", +                        "00:16:FD", "00:22:A0", "00:0B:4C", "00:60:6F", "00:23:3D", "00:C0:59", +                        "00:0A:30"                          ));          public synchronized void loadBondState() { -            if (!mIsEnabled) { +            if (mBluetoothState != BluetoothDevice.BLUETOOTH_STATE_TURNING_ON) {                  return;              }              String[] bonds = listBondingsNative(); @@ -1051,7 +1115,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {                  // If bluetooth is currently expected to be on, then enable or disable bluetooth                  if (Settings.Secure.getInt(resolver, Settings.Secure.BLUETOOTH_ON, 0) > 0) {                      if (enabled) { -                        enable(null, false); +                        enable(false);                      } else {                          disable(false);                      } @@ -1079,52 +1143,63 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {      @Override      protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { -        if (mIsEnabled) { -            pw.println("\nBluetooth ENABLED: " + getAddress() + " (" + getName() + ")"); -            pw.println("\nisDiscovering() = " + isDiscovering()); - -            BluetoothHeadset headset = new BluetoothHeadset(mContext, null); - -            String[] addresses = listRemoteDevices(); - -            pw.println("\n--Known devices--"); -            for (String address : addresses) { -                pw.printf("%s %10s (%d) %s\n", address, -                           toBondStateString(mBondState.getBondState(address)), -                           mBondState.getAttempt(address), -                           getRemoteName(address)); -            } - -            addresses = listAclConnections(); -            pw.println("\n--ACL connected devices--"); -            for (String address : addresses) { -                pw.println(address); -            } - -            // Rather not do this from here, but no-where else and I need this -            // dump -            pw.println("\n--Headset Service--"); -            switch (headset.getState()) { -            case BluetoothHeadset.STATE_DISCONNECTED: -                pw.println("getState() = STATE_DISCONNECTED"); -                break; -            case BluetoothHeadset.STATE_CONNECTING: -                pw.println("getState() = STATE_CONNECTING"); -                break; -            case BluetoothHeadset.STATE_CONNECTED: -                pw.println("getState() = STATE_CONNECTED"); -                break; -            case BluetoothHeadset.STATE_ERROR: -                pw.println("getState() = STATE_ERROR"); -                break; -            } -            pw.println("getHeadsetAddress() = " + headset.getHeadsetAddress()); -            headset.close(); - -        } else { -            pw.println("\nBluetooth DISABLED"); -        } -        pw.println("\nmIsAirplaneSensitive = " + mIsAirplaneSensitive); +        pw.println("\nmIsAirplaneSensitive = " + mIsAirplaneSensitive + "\n"); + +        switch(mBluetoothState) { +        case BluetoothDevice.BLUETOOTH_STATE_OFF: +            pw.println("\nBluetooth OFF\n"); +            return; +        case BluetoothDevice.BLUETOOTH_STATE_TURNING_ON: +            pw.println("\nBluetooth TURNING ON\n"); +            return; +        case BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF: +            pw.println("\nBluetooth TURNING OFF\n"); +            return; +        case BluetoothDevice.BLUETOOTH_STATE_ON: +            pw.println("\nBluetooth ON\n"); +        } + +        pw.println("\nLocal address = " + getAddress()); +        pw.println("\nLocal name = " + getName()); +        pw.println("\nisDiscovering() = " + isDiscovering()); + +        BluetoothHeadset headset = new BluetoothHeadset(mContext, null); + +        String[] addresses = listRemoteDevices(); + +        pw.println("\n--Known devices--"); +        for (String address : addresses) { +            pw.printf("%s %10s (%d) %s\n", address, +                       toBondStateString(mBondState.getBondState(address)), +                       mBondState.getAttempt(address), +                       getRemoteName(address)); +        } + +        addresses = listAclConnections(); +        pw.println("\n--ACL connected devices--"); +        for (String address : addresses) { +            pw.println(address); +        } + +        // Rather not do this from here, but no-where else and I need this +        // dump +        pw.println("\n--Headset Service--"); +        switch (headset.getState()) { +        case BluetoothHeadset.STATE_DISCONNECTED: +            pw.println("getState() = STATE_DISCONNECTED"); +            break; +        case BluetoothHeadset.STATE_CONNECTING: +            pw.println("getState() = STATE_CONNECTING"); +            break; +        case BluetoothHeadset.STATE_CONNECTED: +            pw.println("getState() = STATE_CONNECTED"); +            break; +        case BluetoothHeadset.STATE_ERROR: +            pw.println("getState() = STATE_ERROR"); +            break; +        } +        pw.println("getHeadsetAddress() = " + headset.getHeadsetAddress()); +        headset.close();      }      /* package */ static int bluezStringToScanMode(String mode) { @@ -1159,3 +1234,4 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {          Log.d(TAG, msg);      }  } + diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java index 8e77eed..6be8eb9 100644 --- a/core/java/android/server/BluetoothEventLoop.java +++ b/core/java/android/server/BluetoothEventLoop.java @@ -46,10 +46,10 @@ class BluetoothEventLoop {      private Thread mThread;      private boolean mStarted;      private boolean mInterrupted; -    private HashMap<String, Integer> mPasskeyAgentRequestData; -    private HashMap<String, IBluetoothDeviceCallback> mGetRemoteServiceChannelCallbacks; -    private BluetoothDeviceService mBluetoothService; -    private Context mContext; +    private final HashMap<String, Integer> mPasskeyAgentRequestData; +    private final HashMap<String, IBluetoothDeviceCallback> mGetRemoteServiceChannelCallbacks; +    private final BluetoothDeviceService mBluetoothService; +    private final Context mContext;      private static final int EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 1;      private static final int EVENT_RESTART_BLUETOOTH = 2; @@ -77,7 +77,7 @@ class BluetoothEventLoop {                  break;              case EVENT_RESTART_BLUETOOTH:                  mBluetoothService.disable(); -                mBluetoothService.enable(null); +                mBluetoothService.enable();                  break;              }          } @@ -309,6 +309,12 @@ class BluetoothEventLoop {          address = address.toUpperCase();          mPasskeyAgentRequestData.put(address, new Integer(nativeData)); +        if (mBluetoothService.getBluetoothState() == BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF) { +            // shutdown path +            mBluetoothService.cancelPin(address); +            return; +        } +          if (mBluetoothService.getBondState().getBondState(address) ==                  BluetoothDevice.BOND_BONDING) {              // we initiated the bonding @@ -347,7 +353,7 @@ class BluetoothEventLoop {      private boolean onAuthAgentAuthorize(String address, String service, String uuid) {          boolean authorized = false; -        if (service.endsWith("service_audio")) { +        if (mBluetoothService.isEnabled() && service.endsWith("service_audio")) {              BluetoothA2dp a2dp = new BluetoothA2dp(mContext);              authorized = a2dp.getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF;              if (authorized) { | 
