Merge "Improvements to sl4a." into lmp-dev
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" />