/* package */ void handleAccessPermissionResult(Intent intent) {
    if (!mCheckingAccessPermission) {
      return;
    }

    HeadsetBase headset = mHandsfree.getHeadset();
    // ASSERT: (headset != null) && headSet.isConnected()
    // REASON: mCheckingAccessPermission is true, otherwise resetAtState
    //         has set mCheckingAccessPermission to false

    if (intent.getAction().equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) {

      if (intent.getIntExtra(
              BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, BluetoothDevice.CONNECTION_ACCESS_NO)
          == BluetoothDevice.CONNECTION_ACCESS_YES) {
        BluetoothDevice remoteDevice = headset.getRemoteDevice();
        if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) {
          remoteDevice.setTrust(true);
        }

        AtCommandResult cpbrResult = processCpbrCommand();
        headset.sendURC(cpbrResult.toString());
      } else {
        headset.sendURC("ERROR");
      }
    }
    mCpbrIndex1 = mCpbrIndex2 = -1;
    mCheckingAccessPermission = false;
  }
 private int waitForConnect(HeadsetBase headset) {
   // Try to connect for 20 seconds
   int result = 0;
   for (int i = 0; i < 40 && result == 0; i++) {
     // waitForAsyncConnect returns 0 on timeout, 1 on success, < 0 on error.
     result = headset.waitForAsyncConnect(500, mConnectedStatusHandler);
     if (isInterrupted()) {
       headset.disconnect();
       return EINTERRUPT;
     }
   }
   return result;
 }
    @Override
    public void run() {
      long timestamp;

      timestamp = System.currentTimeMillis();
      HeadsetBase headset = new HeadsetBase(mPowerManager, mAdapter, device, channel);

      int result = waitForConnect(headset);

      if (result != EINTERRUPT && result != 1) {
        if (result == ECONNREFUSED && mDeviceSdpQuery == null) {
          // The rfcomm channel number might have changed, do SDP
          // query and try to connect again.
          mDeviceSdpQuery = getCurrentDevice();
          device.fetchUuidsWithSdp();
          mConnectThread = null;
          return;
        } else {
          Log.i(TAG, "Trying to connect to rfcomm socket again after 1 sec");
          try {
            sleep(1000); // 1 second
          } catch (InterruptedException e) {
          }
        }
        result = waitForConnect(headset);
      }
      mDeviceSdpQuery = null;
      if (result == EINTERRUPT) return;

      if (DBG)
        log("RFCOMM connection attempt took " + (System.currentTimeMillis() - timestamp) + " ms");
      if (isInterrupted()) {
        headset.disconnect();
        return;
      }
      if (result < 0) {
        Log.w(TAG, "headset.waitForAsyncConnect() error: " + result);
        mConnectingStatusHandler.obtainMessage(RFCOMM_ERROR).sendToTarget();
        return;
      } else if (result == 0) {
        mConnectingStatusHandler.obtainMessage(RFCOMM_ERROR).sendToTarget();
        Log.w(TAG, "mHeadset.waitForAsyncConnect() error: " + result + "(timeout)");
        return;
      } else {
        mConnectingStatusHandler.obtainMessage(RFCOMM_CONNECTED, headset).sendToTarget();
      }
    }
        public boolean disconnectHeadsetInternal(BluetoothDevice device) {
          synchronized (BluetoothHeadsetService.this) {
            BluetoothRemoteHeadset remoteHeadset = mRemoteHeadsets.get(device);
            if (remoteHeadset == null) return false;

            if (remoteHeadset.mState == BluetoothHeadset.STATE_CONNECTED) {
              // Send a dummy battery level message to force headset
              // out of sniff mode so that it will immediately notice
              // the disconnection. We are currently sending it for
              // handsfree only.
              // TODO: Call hci_conn_enter_active_mode() from
              // rfcomm_send_disc() in the kernel instead.
              // See http://b/1716887
              HeadsetBase headset = remoteHeadset.mHeadset;
              if (remoteHeadset.mHeadsetType == BluetoothHandsfree.TYPE_HANDSFREE) {
                headset.sendURC("+CIEV: 7,3");
              }

              if (headset != null) {
                headset.disconnect();
                headset = null;
              }
              setState(
                  device,
                  BluetoothHeadset.STATE_DISCONNECTED,
                  BluetoothHeadset.RESULT_CANCELED,
                  BluetoothHeadset.LOCAL_DISCONNECT);
              return true;
            } else if (remoteHeadset.mState == BluetoothHeadset.STATE_CONNECTING) {
              // The state machine would have canceled the connect thread.
              // Just set the state here.
              setState(
                  device,
                  BluetoothHeadset.STATE_DISCONNECTED,
                  BluetoothHeadset.RESULT_CANCELED,
                  BluetoothHeadset.LOCAL_DISCONNECT);
              return true;
            }
            return false;
          }
        }
        public int getBatteryUsageHint() {
          enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");

          return HeadsetBase.getAtInputCount();
        }
        @Override
        public void handleMessage(Message msg) {
          synchronized (BluetoothHeadsetService.this) {
            IncomingConnectionInfo info = (IncomingConnectionInfo) msg.obj;
            int type = BluetoothHandsfree.TYPE_UNKNOWN;
            switch (msg.what) {
              case BluetoothAudioGateway.MSG_INCOMING_HEADSET_CONNECTION:
                type = BluetoothHandsfree.TYPE_HEADSET;
                break;
              case BluetoothAudioGateway.MSG_INCOMING_HANDSFREE_CONNECTION:
                type = BluetoothHandsfree.TYPE_HANDSFREE;
                break;
            }

            Log.i(
                TAG,
                "Incoming rfcomm ("
                    + BluetoothHandsfree.typeToString(type)
                    + ") connection from "
                    + info.mRemoteDevice
                    + "on channel "
                    + info.mRfcommChan);

            int priority = BluetoothHeadset.PRIORITY_OFF;
            HeadsetBase headset;
            priority = getPriority(info.mRemoteDevice);
            if (priority <= BluetoothHeadset.PRIORITY_OFF) {
              Log.i(TAG, "Rejecting incoming connection because priority = " + priority);

              headset =
                  new HeadsetBase(
                      mPowerManager,
                      mAdapter,
                      info.mRemoteDevice,
                      info.mSocketFd,
                      info.mRfcommChan,
                      null);
              headset.disconnect();
              return;
            }

            BluetoothRemoteHeadset remoteHeadset;
            BluetoothDevice device = getCurrentDevice();

            int state = BluetoothHeadset.STATE_DISCONNECTED;
            if (device != null) {
              state = mRemoteHeadsets.get(device).mState;
            }

            switch (state) {
              case BluetoothHeadset.STATE_DISCONNECTED:
                // headset connecting us, lets join
                remoteHeadset = new BluetoothRemoteHeadset(type, info);
                mRemoteHeadsets.put(info.mRemoteDevice, remoteHeadset);

                try {
                  mBluetoothService.notifyIncomingConnection(info.mRemoteDevice.getAddress());
                } catch (RemoteException e) {
                  Log.e(TAG, "notifyIncomingConnection");
                }
                break;
              case BluetoothHeadset.STATE_CONNECTING:
                if (!info.mRemoteDevice.equals(device)) {
                  // different headset, ignoring
                  Log.i(
                      TAG,
                      "Already attempting connect to "
                          + device
                          + ", disconnecting "
                          + info.mRemoteDevice);

                  headset =
                      new HeadsetBase(
                          mPowerManager,
                          mAdapter,
                          info.mRemoteDevice,
                          info.mSocketFd,
                          info.mRfcommChan,
                          null);
                  headset.disconnect();
                  break;
                }

                // Incoming and Outgoing connections to the same headset.
                // The state machine manager will cancel outgoing and accept the incoming one.
                // Update the state
                mRemoteHeadsets.get(info.mRemoteDevice).mHeadsetType = type;
                mRemoteHeadsets.get(info.mRemoteDevice).mIncomingInfo = info;

                try {
                  mBluetoothService.notifyIncomingConnection(info.mRemoteDevice.getAddress());
                } catch (RemoteException e) {
                  Log.e(TAG, "notifyIncomingConnection");
                }
                break;
              case BluetoothHeadset.STATE_CONNECTED:
                Log.i(
                    TAG,
                    "Already connected to " + device + ", disconnecting " + info.mRemoteDevice);

                headset =
                    new HeadsetBase(
                        mPowerManager,
                        mAdapter,
                        info.mRemoteDevice,
                        info.mSocketFd,
                        info.mRfcommChan,
                        null);
                headset.disconnect();
                break;
            }
          }
        }