Improvements to sl4a.

Correct the listner structure of passpoint facade.
Remove type casts in rtt manager facade.
Add the correct RPC APIs in scanner facade,
will deprecate old ones later.
Remove duplicate permissions in manifest.

Change-Id: I00b874ea8ec378eadc64958efdee3eebba62fb2a
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 d1ef771..8f351db 100644
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
@@ -7,6 +7,7 @@
 import android.content.IntentFilter;
 import android.net.NetworkInfo;
 import android.net.wifi.ScanResult;
+import android.net.wifi.WifiAdapter;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
@@ -190,6 +191,18 @@
       return false;
   }
 
+  @Rpc(description = "Check if wifi scanner is supported on this device.")
+  public Boolean wifiIsScannerSupported() {
+      List<WifiAdapter> adapters = mWifi.getAdapters();
+      boolean s = false;
+      for(WifiAdapter a : adapters) {
+          if (a.isWifiScannerSupported()) {
+              s = true;
+          }
+      }
+      return s;
+  }
+
   @Rpc(description = "Add a network.")
   public Integer wifiAddNetwork(@RpcParameter(name = "wifiId") String wifiId) {
       ScanResult target = null;
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiPasspointManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiPasspointManagerFacade.java
index eddeb36..6caff66 100644
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiPasspointManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiPasspointManagerFacade.java
@@ -21,23 +21,16 @@
 import android.net.wifi.ScanResult;
 import android.net.wifi.passpoint.WifiPasspointManager;
 import android.net.wifi.passpoint.WifiPasspointManager.Channel;
-import android.net.wifi.passpoint.WifiPasspointManager.ChannelListener;
 import android.os.Bundle;
-import android.os.Looper;
-
 import com.googlecode.android_scripting.Log;
-import com.googlecode.android_scripting.MainThread;
 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 com.googlecode.android_scripting.rpc.RpcStartEvent;
-
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
-import java.util.concurrent.Callable;
 
 /**
  * Exposes WifiPasspointManger functionality.
@@ -48,8 +41,9 @@
   private final Service mService;
   private final EventFacade mEventFacade;
   private final WifiPasspointManager mWifiPasspointMgr;
-  private static int mWifiPasspointChannelALCnt;
-  private Hashtable<Integer, WifiPasspointChannelActionListener> mWifiPasspointChannelAlList;
+  private Hashtable<Integer, PasspointActionListener> mPasspointActionListeners;
+  private Hashtable<Integer, PasspointChannelListener> mPasspointChannelListeners;
+  private Hashtable<Integer, Channel> mChannels;
   private List<ScanResult> mScanResults;
 
   public WifiPasspointManagerFacade(FacadeManager facadeManager){
@@ -57,63 +51,72 @@
     mService = facadeManager.getService();
     mEventFacade = facadeManager.getReceiver(EventFacade.class);
     mWifiPasspointMgr = (WifiPasspointManager)mService.getSystemService(Context.WIFI_PASSPOINT_SERVICE);
-    mWifiPasspointChannelAlList = new Hashtable<Integer, WifiPasspointChannelActionListener>();
+    mPasspointActionListeners = new Hashtable<Integer, PasspointActionListener>();
+    mPasspointChannelListeners = new Hashtable<Integer, PasspointChannelListener>();
+    mChannels = new Hashtable<Integer, Channel>();
     mScanResults = new ArrayList<ScanResult>();
 
   }
 
-  public class WifiPasspointChannelActionListener implements WifiPasspointManager.ActionListener{
-
-    private ChannelListener mChannelListener;
-    private Channel mChannel;
+  public static class PasspointActionListener implements WifiPasspointManager.ActionListener{
+    private static final String TAG = "PasspointAction";
+    private static int sIndex;
     private int mIndex;
-    private final Bundle mStatus;
+    private final Bundle msg = new Bundle();
+    private final EventFacade mEventFacade;
 
-    public WifiPasspointChannelActionListener(){
-      mChannelListener = new WifiPasspointManager.ChannelListener() {
-        @Override
-        public void onChannelDisconnected() {
-          Log.e("Channel Disconnected with WifiPasspoint Framwork");
-        }
-      };
-      mChannel  = mWifiPasspointMgr.initialize(mService.getApplicationContext(), Looper.getMainLooper() , mChannelListener);
-      mIndex = ++mWifiPasspointChannelALCnt;
-      mStatus = new Bundle();
+    public PasspointActionListener(EventFacade ef){
+      sIndex += 1;
+      mIndex = sIndex;
+      mEventFacade = ef;
     }
 
     @Override
     public void onSuccess() {
-      Log.d("onSuccess " + mEventType + " " + mIndex);
-      mStatus.putString("Type", "onSuccess");
-      mEventFacade.postEvent(mEventType + mIndex, mStatus.clone());
-      mStatus.clear();
+      mEventFacade.postEvent(TAG + mIndex + "onSuccess", null);
     }
 
     @Override
     public void onFailure(int reason){
       Log.d("onFailure " + mEventType + " " + mIndex);
-      mStatus.putString("Type", "onFailure");
-      mStatus.putInt("Reason", reason);
-      mEventFacade.postEvent(mEventType + mIndex, mStatus.clone());
-      mStatus.clear();
+      msg.putInt("Reason", reason);
+      mEventFacade.postEvent(TAG + mIndex + "onFailure", msg);
+      msg.clear();
     }
+  }
 
+  private static class PasspointChannelListener implements WifiPasspointManager.ChannelListener {
+    private static int sIndex;
+    private static EventFacade mEventFacade;
+    private static final String TAG = "PasspointChannel";
+    public final int mIndex;
+
+    public PasspointChannelListener(EventFacade ef) {
+        sIndex += 1;
+        mIndex = sIndex;
+        mEventFacade = ef;
+    }
+    @Override
+    public void onChannelDisconnected() {
+        Log.d("Wifi Passpoint channel disconnected.");
+        mEventFacade.postEvent(TAG + mIndex + "onChannelDisconnected", null);
+    }
+  }
+
+  private PasspointChannelListener genChangeListener() {
+      PasspointChannelListener l = new PasspointChannelListener(mEventFacade);
+      mPasspointChannelListeners.put(l.mIndex, l);
+      return l;
   }
 
   /**
    * Constructs a WifiPasspointChannelListener object and initialize it
    * @return WifiPasspointChannelListener
    */
-  private WifiPasspointChannelActionListener genWifiPasspointChannelAL() {
-    WifiPasspointChannelActionListener mWifiPpChannelAL =
-        MainThread.run(mService, new Callable<WifiPasspointChannelActionListener>() {
-      @Override
-      public WifiPasspointChannelActionListener call() throws Exception {
-        return new WifiPasspointChannelActionListener();
-      }
-    });
-    mWifiPasspointChannelAlList.put(mWifiPpChannelAL.mIndex, mWifiPpChannelAL);
-    return mWifiPpChannelAL;
+  private PasspointActionListener genPasspointActionListener() {
+    PasspointActionListener listener = new PasspointActionListener(mEventFacade);
+    mPasspointActionListeners.put(listener.mIndex, listener);
+    return listener;
   }
 
   /**
@@ -126,20 +129,31 @@
 
   /** RPC Method Section */
 
+  @Rpc(description = "Initialize wifi passpoint.",
+       returns = "The index of the listener and channel associated with the passpoint.")
+  public Integer wifiPasspointInitialize() {
+      PasspointChannelListener listener = genChangeListener();
+      Channel c = mWifiPasspointMgr.initialize(mService, mService.getMainLooper(), listener);
+      mChannels.put(listener.mIndex, c);
+      return listener.mIndex;
+  }
+
   /**
    * Request ANQP Info of Passpoints
    * @param mask
    * @return the id of the Passpoint channel listener associated with this
    */
   @Rpc(description = "Request ANQP info.")
-  @RpcStartEvent("ANQPInfo")
-  public Integer requestAnqpInfoOfPasspoints(@RpcParameter(name = "scanIndex") Integer scanIndex,
+  public Integer requestAnqpInfoOfPasspoints(
+      @RpcParameter(name = "scanIndex") Integer scanIndex,
+      @RpcParameter(name = "channelIndex") Integer channelIndex,
       @RpcParameter(name = "mask") Integer mask) {
-    WifiScannerFacade.getWifiScanResult(scanIndex, mScanResults);
-    if(mScanResults != null && mScanResults.size() >= 0) {
-      WifiPasspointChannelActionListener mWifiPpChannelAL = genWifiPasspointChannelAL();
-      mWifiPasspointMgr.requestAnqpInfo(mWifiPpChannelAL.mChannel,  mScanResults, mask, mWifiPpChannelAL);
-      return mWifiPpChannelAL.mIndex;
+    List<ScanResult> sr = WifiScannerFacade.getWifiScanResult(scanIndex);
+    if(sr != null && sr.size() >= 0) {
+      PasspointActionListener listener = genPasspointActionListener();
+      Channel chl = mChannels.get(channelIndex);
+      mWifiPasspointMgr.requestAnqpInfo(chl, sr, mask, listener);
+      return listener.mIndex;
     }
     return -1;
   }
@@ -148,7 +162,8 @@
    */
   @Override
   public void shutdown() {
-    mWifiPasspointChannelAlList.clear();
+    mPasspointActionListeners.clear();
+    mPasspointChannelListeners.clear();
     mScanResults.clear();
   }
 
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 1acaf4b..d10b7a5 100644
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java
@@ -101,25 +101,25 @@
       JSONObject j = new JSONObject(rttParam);
       RttParams result = new RttParams();
       if (j.has("deviceType")) {
-          result.deviceType = (int) j.get("deviceType"); 
+          result.deviceType = j.getInt("deviceType");
       }
       if (j.has("requestType")) {
-          result.requestType = (int) j.get("requestType"); 
+          result.requestType = j.getInt("requestType");
       }
       if (j.has("bssid")) {
-          result.bssid = (String) j.get("bssid"); 
+          result.bssid = j.getString("bssid");
       }
       if (j.has("frequency")) {
-          result.frequency = (int) j.get("frequency"); 
+          result.frequency = j.getInt("frequency");
       }
       if (j.has("channelWidth")) {
-          result.channelWidth = (int) j.get("channelWidth"); 
+          result.channelWidth = j.getInt("channelWidth");
       }
       if (j.has("num_samples")) {
-          result.num_samples = (int) j.get("num_samples"); 
+          result.num_samples = j.getInt("num_samples");
       }
       if (j.has("num_retries")) {
-          result.num_retries = (int) j.get("num_retries"); 
+          result.num_retries = j.getInt("num_retries");
       }
       return result;
   }
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 470565b..18d5ec0 100644
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiScannerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiScannerFacade.java
@@ -33,6 +33,7 @@
 import com.googlecode.android_scripting.rpc.Rpc;
 import com.googlecode.android_scripting.rpc.RpcParameter;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
@@ -70,16 +71,9 @@
     wifiScannerResultList = new ConcurrentHashMap<Integer, ScanResult[]>();
   }
 
-  public static List<ScanResult> getWifiScanResult(Integer listener_index,
-                                                   List<ScanResult> scanResults){
-    synchronized (wifiScannerResultList) {
-      ScanResult[] scanArray = wifiScannerResultList.get(listener_index);
-      if (scanArray != null){
-        for(ScanResult scanresult :  scanArray)
-          scanResults.add(scanresult);
-      }
-      return scanResults;
-    }
+  public static List<ScanResult> getWifiScanResult(Integer listener_index){
+    ScanResult[] sr = wifiScannerResultList.get(listener_index);
+    return Arrays.asList(sr);
   }
 
   private class WifiActionListener implements WifiScanner.ActionListener {
@@ -314,7 +308,7 @@
    * @throws JSONException
    */
   @Rpc(description = "Starts a periodic WifiScanner scan")
-  public Integer startWifiScannerScan(@RpcParameter(name = "scanSettings") String scanSettings)
+  public Integer wifiStartScannerScan(@RpcParameter(name = "scanSettings") String scanSettings)
           throws JSONException {
     ScanSettings ss = parseScanSettings(scanSettings);
     Log.d("startWifiScannerScan with " + ss.channels);
@@ -358,6 +352,18 @@
    * @throws Exception
    */
   @Rpc(description = "Starts tracking wifi changes")
+  public Integer wifiStartTrackingChange() throws Exception{
+    ChangeListener listener = genWifiChangeListener();
+    mScan.startTrackingWifiChange(listener);
+    return listener.mIndex;
+  }
+
+  /**
+   * 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,
diff --git a/ScriptingLayerForAndroid/AndroidManifest.xml b/ScriptingLayerForAndroid/AndroidManifest.xml
index 09005ae..6f3ddb1 100644
--- a/ScriptingLayerForAndroid/AndroidManifest.xml
+++ b/ScriptingLayerForAndroid/AndroidManifest.xml
@@ -36,8 +36,6 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
-    <uses-permission android:name="android.permission.ACCESS_BLUETOOTH_SHARE" />
-    <uses-permission android:name="com.android.permission.WHITELIST_BLUETOOTH_DEVICE" />
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />