OSDN Git Service

Implement enableNoAutoconnect() for NFC handover
authorGanesh Ganapathi Batta <ganeshg@broadcom.com>
Wed, 8 Aug 2012 22:14:16 +0000 (15:14 -0700)
committerMatthew Xie <mattx@google.com>
Tue, 14 Aug 2012 07:32:12 +0000 (00:32 -0700)
Implementation of  BT enable in Quiet mode without initiating auto connect and  not allowing
Incoming HFP, A2DP and HID  connections.

Change-Id: I857aea8d95677f8287df4641ec0aeae58a9f7a99

src/com/android/bluetooth/a2dp/A2dpStateMachine.java
src/com/android/bluetooth/btservice/AdapterService.java
src/com/android/bluetooth/hfp/HeadsetStateMachine.java
src/com/android/bluetooth/hid/HidService.java

index 3004b5a..2e063d1 100755 (executable)
@@ -202,21 +202,12 @@ final class A2dpStateMachine extends StateMachine {
 
         // in Disconnected state
         private void processConnectionEvent(int state, BluetoothDevice device) {
-            int priority;
             switch (state) {
             case CONNECTION_STATE_DISCONNECTED:
                 Log.w(TAG, "Ignore HF DISCONNECTED event, device: " + device);
                 break;
             case CONNECTION_STATE_CONNECTING:
-                // check priority and accept or reject the connection. if priority is undefined
-                // it is likely that our SDP has not completed and peer is initiating the
-                // connection. Allow this connection, provided the device is bonded
-                // Since the state changes to  Connecting or directly Connected in some cases.Have the check both in
-                // CONNECTION_STATE_CONNECTING and CONNECTION_STATE_CONNECTED.
-                priority = mService.getPriority(device);
-                if ((BluetoothProfile.PRIORITY_OFF < priority) ||
-                    ((BluetoothProfile.PRIORITY_UNDEFINED == priority) &&
-                     (device.getBondState() != BluetoothDevice.BOND_NONE))){
+                if (okToConnect(device)){
                     Log.i(TAG,"Incoming A2DP accepted");
                     broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
                                              BluetoothProfile.STATE_DISCONNECTED);
@@ -238,10 +229,7 @@ final class A2dpStateMachine extends StateMachine {
                 break;
             case CONNECTION_STATE_CONNECTED:
                 Log.w(TAG, "A2DP Connected from Disconnected state");
-                priority = mService.getPriority(device);
-                if ((BluetoothProfile.PRIORITY_OFF < priority) ||
-                    ((BluetoothProfile.PRIORITY_UNDEFINED == priority) &&
-                     (device.getBondState() != BluetoothDevice.BOND_NONE))){
+                if (okToConnect(device)){
                     Log.i(TAG,"Incoming A2DP accepted");
                     broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTED,
                                              BluetoothProfile.STATE_DISCONNECTED);
@@ -631,6 +619,27 @@ final class A2dpStateMachine extends StateMachine {
         return false;
     }
 
+    boolean okToConnect(BluetoothDevice device) {
+        AdapterService adapterService = AdapterService.getAdapterService();
+        int priority = mService.getPriority(device);
+        boolean ret = false;
+        //check if this is an incoming connection in Quiet mode.
+        if((adapterService == null) ||
+           ((adapterService.isQuietModeEnabled() == true) &&
+           (mTargetDevice == null))){
+            ret = false;
+        }
+        // check priority and accept or reject the connection. if priority is undefined
+        // it is likely that our SDP has not completed and peer is initiating the
+        // connection. Allow this connection, provided the device is bonded
+        else if((BluetoothProfile.PRIORITY_OFF < priority) ||
+                ((BluetoothProfile.PRIORITY_UNDEFINED == priority) &&
+                (device.getBondState() != BluetoothDevice.BOND_NONE))){
+            ret= true;
+        }
+        return ret;
+    }
+
     synchronized List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         List<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>();
         Set<BluetoothDevice> bondedDevices = mAdapter.getBondedDevices();
index 7c2d1a3..b7994e1 100755 (executable)
@@ -123,6 +123,7 @@ public class AdapterService extends Service {
     private HashMap<String,Integer> mProfileServicesState = new HashMap<String,Integer>();
     private RemoteCallbackList<IBluetoothCallback> mCallbacks;//Only BluetoothManagerService should be registered
     private int mCurrentRequestId;
+    private boolean mQuietmode = false;
 
     public AdapterService() {
         super();
@@ -509,8 +510,9 @@ public class AdapterService extends Service {
         }
 
         public boolean enableNoAutoConnect() {
-            // TODO(BT)
-            return false;
+            AdapterService service = getService();
+            if (service == null) return false;
+            return service.enableNoAutoConnect();
         }
 
         public boolean disable() {
@@ -733,15 +735,24 @@ public class AdapterService extends Service {
     }
 
      boolean enable() {
-        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                "Need BLUETOOTH ADMIN permission");
-        if (DBG) debugLog("enable() called...");
-        Message m =
-                mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON);
-        mAdapterStateMachine.sendMessage(m);
-        return true;
+        return enable (false);
     }
 
+      public boolean enableNoAutoConnect() {
+         return enable (true);
+     }
+
+     public synchronized boolean enable(boolean quietMode) {
+         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+                 "Need BLUETOOTH ADMIN permission");
+         if (DBG)debugLog("Enable called with quiet mode status =  " + mQuietmode);
+         mQuietmode  = quietMode;
+         Message m =
+                 mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON);
+         mAdapterStateMachine.sendMessage(m);
+         return true;
+     }
+
      boolean disable() {
         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                 "Need BLUETOOTH ADMIN permission");
@@ -851,13 +862,24 @@ public class AdapterService extends Service {
         return true;
     }
 
+      public boolean isQuietModeEnabled() {
+          if (DBG) debugLog("Quiet mode Enabled = " + mQuietmode);
+          return mQuietmode;
+     }
+
      public void autoConnect(){
         if (getState() != BluetoothAdapter.STATE_ON){
              errorLog("BT is not ON. Exiting autoConnect");
              return;
          }
-         autoConnectHeadset();
-         autoConnectA2dp();
+         if (isQuietModeEnabled() == false) {
+            if (DBG) debugLog( "Initiate auto connection on BT on...");
+             autoConnectHeadset();
+             autoConnectA2dp();
+         }
+         else {
+             if (DBG) debugLog( "BT is in Quiet mode. Not initiating  auto connections");
+         }
     }
 
      private void autoConnectHeadset(){
@@ -890,7 +912,8 @@ public class AdapterService extends Service {
     }
 
      public void connectOtherProfile(BluetoothDevice device, int firstProfileStatus){
-        if (mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES) == false){
+        if ((mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES) == false) &&
+            (isQuietModeEnabled()== false)){
             Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES);
             m.obj = device;
             m.arg1 = (int)firstProfileStatus;
index a798121..dd2396a 100755 (executable)
@@ -301,21 +301,12 @@ final class HeadsetStateMachine extends StateMachine {
 
         // in Disconnected state
         private void processConnectionEvent(int state, BluetoothDevice device) {
-            int priority;
             switch (state) {
             case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED:
                 Log.w(TAG, "Ignore HF DISCONNECTED event, device: " + device);
                 break;
             case HeadsetHalConstants.CONNECTION_STATE_CONNECTING:
-                // check priority and accept or reject the connection. if priority is undefined
-                // it is likely that our SDP has not completed and peer is initiating the
-                // connection. Allow this connection, provided the device is bonded
-                // Since the state changes to  Connecting or directly Connected in some cases.Have the check both in
-                // CONNECTION_STATE_CONNECTING and CONNECTION_STATE_CONNECTED.
-                priority = mService.getPriority(device);
-                if ((BluetoothProfile.PRIORITY_OFF < priority) ||
-                    ((BluetoothProfile.PRIORITY_UNDEFINED == priority) &&
-                     (device.getBondState() != BluetoothDevice.BOND_NONE))){
+                if (okToConnect(device)){
                     Log.i(TAG,"Incoming Hf accepted");
                     broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
                                              BluetoothProfile.STATE_DISCONNECTED);
@@ -324,7 +315,7 @@ final class HeadsetStateMachine extends StateMachine {
                         transitionTo(mPending);
                     }
                 } else {
-                    Log.i(TAG,"Incoming Hf rejected. priority=" + priority +
+                    Log.i(TAG,"Incoming Hf rejected. priority=" + mService.getPriority(device)+
                               " bondState=" + device.getBondState());
                     //reject the connection and stay in Disconnected state itself
                     disconnectHfpNative(getByteAddress(device));
@@ -338,13 +329,7 @@ final class HeadsetStateMachine extends StateMachine {
                 break;
             case HeadsetHalConstants.CONNECTION_STATE_CONNECTED:
                 Log.w(TAG, "HFP Connected from Disconnected state");
-                // check priority and accept or reject the connection. if priority is undefined
-                // it is likely that our SDP has not completed and peer is initiating the
-                // connection. Allow this connection, provided the device is bonded
-                priority = mService.getPriority(device);
-                if ((BluetoothProfile.PRIORITY_OFF < priority) ||
-                    ((BluetoothProfile.PRIORITY_UNDEFINED == priority) &&
-                     (device.getBondState() != BluetoothDevice.BOND_NONE))){
+                if (okToConnect(device)){
                     Log.i(TAG,"Incoming Hf accepted");
                     broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTED,
                                              BluetoothProfile.STATE_DISCONNECTED);
@@ -355,7 +340,7 @@ final class HeadsetStateMachine extends StateMachine {
                     configAudioParameters();
                 } else {
                     //reject the connection and stay in Disconnected state itself
-                    Log.i(TAG,"Incoming Hf rejected. priority=" + priority +
+                    Log.i(TAG,"Incoming Hf rejected. priority=" + mService.getPriority(device) +
                               " bondState=" + device.getBondState());
                     disconnectHfpNative(getByteAddress(device));
                     // the other profile connection should be initiated
@@ -1847,6 +1832,28 @@ final class HeadsetStateMachine extends StateMachine {
         return (currentState == mConnected || currentState == mAudioOn);
     }
 
+    boolean okToConnect(BluetoothDevice device) {
+        AdapterService adapterService = AdapterService.getAdapterService();
+        int priority = mService.getPriority(device);
+        boolean ret = false;
+        //check if this is an incoming connection in Quiet mode.
+        if((adapterService == null) ||
+           ((adapterService.isQuietModeEnabled() == true) &&
+           (mTargetDevice == null))){
+            ret = false;
+        }
+        // check priority and accept or reject the connection. if priority is undefined
+        // it is likely that our SDP has not completed and peer is initiating the
+        // connection. Allow this connection, provided the device is bonded
+        else if((BluetoothProfile.PRIORITY_OFF < priority) ||
+                ((BluetoothProfile.PRIORITY_UNDEFINED == priority) &&
+                (device.getBondState() != BluetoothDevice.BOND_NONE))){
+            ret= true;
+        }
+        return ret;
+    }
+
+
     private void log(String msg) {
         if (DBG) {
             Log.d(TAG, msg);
index 8bf9e1f..b606856 100755 (executable)
@@ -26,6 +26,7 @@ import java.util.Map;
 import com.android.bluetooth.Utils;
 import android.content.pm.PackageManager;
 import com.android.bluetooth.btservice.ProfileService;
+import com.android.bluetooth.btservice.AdapterService;
 
 /**
  * Provides Bluetooth Hid Host profile, as a service in
@@ -39,6 +40,7 @@ public class HidService extends ProfileService {
     private Map<BluetoothDevice, Integer> mInputDevices;
     private boolean mNativeAvailable;
     private static HidService sHidService;
+    private BluetoothDevice mTargetDevice = null;
 
     private static final int MESSAGE_CONNECT = 1;
     private static final int MESSAGE_DISCONNECT = 2;
@@ -139,6 +141,7 @@ public class HidService extends ProfileService {
                         broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED);
                         break;
                     }
+                    mTargetDevice = device;
                 }
                     break;
                 case MESSAGE_DISCONNECT:
@@ -160,15 +163,22 @@ public class HidService extends ProfileService {
                         BluetoothInputDevice.STATE_DISCONNECTED :prevStateInteger;
                     if(DBG) Log.d(TAG, "MESSAGE_CONNECT_STATE_CHANGED newState:"+
                         convertHalState(halState)+", prevState:"+prevState);
-                     if(halState == CONN_STATE_CONNECTED &&
-                        prevState == BluetoothInputDevice.STATE_DISCONNECTED &&
-                        (BluetoothProfile.PRIORITY_OFF == getPriority(device) ||
-                        device.getBondState() == BluetoothDevice.BOND_NONE)) {
+                    if(halState == CONN_STATE_CONNECTED &&
+                       prevState == BluetoothInputDevice.STATE_DISCONNECTED &&
+                       (!okToConnect(device))) {
                         Log.d(TAG,"Incoming HID connection rejected");
                         disconnectHidNative(Utils.getByteAddress(device));
                     } else {
                         broadcastConnectionState(device, convertHalState(halState));
                     }
+                    if (halState != CONN_STATE_CONNECTING) {
+                        mTargetDevice = null;
+                    }
+                    else {
+                        // CONN_STATE_CONNECTING is received only during
+                        // local initiated connection.
+                        mTargetDevice = device;
+                    }
                 }
                     break;
                 case MESSAGE_GET_PROTOCOL_MODE:
@@ -573,6 +583,18 @@ public class HidService extends ProfileService {
         sendBroadcast(intent, BLUETOOTH_PERM);
     }
 
+    private boolean okToConnect(BluetoothDevice device) {
+        AdapterService adapterService = AdapterService.getAdapterService();
+        //check if it is inbound connection in Quiet mode, priority and Bond status
+        //to decide if its ok to allow this connection
+        if((adapterService == null)||
+           ((adapterService.isQuietModeEnabled()) &&(mTargetDevice == null)) ||
+           (BluetoothProfile.PRIORITY_OFF == getPriority(device)) ||
+           (device.getBondState() == BluetoothDevice.BOND_NONE))
+            return false;
+
+        return true;
+    }
     private static int convertHalState(int halState) {
         switch (halState) {
             case CONN_STATE_CONNECTED: