Merge commit '8059467' into m-wireless-dev
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 2d5b37d..f56e4ae 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java
@@ -17,6 +17,7 @@
 package com.googlecode.android_scripting.facade.bluetooth;
 
 import android.app.Service;
+import android.bluetooth.BluetoothActivityEnergyInfo;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.content.BroadcastReceiver;
@@ -310,6 +311,20 @@
         return mBluetoothAdapter.configHciSnoopLog(value);
     }
 
+    @Rpc(description = "Get ")
+    public String bluetoothGetControllerActivityEnergyInfo(
+        @RpcParameter(name = "value")
+        Integer value
+            ) {
+        BluetoothActivityEnergyInfo energyInfo = mBluetoothAdapter
+            .getControllerActivityEnergyInfo(value);
+        //TODO (tturney): Fix when method dosn't return null... cosmic issue.
+        while (energyInfo == null) {
+          energyInfo = mBluetoothAdapter.getControllerActivityEnergyInfo(value);
+        }
+        return energyInfo.toString();
+    }
+
     @Override
     public void shutdown() {
         for (Map.Entry<String, BluetoothConnection> entry : connections.entrySet()) {
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java
index 75d8b5a..acde364 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java
@@ -906,6 +906,7 @@
     }
 
     /**
+     * Returns the list of discovered Bluetooth Gatt Services.
      * @throws Exception
      */
     @Rpc(description = "Get Bluetooth Gatt Services")
@@ -921,6 +922,26 @@
     }
 
     /**
+     * Returns the discovered Bluetooth Gatt Service Uuid.
+     * @throws Exception
+     */
+    @Rpc(description = "Get Bluetooth Gatt Service Uuid")
+    public String gattGetDiscoveredServiceUuid (
+            @RpcParameter(name = "index")
+            Integer index,
+            @RpcParameter(name = "serviceIndex")
+            Integer serviceIndex
+            ) throws Exception {
+        List<BluetoothGattService> mBluetoothServiceList =
+            mBluetoothGattDiscoveredServicesList.get(index);
+        if (mBluetoothServiceList != null) {
+            return mBluetoothServiceList.get(serviceIndex).getUuid().toString();
+        } else {
+            throw new Exception("Invalid index input:" + index);
+        }
+    }
+
+    /**
      * Get discovered characteristic uuids from the pheripheral device.
      * @param index the index of the bluetooth gatt discovered services list
      * @param serviceIndex the service to get
diff --git a/Common/src/com/googlecode/android_scripting/facade/tele/PhoneFacade.java b/Common/src/com/googlecode/android_scripting/facade/tele/PhoneFacade.java
index 94b7350..ff63dea 100644
--- a/Common/src/com/googlecode/android_scripting/facade/tele/PhoneFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/tele/PhoneFacade.java
@@ -27,7 +27,6 @@
 import android.provider.ContactsContract;
 import android.telephony.CellLocation;
 import android.telephony.NeighboringCellInfo;
-import android.telephony.CellInfo;
 import android.telephony.PhoneStateListener;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -938,12 +937,6 @@
         return mTelephonyManager.getNeighboringCellInfo();
     }
 
-    @Rpc(description = "Returns all observed cell information from all radios"+
-                       "on the device including the primary and neighboring cells")
-    public List<CellInfo> getAllCellInfo() {
-        return mTelephonyManager.getAllCellInfo();
-    }
-
     @Rpc(description = "Returns True if cellular data is enabled for" +
                        "default data subscription ID.")
     public Boolean isDataEnabled() {
diff --git a/Common/src/com/googlecode/android_scripting/facade/tele/TelephonyStateListeners.java b/Common/src/com/googlecode/android_scripting/facade/tele/TelephonyStateListeners.java
index 88888ba..c080787 100644
--- a/Common/src/com/googlecode/android_scripting/facade/tele/TelephonyStateListeners.java
+++ b/Common/src/com/googlecode/android_scripting/facade/tele/TelephonyStateListeners.java
@@ -15,6 +15,57 @@
  */
 public class TelephonyStateListeners {
 
+    private static String getNetworkTypeString(int type) {
+        switch(type) {
+            case TelephonyManager.NETWORK_TYPE_GPRS:
+                return "GPRS";
+            case TelephonyManager.NETWORK_TYPE_EDGE:
+                return "EDGE";
+            case TelephonyManager.NETWORK_TYPE_UMTS:
+                return "UMTS";
+            case TelephonyManager.NETWORK_TYPE_HSDPA:
+                return "HSDPA";
+            case TelephonyManager.NETWORK_TYPE_HSUPA:
+                return "HSUPA";
+            case TelephonyManager.NETWORK_TYPE_HSPA:
+                return "HSPA";
+            case TelephonyManager.NETWORK_TYPE_CDMA:
+                return "CDMA";
+            case TelephonyManager.NETWORK_TYPE_1xRTT:
+                return "1xRTT";
+            case TelephonyManager.NETWORK_TYPE_EVDO_0:
+                return "EVDO_0";
+            case TelephonyManager.NETWORK_TYPE_EVDO_A:
+                return "EVDO_A";
+            case TelephonyManager.NETWORK_TYPE_EVDO_B:
+                return "EVDO_B";
+            case TelephonyManager.NETWORK_TYPE_EHRPD:
+                return "EHRPD";
+            case TelephonyManager.NETWORK_TYPE_LTE:
+                return "LTE";
+            case TelephonyManager.NETWORK_TYPE_HSPAP:
+                return "HSPAP";
+            case TelephonyManager.NETWORK_TYPE_GSM:
+                return "GSM";
+        }
+        return "UNKNOWN";
+    }
+
+    private static String getNetworkStateString(int state) {
+        switch(state) {
+            case ServiceState.STATE_EMERGENCY_ONLY:
+                return "EMERGENCY_ONLY";
+            case ServiceState.STATE_IN_SERVICE:
+                return "IN_SERVICE";
+            case ServiceState.STATE_OUT_OF_SERVICE:
+                return "OUT_OF_SERVICE";
+            case ServiceState.STATE_POWER_OFF:
+                return "POWER_OFF";
+            default:
+                return "UNKNOWN";
+        }
+   }
+
     public static class CallStateChangeListener extends PhoneStateListener {
 
         private final EventFacade mEventFacade;
@@ -193,7 +244,7 @@
                 subEvent = "Connecting";
             } else if (state == TelephonyManager.DATA_CONNECTED) {
                 subEvent = "Connected";
-                event.putString("DataNetworkType", TelephonyUtils.getNetworkTypeString(
+                event.putString("DataNetworkType", getNetworkTypeString(
                                  mTelephonyManager.getDataNetworkType()));
             } else if (state == TelephonyManager.DATA_SUSPENDED) {
                 subEvent = "Suspended";
@@ -244,13 +295,13 @@
                     subEvent = "PowerOff";
                 break;
             }
-            event.putString("VoiceRegState", TelephonyUtils.getNetworkStateString(
+            event.putString("VoiceRegState", getNetworkStateString(
                              serviceState.getVoiceRegState()));
-            event.putString("VoiceNetworkType", TelephonyUtils.getNetworkTypeString(
+            event.putString("VoiceNetworkType", getNetworkTypeString(
                              serviceState.getVoiceNetworkType()));
-            event.putString("DataRegState", TelephonyUtils.getNetworkStateString(
+            event.putString("DataRegState", getNetworkStateString(
                              serviceState.getDataRegState()));
-            event.putString("DataNetworkType", TelephonyUtils.getNetworkTypeString(
+            event.putString("DataNetworkType", getNetworkTypeString(
                              serviceState.getDataNetworkType()));
             event.putString("OperatorName", serviceState.getOperatorAlphaLong());
             event.putString("OperatorId", serviceState.getOperatorNumeric());
@@ -296,12 +347,29 @@
             mEventFacade = ef;
         }
 
+        private static String getSrvccStateString(int srvccState) {
+            switch (srvccState) {
+                case VoLteServiceState.HANDOVER_STARTED:
+                    return "HANDOVER_STARTED";
+                case VoLteServiceState.HANDOVER_COMPLETED:
+                    return "HANDOVER_COMPLETED";
+                case VoLteServiceState.HANDOVER_FAILED:
+                    return "HANDOVER_FAILED";
+                case VoLteServiceState.HANDOVER_CANCELED:
+                    return "HANDOVER_CANCELED";
+                default:
+                    Log.e(String.format("getSrvccStateString():"
+                            + "unknown state %d", srvccState));
+                    return "UNKNOWN";
+            }
+        }
+
         @Override
         public void onVoLteServiceStateChanged(VoLteServiceState volteInfo) {
             Bundle event = new Bundle();
 
             event.putString("srvccState",
-                    TelephonyUtils.getSrvccStateString(volteInfo.getSrvccState()));
+                    getSrvccStateString(volteInfo.getSrvccState()));
 
             mEventFacade.postEvent(
                     "onVolteServiceStateChanged", event);
diff --git a/Common/src/com/googlecode/android_scripting/facade/tele/TelephonyUtils.java b/Common/src/com/googlecode/android_scripting/facade/tele/TelephonyUtils.java
deleted file mode 100644
index cf174ec..0000000
--- a/Common/src/com/googlecode/android_scripting/facade/tele/TelephonyUtils.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package com.googlecode.android_scripting.facade.tele;
-
-import com.googlecode.android_scripting.Log;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.telephony.VoLteServiceState;
-
-/**
- * Telephony utility functions
- */
-public class TelephonyUtils {
-
-    public static String getNetworkTypeString(int type) {
-        switch(type) {
-            case TelephonyManager.NETWORK_TYPE_GPRS:
-                return "GPRS";
-            case TelephonyManager.NETWORK_TYPE_EDGE:
-                return "EDGE";
-            case TelephonyManager.NETWORK_TYPE_UMTS:
-                return "UMTS";
-            case TelephonyManager.NETWORK_TYPE_HSDPA:
-                return "HSDPA";
-            case TelephonyManager.NETWORK_TYPE_HSUPA:
-                return "HSUPA";
-            case TelephonyManager.NETWORK_TYPE_HSPA:
-                return "HSPA";
-            case TelephonyManager.NETWORK_TYPE_CDMA:
-                return "CDMA";
-            case TelephonyManager.NETWORK_TYPE_1xRTT:
-                return "1xRTT";
-            case TelephonyManager.NETWORK_TYPE_EVDO_0:
-                return "EVDO_0";
-            case TelephonyManager.NETWORK_TYPE_EVDO_A:
-                return "EVDO_A";
-            case TelephonyManager.NETWORK_TYPE_EVDO_B:
-                return "EVDO_B";
-            case TelephonyManager.NETWORK_TYPE_EHRPD:
-                return "EHRPD";
-            case TelephonyManager.NETWORK_TYPE_LTE:
-                return "LTE";
-            case TelephonyManager.NETWORK_TYPE_HSPAP:
-                return "HSPAP";
-            case TelephonyManager.NETWORK_TYPE_GSM:
-                return "GSM";
-            case TelephonyManager. NETWORK_TYPE_TD_SCDMA:
-                return "TD-SCDMA";
-            case TelephonyManager.NETWORK_TYPE_IWLAN:
-                return "WLAN";
-        }
-        return "UNKNOWN";
-    }
-
-    public static String getNetworkStateString(int state) {
-        switch(state) {
-            case ServiceState.STATE_EMERGENCY_ONLY:
-                return "EMERGENCY_ONLY";
-            case ServiceState.STATE_IN_SERVICE:
-                return "IN_SERVICE";
-            case ServiceState.STATE_OUT_OF_SERVICE:
-                return "OUT_OF_SERVICE";
-            case ServiceState.STATE_POWER_OFF:
-                return "POWER_OFF";
-            default:
-                return "UNKNOWN";
-        }
-   }
-
-    public static String getSrvccStateString(int srvccState) {
-        switch (srvccState) {
-            case VoLteServiceState.HANDOVER_STARTED:
-                return "HANDOVER_STARTED";
-            case VoLteServiceState.HANDOVER_COMPLETED:
-                return "HANDOVER_COMPLETED";
-            case VoLteServiceState.HANDOVER_FAILED:
-                return "HANDOVER_FAILED";
-            case VoLteServiceState.HANDOVER_CANCELED:
-                return "HANDOVER_CANCELED";
-            default:
-                Log.e(String.format("getSrvccStateString():"
-                        + "unknown state %d", srvccState));
-                return "UNKNOWN";
-        }
-    };
-}
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
index e7857dc..37e7231 100755
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
@@ -3,6 +3,7 @@
 
 import android.app.Service;
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -49,7 +50,6 @@
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.X509EncodedKeySpec;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 
@@ -172,12 +172,13 @@
 
         @Override
         public void onSuccess() {
+            Log.d("WifiActionListener  onSuccess called for " + mEventType + TAG + "OnSuccess");
             mEventFacade.postEvent(mEventType + TAG + "OnSuccess", null);
         }
 
         @Override
         public void onFailure(int reason) {
-            Log.d("WifiActionListener  " + mEventType);
+            Log.d("WifiActionListener  onFailure called for" + mEventType);
             Bundle msg = new Bundle();
             msg.putInt("reason", reason);
             mEventFacade.postEvent(mEventType + TAG + "OnFailure", msg);
@@ -274,7 +275,7 @@
     }
 
     private WifiConfiguration genEnterpriseConfig(String configStr) throws JSONException,
-    GeneralSecurityException {
+            GeneralSecurityException {
         if (configStr == null) {
             return null;
         }
@@ -321,15 +322,11 @@
             Log.v("Setting password to " + pwd);
             eConfig.setPassword(pwd);
         }
-        //removed non-compiling code for 
-        // missing WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY
-        /*
         if (j.has(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY)) {
             String altSub = j.getString(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY);
             Log.v("Setting Alt Subject to " + altSub);
             eConfig.setAltSubjectMatch(altSub);
         }
-        */
         config.enterpriseConfig = eConfig;
         return config;
     }
@@ -337,6 +334,7 @@
     private WifiConfiguration genWifiConfig(String SSID, String pwd) {
         WifiConfiguration wifiConfig = new WifiConfiguration();
         wifiConfig.SSID = "\"" + SSID + "\"";
+        Log.v("genWifiConfig pwd " + pwd);
         if (pwd == null) {
             wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
         } else {
@@ -403,7 +401,7 @@
     }
 
     private PrivateKey strToPrivateKey(String key) throws NoSuchAlgorithmException,
-    InvalidKeySpecException {
+            InvalidKeySpecException {
         byte[] keyBytes = base64StrToBytes(key);
         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
         KeyFactory fact = KeyFactory.getInstance("RSA");
@@ -412,7 +410,7 @@
     }
 
     private PublicKey strToPublicKey(String key) throws NoSuchAlgorithmException,
-    InvalidKeySpecException {
+            InvalidKeySpecException {
         byte[] keyBytes = base64StrToBytes(key);
         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
         KeyFactory fact = KeyFactory.getInstance("RSA");
@@ -427,10 +425,6 @@
         config.SSID = "\"" + result.SSID + "\"";
         applyingkeyMgmt(config, result);
         config.BSSID = result.BSSID;
-        config.scanResultCache = new HashMap<String, ScanResult>();
-        if (config.scanResultCache == null)
-            return null;
-        config.scanResultCache.put(result.BSSID, result);
         return config;
     }
 
@@ -474,8 +468,8 @@
             returns = "True if the operation succeeded.")
     public Boolean wifiConnect(
             @RpcParameter(name = "SSID") String SSID,
-            @RpcParameter(name = "Password") @RpcOptional @RpcDefault(value = "") String Password)
-                    throws ConnectException {
+            @RpcParameter(name = "Password") @RpcOptional String Password)
+            throws ConnectException {
         WifiConfiguration wifiConfig = genWifiConfig(SSID, Password);
         mWifi.addNetwork(wifiConfig);
         Boolean status = false;
@@ -548,7 +542,7 @@
         return mWifi.getScanResults();
     }
 
-    @Rpc(description = "Check if wifi scanner is supported on this device.")
+    @Rpc(description = "Gets the Wi-Fi AP Configuration.")
     public WifiConfiguration wifiGetApConfiguration() {
         return mWifi.getWifiApConfiguration();
     }
@@ -594,7 +588,7 @@
      */
     @Rpc(description = "Connects a wifi network as priority by pasing ssid")
     public void wifiPriorityConnect(@RpcParameter(name = "SSID") String SSID,
-            @RpcParameter(name = "Password") @RpcOptional @RpcDefault(value = "") String Password) {
+            @RpcParameter(name = "Password") @RpcOptional String Password) {
         WifiConfiguration wifiConfig = genWifiConfig(SSID, Password);
         WifiActionListener listener = new WifiActionListener(mEventFacade, "PriorityConnect");
         mWifi.connect(wifiConfig, listener);
@@ -646,8 +640,8 @@
     @Rpc(description = "Start Wi-fi Protected Setup.")
     public void wifiStartWps(
             @RpcParameter(name = "config",
-            description = "A json string with fields \"setup\", \"BSSID\", and \"pin\"") String config)
-                    throws JSONException {
+                    description = "A json string with fields \"setup\", \"BSSID\", and \"pin\"") String config)
+            throws JSONException {
         WpsInfo info = parseWpsInfo(config);
         WifiWpsCallback listener = new WifiWpsCallback();
         Log.d("Starting wps with: " + info);
@@ -679,6 +673,26 @@
         return enabled;
     }
 
+    @Rpc(description = "Toggle Wifi scan always available on and off.",
+            returns = "True if Wifi scan is always available.")
+    public Boolean wifiToggleScanAlwaysAvailable(
+            @RpcParameter(name = "enabled") @RpcOptional Boolean enabled)
+            throws SettingNotFoundException {
+        ContentResolver cr = mService.getContentResolver();
+        int isSet = 0;
+        if (enabled == null) {
+            isSet = Global.getInt(cr, Global.WIFI_SCAN_ALWAYS_AVAILABLE);
+            isSet ^= 1;
+        } else if (enabled == true) {
+            isSet = 1;
+        }
+        Global.putInt(cr, Global.WIFI_SCAN_ALWAYS_AVAILABLE, isSet);
+        if (isSet == 1) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public void shutdown() {
         wifiLockRelease();
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java
index d10b7a5..58c3fb6 100644
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java
@@ -1,9 +1,11 @@
+
 package com.googlecode.android_scripting.facade.wifi;
 
 import android.app.Service;
 import android.content.Context;
 import android.net.wifi.RttManager;
 import android.net.wifi.RttManager.Capabilities;
+import android.net.wifi.RttManager.RttCapabilities;
 import android.net.wifi.RttManager.RttListener;
 import android.net.wifi.RttManager.RttParams;
 import android.net.wifi.RttManager.RttResult;
@@ -19,6 +21,7 @@
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.Map;
+
 import org.json.JSONException;
 import org.json.JSONObject;
 
@@ -26,128 +29,175 @@
  * WifiRttManager functions.
  */
 public class WifiRttManagerFacade extends RpcReceiver {
-  private final Service mService;
-  private final RttManager mRtt;
-  private final EventFacade mEventFacade;
-  private final Map<Integer, RttListener> mRangingListeners;
-
-  public WifiRttManagerFacade(FacadeManager manager) {
-    super(manager);
-    mService = manager.getService();
-    mRtt = (RttManager) mService.getSystemService(Context.WIFI_RTT_SERVICE);
-    mEventFacade = manager.getReceiver(EventFacade.class);
-    mRangingListeners = new Hashtable<Integer, RttListener>();
-  }
-
-  public static class RangingListener implements RttListener {
-    private static final String TAG = "WifiRttRanging";
-    private static int sCount = 0;
+    private final Service mService;
+    private final RttManager mRtt;
     private final EventFacade mEventFacade;
-    public final int mId;
+    private final Map<Integer, RttListener> mRangingListeners;
 
-    public RangingListener(EventFacade eventFacade) {
-        sCount += 1;
-        mId = sCount;
-        mEventFacade = eventFacade;
+    public WifiRttManagerFacade(FacadeManager manager) {
+        super(manager);
+        mService = manager.getService();
+        mRtt = (RttManager) mService.getSystemService(Context.WIFI_RTT_SERVICE);
+        mEventFacade = manager.getReceiver(EventFacade.class);
+        mRangingListeners = new Hashtable<Integer, RttListener>();
     }
 
-    private Bundle packRttResult(RttResult result) {
-        Bundle rttResult = new Bundle();
-        rttResult.putString("bssid", result.bssid);
-        rttResult.putLong("distance_cm", result.distance_cm);
-        rttResult.putLong("distance_sd_cm", result.distance_sd_cm);
-        rttResult.putLong("distance_spread_cm", result.distance_spread_cm);
-        rttResult.putLong("rtt_ns", result.rtt_ns);
-        rttResult.putLong("rtt_sd_ns", result.rtt_sd_ns);
-        rttResult.putLong("rtt_spread_ns", result.rtt_spread_ns);
-        rttResult.putLong("ts", result.ts);
-        rttResult.putInt("rssi", result.rssi);
-        rttResult.putInt("status", result.status);
-        rttResult.putInt("tx_rate", result.tx_rate);
-        return rttResult;
-    }
+    public static class RangingListener implements RttListener {
+        private static final String TAG = "WifiRttRanging";
+        private static int sCount = 0;
+        private final EventFacade mEventFacade;
+        public final int mId;
 
-    @Override
-    public void onSuccess(RttResult[] results) {
-        Bundle msg = new Bundle();
-        Parcelable[] resultBundles = new Parcelable[results.length];
-        for (int i = 0; i < results.length; i++) {
-            resultBundles[i] = packRttResult(results[i]);
+        public RangingListener(EventFacade eventFacade) {
+            sCount += 1;
+            mId = sCount;
+            mEventFacade = eventFacade;
         }
-        msg.putParcelableArray("Results", resultBundles);
-        mEventFacade.postEvent(RangingListener.TAG + mId + "onSuccess", msg);
+
+        private Bundle packRttResult(RttResult result) {
+            Bundle rttResult = new Bundle();
+            rttResult.putString("BSSID", result.bssid);
+            rttResult.putInt("txRate", result.txRate);
+            rttResult.putInt("rxRate", result.rxRate);
+            rttResult.putInt("distance", result.distance);
+            rttResult.putInt("distanceStandardDeviation",
+                    result.distanceStandardDeviation);
+            rttResult.putInt("distanceSpread", result.distanceSpread);
+            rttResult.putInt("burstDuration", result.burstDuration);
+            rttResult.putLong("rtt", result.rtt);
+            rttResult.putLong("rttStandardDeviation",
+                    result.rttStandardDeviation);
+            rttResult.putLong("rttSpread", result.rttSpread);
+            rttResult.putLong("ts", result.ts);
+            rttResult.putInt("rssi", result.rssi);
+            rttResult.putInt("rssiSpread", result.rssiSpread);
+            rttResult.putInt("retryAfterDuration", result.retryAfterDuration);
+            rttResult.putInt("measurementType", result.measurementType);
+            rttResult.putInt("status", result.status);
+            rttResult.putInt("frameNumberPerBurstPeer",
+                    result.frameNumberPerBurstPeer);
+            rttResult.putInt("successMeasurementFrameNumber",
+                    result.successMeasurementFrameNumber);
+            rttResult.putInt("measurementFrameNumber",
+                    result.measurementFrameNumber);
+            rttResult.putInt("burstNumber", result.burstNumber);
+            rttResult.putInt("status", result.status);
+            return rttResult;
+        }
+
+        @Override
+        public void onSuccess(RttResult[] results) {
+            Bundle msg = new Bundle();
+            Parcelable[] resultBundles = new Parcelable[results.length];
+            for (int i = 0; i < results.length; i++) {
+                resultBundles[i] = packRttResult(results[i]);
+            }
+            msg.putParcelableArray("Results", resultBundles);
+            mEventFacade
+                    .postEvent(RangingListener.TAG + mId + "onSuccess", msg);
+        }
+
+        @Override
+        public void onFailure(int reason, String description) {
+            Bundle msg = new Bundle();
+            msg.putInt("Reason", reason);
+            msg.putString("Description", description);
+            mEventFacade
+                    .postEvent(RangingListener.TAG + mId + "onFailure", msg);
+        }
+
+        @Override
+        public void onAborted() {
+            mEventFacade.postEvent(RangingListener.TAG + mId + "onAborted",
+                    new Bundle());
+        }
+    }
+
+    @Rpc(description = "Get wifi Rtt capabilities.")
+    public RttCapabilities wifiRttGetCapabilities() {
+        return mRtt.getRttCapabilities();
+    }
+
+    private RttParams parseRttParam(String rttParam) throws JSONException {
+        JSONObject j = new JSONObject(rttParam);
+        RttParams result = new RttParams();
+        if (j.has("deviceType")) {
+            result.deviceType = j.getInt("deviceType");
+        }
+        if (j.has("requestType")) {
+            result.requestType = j.getInt("requestType");
+        }
+        if (j.has("bssid")) {
+            result.bssid = j.getString("bssid");
+        }
+        if (j.has("frequency")) {
+            result.frequency = j.getInt("frequency");
+        }
+        if (j.has("channelWidth")) {
+            result.channelWidth = j.getInt("channelWidth");
+        }
+        if (j.has("centerFreq0")) {
+            result.centerFreq0 = j.getInt("centerFreq0");
+        }
+        if (j.has("centerFreq1")) {
+            result.centerFreq1 = j.getInt("centerFreq1");
+        }
+        if (j.has("numberBurst")) {
+            result.numberBurst = j.getInt("numberBurst");
+        }
+        if (j.has("interval")) {
+            result.interval = j.getInt("interval");
+        }
+        if (j.has("numSamplesPerBurst")) {
+            result.numSamplesPerBurst = j.getInt("numSamplesPerBurst");
+        }
+        if (j.has("numRetriesPerMeasurementFrame")) {
+            result.numRetriesPerMeasurementFrame = j
+                    .getInt("numRetriesPerMeasurementFrame");
+        }
+        if (j.has("numRetriesPerFTMR")) {
+            result.numRetriesPerFTMR = j.getInt("numRetriesPerFTMR");
+        }
+        if (j.has("LCIRequest")) {
+            result.LCIRequest = j.getBoolean("LCIRequest");
+        }
+        if (j.has("LCRRequest")) {
+            result.LCRRequest = j.getBoolean("LCRRequest");
+        }
+        if (j.has("preamble")) {
+            result.preamble = j.getInt("preamble");
+        }
+        if (j.has("bandwidth")) {
+            result.bandwidth = j.getInt("bandwidth");
+        }
+        return result;
+    }
+
+    @Rpc(description = "Start ranging.", returns = "Id of the listener associated with the started ranging.")
+    public Integer wifiRttStartRanging(
+            @RpcParameter(name = "params") String[] params)
+            throws JSONException {
+        RttParams[] rParams = new RttParams[params.length];
+        for (int i = 0; i < params.length; i++) {
+            rParams[i] = parseRttParam(params[i]);
+        }
+        RangingListener listener = new RangingListener(mEventFacade);
+        mRangingListeners.put(listener.mId, listener);
+        mRtt.startRanging(rParams, listener);
+        return listener.mId;
+    }
+
+    @Rpc(description = "Stop ranging.")
+    public void wifiRttStopRanging(@RpcParameter(name = "index") Integer index) {
+        mRtt.stopRanging(mRangingListeners.remove(index));
     }
 
     @Override
-    public void onFailure(int reason, String description) {
-        Bundle msg = new Bundle();
-        msg.putInt("Reason", reason);
-        msg.putString("Description", description);
-        mEventFacade.postEvent(RangingListener.TAG + mId + "onFailure", msg);
+    public void shutdown() {
+        ArrayList<Integer> keys = new ArrayList<Integer>(
+                mRangingListeners.keySet());
+        for (int k : keys) {
+            wifiRttStopRanging(k);
+        }
     }
-
-    @Override
-    public void onAborted() {
-        mEventFacade.postEvent(RangingListener.TAG + mId + "onAborted", new Bundle());
-    }
-  }
-
-  @Rpc(description = "Get wifi Rtt capabilities.")
-  public Capabilities wifiRttGetCapabilities() {
-      return mRtt.getCapabilities();
-  }
-
-  private RttParams parseRttParam(String rttParam) throws JSONException {
-      JSONObject j = new JSONObject(rttParam);
-      RttParams result = new RttParams();
-      if (j.has("deviceType")) {
-          result.deviceType = j.getInt("deviceType");
-      }
-      if (j.has("requestType")) {
-          result.requestType = j.getInt("requestType");
-      }
-      if (j.has("bssid")) {
-          result.bssid = j.getString("bssid");
-      }
-      if (j.has("frequency")) {
-          result.frequency = j.getInt("frequency");
-      }
-      if (j.has("channelWidth")) {
-          result.channelWidth = j.getInt("channelWidth");
-      }
-      if (j.has("num_samples")) {
-          result.num_samples = j.getInt("num_samples");
-      }
-      if (j.has("num_retries")) {
-          result.num_retries = j.getInt("num_retries");
-      }
-      return result;
-  }
-
-  @Rpc(description = "Start ranging.",
-       returns = "Id of the listener associated with the started ranging.")
-  public Integer wifiRttStartRanging(@RpcParameter(name = "params")
-                                  String[] params) throws JSONException {
-      RttParams[] rParams = new RttParams[params.length];
-      for (int i = 0; i < params.length; i++) {
-          rParams[i] = parseRttParam(params[i]);
-      }
-      RangingListener listener = new RangingListener(mEventFacade);
-      mRangingListeners.put(listener.mId, listener);
-      mRtt.startRanging(rParams, listener);
-      return listener.mId;
-  }
-
-  @Rpc(description = "Stop ranging.")
-  public void wifiRttStopRanging(@RpcParameter(name = "index") Integer index) {
-      mRtt.stopRanging(mRangingListeners.remove(index));
-  }
-
-  @Override
-  public void shutdown() {
-      ArrayList<Integer> keys = new ArrayList<Integer>(mRangingListeners.keySet());
-      for (int k : keys) {
-          wifiRttStopRanging(k);
-      }
-  }
 }
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiScannerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiScannerFacade.java
index 28ebe3c..2875652 100644
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiScannerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiScannerFacade.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
+
 package com.googlecode.android_scripting.facade.wifi;
 
 import android.app.Service;
@@ -21,6 +22,7 @@
 import android.net.wifi.WifiScanner;
 import android.net.wifi.WifiScanner.BssidInfo;
 import android.net.wifi.WifiScanner.ChannelSpec;
+import android.net.wifi.WifiScanner.ScanData;
 import android.net.wifi.WifiScanner.ScanSettings;
 import android.os.Bundle;
 import android.os.SystemClock;
@@ -46,498 +48,542 @@
 
 /**
  * WifiScanner functions.
- *
  */
 public class WifiScannerFacade extends RpcReceiver {
-  private final Service mService;
-  private final EventFacade mEventFacade;
-  private final WifiScanner mScan;
-  //These counters are just for indexing;
-  //they do not represent the total number of listeners
-  private static int WifiScanListenerCnt;
-  private static int WifiChangeListenerCnt;
-  private static int WifiBssidListenerCnt;
-  private final ConcurrentHashMap<Integer, WifiScanListener> scanListeners;
-  private final ConcurrentHashMap<Integer, ChangeListener> trackChangeListeners;
-  private final ConcurrentHashMap<Integer, WifiBssidListener> trackBssidListeners;
-  private static ConcurrentHashMap<Integer, ScanResult[]> wifiScannerResultList;
+    private final Service mService;
+    private final EventFacade mEventFacade;
+    private final WifiScanner mScan;
+    // These counters are just for indexing;
+    // they do not represent the total number of listeners
+    private static int WifiScanListenerCnt;
+    private static int WifiChangeListenerCnt;
+    private static int WifiBssidListenerCnt;
+    private final ConcurrentHashMap<Integer, WifiScanListener> scanListeners;
+    private final ConcurrentHashMap<Integer, ChangeListener> trackChangeListeners;
+    private final ConcurrentHashMap<Integer, WifiBssidListener> trackBssidListeners;
+    private static ConcurrentHashMap<Integer, ScanResult[]> wifiScannerResultList;
+    private static ConcurrentHashMap<Integer, ScanData[]> wifiScannerDataList;
 
-  public WifiScannerFacade(FacadeManager manager) {
-    super(manager);
-    mService = manager.getService();
-    mScan = (WifiScanner) mService.getSystemService(Context.WIFI_SCANNING_SERVICE);
-    mEventFacade = manager.getReceiver(EventFacade.class);
-    scanListeners = new ConcurrentHashMap<Integer, WifiScanListener>();
-    trackChangeListeners = new ConcurrentHashMap<Integer, ChangeListener>();
-    trackBssidListeners = new ConcurrentHashMap<Integer, WifiBssidListener>();
-    wifiScannerResultList = new ConcurrentHashMap<Integer, ScanResult[]>();
-  }
-
-  public static List<ScanResult> getWifiScanResult(Integer listener_index){
-    ScanResult[] sr = wifiScannerResultList.get(listener_index);
-    return Arrays.asList(sr);
-  }
-
-  private class WifiActionListener implements WifiScanner.ActionListener {
-    private final Bundle mResults;
-    public int mIndex;
-    protected String mEventType;
-
-    public WifiActionListener(String type, int idx, Bundle resultBundle) {
-      this.mIndex = idx;
-      this.mEventType = type;
-      this.mResults = resultBundle;
+    public WifiScannerFacade(FacadeManager manager) {
+        super(manager);
+        mService = manager.getService();
+        mScan = (WifiScanner) mService.getSystemService(Context.WIFI_SCANNING_SERVICE);
+        mEventFacade = manager.getReceiver(EventFacade.class);
+        scanListeners = new ConcurrentHashMap<Integer, WifiScanListener>();
+        trackChangeListeners = new ConcurrentHashMap<Integer, ChangeListener>();
+        trackBssidListeners = new ConcurrentHashMap<Integer, WifiBssidListener>();
+        wifiScannerResultList = new ConcurrentHashMap<Integer, ScanResult[]>();
+        wifiScannerDataList = new ConcurrentHashMap<Integer, ScanData[]>();
     }
 
-    @Override
-    public void onSuccess() {
-      Log.d("onSuccess " + mEventType + " " + mIndex);
-      mResults.putString("Type", "onSuccess");
-      mResults.putLong("Realtime", SystemClock.elapsedRealtime());
-      mEventFacade.postEvent(mEventType + mIndex + "onSuccess", mResults.clone());
-      mResults.clear();
+    public static List<ScanResult> getWifiScanResult(Integer listener_index) {
+        ScanResult[] sr = wifiScannerResultList.get(listener_index);
+        return Arrays.asList(sr);
     }
 
-    @Override
-    public void onFailure(int reason, String description) {
-      Log.d("onFailure " + mEventType + " " + mIndex);
-      mResults.putString("Type", "onFailure");
-      mResults.putInt("Reason", reason);
-      mResults.putString("Description", description);
-      mEventFacade.postEvent(mEventType + mIndex + "onFailure", mResults.clone());
-      mResults.clear();
-    }
+    private class WifiActionListener implements WifiScanner.ActionListener {
+        private final Bundle mResults;
+        public int mIndex;
+        protected String mEventType;
 
-    public void reportResult(ScanResult[] results, String type) {
-      Log.d("reportResult "+ mEventType + " "+ mIndex);
-      mResults.putLong("Timestamp", System.currentTimeMillis()/1000);
-      mResults.putString("Type", type);
-      mResults.putParcelableArray("Results", results);
-      mEventFacade.postEvent(mEventType + mIndex + type, mResults.clone());
-      mResults.clear();
-    }
-  }
+        public WifiActionListener(String type, int idx, Bundle resultBundle) {
+            this.mIndex = idx;
+            this.mEventType = type;
+            this.mResults = resultBundle;
+        }
 
-  /**
-   * Constructs a wifiScanListener obj and returns it
-   * @return WifiScanListener
-   */
-  private WifiScanListener genWifiScanListener() {
-    WifiScanListener mWifiScannerListener = MainThread.run(mService,
-      new Callable<WifiScanListener>() {
         @Override
-        public WifiScanListener call() throws Exception {
-          return new WifiScanListener();
+        public void onSuccess() {
+            Log.d("onSuccess " + mEventType + " " + mIndex);
+            mResults.putString("Type", "onSuccess");
+            mResults.putLong("Realtime", SystemClock.elapsedRealtime());
+            mEventFacade.postEvent(mEventType + mIndex + "onSuccess", mResults.clone());
+            mResults.clear();
         }
-      });
-    scanListeners.put(mWifiScannerListener.mIndex, mWifiScannerListener);
-    return mWifiScannerListener;
-  }
 
-  private class WifiScanListener implements WifiScanner.ScanListener {
-    private static final String mEventType =  "WifiScannerScan";
-    protected final Bundle mScanResults;
-    private final WifiActionListener mWAL;
-    public int mIndex;
+        @Override
+        public void onFailure(int reason, String description) {
+            Log.d("onFailure " + mEventType + " " + mIndex);
+            mResults.putString("Type", "onFailure");
+            mResults.putInt("Reason", reason);
+            mResults.putString("Description", description);
+            mEventFacade.postEvent(mEventType + mIndex + "onFailure", mResults.clone());
+            mResults.clear();
+        }
 
-    public WifiScanListener() {
-      mScanResults = new Bundle();
-      WifiScanListenerCnt += 1;
-      mIndex = WifiScanListenerCnt;
-      mWAL = new WifiActionListener(mEventType, mIndex, mScanResults);
+        public void reportResult(ScanResult[] results, String type) {
+            Log.d("reportResult " + mEventType + " " + mIndex);
+            mResults.putLong("Timestamp", System.currentTimeMillis() / 1000);
+            mResults.putString("Type", type);
+            mResults.putParcelableArray("Results", results);
+            mEventFacade.postEvent(mEventType + mIndex + type, mResults.clone());
+            mResults.clear();
+        }
     }
 
-    @Override
-    public void onSuccess() {
-      mWAL.onSuccess();
+    /**
+     * Constructs a wifiScanListener obj and returns it
+     *
+     * @return WifiScanListener
+     */
+    private WifiScanListener genWifiScanListener() {
+        WifiScanListener mWifiScannerListener = MainThread.run(mService,
+                new Callable<WifiScanListener>() {
+                    @Override
+                    public WifiScanListener call() throws Exception {
+                        return new WifiScanListener();
+                    }
+                });
+        scanListeners.put(mWifiScannerListener.mIndex, mWifiScannerListener);
+        return mWifiScannerListener;
     }
 
-    @Override
-    public void onFailure(int reason, String description) {
-      scanListeners.remove(mIndex);
-      mWAL.onFailure(reason, description);
+    private class WifiScanListener implements WifiScanner.ScanListener {
+        private static final String mEventType = "WifiScannerScan";
+        protected final Bundle mScanResults;
+        protected final Bundle mScanData;
+        private final WifiActionListener mWAL;
+        public int mIndex;
+
+        public WifiScanListener() {
+            mScanResults = new Bundle();
+            mScanData = new Bundle();
+            WifiScanListenerCnt += 1;
+            mIndex = WifiScanListenerCnt;
+            mWAL = new WifiActionListener(mEventType, mIndex, mScanResults);
+        }
+
+        @Override
+        public void onSuccess() {
+            mWAL.onSuccess();
+        }
+
+        @Override
+        public void onFailure(int reason, String description) {
+            scanListeners.remove(mIndex);
+            mWAL.onFailure(reason, description);
+        }
+
+        @Override
+        public void onPeriodChanged(int periodInMs) {
+            Log.d("onPeriodChanged " + mEventType + " " + mIndex);
+            mScanResults.putString("Type", "onPeriodChanged");
+            mScanResults.putInt("NewPeriod", periodInMs);
+            mEventFacade.postEvent(mEventType + mIndex, mScanResults.clone());
+            mScanResults.clear();
+        }
+
+        @Override
+        public void onFullResult(ScanResult fullScanResult) {
+            Log.d("onFullResult WifiScanListener " + mIndex);
+            mWAL.reportResult(new ScanResult[]{fullScanResult}, "onFullResult");
+        }
+
+        @Override
+        public void onResults(ScanResult[] results) {
+            /* deprecated : Will not be called */
+        }
+        
+        @Override
+        public void onResults(ScanData[] results) {
+            Log.d("onResult WifiScanListener " + mIndex);
+            wifiScannerDataList.put(mIndex, results);
+            mScanData.putLong("Timestamp", System.currentTimeMillis()/1000);
+            mScanData.putString("Type", "onResults");
+            mScanData.putParcelableArray("Results", results);
+            mEventFacade.postEvent(mEventType + mIndex + "onResults", mScanData.clone());
+            mScanData.clear();
+        }
     }
 
-    @Override
-    public void onPeriodChanged(int periodInMs) {
-      Log.d("onPeriodChanged " + mEventType + " " + mIndex);
-      mScanResults.putString("Type", "onPeriodChanged");
-      mScanResults.putInt("NewPeriod", periodInMs);
-      mEventFacade.postEvent(mEventType + mIndex, mScanResults.clone());
-      mScanResults.clear();
+    /**
+     * Constructs a ChangeListener obj and returns it
+     *
+     * @return ChangeListener
+     */
+    private ChangeListener genWifiChangeListener() {
+        ChangeListener mWifiChangeListener = MainThread.run(mService,
+                new Callable<ChangeListener>() {
+                    @Override
+                    public ChangeListener call() throws Exception {
+                        return new ChangeListener();
+                    }
+                });
+        trackChangeListeners.put(mWifiChangeListener.mIndex, mWifiChangeListener);
+        return mWifiChangeListener;
     }
 
-    @Override
-    public void onResults(ScanResult[] results) {
-      wifiScannerResultList.put(mIndex, results);
-      mWAL.reportResult(results, "onResults");
+    private class ChangeListener implements WifiScanner.WifiChangeListener {
+        private static final String mEventType = "WifiScannerChange";
+        protected final Bundle mResults;
+        private final WifiActionListener mWAL;
+        public int mIndex;
+
+        public ChangeListener() {
+            mResults = new Bundle();
+            WifiChangeListenerCnt += 1;
+            mIndex = WifiChangeListenerCnt;
+            mWAL = new WifiActionListener(mEventType, mIndex, mResults);
+        }
+
+        @Override
+        public void onSuccess() {
+            mWAL.onSuccess();
+        }
+
+        @Override
+        public void onFailure(int reason, String description) {
+            trackChangeListeners.remove(mIndex);
+            mWAL.onFailure(reason, description);
+        }
+
+        /**
+         * indicates that changes were detected in wifi environment
+         *
+         * @param results indicate the access points that exhibited change
+         */
+        @Override
+        public void onChanging(ScanResult[] results) { /* changes are found */
+            mWAL.reportResult(results, "onChanging");
+        }
+
+        /**
+         * indicates that no wifi changes are being detected for a while
+         *
+         * @param results indicate the access points that are bing monitored for change
+         */
+        @Override
+        public void onQuiescence(ScanResult[] results) { /* changes settled down */
+            mWAL.reportResult(results, "onQuiescence");
+        }
     }
 
-    @Override
-    public void onFullResult(ScanResult fullScanResult) {
-      Log.d("onFullResult WifiScanListener " + mIndex);
-      mWAL.reportResult(new ScanResult[]{fullScanResult}, "onFullResult");
-    }
-  }
-
-  /**
-   * Constructs a ChangeListener obj and returns it
-   * @return ChangeListener
-   */
-  private ChangeListener genWifiChangeListener() {
-    ChangeListener mWifiChangeListener = MainThread.run(mService,
-                                                        new Callable<ChangeListener>() {
-      @Override
-      public ChangeListener call() throws Exception {
-        return new ChangeListener();
-      }
-    });
-    trackChangeListeners.put(mWifiChangeListener.mIndex, mWifiChangeListener);
-    return mWifiChangeListener;
-  }
-
-  private class ChangeListener implements WifiScanner.WifiChangeListener {
-    private static final String mEventType =  "WifiScannerChange";
-    protected final Bundle mResults;
-    private final WifiActionListener mWAL;
-    public int mIndex;
-
-    public ChangeListener() {
-      mResults = new Bundle();
-      WifiChangeListenerCnt += 1;
-      mIndex = WifiChangeListenerCnt;
-      mWAL = new WifiActionListener(mEventType, mIndex, mResults);
+    private WifiBssidListener genWifiBssidListener() {
+        WifiBssidListener mWifiBssidListener = MainThread.run(mService,
+                new Callable<WifiBssidListener>() {
+                    @Override
+                    public WifiBssidListener call() throws Exception {
+                        return new WifiBssidListener();
+                    }
+                });
+        trackBssidListeners.put(mWifiBssidListener.mIndex, mWifiBssidListener);
+        return mWifiBssidListener;
     }
 
-    @Override
-    public void onSuccess() {
-      mWAL.onSuccess();
+    private class WifiBssidListener implements WifiScanner.BssidListener {
+        private static final String mEventType = "WifiScannerBssid";
+        protected final Bundle mResults;
+        private final WifiActionListener mWAL;
+        public int mIndex;
+
+        public WifiBssidListener() {
+            mResults = new Bundle();
+            WifiBssidListenerCnt += 1;
+            mIndex = WifiBssidListenerCnt;
+            mWAL = new WifiActionListener(mEventType, mIndex, mResults);
+        }
+
+        @Override
+        public void onSuccess() {
+            mWAL.onSuccess();
+        }
+
+        @Override
+        public void onFailure(int reason, String description) {
+            trackBssidListeners.remove(mIndex);
+            mWAL.onFailure(reason, description);
+        }
+
+        @Override
+        public void onFound(ScanResult[] results) {
+            mWAL.reportResult(results, "onFound");
+        }
+
+        @Override
+        public void onLost(ScanResult[] results) {
+            mWAL.reportResult(results, "onLost");
+        }
     }
 
-    @Override
-    public void onFailure(int reason, String description) {
-      trackChangeListeners.remove(mIndex);
-      mWAL.onFailure(reason, description);
+    private ScanSettings parseScanSettings(String scanSettings) throws JSONException {
+        JSONObject j = new JSONObject(scanSettings);
+        ScanSettings result = new ScanSettings();
+        if (j.has("band")) {
+            result.band = j.optInt("band");
+        }
+        if (j.has("channels")) {
+            JSONArray chs = j.getJSONArray("channels");
+            ChannelSpec[] channels = new ChannelSpec[chs.length()];
+            for (int i = 0; i < channels.length; i++) {
+                channels[i] = new ChannelSpec(chs.getInt(i));
+            }
+            result.channels = channels;
+        }
+        if (j.has("maxScansToCache")) {
+            result.maxScansToCache = j.getInt("maxScansToCache");
+        }
+        /* periodInMs and reportEvents are required */
+        result.periodInMs = j.getInt("periodInMs");
+        result.reportEvents = j.getInt("reportEvents");
+        if (j.has("numBssidsPerScan")) {
+            result.numBssidsPerScan = j.getInt("numBssidsPerScan");
+        }
+        return result;
     }
-    /** indicates that changes were detected in wifi environment
-     * @param results indicate the access points that exhibited change
+
+    private BssidInfo[] parseBssidInfo(JSONArray jBssids) throws JSONException {
+        BssidInfo[] bssids = new BssidInfo[jBssids.length()];
+        for (int i = 0; i < bssids.length; i++) {
+              JSONObject bi = (JSONObject)jBssids.get(i);
+              BssidInfo bssidInfo = new BssidInfo();
+              bssidInfo.bssid = bi.getString("BSSID");
+              bssidInfo.high = bi.getInt("high");
+              bssidInfo.low = bi.getInt("low");
+              if (bi.has("frequencyHint")) {
+                bssidInfo.frequencyHint = bi.getInt("frequencyHint");
+              }
+              bssids[i] = bssidInfo;
+          }
+        return bssids;
+    }
+
+    /**
+     * Starts periodic WifiScanner scan
+     * @param scanSettings
+     * @return the id of the scan listener associated with this scan
+     * @throws JSONException
+     */
+    @Rpc(description = "Starts a WifiScanner Background scan")
+    public Integer wifiScannerStartBackgroundScan(@RpcParameter(name = "scanSettings") String scanSettings)
+            throws JSONException {
+        ScanSettings ss = parseScanSettings(scanSettings);
+        Log.d("startWifiScannerScan with " + ss.channels);
+        WifiScanListener mListener = genWifiScanListener();
+        mScan.startBackgroundScan(ss, mListener);
+        return mListener.mIndex;
+    }
+
+    /**
+     * Get currently available scan results on appropriate listeners
+     * @return true if all scan results were reported correctly
+     * @throws JSONException
+     */
+    @Rpc(description = "Get currently available scan results on appropriate listeners")
+    public Boolean getScanResults() throws JSONException {
+        mScan.getScanResults();
+        return true;
+    }
+
+    /**
+     * Stops a WifiScanner scan
+     * @param listener_mIndex the id of the scan listener whose scan to stop
+     * @throws Exception
+     */
+    @Rpc(description = "Stops an ongoing  WifiScanner Background scan")
+    public void wifiScannerStopBackgroundScan(@RpcParameter(name = "listener") Integer listener_index)
+            throws Exception {
+        if(!scanListeners.containsKey(listener_index)) {
+          throw new Exception("Background scan session " + listener_index + " does not exist");
+        }
+        WifiScanListener mListener = scanListeners.get(listener_index);
+        Log.d("stopWifiScannerScan mListener "+ mListener.mIndex );
+        mScan.stopBackgroundScan(mListener);
+        wifiScannerResultList.remove(listener_index);
+        scanListeners.remove(listener_index);
+    }
+
+    /**
+     * Starts periodic WifiScanner scan
+     * @param scanSettings
+     * @return the id of the scan listener associated with this scan
+     * @throws JSONException
+     */
+    @Rpc(description = "Starts a WifiScanner single scan")
+    public Integer wifiScannerStartScan(@RpcParameter(name = "scanSettings") String scanSettings)
+            throws JSONException {
+        ScanSettings ss = parseScanSettings(scanSettings);
+        Log.d("startWifiScannerScan with " + ss.channels);
+        WifiScanListener mListener = genWifiScanListener();
+        mScan.startScan(ss, mListener);
+        return mListener.mIndex;
+    }
+
+
+    /**
+     * Stops a WifiScanner scan
+     * @param listener_mIndex the id of the scan listener whose scan to stop
+     * @throws Exception
+     */
+    @Rpc(description = "Stops an ongoing  WifiScanner single scan")
+    public void wifiScannerStopScan(@RpcParameter(name = "listener") Integer listener_index)
+            throws Exception {
+        if(!scanListeners.containsKey(listener_index)) {
+          throw new Exception("Background scan session " + listener_index + " does not exist");
+        }
+        WifiScanListener mListener = scanListeners.get(listener_index);
+        Log.d("stopWifiScannerScan mListener "+ mListener.mIndex );
+        mScan.stopScan(mListener);
+        wifiScannerResultList.remove(listener_index);
+        scanListeners.remove(listener_index);
+    }
+
+    /** RPC Methods */
+    @Rpc(description = "Returns the channels covered by the specified band number.")
+    public List<Integer> wifiScannerGetAvailableChannels(@RpcParameter(name = "band") Integer band) {
+        return mScan.getAvailableChannels(band);
+    }
+
+    /**
+     * Starts tracking wifi changes
+     *
+     * @return the id of the change listener associated with this track
+     * @throws Exception
+     */
+    @Rpc(description = "Starts tracking wifi changes")
+    public Integer wifiScannerStartTrackingChange() throws Exception {
+        ChangeListener listener = genWifiChangeListener();
+        mScan.startTrackingWifiChange(listener);
+        return listener.mIndex;
+    }
+
+    /**
+     * Stops tracking wifi changes
+     *
+     * @param listener_index the id of the change listener whose track to stop
+     * @throws Exception
+     */
+    @Rpc(description = "Stops tracking wifi changes")
+    public void wifiScannerStopTrackingChange(
+            @RpcParameter(name = "listener") Integer listener_index
+            ) throws Exception {
+        if (!trackChangeListeners.containsKey(listener_index)) {
+            throw new Exception("Wifi change tracking session " + listener_index
+                    + " does not exist");
+        }
+        ChangeListener mListener = trackChangeListeners.get(listener_index);
+        mScan.stopTrackingWifiChange(mListener);
+        trackChangeListeners.remove(listener_index);
+    }
+
+    /**
+     * Starts tracking changes of the specified bssids.
+     *
+     * @param bssidInfos An array of json strings, each representing a BssidInfo object.
+     * @param apLostThreshold
+     * @return The index of the listener used to start the tracking.
+     * @throws JSONException
+     */
+    @Rpc(description = "Starts tracking changes of the specified bssids.")
+    public Integer wifiScannerStartTrackingBssids(
+            @RpcParameter(name = "bssidInfos") JSONArray  bssidInfos,
+            @RpcParameter(name = "apLostThreshold") Integer  apLostThreshold)throws JSONException {
+        BssidInfo[] bssids = parseBssidInfo(bssidInfos);
+        WifiBssidListener listener = genWifiBssidListener();
+        mScan.startTrackingBssids(bssids, apLostThreshold, listener);
+        return listener.mIndex;
+    }
+
+    /**
+     * Stops tracking the list of APs associated with the input listener
+     *
+     * @param listener_index the id of the bssid listener whose track to stop
+     * @throws Exception
+     */
+    @Rpc(description = "Stops tracking changes in the APs on the list")
+    public void wifiScannerStopTrackingBssids(
+            @RpcParameter(name = "listener") Integer listener_index
+            ) throws Exception {
+        if (!trackBssidListeners.containsKey(listener_index)) {
+            throw new Exception("Bssid tracking session " + listener_index + " does not exist");
+        }
+        WifiBssidListener mListener = trackBssidListeners.get(listener_index);
+        mScan.stopTrackingBssids(mListener);
+        trackBssidListeners.remove(listener_index);
+    }
+
+    @Rpc(description = "Returns a list of mIndexes of existing listeners")
+    public Set<Integer> wifiGetCurrentScanIndexes() {
+        return scanListeners.keySet();
+    }
+
+    /**
+     * Starts tracking wifi changes
+     *
+     * @return the id of the change listener associated with this track
+     * @throws Exception
+     */
+    @Rpc(description = "Starts tracking wifi changes")
+    public Integer startTrackingChange(
+            @RpcParameter(name = "bssidInfos") String[] bssidInfos,
+            @RpcParameter(name = "rssiSS") Integer rssiSS,
+            @RpcParameter(name = "lostApSS") Integer lostApSS,
+            @RpcParameter(name = "unchangedSS") Integer unchangedSS,
+            @RpcParameter(name = "minApsBreachingThreshold") Integer minApsBreachingThreshold,
+            @RpcParameter(name = "periodInMs") Integer periodInMs) throws Exception {
+        Log.d("starting change track");
+        BssidInfo[] mBssidInfos = new BssidInfo[bssidInfos.length];
+        for (int i = 0; i < bssidInfos.length; i++) {
+            Log.d("android_scripting " + bssidInfos[i]);
+            String[] tokens = bssidInfos[i].split(" ");
+            if (tokens.length != 3) {
+                throw new Exception("Invalid bssid info: " + bssidInfos[i]);
+
+            }
+            int rssiHI = Integer.parseInt(tokens[1]);
+            BssidInfo mBI = new BssidInfo();
+            mBI.bssid = tokens[0];
+            mBI.low = rssiHI - unchangedSS;
+            mBI.high = rssiHI + unchangedSS;
+            mBI.frequencyHint = Integer.parseInt(tokens[2]);
+            mBssidInfos[i] = mBI;
+        }
+        ChangeListener mListener = genWifiChangeListener();
+        mScan.configureWifiChange(rssiSS, lostApSS, unchangedSS, minApsBreachingThreshold,
+                periodInMs, mBssidInfos);
+        mScan.startTrackingWifiChange(mListener);
+        return mListener.mIndex;
+    }
+
+    /**
+     * Shuts down all activities associated with WifiScanner
+     */
+    @Rpc(description = "Shuts down all WifiScanner activities and remove listeners.")
+    public void wifiScannerShutdown() {
+        this.shutdown();
+    }
+
+    /**
+     * Stops all activity
      */
     @Override
-    public void onChanging(ScanResult[] results) {           /* changes are found */
-      mWAL.reportResult(results, "onChanging");
-    }
-    /** indicates that no wifi changes are being detected for a while
-     * @param results indicate the access points that are bing monitored for change
-     */
-    @Override
-    public void onQuiescence(ScanResult[] results) {         /* changes settled down */
-      mWAL.reportResult(results, "onQuiescence");
-    }
-  }
-
-  private WifiBssidListener genWifiBssidListener() {
-    WifiBssidListener mWifiBssidListener = MainThread.run(mService,
-                                                          new Callable<WifiBssidListener>() {
-      @Override
-      public WifiBssidListener call() throws Exception {
-        return new WifiBssidListener();
-      }
-    });
-    trackBssidListeners.put(mWifiBssidListener.mIndex, mWifiBssidListener);
-    return mWifiBssidListener;
-  }
-
-  private class WifiBssidListener implements WifiScanner.BssidListener {
-    private static final String mEventType =  "WifiScannerBssid";
-    protected final Bundle mResults;
-    private final WifiActionListener mWAL;
-    public int mIndex;
-
-    public WifiBssidListener() {
-      mResults = new Bundle();
-      WifiBssidListenerCnt += 1;
-      mIndex = WifiBssidListenerCnt;
-      mWAL = new WifiActionListener(mEventType, mIndex, mResults);
-    }
-
-    @Override
-    public void onSuccess() {
-      mWAL.onSuccess();
-    }
-
-    @Override
-    public void onFailure(int reason, String description) {
-      trackBssidListeners.remove(mIndex);
-      mWAL.onFailure(reason, description);
-    }
-
-    @Override
-    public void onFound(ScanResult[] results) {
-      mWAL.reportResult(results, "onFound");
-    }
-  }
-
-  private ScanSettings parseScanSettings(String scanSettings) throws JSONException {
-      JSONObject j = new JSONObject(scanSettings);
-      ScanSettings result = new ScanSettings();
-      if (j.has("band")) {
-          result.band = j.optInt("band");
-      }
-      if (j.has("channels")) {
-          JSONArray chs = j.getJSONArray("channels");
-          ChannelSpec[] channels = new ChannelSpec[chs.length()];
-          for (int i = 0; i < channels.length; i++) {
-              channels[i] = new ChannelSpec(chs.getInt(i));
-          }
-          result.channels = channels;
-      }
-      /* periodInMs and reportEvents are required */
-      result.periodInMs = j.getInt("periodInMs");
-      result.reportEvents = j.getInt("reportEvents");
-      if (j.has("numBssidsPerScan")) {
-          result.numBssidsPerScan = j.getInt("numBssidsPerScan");
-      }
-      return result;
-  }
-
-  private BssidInfo parseBssidInfo(String info) throws JSONException {
-      JSONObject bi = new JSONObject(info);
-      BssidInfo bssidInfo = new BssidInfo();
-      bssidInfo.bssid = bi.getString("bssid");
-      bssidInfo.high = bi.getInt("high");
-      bssidInfo.low = bi.getInt("low");
-      bssidInfo.frequencyHint = bi.getInt("frequencyHint");
-      return bssidInfo;
-  }
-
-/**
-   * Starts periodic WifiScanner scan
-   * @param periodInMs
-   * @param channel_freqs frequencies of channels to scan
-   * @return the id of the scan listener associated with this scan
-   * @throws JSONException
-   */
-  @Rpc(description = "Starts a periodic WifiScanner scan")
-  public Integer wifiScannerStartScan(@RpcParameter(name = "scanSettings") String scanSettings)
-          throws JSONException {
-    ScanSettings ss = parseScanSettings(scanSettings);
-    Log.d("startWifiScannerScan with " + ss.channels);
-    WifiScanListener mListener = genWifiScanListener();
-    mScan.startBackgroundScan(ss, mListener);
-    return mListener.mIndex;
-  }
-
-
-/**
-   * Stops a WifiScanner scan
-   * @param listener_mIndex the id of the scan listener whose scan to stop
-   * @throws Exception
-   */
-  @Rpc(description = "Stops an ongoing periodic WifiScanner scan")
-  public void wifiScannerStopScan(@RpcParameter(name = "listener") Integer listener_index)
-          throws Exception {
-    if(!scanListeners.containsKey(listener_index)) {
-      throw new Exception("Background scan session " + listener_index + " does not exist");
-    }
-    WifiScanListener mListener = scanListeners.get(listener_index);
-    Log.d("stopWifiScannerScan mListener "+ mListener.mIndex );
-    mScan.stopBackgroundScan(mListener);
-    wifiScannerResultList.remove(listener_index);
-    scanListeners.remove(listener_index);
-  }
-
-
-/** RPC Methods */
-  @Rpc(description = "Returns the channels covered by the specified band number.")
-  public List<Integer> wifiScannerGetAvailableChannels(@RpcParameter(name = "band") Integer band) {
-    return mScan.getAvailableChannels(band);
-  }
-
-/**
-   * Starts tracking wifi changes
-   * @return the id of the change listener associated with this track
-   * @throws Exception
-   */
-  @Rpc(description = "Starts tracking wifi changes")
-  public Integer wifiScannerStartTrackingChange() throws Exception{
-    ChangeListener listener = genWifiChangeListener();
-    mScan.startTrackingWifiChange(listener);
-    return listener.mIndex;
-  }
-
-/**
-   * Stops tracking wifi changes
-   * @param listener_index the id of the change listener whose track to stop
-   * @throws Exception
-   */
-  @Rpc(description = "Stops tracking wifi changes")
-  public void wifiScannerStopTrackingChange(
-          @RpcParameter(name = "listener") Integer listener_index
-          )throws Exception {
-    if(!trackChangeListeners.containsKey(listener_index)) {
-      throw new Exception("Wifi change tracking session " + listener_index + " does not exist");
-    }
-    ChangeListener mListener = trackChangeListeners.get(listener_index);
-    mScan.stopTrackingWifiChange(mListener);
-    trackChangeListeners.remove(listener_index);
-  }
-
-
-/**
-   * Starts tracking changes of the specified bssids.
-   *
-   * @param bssidInfos An array of json strings, each representing a BssidInfo object.
-   * @param apLostThreshold
-   * @return The index of the listener used to start the tracking.
-   * @throws JSONException
-   */
-  @Rpc(description = "Starts tracking changes of the specified bssids.")
-  public Integer wifiScannerStartTrackingBssids(
-          @RpcParameter(name = "bssidInfos")
-          String[] bssidInfos,
-          @RpcParameter(name = "apLostThreshold")
-          Integer apLostThreshold
-          ) throws JSONException {
-      BssidInfo[] infos = new BssidInfo[bssidInfos.length];
-      for(int i=0; i<bssidInfos.length; i++) {
-          infos[i] = parseBssidInfo(bssidInfos[i]);
-      }
-      WifiBssidListener listener = genWifiBssidListener();
-      mScan.startTrackingBssids(infos, apLostThreshold, listener);
-      return listener.mIndex;
-  }
-
-/**
-   * Stops tracking the list of APs associated with the input listener
-   * @param listener_index the id of the bssid listener whose track to stop
-   * @throws Exception
-   */
-  @Rpc(description = "Stops tracking changes in the APs on the list")
-  public void wifiScannerStopTrackingBssids(
-          @RpcParameter(name = "listener") Integer listener_index
-          )throws Exception {
-    if(!trackBssidListeners.containsKey(listener_index)) {
-      throw new Exception("Bssid tracking session " + listener_index + " does not exist");
-    }
-    WifiBssidListener mListener = trackBssidListeners.get(listener_index);
-    mScan.stopTrackingBssids(mListener);
-    trackBssidListeners.remove(listener_index);
-  }
-
-  @Rpc(description = "Returns a list of mIndexes of existing listeners")
-  public Set<Integer> wifiGetCurrentScanIndexes() {
-    return scanListeners.keySet();
-  }
-
-  /**
-   * Starts tracking wifi changes
-   * @return the id of the change listener associated with this track
-   * @throws Exception
-   */
-  @Rpc(description = "Starts tracking wifi changes")
-  public Integer startTrackingChange(
-      @RpcParameter(name = "bssidInfos") String[] bssidInfos,
-      @RpcParameter(name = "rssiSS") Integer rssiSS,
-      @RpcParameter(name = "lostApSS") Integer lostApSS,
-      @RpcParameter(name = "unchangedSS") Integer unchangedSS,
-      @RpcParameter(name = "minApsBreachingThreshold") Integer minApsBreachingThreshold,
-      @RpcParameter(name = "periodInMs") Integer periodInMs ) throws Exception{
-    Log.d("starting change track");
-    BssidInfo[] mBssidInfos = new BssidInfo[bssidInfos.length];
-    for(int i=0; i<bssidInfos.length; i++) {
-      Log.d("android_scripting " + bssidInfos[i]);
-      String[] tokens = bssidInfos[i].split(" ");
-      if(tokens.length != 3) {
-        throw new Exception("Invalid bssid info: "+bssidInfos[i]);
-
-      }
-      int rssiHI = Integer.parseInt(tokens[1]);
-      BssidInfo mBI = new BssidInfo();
-      mBI.bssid = tokens[0];
-      mBI.low = rssiHI - unchangedSS;
-      mBI.high = rssiHI + unchangedSS;
-      mBI.frequencyHint = Integer.parseInt(tokens[2]);
-      mBssidInfos[i] = mBI;
-    }
-    ChangeListener mListener = genWifiChangeListener();
-    mScan.configureWifiChange(rssiSS, lostApSS, unchangedSS, minApsBreachingThreshold,
-                              periodInMs, mBssidInfos);
-    mScan.startTrackingWifiChange(mListener);
-    return mListener.mIndex;
-  }
-
-  /**
-   * Starts tracking changes of the wifi networks specified in a list of bssid
-   * @param bssidInfos a list specifying which wifi networks to track
-   * @param apLostThreshold signal strength below which an AP is considered lost
-   * @return the id of the bssid listener associated with this track
-   * @throws Exception
-   */
-  @Rpc(description = "Starts tracking changes in the APs specified by the list")
-  public Integer startTrackingBssid(String[] bssidInfos, Integer apLostThreshold)
-          throws Exception {
-    //Instantiates BssidInfo objs
-    BssidInfo[] mBssidInfos = new BssidInfo[bssidInfos.length];
-    for(int i=0; i<bssidInfos.length; i++) {
-      Log.d("android_scripting " + bssidInfos[i]);
-      String[] tokens = bssidInfos[i].split(" ");
-      if(tokens.length!=3) {
-        throw new Exception("Invalid bssid info: "+bssidInfos[i]);
-
-      }
-      int a = Integer.parseInt(tokens[1]);
-      int b = Integer.parseInt(tokens[2]);
-      BssidInfo mBI = new BssidInfo();
-      mBI.bssid = tokens[0];
-      mBI.low = a<b ? a:b;
-      mBI.high = a<b ? b:a;
-      mBssidInfos[i] = mBI;
-    }
-    WifiBssidListener mWHL = genWifiBssidListener();
-    mScan.startTrackingBssids(mBssidInfos, apLostThreshold, mWHL);
-    return mWHL.mIndex;
-  }
-
-  /**
-   * Shuts down all activities associated with WifiScanner
-   */
-  @Rpc(description = "Shuts down all WifiScanner activities and remove listeners.")
-  public void wifiScannerShutdown() {
-    this.shutdown();
-  }
-
-  /**
-   * Stops all activity
-   */
-  @Override
-  public void shutdown() {
-    try {
-      if(!scanListeners.isEmpty()) {
-        Iterator<ConcurrentHashMap.Entry<Integer, WifiScanListener>> iter
-            = scanListeners.entrySet().iterator();
-        while(iter.hasNext()) {
-            ConcurrentHashMap.Entry<Integer, WifiScanListener> entry = iter.next();
-          this.wifiScannerStopScan(entry.getKey());
+    public void shutdown() {
+        try {
+            if (!scanListeners.isEmpty()) {
+                Iterator<ConcurrentHashMap.Entry<Integer, WifiScanListener>> iter = scanListeners
+                        .entrySet().iterator();
+                while (iter.hasNext()) {
+                    ConcurrentHashMap.Entry<Integer, WifiScanListener> entry = iter.next();
+                    this.wifiScannerStopScan(entry.getKey());
+                }
+            }
+            if (!trackChangeListeners.isEmpty()) {
+                Iterator<ConcurrentHashMap.Entry<Integer, ChangeListener>> iter = trackChangeListeners
+                        .entrySet().iterator();
+                while (iter.hasNext()) {
+                    ConcurrentHashMap.Entry<Integer, ChangeListener> entry = iter.next();
+                    this.wifiScannerStopScan(entry.getKey());
+                }
+            }
+            if (!trackBssidListeners.isEmpty()) {
+                Iterator<ConcurrentHashMap.Entry<Integer, WifiBssidListener>> iter = trackBssidListeners
+                        .entrySet().iterator();
+                while (iter.hasNext()) {
+                    ConcurrentHashMap.Entry<Integer, WifiBssidListener> entry = iter.next();
+                    this.wifiScannerStopScan(entry.getKey());
+                }
+            }
+        } catch (Exception e) {
+            Log.e("Shutdown failed: " + e.toString());
         }
-      }
-      if(!trackChangeListeners.isEmpty()) {
-          Iterator<ConcurrentHashMap.Entry<Integer, ChangeListener>> iter
-              = trackChangeListeners.entrySet().iterator();
-          while(iter.hasNext()) {
-              ConcurrentHashMap.Entry<Integer, ChangeListener> entry = iter.next();
-            this.wifiScannerStopScan(entry.getKey());
-          }
-        }
-      if(!trackBssidListeners.isEmpty()) {
-          Iterator<ConcurrentHashMap.Entry<Integer, WifiBssidListener>> iter
-              = trackBssidListeners.entrySet().iterator();
-          while(iter.hasNext()) {
-              ConcurrentHashMap.Entry<Integer, WifiBssidListener> entry = iter.next();
-            this.wifiScannerStopScan(entry.getKey());
-          }
-        }
-    } catch (Exception e) {
-      Log.e("Shutdown failed: " + e.toString());
     }
-  }
 }
diff --git a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
index 4e056b8..1b82dd9 100644
--- a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
+++ b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
@@ -19,7 +19,6 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -42,11 +41,12 @@
 import android.location.Address;
 import android.location.Location;
 import android.net.NetworkInfo;
-import android.net.wifi.RttManager.Capabilities;
+import android.net.wifi.RttManager.RttCapabilities;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiActivityEnergyInfo;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiScanner.ScanData;
 import android.net.wifi.p2p.WifiP2pDevice;
 import android.net.wifi.p2p.WifiP2pGroup;
 import android.net.wifi.p2p.WifiP2pInfo;
@@ -55,23 +55,9 @@
 import android.telecom.AudioState;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
-import android.telephony.CellIdentityCdma;
-import android.telephony.CellIdentityGsm;
-import android.telephony.CellIdentityLte;
-import android.telephony.CellIdentityWcdma;
-import android.telephony.CellInfoCdma;
-import android.telephony.CellInfoGsm;
-import android.telephony.CellInfoLte;
-import android.telephony.CellInfoWcdma;
 import android.telephony.CellLocation;
-import android.telephony.CellSignalStrengthCdma;
-import android.telephony.CellSignalStrengthGsm;
-import android.telephony.CellSignalStrengthLte;
-import android.telephony.CellSignalStrengthWcdma;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.SmsMessage;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
 import android.telephony.gsm.GsmCellLocation;
 import android.telephony.SubscriptionInfo;
 import android.util.DisplayMetrics;
@@ -80,7 +66,6 @@
 import com.googlecode.android_scripting.ConvertUtils;
 import com.googlecode.android_scripting.Log;
 import com.googlecode.android_scripting.event.Event;
-import com.googlecode.android_scripting.facade.tele.TelephonyUtils;
 
 public class JsonBuilder {
 
@@ -143,7 +128,8 @@
             return buildJsonEvent((Event) data);
         }
         if (data instanceof Map<?, ?>) {
-            // TODO(damonkohler): I would like to make this a checked cast if possible.
+            // TODO(damonkohler): I would like to make this a checked cast if
+            // possible.
             return buildJsonMap((Map<String, ?>) data);
         }
         if (data instanceof ParcelUuid) {
@@ -152,6 +138,9 @@
         if (data instanceof ScanResult) {
             return buildJsonScanResult((ScanResult) data);
         }
+        if (data instanceof ScanData) {
+            return buildJsonScanData((ScanData) data);
+        }
         if (data instanceof android.bluetooth.le.ScanResult) {
             return buildJsonBleScanResult((android.bluetooth.le.ScanResult) data);
         }
@@ -191,6 +180,7 @@
         if (data instanceof Point) {
             return buildPoint((Point) data);
         }
+
         if (data instanceof SmsMessage) {
             return buildSmsMessage((SmsMessage) data);
         }
@@ -206,8 +196,8 @@
         if (data instanceof DisplayMetrics) {
             return buildDisplayMetrics((DisplayMetrics) data);
         }
-        if (data instanceof Capabilities) {
-            return buildRttCapabilities((Capabilities) data);
+        if (data instanceof RttCapabilities) {
+            return buildRttCapabilities((RttCapabilities) data);
         }
         if (data instanceof WifiActivityEnergyInfo) {
             return buildWifiActivityEnergyInfo((WifiActivityEnergyInfo) data);
@@ -230,31 +220,22 @@
         if (data instanceof Object[]) {
             return buildJSONArray((Object[]) data);
         }
-        if (data instanceof CellInfoLte) {
-            return buildCellInfoLte((CellInfoLte) data);
-        }
-        if (data instanceof CellInfoWcdma) {
-            return buildCellInfoWcdma((CellInfoWcdma) data);
-        }
-        if (data instanceof CellInfoGsm) {
-            return buildCellInfoGsm((CellInfoGsm) data);
-        }
-        if (data instanceof CellInfoCdma) {
-            return buildCellInfoCdma((CellInfoCdma) data);
-        }
 
         return data.toString();
-        // throw new JSONException("Failed to build JSON result. " + data.getClass().getName());
+        // throw new JSONException("Failed to build JSON result. " +
+        // data.getClass().getName());
     }
 
-    private static JSONObject buildJsonAudioState(AudioState data) throws JSONException {
+    private static JSONObject buildJsonAudioState(AudioState data)
+            throws JSONException {
         JSONObject state = new JSONObject();
         state.put("isMuted", data.isMuted);
         state.put("AudioRoute", AudioState.audioRouteToString(data.route));
         return state;
     }
 
-    private static Object buildDisplayMetrics(DisplayMetrics data) throws JSONException {
+    private static Object buildDisplayMetrics(DisplayMetrics data)
+            throws JSONException {
         JSONObject dm = new JSONObject();
         dm.put("widthPixels", data.widthPixels);
         dm.put("heightPixels", data.heightPixels);
@@ -277,7 +258,8 @@
         return address;
     }
 
-    private static JSONObject buildJsonAddress(Address address) throws JSONException {
+    private static JSONObject buildJsonAddress(Address address)
+            throws JSONException {
         JSONObject result = new JSONObject();
         result.put("admin_area", address.getAdminArea());
         result.put("country_code", address.getCountryCode());
@@ -300,8 +282,8 @@
         return result;
     }
 
-    private static JSONObject buildJsonBleAdvertiseSettings(AdvertiseSettings advertiseSettings)
-            throws JSONException {
+    private static JSONObject buildJsonBleAdvertiseSettings(
+            AdvertiseSettings advertiseSettings) throws JSONException {
         JSONObject result = new JSONObject();
         result.put("mode", advertiseSettings.getMode());
         result.put("txPowerLevel", advertiseSettings.getTxPowerLevel());
@@ -309,22 +291,24 @@
         return result;
     }
 
-    private static JSONObject buildJsonBleScanResult(android.bluetooth.le.ScanResult scanResult)
-            throws JSONException {
+    private static JSONObject buildJsonBleScanResult(
+            android.bluetooth.le.ScanResult scanResult) throws JSONException {
         JSONObject result = new JSONObject();
         result.put("rssi", scanResult.getRssi());
         result.put("timestampNanos", scanResult.getTimestampNanos());
         result.put("deviceName", scanResult.getScanRecord().getDeviceName());
         result.put("txPowerLevel", scanResult.getScanRecord().getTxPowerLevel());
-        result.put("advertiseFlags", scanResult.getScanRecord().getAdvertiseFlags());
+        result.put("advertiseFlags", scanResult.getScanRecord()
+                .getAdvertiseFlags());
         ArrayList<String> manufacturerDataList = new ArrayList<String>();
         ArrayList<Integer> idList = new ArrayList<Integer>();
         if (scanResult.getScanRecord().getManufacturerSpecificData() != null) {
-            SparseArray<byte[]> manufacturerSpecificData = scanResult.getScanRecord()
-                    .getManufacturerSpecificData();
+            SparseArray<byte[]> manufacturerSpecificData = scanResult
+                    .getScanRecord().getManufacturerSpecificData();
             for (int i = 0; i < manufacturerSpecificData.size(); i++) {
                 manufacturerDataList.add(ConvertUtils
-                        .convertByteArrayToString(manufacturerSpecificData.valueAt(i)));
+                        .convertByteArrayToString(manufacturerSpecificData
+                                .valueAt(i)));
                 idList.add(manufacturerSpecificData.keyAt(i));
             }
         }
@@ -333,16 +317,19 @@
         ArrayList<String> serviceUuidList = new ArrayList<String>();
         ArrayList<String> serviceDataList = new ArrayList<String>();
         if (scanResult.getScanRecord().getServiceData() != null) {
-            Map<ParcelUuid, byte[]> serviceDataMap = scanResult.getScanRecord().getServiceData();
+            Map<ParcelUuid, byte[]> serviceDataMap = scanResult.getScanRecord()
+                    .getServiceData();
             for (ParcelUuid serviceUuid : serviceDataMap.keySet()) {
                 serviceUuidList.add(serviceUuid.toString());
-                serviceDataList.add(ConvertUtils.convertByteArrayToString(serviceDataMap
-                        .get(serviceUuid)));
+                serviceDataList.add(ConvertUtils
+                        .convertByteArrayToString(serviceDataMap
+                                .get(serviceUuid)));
             }
         }
         result.put("serviceUuidList", serviceUuidList);
         result.put("serviceDataList", serviceDataList);
-        List<ParcelUuid> serviceUuids = scanResult.getScanRecord().getServiceUuids();
+        List<ParcelUuid> serviceUuids = scanResult.getScanRecord()
+                .getServiceUuids();
         String serviceUuidsString = "";
         if (serviceUuids != null && serviceUuids.size() > 0) {
             for (ParcelUuid uuid : serviceUuids) {
@@ -350,13 +337,15 @@
             }
         }
         result.put("serviceUuids", serviceUuidsString);
-        result.put("scanRecord", build(ConvertUtils.convertByteArrayToString(
-                scanResult.getScanRecord().getBytes())));
+        result.put("scanRecord",
+                build(ConvertUtils.convertByteArrayToString(scanResult
+                        .getScanRecord().getBytes())));
         result.put("deviceInfo", build(scanResult.getDevice()));
         return result;
     }
 
-    private static JSONObject buildJsonBluetoothDevice(BluetoothDevice data) throws JSONException {
+    private static JSONObject buildJsonBluetoothDevice(BluetoothDevice data)
+            throws JSONException {
         JSONObject deviceInfo = new JSONObject();
         deviceInfo.put("address", data.getAddress());
         deviceInfo.put("state", data.getBondState());
@@ -365,8 +354,8 @@
         return deviceInfo;
     }
 
-    private static Object buildJsonBluetoothGattCharacteristic(BluetoothGattCharacteristic data)
-            throws JSONException {
+    private static Object buildJsonBluetoothGattCharacteristic(
+            BluetoothGattCharacteristic data) throws JSONException {
         JSONObject result = new JSONObject();
         result.put("instanceId", data.getInstanceId());
         result.put("permissions", data.getPermissions());
@@ -379,8 +368,8 @@
         return result;
     }
 
-    private static Object buildJsonBluetoothGattDescriptor(BluetoothGattDescriptor data)
-            throws JSONException {
+    private static Object buildJsonBluetoothGattDescriptor(
+            BluetoothGattDescriptor data) throws JSONException {
         JSONObject result = new JSONObject();
         result.put("instanceId", data.getInstanceId());
         result.put("permissions", data.getPermissions());
@@ -390,8 +379,8 @@
         return result;
     }
 
-    private static Object buildJsonBluetoothGattService(BluetoothGattService data)
-            throws JSONException {
+    private static Object buildJsonBluetoothGattService(
+            BluetoothGattService data) throws JSONException {
         JSONObject result = new JSONObject();
         result.put("instanceId", data.getInstanceId());
         result.put("type", data.getType());
@@ -401,7 +390,8 @@
         return result;
     }
 
-    private static JSONObject buildJsonBundle(Bundle bundle) throws JSONException {
+    private static JSONObject buildJsonBundle(Bundle bundle)
+            throws JSONException {
         JSONObject result = new JSONObject();
         for (String key : bundle.keySet()) {
             result.put(key, build(bundle.get(key)));
@@ -417,7 +407,8 @@
             result.put("lac", location.getLac());
             result.put("cid", location.getCid());
         }
-        // TODO(damonkohler): Add support for CdmaCellLocation. Not supported until API level 5.
+        // TODO(damonkohler): Add support for CdmaCellLocation. Not supported
+        // until API level 5.
         return result;
     }
 
@@ -445,7 +436,8 @@
         return result;
     }
 
-    private static <T> JSONArray buildJsonList(final List<T> list) throws JSONException {
+    private static <T> JSONArray buildJsonList(final List<T> list)
+            throws JSONException {
         JSONArray result = new JSONArray();
         for (T item : list) {
             result.put(build(item));
@@ -453,7 +445,8 @@
         return result;
     }
 
-    private static JSONObject buildJsonLocation(Location location) throws JSONException {
+    private static JSONObject buildJsonLocation(Location location)
+            throws JSONException {
         JSONObject result = new JSONObject();
         result.put("altitude", location.getAltitude());
         result.put("latitude", location.getLatitude());
@@ -466,7 +459,8 @@
         return result;
     }
 
-    private static JSONObject buildJsonMap(Map<String, ?> map) throws JSONException {
+    private static JSONObject buildJsonMap(Map<String, ?> map)
+            throws JSONException {
         JSONObject result = new JSONObject();
         for (Entry<String, ?> entry : map.entrySet()) {
             result.put(entry.getKey(), build(entry.getValue()));
@@ -474,21 +468,24 @@
         return result;
     }
 
-    private static JSONObject buildJsonScanResult(ScanResult scanResult) throws JSONException {
+    private static JSONObject buildJsonScanResult(ScanResult scanResult)
+            throws JSONException {
         JSONObject result = new JSONObject();
-        result.put("bssid", scanResult.BSSID);
-        result.put("ssid", scanResult.SSID);
+        result.put("BSSID", scanResult.BSSID);
+        result.put("SSID", scanResult.SSID);
         result.put("frequency", scanResult.frequency);
         result.put("level", scanResult.level);
         result.put("capabilities", scanResult.capabilities);
         result.put("timestamp", scanResult.timestamp);
-        // The following fields are hidden for now, uncomment when they're unhidden
+        // The following fields are hidden for now, uncomment when they're
+        // unhidden
         // result.put("seen", scanResult.seen);
         // result.put("distanceCm", scanResult.distanceCm);
         // result.put("distanceSdCm", scanResult.distanceSdCm);
         // if (scanResult.informationElements != null){
         // JSONArray infoEles = new JSONArray();
-        // for(ScanResult.InformationElement ie : scanResult.informationElements) {
+        // for(ScanResult.InformationElement ie :
+        // scanResult.informationElements) {
         // JSONObject infoEle = new JSONObject();
         // infoEle.put("id", ie.id);
         // infoEle.put("bytes", Base64Codec.encodeBase64(ie.bytes));
@@ -500,11 +497,25 @@
         return result;
     }
 
-    private static JSONObject buildWifiActivityEnergyInfo(WifiActivityEnergyInfo data)
+    private static JSONObject buildJsonScanData(ScanData scanData)
             throws JSONException {
         JSONObject result = new JSONObject();
+        result.put("Id", scanData.getId());
+        result.put("Flags", scanData.getFlags());
+        JSONArray scanResults = new JSONArray();
+        for (ScanResult sr : scanData.getResults()) {
+            scanResults.put(buildJsonScanResult(sr));
+        }
+        result.put("ScanResults", scanResults);
+        return result;
+    }
+
+    private static JSONObject buildWifiActivityEnergyInfo(
+            WifiActivityEnergyInfo data) throws JSONException {
+        JSONObject result = new JSONObject();
         result.put("ControllerEnergyUserd", data.getControllerEnergyUsed());
-        result.put("ControllerIdleTimeMillis", data.getControllerIdleTimeMillis());
+        result.put("ControllerIdleTimeMillis",
+                data.getControllerIdleTimeMillis());
         result.put("ControllerRxTimeMillis", data.getControllerRxTimeMillis());
         result.put("ControllerTxTimeMillis", data.getControllerTxTimeMillis());
         result.put("StackState", data.getStackState());
@@ -512,16 +523,17 @@
         return result;
     }
 
-    private static JSONObject buildJsonWifiInfo(WifiInfo data) throws JSONException {
+    private static JSONObject buildJsonWifiInfo(WifiInfo data)
+            throws JSONException {
         JSONObject result = new JSONObject();
         result.put("hidden_ssid", data.getHiddenSSID());
         result.put("ip_address", data.getIpAddress());
         result.put("link_speed", data.getLinkSpeed());
         result.put("network_id", data.getNetworkId());
         result.put("rssi", data.getRssi());
-        result.put("bssid", data.getBSSID());
+        result.put("BSSID", data.getBSSID());
         result.put("mac_address", data.getMacAddress());
-        result.put("ssid", data.getSSID());
+        result.put("SSID", data.getSSID());
         String supplicantState = "";
         switch (data.getSupplicantState()) {
             case ASSOCIATED:
@@ -566,96 +578,15 @@
 
     private static JSONObject buildNeighboringCellInfo(NeighboringCellInfo data)
             throws JSONException {
+        // TODO(damonkohler): Additional information available at API level 5.
         JSONObject result = new JSONObject();
         result.put("cid", data.getCid());
         result.put("rssi", data.getRssi());
-        result.put("lac", data.getLac());
-        result.put("psc", data.getPsc());
-        String networkType =
-                TelephonyUtils.getNetworkTypeString(data.getNetworkType());
-        result.put("network_type", build(networkType));
         return result;
     }
 
-    private static JSONObject buildCellInfoLte(CellInfoLte data)
+    private static Object buildNetworkInfo(NetworkInfo data)
             throws JSONException {
-        JSONObject result = new JSONObject();
-        result.put("rat", "lte");
-        result.put("registered", data.isRegistered());
-        CellIdentityLte cellidentity =
-                        ((CellInfoLte) data).getCellIdentity();
-        CellSignalStrengthLte signalstrength =
-                        ((CellInfoLte) data).getCellSignalStrength();
-        result.put("mcc", cellidentity.getMcc());
-        result.put("mnc", cellidentity.getMnc());
-        result.put("cid", cellidentity.getCi());
-        result.put("pcid", cellidentity.getPci());
-        result.put("tac", cellidentity.getTac());
-        result.put("rsrp", signalstrength.getDbm());
-        result.put("asulevel", signalstrength.getAsuLevel());
-        result.put("timing_advance", signalstrength.getTimingAdvance());
-        return result;
-    }
-
-    private static JSONObject buildCellInfoGsm(CellInfoGsm data)
-            throws JSONException {
-        JSONObject result = new JSONObject();
-        result.put("rat", "gsm");
-        result.put("registered", data.isRegistered());
-        CellIdentityGsm cellidentity =
-                      ((CellInfoGsm) data).getCellIdentity();
-        CellSignalStrengthGsm signalstrength =
-                      ((CellInfoGsm) data).getCellSignalStrength();
-        result.put("mcc", cellidentity.getMcc());
-        result.put("mnc", cellidentity.getMnc());
-        result.put("cid", cellidentity.getCid());
-        result.put("lac", cellidentity.getLac());
-        result.put("signal_strength", signalstrength.getDbm());
-        result.put("asulevel", signalstrength.getAsuLevel());
-        return result;
-    }
-
-    private static JSONObject buildCellInfoWcdma(CellInfoWcdma data)
-            throws JSONException {
-        JSONObject result = new JSONObject();
-        result.put("rat", "wcdma");
-        result.put("registered", data.isRegistered());
-        CellIdentityWcdma cellidentity =
-                          ((CellInfoWcdma) data).getCellIdentity();
-        CellSignalStrengthWcdma signalstrength =
-                          ((CellInfoWcdma) data).getCellSignalStrength();
-        result.put("mcc", cellidentity.getMcc());
-        result.put("mnc", cellidentity.getMnc());
-        result.put("cid", cellidentity.getCid());
-        result.put("lac", cellidentity.getLac());
-        result.put("signal_strength", signalstrength.getDbm());
-        result.put("asulevel", signalstrength.getAsuLevel());
-        return result;
-    }
-
-    private static JSONObject buildCellInfoCdma(CellInfoCdma data)
-            throws JSONException {
-        JSONObject result = new JSONObject();
-        result.put("rat", "cdma");
-        result.put("registered", data.isRegistered());
-        CellIdentityCdma cellidentity =
-                       ((CellInfoCdma) data).getCellIdentity();
-        CellSignalStrengthCdma signalstrength =
-                       ((CellInfoCdma) data).getCellSignalStrength();
-        result.put("network_id", cellidentity.getNetworkId());
-        result.put("system_id", cellidentity.getSystemId());
-        result.put("basestation_id", cellidentity.getBasestationId());
-        result.put("longitude", cellidentity.getLongitude());
-        result.put("latitude", cellidentity.getLatitude());
-        result.put("cdma_dbm", signalstrength.getCdmaDbm());
-        result.put("cdma_ecio", signalstrength.getCdmaEcio());
-        result.put("evdo_dbm", signalstrength.getEvdoDbm());
-        result.put("evdo_ecio", signalstrength.getEvdoEcio());
-        result.put("evdo_snr", signalstrength.getEvdoSnr());
-        return result;
-    }
-
-    private static Object buildNetworkInfo(NetworkInfo data) throws JSONException {
         JSONObject info = new JSONObject();
         info.put("isAvailable", data.isAvailable());
         info.put("isConnected", data.isConnected());
@@ -669,23 +600,27 @@
         return info;
     }
 
-    private static JSONObject buildPhoneAccount(PhoneAccount data) throws JSONException {
+    private static JSONObject buildPhoneAccount(PhoneAccount data)
+            throws JSONException {
         JSONObject acct = new JSONObject();
         acct.put("Address", data.getAddress().toSafeString());
-        acct.put("SubscriptionAddress", data.getSubscriptionAddress().toSafeString());
+        acct.put("SubscriptionAddress", data.getSubscriptionAddress()
+                .toSafeString());
         acct.put("Label", data.getLabel().toString());
         acct.put("ShortDescription", data.getShortDescription().toString());
         return acct;
     }
 
-    private static Object buildPhoneAccountHandle(PhoneAccountHandle data) throws JSONException {
+    private static Object buildPhoneAccountHandle(PhoneAccountHandle data)
+            throws JSONException {
         JSONObject msg = new JSONObject();
         msg.put("id", data.getId());
         msg.put("ComponentName", data.getComponentName().flattenToString());
         return msg;
     }
 
-    private static Object buildSubscriptionInfoRecord(SubscriptionInfo data) throws JSONException {
+    private static Object buildSubscriptionInfoRecord(SubscriptionInfo data)
+            throws JSONException {
         JSONObject msg = new JSONObject();
         msg.put("subscriptionId", data.getSubscriptionId());
         msg.put("iccId", data.getIccId());
@@ -707,10 +642,15 @@
         return point;
     }
 
-    private static Object buildRttCapabilities(Capabilities data) throws JSONException {
+    private static Object buildRttCapabilities(RttCapabilities data)
+            throws JSONException {
         JSONObject cap = new JSONObject();
-        cap.put("supportedType", data.supportedType);
-        cap.put("supportedPeerType", data.supportedPeerType);
+        cap.put("bwSupported", data.bwSupported);
+        cap.put("lciSupported", data.lciSupported);
+        cap.put("lcrSupported", data.lcrSupported);
+        cap.put("oneSidedRttSupported", data.oneSidedRttSupported);
+        cap.put("preambleSupported", data.preambleSupported);
+        cap.put("twoSided11McRttSupported", data.twoSided11McRttSupported);
         return cap;
     }
 
@@ -721,16 +661,18 @@
         return msg;
     }
 
-    private static Object buildWifiConfiguration(WifiConfiguration data) throws JSONException {
+    private static Object buildWifiConfiguration(WifiConfiguration data)
+            throws JSONException {
         JSONObject config = new JSONObject();
         config.put("networkId", data.networkId);
         // Trim the double quotes if exist
-        if (data.SSID.charAt(0) == '"' && data.SSID.charAt(data.SSID.length() - 1) == '"') {
-            config.put("ssid", data.SSID.substring(1, data.SSID.length() - 1));
+        if (data.SSID.charAt(0) == '"'
+                && data.SSID.charAt(data.SSID.length() - 1) == '"') {
+            config.put("SSID", data.SSID.substring(1, data.SSID.length() - 1));
         } else {
-            config.put("ssid", data.SSID);
+            config.put("SSID", data.SSID);
         }
-        config.put("bssid", data.BSSID);
+        config.put("BSSID", data.BSSID);
         config.put("priority", data.priority);
         config.put("hiddenSSID", data.hiddenSSID);
         if (data.status == WifiConfiguration.Status.CURRENT) {
@@ -745,14 +687,16 @@
         return config;
     }
 
-    private static JSONObject buildWifiP2pDevice(WifiP2pDevice data) throws JSONException {
+    private static JSONObject buildWifiP2pDevice(WifiP2pDevice data)
+            throws JSONException {
         JSONObject deviceInfo = new JSONObject();
         deviceInfo.put("Name", data.deviceName);
         deviceInfo.put("Address", data.deviceAddress);
         return deviceInfo;
     }
 
-    private static JSONObject buildWifiP2pGroup(WifiP2pGroup data) throws JSONException {
+    private static JSONObject buildWifiP2pGroup(WifiP2pGroup data)
+            throws JSONException {
         JSONObject group = new JSONObject();
         Log.d("build p2p group.");
         group.put("ClientList", build(data.getClientList()));
@@ -764,7 +708,8 @@
         return group;
     }
 
-    private static JSONObject buildWifiP2pInfo(WifiP2pInfo data) throws JSONException {
+    private static JSONObject buildWifiP2pInfo(WifiP2pInfo data)
+            throws JSONException {
         JSONObject info = new JSONObject();
         Log.d("build p2p info.");
         info.put("groupFormed", data.groupFormed);