Merge "Facade changes for WifiTetheringTest"
diff --git a/Common/src/com/googlecode/android_scripting/facade/SettingsFacade.java b/Common/src/com/googlecode/android_scripting/facade/SettingsFacade.java
index 65625ed..5f42cc5 100644
--- a/Common/src/com/googlecode/android_scripting/facade/SettingsFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/SettingsFacade.java
@@ -29,6 +29,7 @@
 import android.view.WindowManager;
 
 import com.android.internal.widget.LockPatternUtils;
+
 import com.googlecode.android_scripting.BaseApplication;
 import com.googlecode.android_scripting.FutureActivityTaskExecutor;
 import com.googlecode.android_scripting.Log;
@@ -149,6 +150,24 @@
         mAudio.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
     }
 
+    /**
+    * Sets the voice call volume.
+    * @param volume the volume number to be set for voice call.
+    */
+    @Rpc(description = "Sets the voice call volume.")
+    public void setVoiceCallVolume(@RpcParameter(name = "volume") Integer volume) {
+        mAudio.setStreamVolume(AudioManager.STREAM_VOICE_CALL, volume, 0);
+    }
+
+    /**
+    * Sets the alarm volume.
+    * @param volume the volume number to be set for alarm.
+    */
+    @Rpc(description = "Sets the alarm volume.")
+    public void setAlarmVolume(@RpcParameter(name = "volume") Integer volume) {
+        mAudio.setStreamVolume(AudioManager.STREAM_ALARM, volume, 0);
+    }
+
     @Rpc(description = "Returns the screen backlight brightness.",
             returns = "the current screen brightness between 0 and 255")
     public Integer getScreenBrightness() {
diff --git a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java
index d9bb6b6..059dfcb 100644
--- a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java
@@ -16,6 +16,7 @@
 
 package com.googlecode.android_scripting.facade.telephony;
 
+import android.annotation.Nullable;
 import android.app.Service;
 import android.content.ContentResolver;
 import android.content.ContentValues;
@@ -61,6 +62,7 @@
 import com.googlecode.android_scripting.rpc.RpcOptional;
 import com.googlecode.android_scripting.rpc.RpcParameter;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 
@@ -113,6 +115,19 @@
         mSubscriptionManager = SubscriptionManager.from(mService);
     }
 
+    /**
+    * Reset TelephonyManager settings to factory default.
+    * @param subId the subriber id to be reset, use default id if not provided.
+    */
+    @Rpc(description = "Resets TelephonyManager settings to factory default.")
+    public void telephonyFactoryReset(
+            @RpcOptional @RpcParameter(name = "subId") Integer subId) {
+        if (subId == null) {
+            subId = SubscriptionManager.getDefaultVoiceSubscriptionId();
+        }
+        mTelephonyManager.factoryReset(subId);
+    }
+
     @Rpc(description = "Set network preference.")
     public boolean telephonySetPreferredNetworkTypes(
         @RpcParameter(name = "nwPreference") String nwPreference) {
@@ -1139,6 +1154,22 @@
         return mTelephonyManager.getSimCount();
     }
 
+    /**
+     * Get the list of Forbidden PLMNs stored on the USIM
+     * profile of the SIM for the default subscription.
+     */
+    @Rpc(description = "Returns a list of forbidden PLMNs")
+    public @Nullable List<String> telephonyGetForbiddenPlmns() {
+        String[] fplmns = mTelephonyManager.getForbiddenPlmns(
+                SubscriptionManager.getDefaultSubscriptionId(),
+                TelephonyManager.APPTYPE_USIM);
+
+        if (fplmns != null) {
+            return Arrays.asList(fplmns);
+        }
+        return null;
+    }
+
     private StateChangeListener getStateChangeListenerForSubscription(
             int subId,
             boolean createIfNeeded) {
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiAwareManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiAwareManagerFacade.java
index ce80184..c5f3fe4 100644
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiAwareManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiAwareManagerFacade.java
@@ -140,6 +140,21 @@
         if (j.has("ClusterHigh")) {
             builder.setClusterHigh(j.getInt("ClusterHigh"));
         }
+        if (j.has("DiscoveryWindowInterval")) {
+            JSONArray interval = j.getJSONArray("DiscoveryWindowInterval");
+            if (interval.length() != 2) {
+                throw new JSONException(
+                        "Expect 'DiscoveryWindowInterval' to be an array with 2 elements!");
+            }
+            int intervalValue = interval.getInt(ConfigRequest.NAN_BAND_24GHZ);
+            if (intervalValue != ConfigRequest.DW_INTERVAL_NOT_INIT) {
+                builder.setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, intervalValue);
+            }
+            intervalValue = interval.getInt(ConfigRequest.NAN_BAND_5GHZ);
+            if (intervalValue != ConfigRequest.DW_INTERVAL_NOT_INIT) {
+                builder.setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, intervalValue);
+            }
+        }
 
         return builder.build();
     }
@@ -245,20 +260,6 @@
         mService.unregisterReceiver(mStateChangedReceiver);
     }
 
-    @Rpc(description = "Enable Aware Usage.")
-    public void wifiAwareEnableUsage() throws RemoteException {
-        synchronized (mLock) {
-            mMgr.enableUsage();
-        }
-    }
-
-    @Rpc(description = "Disable Aware Usage.")
-    public void wifiAwareDisableUsage() throws RemoteException {
-        synchronized (mLock) {
-            mMgr.disableUsage();
-        }
-    }
-
     @Rpc(description = "Is Aware Usage Enabled?")
     public Boolean wifiIsAwareAvailable() throws RemoteException {
         synchronized (mLock) {
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 bcd9d81..05e7b3c 100755
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
@@ -27,6 +27,8 @@
 import android.net.Network;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
+import android.net.wifi.hotspot2.ConfigParser;
+import android.net.wifi.hotspot2.PasspointConfiguration;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiActivityEnergyInfo;
 import android.net.wifi.WifiConfiguration;
@@ -41,6 +43,7 @@
 import android.provider.Settings.Global;
 import android.provider.Settings.SettingNotFoundException;
 import android.util.Base64;
+import java.util.Arrays;
 
 import com.googlecode.android_scripting.Log;
 import com.googlecode.android_scripting.facade.EventFacade;
@@ -75,7 +78,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-
 /**
  * WifiManager functions.
  */
@@ -83,6 +85,8 @@
 // e.g. wifi connection result will be null when flight mode is on
 public class WifiManagerFacade extends RpcReceiver {
     private final static String mEventType = "WifiManager";
+    // MIME type for passpoint config.
+    private final static String TYPE_WIFICONFIG = "application/x-wifi-config";
     private final Service mService;
     private final WifiManager mWifi;
     private final EventFacade mEventFacade;
@@ -561,6 +565,76 @@
         mWifi.connect(wifiConfig, listener);
     }
 
+   /**
+     * Generate a Passpoint configuration from JSON config.
+     * @param config JSON config containing base64 encoded Passpoint profile
+     */
+    @Rpc(description = "Generate Passpoint configuration", returns = "PasspointConfiguration object")
+    public PasspointConfiguration genWifiPasspointConfig(@RpcParameter(
+            name = "config") JSONObject config)
+            throws JSONException,CertificateException, IOException {
+        String profileStr = "";
+        if (config == null) {
+            return null;
+        }
+        if (config.has("profile")) {
+            profileStr =  config.getString("profile");
+        }
+        return ConfigParser.parsePasspointConfig(TYPE_WIFICONFIG,
+                profileStr.getBytes());
+    }
+
+   /**
+     * Add or update a Passpoint configuration.
+     * @param config base64 encoded message containing Passpoint profile
+     * @throws JSONException
+     */
+    @Rpc(description = "Add or update a Passpoint configuration")
+    public boolean addUpdatePasspointConfig(@RpcParameter(
+            name = "config") JSONObject config)
+            throws JSONException,CertificateException, IOException {
+        PasspointConfiguration passpointConfig = genWifiPasspointConfig(config);
+        return mWifi.addOrUpdatePasspointConfiguration(passpointConfig);
+    }
+
+    /**
+     * Remove a Passpoint configuration.
+     * @param fqdn The FQDN of the passpoint configuration to be removed
+     * @return true on success; false otherwise
+     */
+    @Rpc(description = "Remove a Passpoint configuration", returns = "true if operation succeeds; false otherwise")
+    public boolean removePasspointConfig(
+            @RpcParameter(name = "fqdn") String fqdn) {
+        return mWifi.removePasspointConfiguration(fqdn);
+    }
+
+    /**
+     * Get list of Passpoint configurations.
+     * @return A list of FQDNs of the Passpoint configurations
+     */
+    @Rpc(description = "Return the list of installed Passpoint configurations", returns = "A list of Passpoint configurations")
+    public List<String> getPasspointConfigs() {
+        List<String> fqdnList = new ArrayList<String>();
+        for(PasspointConfiguration passpoint :
+            mWifi.getPasspointConfigurations()) {
+            fqdnList.add(passpoint.getHomeSp().getFqdn());
+        }
+        return fqdnList;
+    }
+
+     /**
+     * Connects to a wifi network using networkId.
+     * @param networkId the network identity for the network in the supplicant
+     */
+    @Rpc(description = "Connects to the network with the given networkId")
+    public void wifiConnectByNetworkId(
+            @RpcParameter(name = "networkId") Integer networkId) {
+        WifiActionListener listener;
+        listener = new WifiActionListener(mEventFacade,
+                WifiConstants.WIFI_CONNECT_BY_NETID_CALLBACK);
+        mWifi.connect(networkId, listener);
+    }
+
     @Rpc(description = "Disconnects from the currently active access point.", returns = "True if the operation succeeded.")
     public Boolean wifiDisconnect() {
         return mWifi.disconnect();
diff --git a/ScriptingLayerForAndroid/AndroidManifest.xml b/ScriptingLayerForAndroid/AndroidManifest.xml
index 03bc818..1675097 100644
--- a/ScriptingLayerForAndroid/AndroidManifest.xml
+++ b/ScriptingLayerForAndroid/AndroidManifest.xml
@@ -52,6 +52,7 @@
     <uses-permission android:name="android.permission.VIBRATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
     <uses-permission android:name="android.permission.PERSISTENT_ACTIVITY" />