Update telephony/telecomm related functions in sl4a.

Rename all occurrences of telecomm to telecom.
Add more rpc methods to telecom and connectivity facade.

Change-Id: If2970da6e1276f94aabcf4a9b924cfee88457103
diff --git a/Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java
index 6b05c9d..f679936 100644
--- a/Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java
@@ -31,15 +31,6 @@
  * Access ConnectivityManager functions.
  */
 public class ConnectivityManagerFacade extends RpcReceiver {
-    private final Service mService;
-    private final ConnectivityManager mCon;
-
-    public ConnectivityManagerFacade(FacadeManager manager) {
-        super(manager);
-        mService = manager.getService();
-        mCon = (ConnectivityManager) mService.getSystemService(Context.CONNECTIVITY_SERVICE);
-    }
-
     class ConnectivityReceiver extends BroadcastReceiver {
 
         @Override
@@ -51,6 +42,51 @@
         }
     }
 
+    private final ConnectivityManager mCon;
+
+    private final Service mService;
+
+    public ConnectivityManagerFacade(FacadeManager manager) {
+        super(manager);
+        mService = manager.getService();
+        mCon = (ConnectivityManager) mService.getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
+    @Rpc(description = "Get the extra information about the network state provided by lower network layers.")
+    public String networkGetActiveConnectionExtraInfo() {
+        NetworkInfo current = mCon.getActiveNetworkInfo();
+        if (current == null) {
+            Log.d("No network is active at the moment.");
+            return null;
+        }
+        return current.getExtraInfo();
+    }
+
+    @Rpc(description = "Return the subtype name of the current network, null if not connected")
+    public String networkGetActiveConnectionSubtypeName() {
+        NetworkInfo current = mCon.getActiveNetworkInfo();
+        if (current == null) {
+            Log.d("No network is active at the moment.");
+            return null;
+        }
+        return current.getSubtypeName();
+    }
+
+    @Rpc(description = "Return a human-readable name describe the type of the network, e.g. WIFI")
+    public String networkGetActiveConnectionTypeName() {
+        NetworkInfo current = mCon.getActiveNetworkInfo();
+        if (current == null) {
+            Log.d("No network is active at the moment.");
+            return null;
+        }
+        return current.getTypeName();
+    }
+
+    @Rpc(description = "Get connection status information about all network types supported by the device.")
+    public NetworkInfo[] networkGetAllInfo() {
+        return mCon.getAllNetworkInfo();
+    }
+
     @Rpc(description = "Check whether the active network is connected to the Internet.")
     public Boolean networkIsConnected() {
         NetworkInfo current = mCon.getActiveNetworkInfo();
@@ -61,29 +97,6 @@
         return current.isConnected();
     }
 
-    @Rpc(description = "Return the type of the current network. Null if not connected")
-    public String networkGetConnectionType() {
-        NetworkInfo current = mCon.getActiveNetworkInfo();
-        if (current == null) {
-            Log.d("No network is active at the moment.");
-            return null;
-        }
-        int type = current.getType();
-        String typrStr = null;
-        if (type == ConnectivityManager.TYPE_BLUETOOTH) {
-            typrStr = "BLUETOOTH";
-        } else if (type == ConnectivityManager.TYPE_ETHERNET) {
-            typrStr = "ETHERNET";
-        } else if (ConnectivityManager.isNetworkTypeMobile(type)) {
-            typrStr = "MOBILE";
-        } else if (ConnectivityManager.isNetworkTypeWifi(type)) {
-            typrStr = "WIFI";
-        } else if (type == ConnectivityManager.TYPE_WIMAX) {
-            typrStr = "WIMAX";
-        }
-        return typrStr;
-    }
-
     @Override
     public void shutdown() {
     }
diff --git a/Common/src/com/googlecode/android_scripting/facade/tele/TelecomManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/tele/TelecomManagerFacade.java
new file mode 100644
index 0000000..1549ff3
--- /dev/null
+++ b/Common/src/com/googlecode/android_scripting/facade/tele/TelecomManagerFacade.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.googlecode.android_scripting.facade.tele;
+
+import java.util.List;
+
+import android.app.Service;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telephony.TelephonyManager;
+
+import com.googlecode.android_scripting.facade.FacadeManager;
+import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
+import com.googlecode.android_scripting.rpc.Rpc;
+
+/**
+ * Exposes TelecomManager functionality.
+ */
+public class TelecomManagerFacade extends RpcReceiver {
+    private final Service mService;
+    private final TelecomManager mTelecomManager;
+
+    private List<PhoneAccountHandle> mEnabledAccountHandles = null;
+
+    public TelecomManagerFacade(FacadeManager manager) {
+        super(manager);
+        mService = manager.getService();
+        mTelecomManager = new TelecomManager(mService);
+    }
+
+    @Override
+    public void shutdown() {
+    }
+
+    @Rpc(description = "If there's a ringing call, accept on behalf of the user.")
+    public void telecomAcceptRingingCall() {
+        mTelecomManager.acceptRingingCall();
+    }
+
+    @Rpc(description = "Removes the missed-call notification if one is present.")
+    public void telecomCancelMissedCallsNotification() {
+        mTelecomManager.cancelMissedCallsNotification();
+    }
+
+    @Rpc(description = "Remove all Accounts that belong to the calling package from the system.")
+    public void telecomClearAccounts() {
+        mTelecomManager.clearAccounts();
+    }
+
+    @Rpc(description = "End an ongoing call.")
+    public Boolean telecomEndCall() {
+        return mTelecomManager.endCall();
+    }
+
+    @Rpc(description = "Get a list of all PhoneAccounts.")
+    public List<PhoneAccount> telecomGetAllPhoneAccounts() {
+        return mTelecomManager.getAllPhoneAccounts();
+    }
+
+    @Rpc(description = "Get the current call state.")
+    public String telecomGetCallState() {
+        int state = mTelecomManager.getCallState();
+        String stateStr = null;
+        if (state == TelephonyManager.CALL_STATE_RINGING) {
+            stateStr = "RINGING";
+        } else if (state == TelephonyManager.CALL_STATE_IDLE) {
+            stateStr = "IDLE";
+        } else if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
+            stateStr = "OFFHOOK";
+        }
+        return stateStr;
+    }
+
+    @Rpc(description = "Get the current tty mode.")
+    public String telecomGetCurrentTtyMode() {
+        int mode = mTelecomManager.getCurrentTtyMode();
+        String modeStr = null;
+        if (mode == TelecomManager.TTY_MODE_FULL) {
+            modeStr = "FULL";
+        } else if (mode == TelecomManager.TTY_MODE_HCO) {
+            modeStr = "HCO";
+        } else if (mode == TelecomManager.TTY_MODE_OFF) {
+            modeStr = "OFF";
+        } else if (mode == TelecomManager.TTY_MODE_VCO) {
+            modeStr = "VCO";
+        }
+        return modeStr;
+    }
+
+    @Rpc(description = "Get the list of enabled PhoneAccountHandles.")
+    public List<PhoneAccountHandle> telecomGetEnabledPhoneAccounts() {
+        mEnabledAccountHandles = mTelecomManager.getEnabledPhoneAccounts();
+        return mEnabledAccountHandles;
+    }
+
+    @Rpc(description = "Get the user-chosen default PhoneAccount for making outgoing phone calls.")
+    public PhoneAccountHandle telecomGetUserSelectedOutgoingPhoneAccount() {
+        return mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+
+    }
+
+    @Rpc(description = "Returns whether there is an ongoing phone call.")
+    public Boolean telecomIsInCall() {
+        return mTelecomManager.isInCall();
+    }
+
+    @Rpc(description = "Returns whether there is a ringing incoming call.")
+    public Boolean telecomIsRinging() {
+        return mTelecomManager.isRinging();
+    }
+
+    @Rpc(description = "Silences the rigner if there's a ringing call.")
+    public void telecomSilenceRinger() {
+        mTelecomManager.silenceRinger();
+    }
+}
diff --git a/Common/src/com/googlecode/android_scripting/facade/tele/TelecommManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/tele/TelecommManagerFacade.java
deleted file mode 100644
index 0cea797..0000000
--- a/Common/src/com/googlecode/android_scripting/facade/tele/TelecommManagerFacade.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.googlecode.android_scripting.facade.tele;
-
-import java.util.List;
-
-import android.app.Service;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
-
-import com.googlecode.android_scripting.facade.FacadeManager;
-import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
-import com.googlecode.android_scripting.rpc.Rpc;
-
-/**
- * Exposes TelecommManager functionality.
- *
- */
-public class TelecommManagerFacade extends RpcReceiver {
-    private final TelecomManager mTelecommManager;
-    private final Service mService;
-
-    public TelecommManagerFacade(FacadeManager manager) {
-        super(manager);
-        mService = manager.getService();
-        mTelecommManager = new TelecomManager(mService);
-    }
-
-    @Rpc(description = "If there's a ringing call, accept on behalf of the user.")
-    public List<PhoneAccountHandle> telecommGetEnabledPhoneAccounts() {
-        return mTelecommManager.getEnabledPhoneAccounts();
-    }
-
-    @Rpc(description = "If there's a ringing call, accept on behalf of the user.")
-    public void telecommAcceptRingingCall() {
-        mTelecommManager.acceptRingingCall();
-    }
-
-    @Rpc(description = "End an ongoing call.")
-    public Boolean telecommEndCall() {
-        return mTelecommManager.endCall();
-    }
-
-    @Rpc(description = "Returns whether there is a ringing incoming call.")
-    public Boolean telecommIsRinging() {
-        return mTelecommManager.isRinging();
-    }
-
-    @Rpc(description = "Returns whether there is an ongoing phone call.")
-    public Boolean telecommIsInCall() {
-        return mTelecommManager.isInCall();
-    }
-
-    @Rpc(description = "Silences the rigner if there's a ringing call.")
-    public void telecommSilenceRinger() {
-        mTelecommManager.silenceRinger();
-    }
-
-    @Override
-    public void shutdown() {
-    }
-
-}
diff --git a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
index 561a844..f42ba49 100644
--- a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
+++ b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
@@ -16,6 +16,20 @@
 
 package com.googlecode.android_scripting.jsonrpc;
 
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.commons.codec.binary.Base64Codec;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothGattCharacteristic;
 import android.bluetooth.BluetoothGattDescriptor;
@@ -26,6 +40,7 @@
 import android.graphics.Point;
 import android.location.Address;
 import android.location.Location;
+import android.net.NetworkInfo;
 import android.net.wifi.RttManager.Capabilities;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
@@ -35,6 +50,7 @@
 import android.net.wifi.p2p.WifiP2pInfo;
 import android.os.Bundle;
 import android.os.ParcelUuid;
+import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.CellLocation;
 import android.telephony.NeighboringCellInfo;
@@ -47,26 +63,8 @@
 import com.googlecode.android_scripting.Log;
 import com.googlecode.android_scripting.event.Event;
 
-import org.apache.commons.codec.binary.Base64Codec;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
 public class JsonBuilder {
 
-    private JsonBuilder() {
-        // This is a utility class.
-    }
-
     @SuppressWarnings("unchecked")
     public static Object build(Object data) throws JSONException {
         if (data == null) {
@@ -159,6 +157,9 @@
         if (data instanceof NeighboringCellInfo) {
             return buildNeighboringCellInfo((NeighboringCellInfo) data);
         }
+        if (data instanceof NetworkInfo) {
+            return buildNetworkInfo((NetworkInfo) data);
+        }
         if (data instanceof InetSocketAddress) {
             return buildInetSocketAddress((InetSocketAddress) data);
         }
@@ -168,9 +169,13 @@
         if (data instanceof Point) {
             return buildPoint((Point) data);
         }
+
         if (data instanceof SmsMessage) {
             return buildSmsMessage((SmsMessage) data);
         }
+        if (data instanceof PhoneAccount) {
+            return buildPhoneAccount((PhoneAccount) data);
+        }
         if (data instanceof PhoneAccountHandle) {
             return buildPhoneAccountHandle((PhoneAccountHandle) data);
         }
@@ -202,28 +207,13 @@
         // throw new JSONException("Failed to build JSON result. " + data.getClass().getName());
     }
 
-    private static JSONObject buildJsonBluetoothDevice(BluetoothDevice data) throws JSONException {
-        JSONObject deviceInfo = new JSONObject();
-        deviceInfo.put("address", data.getAddress());
-        deviceInfo.put("state", data.getBondState());
-        deviceInfo.put("name", data.getName());
-        deviceInfo.put("type", data.getType());
-        return deviceInfo;
-    }
-
-    private static JSONArray buildJSONArray(Object[] data) throws JSONException {
-        JSONArray result = new JSONArray();
-        for (Object o : data) {
-            result.put(build(o));
-        }
-        return result;
-    }
-
-    private static Object buildInetSocketAddress(InetSocketAddress data) {
-        JSONArray address = new JSONArray();
-        address.put(data.getHostName());
-        address.put(data.getPort());
-        return address;
+    private static Object buildDisplayMetrics(DisplayMetrics data) throws JSONException {
+        JSONObject dm = new JSONObject();
+        dm.put("widthPixels", data.widthPixels);
+        dm.put("heightPixels", data.heightPixels);
+        dm.put("noncompatHeightPixels", data.noncompatHeightPixels);
+        dm.put("noncompatWidthPixels", data.noncompatWidthPixels);
+        return dm;
     }
 
     private static Object buildInetAddress(InetAddress data) {
@@ -233,12 +223,11 @@
         return address;
     }
 
-    private static <T> JSONArray buildJsonList(final List<T> list) throws JSONException {
-        JSONArray result = new JSONArray();
-        for (T item : list) {
-            result.put(build(item));
-        }
-        return result;
+    private static Object buildInetSocketAddress(InetSocketAddress data) {
+        JSONArray address = new JSONArray();
+        address.put(data.getHostName());
+        address.put(data.getPort());
+        return address;
     }
 
     private static JSONObject buildJsonAddress(Address address) throws JSONException {
@@ -256,82 +245,20 @@
         return result;
     }
 
-    private static JSONObject buildJsonLocation(Location location) throws JSONException {
-        JSONObject result = new JSONObject();
-        result.put("altitude", location.getAltitude());
-        result.put("latitude", location.getLatitude());
-        result.put("longitude", location.getLongitude());
-        result.put("time", location.getTime());
-        result.put("accuracy", location.getAccuracy());
-        result.put("speed", location.getSpeed());
-        result.put("provider", location.getProvider());
-        result.put("bearing", location.getBearing());
-        return result;
-    }
-
-    private static JSONObject buildJsonBundle(Bundle bundle) throws JSONException {
-        JSONObject result = new JSONObject();
-        for (String key : bundle.keySet()) {
-            result.put(key, build(bundle.get(key)));
+    private static JSONArray buildJSONArray(Object[] data) throws JSONException {
+        JSONArray result = new JSONArray();
+        for (Object o : data) {
+            result.put(build(o));
         }
         return result;
     }
 
-    private static JSONObject buildJsonIntent(Intent data) throws JSONException {
+    private static JSONObject buildJsonBleAdvertiseSettings(AdvertiseSettings advertiseSettings)
+            throws JSONException {
         JSONObject result = new JSONObject();
-        result.put("data", data.getDataString());
-        result.put("type", data.getType());
-        result.put("extras", build(data.getExtras()));
-        result.put("categories", build(data.getCategories()));
-        result.put("action", data.getAction());
-        ComponentName component = data.getComponent();
-        if (component != null) {
-            result.put("packagename", component.getPackageName());
-            result.put("classname", component.getClassName());
-        }
-        result.put("flags", data.getFlags());
-        return result;
-    }
-
-    private static JSONObject buildJsonEvent(Event event) throws JSONException {
-        JSONObject result = new JSONObject();
-        result.put("name", event.getName());
-        result.put("data", build(event.getData()));
-        result.put("time", event.getCreationTime());
-        return result;
-    }
-
-    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()));
-        }
-        return result;
-    }
-
-    private static JSONObject buildJsonScanResult(ScanResult scanResult) throws JSONException {
-        JSONObject result = new JSONObject();
-        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
-        // 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) {
-        // JSONObject infoEle = new JSONObject();
-        // infoEle.put("id", ie.id);
-        // infoEle.put("bytes", Base64Codec.encodeBase64(ie.bytes));
-        // infoEles.put(infoEle);
-        // }
-        // result.put("InfomationElements", infoEles);
-        // } else
-        // result.put("InfomationElements", null);
+        result.put("mode", advertiseSettings.getMode());
+        result.put("txPowerLevel", advertiseSettings.getTxPowerLevel());
+        result.put("isConnectable", advertiseSettings.isConnectable());
         return result;
     }
 
@@ -382,24 +309,13 @@
         return result;
     }
 
-    private static JSONObject buildJsonBleAdvertiseSettings(AdvertiseSettings advertiseSettings)
-            throws JSONException {
-        JSONObject result = new JSONObject();
-        result.put("mode", advertiseSettings.getMode());
-        result.put("txPowerLevel", advertiseSettings.getTxPowerLevel());
-        result.put("isConnectable", advertiseSettings.isConnectable());
-        return result;
-    }
-
-    private static Object buildJsonBluetoothGattService(BluetoothGattService data)
-            throws JSONException {
-        JSONObject result = new JSONObject();
-        result.put("instanceId", data.getInstanceId());
-        result.put("type", data.getType());
-        result.put("gattCharacteristicList", build(data.getCharacteristics()));
-        result.put("includedServices", build(data.getIncludedServices()));
-        result.put("uuid", data.getUuid().toString());
-        return result;
+    private static JSONObject buildJsonBluetoothDevice(BluetoothDevice data) throws JSONException {
+        JSONObject deviceInfo = new JSONObject();
+        deviceInfo.put("address", data.getAddress());
+        deviceInfo.put("state", data.getBondState());
+        deviceInfo.put("name", data.getName());
+        deviceInfo.put("type", data.getType());
+        return deviceInfo;
     }
 
     private static Object buildJsonBluetoothGattCharacteristic(BluetoothGattCharacteristic data)
@@ -427,92 +343,23 @@
         return result;
     }
 
-    private static Object buildPoint(Point data) throws JSONException {
-        JSONObject point = new JSONObject();
-        point.put("x", data.x);
-        point.put("y", data.y);
-        return point;
+    private static Object buildJsonBluetoothGattService(BluetoothGattService data)
+            throws JSONException {
+        JSONObject result = new JSONObject();
+        result.put("instanceId", data.getInstanceId());
+        result.put("type", data.getType());
+        result.put("gattCharacteristicList", build(data.getCharacteristics()));
+        result.put("includedServices", build(data.getIncludedServices()));
+        result.put("uuid", data.getUuid().toString());
+        return result;
     }
 
-    private static Object buildSmsMessage(SmsMessage data) throws JSONException {
-        JSONObject msg = new JSONObject();
-        msg.put("originatingAddress", data.getOriginatingAddress());
-        msg.put("messageBody", data.getMessageBody());
-        return msg;
-    }
-
-    private static Object buildPhoneAccountHandle(PhoneAccountHandle data) throws JSONException {
-        JSONObject msg = new JSONObject();
-        msg.put("id", data.getId());
-        return msg;
-    }
-
-    private static Object buildDisplayMetrics(DisplayMetrics data) throws JSONException {
-        JSONObject dm = new JSONObject();
-        dm.put("widthPixels", data.widthPixels);
-        dm.put("heightPixels", data.heightPixels);
-        dm.put("noncompatHeightPixels", data.noncompatHeightPixels);
-        dm.put("noncompatWidthPixels", data.noncompatWidthPixels);
-        return dm;
-    }
-
-    private static Object buildRttCapabilities(Capabilities data) throws JSONException {
-        JSONObject cap = new JSONObject();
-        cap.put("supportedType", data.supportedType);
-        cap.put("supportedPeerType", data.supportedPeerType);
-        return cap;
-    }
-
-    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));
-        } else {
-            config.put("ssid", data.SSID);
+    private static JSONObject buildJsonBundle(Bundle bundle) throws JSONException {
+        JSONObject result = new JSONObject();
+        for (String key : bundle.keySet()) {
+            result.put(key, build(bundle.get(key)));
         }
-        config.put("bssid", data.BSSID);
-        config.put("priority", data.priority);
-        config.put("hiddenSSID", data.hiddenSSID);
-        if (data.status == WifiConfiguration.Status.CURRENT) {
-            config.put("status", "CURRENT");
-        } else if (data.status == WifiConfiguration.Status.DISABLED) {
-            config.put("status", "DISABLED");
-        } else if (data.status == WifiConfiguration.Status.ENABLED) {
-            config.put("status", "ENABLED");
-        } else {
-            config.put("status", "UNKNOWN");
-        }
-        return config;
-    }
-
-    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 {
-        JSONObject group = new JSONObject();
-        Log.d("build p2p group.");
-        group.put("ClientList", build(data.getClientList()));
-        group.put("Interface", data.getInterface());
-        group.put("Networkname", data.getNetworkName());
-        group.put("Owner", data.getOwner());
-        group.put("Passphrase", data.getPassphrase());
-        group.put("NetworkId", data.getNetworkId());
-        return group;
-    }
-
-    private static JSONObject buildWifiP2pInfo(WifiP2pInfo data) throws JSONException {
-        JSONObject info = new JSONObject();
-        Log.d("build p2p info.");
-        info.put("groupFormed", data.groupFormed);
-        info.put("isGroupOwner", data.isGroupOwner);
-        info.put("groupOwnerAddress", data.groupOwnerAddress);
-        return info;
+        return result;
     }
 
     private static JSONObject buildJsonCellLocation(CellLocation cellLocation)
@@ -527,6 +374,85 @@
         return result;
     }
 
+    private static JSONObject buildJsonEvent(Event event) throws JSONException {
+        JSONObject result = new JSONObject();
+        result.put("name", event.getName());
+        result.put("data", build(event.getData()));
+        result.put("time", event.getCreationTime());
+        return result;
+    }
+
+    private static JSONObject buildJsonIntent(Intent data) throws JSONException {
+        JSONObject result = new JSONObject();
+        result.put("data", data.getDataString());
+        result.put("type", data.getType());
+        result.put("extras", build(data.getExtras()));
+        result.put("categories", build(data.getCategories()));
+        result.put("action", data.getAction());
+        ComponentName component = data.getComponent();
+        if (component != null) {
+            result.put("packagename", component.getPackageName());
+            result.put("classname", component.getClassName());
+        }
+        result.put("flags", data.getFlags());
+        return result;
+    }
+
+    private static <T> JSONArray buildJsonList(final List<T> list) throws JSONException {
+        JSONArray result = new JSONArray();
+        for (T item : list) {
+            result.put(build(item));
+        }
+        return result;
+    }
+
+    private static JSONObject buildJsonLocation(Location location) throws JSONException {
+        JSONObject result = new JSONObject();
+        result.put("altitude", location.getAltitude());
+        result.put("latitude", location.getLatitude());
+        result.put("longitude", location.getLongitude());
+        result.put("time", location.getTime());
+        result.put("accuracy", location.getAccuracy());
+        result.put("speed", location.getSpeed());
+        result.put("provider", location.getProvider());
+        result.put("bearing", location.getBearing());
+        return result;
+    }
+
+    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()));
+        }
+        return result;
+    }
+
+    private static JSONObject buildJsonScanResult(ScanResult scanResult) throws JSONException {
+        JSONObject result = new JSONObject();
+        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
+        // 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) {
+        // JSONObject infoEle = new JSONObject();
+        // infoEle.put("id", ie.id);
+        // infoEle.put("bytes", Base64Codec.encodeBase64(ie.bytes));
+        // infoEles.put(infoEle);
+        // }
+        // result.put("InfomationElements", infoEles);
+        // } else
+        // result.put("InfomationElements", null);
+        return result;
+    }
+
     private static JSONObject buildJsonWifiInfo(WifiInfo data) throws JSONException {
         JSONObject result = new JSONObject();
         result.put("hidden_ssid", data.getHiddenSSID());
@@ -587,4 +513,111 @@
         result.put("rssi", data.getRssi());
         return result;
     }
+
+    private static Object buildNetworkInfo(NetworkInfo data) throws JSONException {
+        JSONObject info = new JSONObject();
+        info.put("isAvailable", data.isAvailable());
+        info.put("isConnected", data.isConnected());
+        info.put("isConnected", data.isFailover());
+        info.put("isConnected", data.isRoaming());
+        info.put("ExtraInfo", data.getExtraInfo());
+        info.put("FailedReason", data.getReason());
+        info.put("TypeName", data.getTypeName());
+        info.put("SubtypeName", data.getSubtypeName());
+        info.put("State", data.getState().name().toString());
+        return info;
+    }
+
+    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("Label", data.getLabel().toString());
+        acct.put("ShortDescription", data.getShortDescription().toString());
+        return acct;
+    }
+
+    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 buildPoint(Point data) throws JSONException {
+        JSONObject point = new JSONObject();
+        point.put("x", data.x);
+        point.put("y", data.y);
+        return point;
+    }
+
+    private static Object buildRttCapabilities(Capabilities data) throws JSONException {
+        JSONObject cap = new JSONObject();
+        cap.put("supportedType", data.supportedType);
+        cap.put("supportedPeerType", data.supportedPeerType);
+        return cap;
+    }
+
+    private static Object buildSmsMessage(SmsMessage data) throws JSONException {
+        JSONObject msg = new JSONObject();
+        msg.put("originatingAddress", data.getOriginatingAddress());
+        msg.put("messageBody", data.getMessageBody());
+        return msg;
+    }
+
+    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));
+        } else {
+            config.put("ssid", data.SSID);
+        }
+        config.put("bssid", data.BSSID);
+        config.put("priority", data.priority);
+        config.put("hiddenSSID", data.hiddenSSID);
+        if (data.status == WifiConfiguration.Status.CURRENT) {
+            config.put("status", "CURRENT");
+        } else if (data.status == WifiConfiguration.Status.DISABLED) {
+            config.put("status", "DISABLED");
+        } else if (data.status == WifiConfiguration.Status.ENABLED) {
+            config.put("status", "ENABLED");
+        } else {
+            config.put("status", "UNKNOWN");
+        }
+        return config;
+    }
+
+    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 {
+        JSONObject group = new JSONObject();
+        Log.d("build p2p group.");
+        group.put("ClientList", build(data.getClientList()));
+        group.put("Interface", data.getInterface());
+        group.put("Networkname", data.getNetworkName());
+        group.put("Owner", data.getOwner());
+        group.put("Passphrase", data.getPassphrase());
+        group.put("NetworkId", data.getNetworkId());
+        return group;
+    }
+
+    private static JSONObject buildWifiP2pInfo(WifiP2pInfo data) throws JSONException {
+        JSONObject info = new JSONObject();
+        Log.d("build p2p info.");
+        info.put("groupFormed", data.groupFormed);
+        info.put("isGroupOwner", data.isGroupOwner);
+        info.put("groupOwnerAddress", data.groupOwnerAddress);
+        return info;
+    }
+
+    private JsonBuilder() {
+        // This is a utility class.
+    }
 }
diff --git a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java b/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
index f3ae2d4..29b3f14 100644
--- a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
+++ b/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
@@ -35,7 +35,7 @@
 import com.googlecode.android_scripting.facade.media.MediaScannerFacade;
 import com.googlecode.android_scripting.facade.media.MediaSessionFacade;
 import com.googlecode.android_scripting.facade.tele.PhoneFacade;
-import com.googlecode.android_scripting.facade.tele.TelecommManagerFacade;
+import com.googlecode.android_scripting.facade.tele.TelecomManagerFacade;
 import com.googlecode.android_scripting.facade.ui.UiFacade;
 import com.googlecode.android_scripting.facade.wifi.WifiManagerFacade;
 import com.googlecode.android_scripting.facade.wifi.WifiP2pManagerFacade;
@@ -133,7 +133,7 @@
             sFacadeClassList.add(BluetoothLeAdvertiseFacade.class);
             sFacadeClassList.add(ConnectivityManagerFacade.class);
             sFacadeClassList.add(DisplayFacade.class);
-            sFacadeClassList.add(TelecommManagerFacade.class);
+            sFacadeClassList.add(TelecomManagerFacade.class);
             sFacadeClassList.add(WifiRttManagerFacade.class);
             sFacadeClassList.add(WifiScannerFacade.class);
         }