Added BleStateReceiver and support for M APIs

Change-Id: If619aea9d6a0e06734d319d52cbcde2925be16d0
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java
index 965af94..552a775 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java
@@ -55,6 +55,7 @@
     private final IntentFilter discoveryFilter;
     private final EventFacade mEventFacade;
     private final BluetoothStateReceiver mStateReceiver;
+    private final BleStateReceiver mBleStateReceiver;
     private Map<String, BluetoothConnection> connections =
             new HashMap<String, BluetoothConnection>();
     private BluetoothAdapter mBluetoothAdapter;
@@ -77,6 +78,7 @@
         discoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
         mDiscoveryReceiver = new DiscoveryCacheReceiver();
         mStateReceiver = new BluetoothStateReceiver();
+        mBleStateReceiver = new BleStateReceiver();
     }
 
     class DiscoveryCacheReceiver extends BroadcastReceiver {
@@ -107,7 +109,7 @@
             String action = intent.getAction();
             // TODO: Keep track of the separate states be a separate method.
             if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
-                final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
+                final int state = mBluetoothAdapter.getState();
                 Bundle msg = new Bundle();
                 if (state == BluetoothAdapter.STATE_ON) {
                     msg.putString("State", "ON");
@@ -123,6 +125,25 @@
         }
     }
 
+    class BleStateReceiver extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)) {
+                int state = mBluetoothAdapter.getLeState();
+                if (state == BluetoothAdapter.STATE_BLE_ON) {
+                    mEventFacade.postEvent("BleStateChangedOn", new Bundle());
+                    mService.unregisterReceiver(mBleStateReceiver);
+                } else if (state == BluetoothAdapter.STATE_OFF) {
+                    mEventFacade.postEvent("BleStateChangedOff", new Bundle());
+                    mService.unregisterReceiver(mBleStateReceiver);
+                }
+            }
+        }
+    }
+
+
     public static boolean deviceMatch(BluetoothDevice device, String deviceID) {
         return deviceID.equals(device.getAliasName()) || deviceID.equals(device.getAddress());
     }
@@ -325,13 +346,28 @@
         return energyInfo.toString();
     }
 
+    @Rpc(description = "Return true if hardware has entries" +
+            "available for matching beacons.")
+    public boolean bluetoothIsHardwareTrackingFiltersAvailable() {
+        return mBluetoothAdapter.isHardwareTrackingFiltersAvailable();
+    }
+
+    @Rpc(description = "Gets the current state of LE.")
+    public int bluetoothGetLeState() {
+        return mBluetoothAdapter.getLeState();
+    }
+
     @Rpc(description = "Enables BLE functionalities.")
     public boolean bluetoothEnableBLE() {
+        mService.registerReceiver(mBleStateReceiver,
+            new IntentFilter(BluetoothAdapter.ACTION_BLE_STATE_CHANGED));
         return mBluetoothAdapter.enableBLE();
     }
 
     @Rpc(description = "Disables BLE functionalities.")
     public boolean bluetoothDisableBLE() {
+        mService.registerReceiver(mBleStateReceiver,
+            new IntentFilter(BluetoothAdapter.ACTION_BLE_STATE_CHANGED));
         return mBluetoothAdapter.disableBLE();
     }
 
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothLeScanFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothLeScanFacade.java
index 59c457d..d104f79 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothLeScanFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothLeScanFacade.java
@@ -789,6 +789,32 @@
             mScanFilterBuilder.setDeviceName(name);
     }
 
+    @Rpc(description = "Set the scan setting's match mode")
+    public void bleSetScanSettingsMatchMode(
+            @RpcParameter(name = "mode") Integer mode) {
+        mScanSettingsBuilder.setMatchMode(mode);
+    }
+
+    @Rpc(description = "Get the scan setting's match mode")
+    public int bleGetScanSettingsMatchMode(
+            @RpcParameter(name = "scanSettingsIndex") Integer scanSettingsIndex
+            ) {
+        return mScanSettingsList.get(scanSettingsIndex).getMatchMode();
+    }
+
+    @Rpc(description = "Set the scan setting's number of matches")
+    public void bleSetScanSettingsNumOfMatches(
+            @RpcParameter(name = "matches") Integer matches) {
+        mScanSettingsBuilder.setNumOfMatches(matches);
+    }
+
+    @Rpc(description = "Get the scan setting's number of matches")
+    public int bleGetScanSettingsNumberOfMatches(
+            @RpcParameter(name = "scanSettingsIndex")
+            Integer scanSettingsIndex) {
+        return  mScanSettingsList.get(scanSettingsIndex).getNumOfMatches();
+    }
+
     private class myScanCallback extends ScanCallback {
         public Integer index;
         String mEventType;
@@ -844,7 +870,6 @@
             mEventFacade.postEvent(mEventType + index + "onBatchScanResult", mResults.clone());
             mResults.clear();
         }
-
     }
 
     private class myLeScanCallback implements LeScanCallback {