resolved conflicts for merge of a7a34188 to master

Change-Id: Ie146ce54fc1f00b575bb772eb25f76cd9c3e5149
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiP2pManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiP2pManagerFacade.java
new file mode 100644
index 0000000..b2f24d2
--- /dev/null
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiP2pManagerFacade.java
@@ -0,0 +1,241 @@
+
+package com.googlecode.android_scripting.facade.wifi;
+
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.NetworkInfo;
+import android.net.wifi.WpsInfo;
+import android.net.wifi.p2p.WifiP2pConfig;
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pDeviceList;
+import android.net.wifi.p2p.WifiP2pGroup;
+import android.net.wifi.p2p.WifiP2pInfo;
+import android.net.wifi.p2p.WifiP2pManager;
+import android.os.Bundle;
+
+import com.googlecode.android_scripting.Log;
+import com.googlecode.android_scripting.facade.EventFacade;
+import com.googlecode.android_scripting.facade.FacadeManager;
+import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
+import com.googlecode.android_scripting.rpc.Rpc;
+import com.googlecode.android_scripting.rpc.RpcParameter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * WifiP2pManager functions.
+ */
+public class WifiP2pManagerFacade extends RpcReceiver {
+
+    class WifiP2pPeerListListener implements WifiP2pManager.PeerListListener {
+        private final EventFacade mEventFacade;
+
+        public WifiP2pPeerListListener(EventFacade eventFacade) {
+            mEventFacade = eventFacade;
+        }
+
+        @Override
+        public void onPeersAvailable(WifiP2pDeviceList newPeers) {
+            Collection<WifiP2pDevice> devices = newPeers.getDeviceList();
+            Log.d(devices.toString());
+            if (devices.size() > 0) {
+                mP2pPeers.clear();
+                mP2pPeers.addAll(devices);
+                Bundle msg = new Bundle();
+                msg.putParcelableList("Peers", mP2pPeers);
+                mEventFacade.postEvent(mEventType + "OnPeersAvailable", msg);
+            }
+        }
+    }
+
+    class WifiP2pActionListener implements WifiP2pManager.ActionListener {
+        private final EventFacade mEventFacade;
+        private final String mEventType;
+        private final String TAG;
+
+        public WifiP2pActionListener(EventFacade eventFacade, String tag) {
+            mEventType = "WifiP2pManager";
+            mEventFacade = eventFacade;
+            TAG = tag;
+        }
+
+        @Override
+        public void onFailure(int reason) {
+            Log.d("WifiActionListener  " + mEventType);
+            Bundle msg = new Bundle();
+            if (reason == WifiP2pManager.P2P_UNSUPPORTED) {
+                msg.putString("reason", "P2P_UNSUPPORTED");
+            } else if (reason == WifiP2pManager.ERROR) {
+                msg.putString("reason", "ERROR");
+            } else if (reason == WifiP2pManager.BUSY) {
+                msg.putString("reason", "BUSY");
+            } else if (reason == WifiP2pManager.NO_SERVICE_REQUESTS) {
+                msg.putString("reason", "NO_SERVICE_REQUESTS");
+            } else {
+                msg.putInt("reason", reason);
+            }
+            mEventFacade.postEvent(mEventType + TAG + "OnFailure", msg);
+        }
+
+        @Override
+        public void onSuccess() {
+            mEventFacade.postEvent(mEventType + TAG + "OnSuccess", null);
+        }
+    }
+
+    class WifiP2pStateChangedReceiver extends BroadcastReceiver {
+        private final EventFacade mEventFacade;
+        private final Bundle mResults;
+
+        WifiP2pStateChangedReceiver(EventFacade eventFacade) {
+            mEventFacade = eventFacade;
+            mResults = new Bundle();
+        }
+
+        @Override
+        public void onReceive(Context c, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) {
+                Log.d("Wifi P2p State Changed.");
+                int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, 0);
+                if (state == WifiP2pManager.WIFI_P2P_STATE_DISABLED) {
+                    Log.d("Disabled");
+                    isP2pEnabled = false;
+                } else if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
+                    Log.d("Enabled");
+                    isP2pEnabled = true;
+                }
+            } else if (action.equals(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION)) {
+                Log.d("Wifi P2p Peers Changed. Requesting peers.");
+                WifiP2pDeviceList peers = intent
+                        .getParcelableExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST);
+                Log.d(peers.toString());
+                wifiP2pRequestPeers();
+            } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
+                Log.d("Wifi P2p Connection Changed.");
+                WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
+                NetworkInfo networkInfo = intent
+                        .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
+                WifiP2pGroup group = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
+                if (networkInfo.isConnected()) {
+                    Log.d("Wifi P2p Connected.");
+                    mResults.putParcelable("P2pInfo", p2pInfo);
+                    mResults.putParcelable("Group", group);
+                    mEventFacade.postEvent(mEventType + "Connected", mResults);
+                    mResults.clear();
+                } else {
+                    mEventFacade.postEvent(mEventType + "Disconnected", null);
+                }
+            } else if (action.equals(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)) {
+                Log.d("Wifi P2p This Device Changed.");
+                WifiP2pDevice device = intent
+                        .getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
+                mResults.putParcelable("Device", device);
+                mEventFacade.postEvent(mEventType + "ThisDeviceChanged", mResults);
+                mResults.clear();
+            } else if (action.equals(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION)) {
+                Log.d("Wifi P2p Discovery Changed.");
+                int state = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, 0);
+                if (state == WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED) {
+                    Log.d("discovery started.");
+                } else if (state == WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED) {
+                    Log.d("discovery stoped.");
+                }
+            }
+        }
+    }
+
+    private final static String mEventType = "WifiP2pManager";
+    private WifiP2pManager.Channel mChannel;
+    private final EventFacade mEventFacade;
+
+    private final WifiP2pManager mP2p;
+    private final WifiP2pStateChangedReceiver mP2pStateChangedReceiver;
+
+    private final Service mService;
+
+    private final IntentFilter mStateChangeFilter;
+
+    private boolean isP2pEnabled;
+    private List<WifiP2pDevice> mP2pPeers = new ArrayList<WifiP2pDevice>();
+
+    public WifiP2pManagerFacade(FacadeManager manager) {
+        super(manager);
+        mService = manager.getService();
+        mP2p = (WifiP2pManager) mService.getSystemService(Context.WIFI_P2P_SERVICE);
+        mEventFacade = manager.getReceiver(EventFacade.class);
+
+        mStateChangeFilter = new IntentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
+        mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
+        mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
+        mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
+        mStateChangeFilter.setPriority(999);
+
+        mP2pStateChangedReceiver = new WifiP2pStateChangedReceiver(mEventFacade);
+    }
+
+    @Override
+    public void shutdown() {
+        mService.unregisterReceiver(mP2pStateChangedReceiver);
+    }
+
+    private boolean wifiP2pDeviceMatches(WifiP2pDevice d, String deviceId) {
+        return d.deviceName.equals(deviceId) || d.deviceAddress.equals(deviceId);
+    }
+
+    @Rpc(description = "Initialize wifi p2p. Must be called before any other p2p functions.")
+    public void wifiP2pInitialize() {
+        mService.registerReceiver(mP2pStateChangedReceiver, mStateChangeFilter);
+        mChannel = mP2p.initialize(mService, mService.getMainLooper(), null);
+    }
+
+    @Rpc(description = "Returns true if wifi p2p is enabled, false otherwise.")
+    public Boolean wifiP2pIsEnabled() {
+        return isP2pEnabled;
+    }
+
+    @Rpc(description = "Connects to a discovered wifi p2p device.")
+    public void wifiP2pConnect(@RpcParameter(name = "deviceId") String deviceId) {
+        for (WifiP2pDevice d : mP2pPeers) {
+            if (wifiP2pDeviceMatches(d, deviceId)) {
+                WifiP2pConfig config = new WifiP2pConfig();
+                config.deviceAddress = d.deviceAddress;
+                config.wps.setup = WpsInfo.PBC;
+                mP2p.connect(mChannel, config,
+                        new WifiP2pActionListener(mEventFacade, "Connect"));
+            }
+        }
+    }
+
+    @Rpc(description = "Disconnects wifi p2p.")
+    public void wifiP2pDisconnect() {
+        mP2p.removeGroup(mChannel, new WifiP2pManager.ActionListener() {
+            @Override
+            public void onSuccess() {
+                Log.d("removeGroup onSuccess.");
+                mEventFacade.postEvent(mEventType + "Disconnected", null);
+            }
+
+            @Override
+            public void onFailure(int reason) {
+                Log.d("removeGroup failed for reason: " + reason);
+            }
+        });
+    }
+
+    @Rpc(description = "Start peers discovery for wifi p2p.")
+    public void wifiP2pDiscoverPeers() {
+        mP2p.discoverPeers(mChannel, new WifiP2pActionListener(mEventFacade, "DiscoverPeers"));
+    }
+
+    @Rpc(description = "Request peers that are discovered for wifi p2p.")
+    public void wifiP2pRequestPeers() {
+        mP2p.requestPeers(mChannel, new WifiP2pPeerListListener(mEventFacade));
+    }
+
+}
diff --git a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
index 5454fc3..ccec6fb 100644
--- a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
+++ b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
@@ -16,19 +16,6 @@
 
 package com.googlecode.android_scripting.jsonrpc;
 
-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;
@@ -43,6 +30,9 @@
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pGroup;
+import android.net.wifi.p2p.WifiP2pInfo;
 import android.os.Bundle;
 import android.os.ParcelUuid;
 import android.telecomm.PhoneAccountHandle;
@@ -54,8 +44,23 @@
 import android.util.SparseArray;
 
 import com.googlecode.android_scripting.ConvertUtils;
+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() {
@@ -96,8 +101,8 @@
             return buildJsonList(items);
         }
         if (data instanceof Collection<?>) {
-          List<Object> items = new ArrayList<Object>((Collection<?>) data);
-          return buildJsonList(items);
+            List<Object> items = new ArrayList<Object>((Collection<?>) data);
+            return buildJsonList(items);
         }
         if (data instanceof List<?>) {
             return buildJsonList((List<?>) data);
@@ -122,7 +127,7 @@
             return buildJsonMap((Map<String, ?>) data);
         }
         if (data instanceof ParcelUuid) {
-          return data.toString();
+            return data.toString();
         }
         if (data instanceof ScanResult) {
             return buildJsonScanResult((ScanResult) data);
@@ -157,6 +162,9 @@
         if (data instanceof InetSocketAddress) {
             return buildInetSocketAddress((InetSocketAddress) data);
         }
+        if (data instanceof InetAddress) {
+            return buildInetAddress((InetAddress) data);
+        }
         if (data instanceof Point) {
             return buildPoint((Point) data);
         }
@@ -175,6 +183,15 @@
         if (data instanceof WifiConfiguration) {
             return buildWifiConfiguration((WifiConfiguration) data);
         }
+        if (data instanceof WifiP2pDevice) {
+            return buildWifiP2pDevice((WifiP2pDevice) data);
+        }
+        if (data instanceof WifiP2pInfo) {
+            return buildWifiP2pInfo((WifiP2pInfo) data);
+        }
+        if (data instanceof WifiP2pGroup) {
+            return buildWifiP2pGroup((WifiP2pGroup) data);
+        }
         if (data instanceof byte[]) {
             return Base64Codec.encodeBase64((byte[]) data);
         }
@@ -185,7 +202,7 @@
         // throw new JSONException("Failed to build JSON result. " + data.getClass().getName());
     }
 
-    private static Object 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());
@@ -209,6 +226,13 @@
         return address;
     }
 
+    private static Object buildInetAddress(InetAddress data) {
+        JSONArray address = new JSONArray();
+        address.put(data.getHostName());
+        address.put(data.getHostAddress());
+        return address;
+    }
+
     private static <T> JSONArray buildJsonList(final List<T> list) throws JSONException {
         JSONArray result = new JSONArray();
         for (T item : list) {
@@ -324,9 +348,11 @@
         ArrayList<String> manufacturerDataList = new ArrayList<String>();
         ArrayList<Integer> idList = new ArrayList<Integer>();
         if (scanResult.getScanRecord().getManufacturerSpecificData() != null) {
-            SparseArray<byte[]> manufacturerSpecificData = scanResult.getScanRecord().getManufacturerSpecificData();
-            for(int i = 0; i < manufacturerSpecificData.size(); i++) {
-                manufacturerDataList.add(ConvertUtils.convertByteArrayToString(manufacturerSpecificData.valueAt(i)));
+            SparseArray<byte[]> manufacturerSpecificData = scanResult.getScanRecord()
+                    .getManufacturerSpecificData();
+            for (int i = 0; i < manufacturerSpecificData.size(); i++) {
+                manufacturerDataList.add(ConvertUtils
+                        .convertByteArrayToString(manufacturerSpecificData.valueAt(i)));
                 idList.add(manufacturerSpecificData.keyAt(i));
             }
         }
@@ -336,9 +362,10 @@
         ArrayList<String> serviceDataList = new ArrayList<String>();
         if (scanResult.getScanRecord().getServiceData() != null) {
             Map<ParcelUuid, byte[]> serviceDataMap = scanResult.getScanRecord().getServiceData();
-            for (ParcelUuid serviceUuid : serviceDataMap.keySet()){
+            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);
@@ -442,19 +469,19 @@
         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("bssid", data.BSSID);
         config.put("priority", data.priority);
         config.put("hiddenSSID", data.hiddenSSID);
-        if (data.status==WifiConfiguration.Status.CURRENT) {
+        if (data.status == WifiConfiguration.Status.CURRENT) {
             config.put("status", "CURRENT");
-        } else if (data.status==WifiConfiguration.Status.DISABLED) {
+        } else if (data.status == WifiConfiguration.Status.DISABLED) {
             config.put("status", "DISABLED");
-        } else if (data.status==WifiConfiguration.Status.ENABLED) {
+        } else if (data.status == WifiConfiguration.Status.ENABLED) {
             config.put("status", "ENABLED");
         } else {
             config.put("status", "UNKNOWN");
@@ -462,8 +489,36 @@
         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 static JSONObject buildJsonCellLocation(CellLocation cellLocation)
-        throws JSONException {
+            throws JSONException {
         JSONObject result = new JSONObject();
         if (cellLocation instanceof GsmCellLocation) {
             GsmCellLocation location = (GsmCellLocation) cellLocation;
diff --git a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java b/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
index 236c870..f3ae2d4 100644
--- a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
+++ b/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
@@ -18,11 +18,29 @@
 
 import com.google.common.collect.Maps;
 import com.googlecode.android_scripting.Log;
-import com.googlecode.android_scripting.facade.bluetooth.*;
-import com.googlecode.android_scripting.facade.media.*;
-import com.googlecode.android_scripting.facade.tele.*;
+import com.googlecode.android_scripting.facade.bluetooth.BluetoothA2dpFacade;
+import com.googlecode.android_scripting.facade.bluetooth.BluetoothAvrcpFacade;
+import com.googlecode.android_scripting.facade.bluetooth.BluetoothConnectionFacade;
+import com.googlecode.android_scripting.facade.bluetooth.BluetoothFacade;
+import com.googlecode.android_scripting.facade.bluetooth.BluetoothGattFacade;
+import com.googlecode.android_scripting.facade.bluetooth.BluetoothHidFacade;
+import com.googlecode.android_scripting.facade.bluetooth.BluetoothHspFacade;
+import com.googlecode.android_scripting.facade.bluetooth.BluetoothLeAdvertiseFacade;
+import com.googlecode.android_scripting.facade.bluetooth.BluetoothLeScanFacade;
+import com.googlecode.android_scripting.facade.bluetooth.BluetoothMapFacade;
+import com.googlecode.android_scripting.facade.bluetooth.BluetoothRfcommFacade;
+import com.googlecode.android_scripting.facade.media.AudioManagerFacade;
+import com.googlecode.android_scripting.facade.media.MediaPlayerFacade;
+import com.googlecode.android_scripting.facade.media.MediaRecorderFacade;
+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.ui.UiFacade;
-import com.googlecode.android_scripting.facade.wifi.*;
+import com.googlecode.android_scripting.facade.wifi.WifiManagerFacade;
+import com.googlecode.android_scripting.facade.wifi.WifiP2pManagerFacade;
+import com.googlecode.android_scripting.facade.wifi.WifiRttManagerFacade;
+import com.googlecode.android_scripting.facade.wifi.WifiScannerFacade;
 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
 import com.googlecode.android_scripting.rpc.MethodDescriptor;
 import com.googlecode.android_scripting.rpc.RpcDeprecated;
@@ -43,159 +61,161 @@
 
 /**
  * Encapsulates the list of supported facades and their construction.
- *
  */
 public class FacadeConfiguration {
-  private final static Set<Class<? extends RpcReceiver>> sFacadeClassList;
-  private final static SortedMap<String, MethodDescriptor> sRpcs =
-      new TreeMap<String, MethodDescriptor>();
+    private final static Set<Class<? extends RpcReceiver>> sFacadeClassList;
+    private final static SortedMap<String, MethodDescriptor> sRpcs =
+            new TreeMap<String, MethodDescriptor>();
 
-  private static int sSdkLevel;
+    private static int sSdkLevel;
 
-  static {
-    sSdkLevel = android.os.Build.VERSION.SDK_INT;
+    static {
+        sSdkLevel = android.os.Build.VERSION.SDK_INT;
 
-    sFacadeClassList = new HashSet<Class<? extends RpcReceiver>>();
-    sFacadeClassList.add(ActivityResultFacade.class);
-    sFacadeClassList.add(AndroidFacade.class);
-    sFacadeClassList.add(ApplicationManagerFacade.class);
-    sFacadeClassList.add(AudioManagerFacade.class);
-    sFacadeClassList.add(BatteryManagerFacade.class);
-    sFacadeClassList.add(CameraFacade.class);
-    sFacadeClassList.add(CommonIntentsFacade.class);
-    sFacadeClassList.add(ContactsFacade.class);
-    sFacadeClassList.add(EventFacade.class);
-    sFacadeClassList.add(LocationFacade.class);
-    sFacadeClassList.add(PhoneFacade.class);
-    sFacadeClassList.add(PreferencesFacade.class);
-    sFacadeClassList.add(MediaPlayerFacade.class);
-    sFacadeClassList.add(MediaRecorderFacade.class);
-    sFacadeClassList.add(MediaScannerFacade.class);
-    sFacadeClassList.add(MediaSessionFacade.class);
-    sFacadeClassList.add(SensorManagerFacade.class);
-    sFacadeClassList.add(SettingsFacade.class);
-    sFacadeClassList.add(SmsFacade.class);
-    sFacadeClassList.add(SpeechRecognitionFacade.class);
-    sFacadeClassList.add(ToneGeneratorFacade.class);
-    sFacadeClassList.add(WakeLockFacade.class);
-    sFacadeClassList.add(WifiManagerFacade.class);
-    sFacadeClassList.add(UiFacade.class);
+        sFacadeClassList = new HashSet<Class<? extends RpcReceiver>>();
+        sFacadeClassList.add(ActivityResultFacade.class);
+        sFacadeClassList.add(AndroidFacade.class);
+        sFacadeClassList.add(ApplicationManagerFacade.class);
+        sFacadeClassList.add(AudioManagerFacade.class);
+        sFacadeClassList.add(BatteryManagerFacade.class);
+        sFacadeClassList.add(CameraFacade.class);
+        sFacadeClassList.add(CommonIntentsFacade.class);
+        sFacadeClassList.add(ContactsFacade.class);
+        sFacadeClassList.add(EventFacade.class);
+        sFacadeClassList.add(LocationFacade.class);
+        sFacadeClassList.add(PhoneFacade.class);
+        sFacadeClassList.add(PreferencesFacade.class);
+        sFacadeClassList.add(MediaPlayerFacade.class);
+        sFacadeClassList.add(MediaRecorderFacade.class);
+        sFacadeClassList.add(MediaScannerFacade.class);
+        sFacadeClassList.add(MediaSessionFacade.class);
+        sFacadeClassList.add(SensorManagerFacade.class);
+        sFacadeClassList.add(SettingsFacade.class);
+        sFacadeClassList.add(SmsFacade.class);
+        sFacadeClassList.add(SpeechRecognitionFacade.class);
+        sFacadeClassList.add(ToneGeneratorFacade.class);
+        sFacadeClassList.add(WakeLockFacade.class);
+        sFacadeClassList.add(WifiManagerFacade.class);
+        sFacadeClassList.add(UiFacade.class);
 
-    if (sSdkLevel >= 4) {
-      sFacadeClassList.add(TextToSpeechFacade.class);
-    } else {
-      sFacadeClassList.add(EyesFreeFacade.class);
-    }
-
-    if (sSdkLevel >= 5) {
-      sFacadeClassList.add(BluetoothFacade.class);
-      sFacadeClassList.add(BluetoothA2dpFacade.class);
-      sFacadeClassList.add(BluetoothAvrcpFacade.class);
-      sFacadeClassList.add(BluetoothConnectionFacade.class);
-      sFacadeClassList.add(BluetoothHspFacade.class);
-      sFacadeClassList.add(BluetoothHidFacade.class);
-      sFacadeClassList.add(BluetoothMapFacade.class);
-      sFacadeClassList.add(BluetoothRfcommFacade.class);
-    }
-
-    if (sSdkLevel >= 7) {
-      sFacadeClassList.add(SignalStrengthFacade.class);
-    }
-
-    if (sSdkLevel >= 8) {
-      sFacadeClassList.add(WebCamFacade.class);
-    }
-
-    if (sSdkLevel >= 19) {
-      sFacadeClassList.add(BluetoothLeScanFacade.class);
-      sFacadeClassList.add(BluetoothGattFacade.class);
-      sFacadeClassList.add(BluetoothLeAdvertiseFacade.class);
-      sFacadeClassList.add(ConnectivityManagerFacade.class);
-      sFacadeClassList.add(DisplayFacade.class);
-      sFacadeClassList.add(TelecommManagerFacade.class);
-      sFacadeClassList.add(WifiPasspointManagerFacade.class);
-      sFacadeClassList.add(WifiRttManagerFacade.class);
-      sFacadeClassList.add(WifiScannerFacade.class);
-    }
-
-    for (Class<? extends RpcReceiver> recieverClass : sFacadeClassList) {
-      for (MethodDescriptor rpcMethod : MethodDescriptor.collectFrom(recieverClass)) {
-        sRpcs.put(rpcMethod.getName(), rpcMethod);
-      }
-    }
-  }
-
-  private FacadeConfiguration() {
-    // Utility class.
-  }
-
-  public static int getSdkLevel() {
-    return sSdkLevel;
-  }
-
-  /** Returns a list of {@link MethodDescriptor} objects for all facades. */
-  public static List<MethodDescriptor> collectMethodDescriptors() {
-    return new ArrayList<MethodDescriptor>(sRpcs.values());
-  }
-
-  /**
-   * Returns a list of not deprecated {@link MethodDescriptor} objects for facades supported by the
-   * current SDK version.
-   */
-  public static List<MethodDescriptor> collectSupportedMethodDescriptors() {
-    List<MethodDescriptor> list = new ArrayList<MethodDescriptor>();
-    for (MethodDescriptor descriptor : sRpcs.values()) {
-      Method method = descriptor.getMethod();
-      if (method.isAnnotationPresent(RpcDeprecated.class)) {
-        continue;
-      } else if (method.isAnnotationPresent(RpcMinSdk.class)) {
-        int requiredSdkLevel = method.getAnnotation(RpcMinSdk.class).value();
-        if (sSdkLevel < requiredSdkLevel) {
-          continue;
+        if (sSdkLevel >= 4) {
+            sFacadeClassList.add(TextToSpeechFacade.class);
+        } else {
+            sFacadeClassList.add(EyesFreeFacade.class);
         }
-      }
-      list.add(descriptor);
-    }
-    return list;
-  }
 
-  public static Map<String, MethodDescriptor> collectStartEventMethodDescriptors() {
-    Map<String, MethodDescriptor> map = Maps.newHashMap();
-    for (MethodDescriptor descriptor : sRpcs.values()) {
-      Method method = descriptor.getMethod();
-      if (method.isAnnotationPresent(RpcStartEvent.class)) {
-        String eventName = method.getAnnotation(RpcStartEvent.class).value();
-        if (map.containsKey(eventName)) {
-          Log.d("Duplicate eventName " + eventName);
-          throw new RuntimeException("Duplicate start event method descriptor found.");
+        if (sSdkLevel >= 5) {
+            sFacadeClassList.add(BluetoothFacade.class);
+            sFacadeClassList.add(BluetoothA2dpFacade.class);
+            sFacadeClassList.add(BluetoothAvrcpFacade.class);
+            sFacadeClassList.add(BluetoothConnectionFacade.class);
+            sFacadeClassList.add(BluetoothHspFacade.class);
+            sFacadeClassList.add(BluetoothHidFacade.class);
+            sFacadeClassList.add(BluetoothMapFacade.class);
+            sFacadeClassList.add(BluetoothRfcommFacade.class);
         }
-        map.put(eventName, descriptor);
-      }
-    }
-    return map;
-  }
 
-  public static Map<String, MethodDescriptor> collectStopEventMethodDescriptors() {
-    Map<String, MethodDescriptor> map = Maps.newHashMap();
-    for (MethodDescriptor descriptor : sRpcs.values()) {
-      Method method = descriptor.getMethod();
-      if (method.isAnnotationPresent(RpcStopEvent.class)) {
-        String eventName = method.getAnnotation(RpcStopEvent.class).value();
-        if (map.containsKey(eventName)) {
-          throw new RuntimeException("Duplicate stop event method descriptor found.");
+        if (sSdkLevel >= 7) {
+            sFacadeClassList.add(SignalStrengthFacade.class);
         }
-        map.put(eventName, descriptor);
-      }
+
+        if (sSdkLevel >= 8) {
+            sFacadeClassList.add(WebCamFacade.class);
+        }
+
+        if (sSdkLevel >= 14) {
+            sFacadeClassList.add(WifiP2pManagerFacade.class);
+        }
+
+        if (sSdkLevel >= 19) {
+            sFacadeClassList.add(BluetoothLeScanFacade.class);
+            sFacadeClassList.add(BluetoothGattFacade.class);
+            sFacadeClassList.add(BluetoothLeAdvertiseFacade.class);
+            sFacadeClassList.add(ConnectivityManagerFacade.class);
+            sFacadeClassList.add(DisplayFacade.class);
+            sFacadeClassList.add(TelecommManagerFacade.class);
+            sFacadeClassList.add(WifiRttManagerFacade.class);
+            sFacadeClassList.add(WifiScannerFacade.class);
+        }
+
+        for (Class<? extends RpcReceiver> recieverClass : sFacadeClassList) {
+            for (MethodDescriptor rpcMethod : MethodDescriptor.collectFrom(recieverClass)) {
+                sRpcs.put(rpcMethod.getName(), rpcMethod);
+            }
+        }
     }
-    return map;
-  }
 
-  /** Returns a method by name. */
-  public static MethodDescriptor getMethodDescriptor(String name) {
-    return sRpcs.get(name);
-  }
+    private FacadeConfiguration() {
+        // Utility class.
+    }
 
-  public static Collection<Class<? extends RpcReceiver>> getFacadeClasses() {
-    return sFacadeClassList;
-  }
+    public static int getSdkLevel() {
+        return sSdkLevel;
+    }
+
+    /** Returns a list of {@link MethodDescriptor} objects for all facades. */
+    public static List<MethodDescriptor> collectMethodDescriptors() {
+        return new ArrayList<MethodDescriptor>(sRpcs.values());
+    }
+
+    /**
+     * Returns a list of not deprecated {@link MethodDescriptor} objects for facades supported by
+     * the current SDK version.
+     */
+    public static List<MethodDescriptor> collectSupportedMethodDescriptors() {
+        List<MethodDescriptor> list = new ArrayList<MethodDescriptor>();
+        for (MethodDescriptor descriptor : sRpcs.values()) {
+            Method method = descriptor.getMethod();
+            if (method.isAnnotationPresent(RpcDeprecated.class)) {
+                continue;
+            } else if (method.isAnnotationPresent(RpcMinSdk.class)) {
+                int requiredSdkLevel = method.getAnnotation(RpcMinSdk.class).value();
+                if (sSdkLevel < requiredSdkLevel) {
+                    continue;
+                }
+            }
+            list.add(descriptor);
+        }
+        return list;
+    }
+
+    public static Map<String, MethodDescriptor> collectStartEventMethodDescriptors() {
+        Map<String, MethodDescriptor> map = Maps.newHashMap();
+        for (MethodDescriptor descriptor : sRpcs.values()) {
+            Method method = descriptor.getMethod();
+            if (method.isAnnotationPresent(RpcStartEvent.class)) {
+                String eventName = method.getAnnotation(RpcStartEvent.class).value();
+                if (map.containsKey(eventName)) {
+                    Log.d("Duplicate eventName " + eventName);
+                    throw new RuntimeException("Duplicate start event method descriptor found.");
+                }
+                map.put(eventName, descriptor);
+            }
+        }
+        return map;
+    }
+
+    public static Map<String, MethodDescriptor> collectStopEventMethodDescriptors() {
+        Map<String, MethodDescriptor> map = Maps.newHashMap();
+        for (MethodDescriptor descriptor : sRpcs.values()) {
+            Method method = descriptor.getMethod();
+            if (method.isAnnotationPresent(RpcStopEvent.class)) {
+                String eventName = method.getAnnotation(RpcStopEvent.class).value();
+                if (map.containsKey(eventName)) {
+                    throw new RuntimeException("Duplicate stop event method descriptor found.");
+                }
+                map.put(eventName, descriptor);
+            }
+        }
+        return map;
+    }
+
+    /** Returns a method by name. */
+    public static MethodDescriptor getMethodDescriptor(String name) {
+        return sRpcs.get(name);
+    }
+
+    public static Collection<Class<? extends RpcReceiver>> getFacadeClasses() {
+        return sFacadeClassList;
+    }
 }