wifi: WifiManager.startScan() will now do passive scans by default.

Active scans will only happen if a hidden AP is in use, or if the new method
WifiManager.startScanActive() is called.
This fixes some audio playback problems with bluetooth A2DP.

Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 9f93e2f..ae744a8 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -27,6 +27,8 @@
 
 namespace android {
 
+static jboolean sScanModeActive = false;
+
 /*
  * The following remembers the jfieldID's of the fields
  * of the DhcpInfo Java object, so that we don't have
@@ -254,27 +256,29 @@
     return doBooleanCommand("REASSOCIATE", "OK");
 }
 
-static jboolean android_net_wifi_scanCommand(JNIEnv* env, jobject clazz)
+static jboolean doSetScanMode(jboolean setActive)
+{
+    return doBooleanCommand((setActive ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE"), "OK");
+}
+
+static jboolean android_net_wifi_scanCommand(JNIEnv* env, jobject clazz, jboolean forceActive)
 {
     jboolean result;
+
     // Ignore any error from setting the scan mode.
     // The scan will still work.
-    (void)doBooleanCommand("DRIVER SCAN-ACTIVE", "OK");
+    if (forceActive && !sScanModeActive)
+        doSetScanMode(true);
     result = doBooleanCommand("SCAN", "OK");
-    (void)doBooleanCommand("DRIVER SCAN-PASSIVE", "OK");
+    if (forceActive && !sScanModeActive)
+        doSetScanMode(sScanModeActive);
     return result;
 }
 
 static jboolean android_net_wifi_setScanModeCommand(JNIEnv* env, jobject clazz, jboolean setActive)
 {
-    jboolean result;
-    // Ignore any error from setting the scan mode.
-    // The scan will still work.
-    if (setActive) {
-        return doBooleanCommand("DRIVER SCAN-ACTIVE", "OK");
-    } else {
-        return doBooleanCommand("DRIVER SCAN-PASSIVE", "OK");
-    }
+    sScanModeActive = setActive;
+    return doSetScanMode(setActive);
 }
 
 static jboolean android_net_wifi_startDriverCommand(JNIEnv* env, jobject clazz)
@@ -509,7 +513,7 @@
     { "disconnectCommand", "()Z",  (void *)android_net_wifi_disconnectCommand },
     { "reconnectCommand", "()Z",  (void *)android_net_wifi_reconnectCommand },
     { "reassociateCommand", "()Z",  (void *)android_net_wifi_reassociateCommand },
-    { "scanCommand", "()Z", (void*) android_net_wifi_scanCommand },
+    { "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },
     { "setScanModeCommand", "(Z)Z", (void*) android_net_wifi_setScanModeCommand },
     { "startDriverCommand", "()Z", (void*) android_net_wifi_startDriverCommand },
     { "stopDriverCommand", "()Z", (void*) android_net_wifi_stopDriverCommand },
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index a940af3..01394ad 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -436,7 +436,7 @@
      * see {@link android.net.wifi.WifiManager#startScan()}
      * @return {@code true} if the operation succeeds
      */
-    public boolean startScan() {
+    public boolean startScan(boolean forceActive) {
         enforceChangePermission();
         synchronized (mWifiStateTracker) {
             switch (mWifiStateTracker.getSupplicantState()) {
@@ -450,7 +450,7 @@
                             WifiStateTracker.SUPPL_SCAN_HANDLING_LIST_ONLY);
                     break;
             }
-            return WifiNative.scanCommand();
+            return WifiNative.scanCommand(forceActive);
         }
     }
 
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 3d65d3c..fa328e8 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -40,7 +40,7 @@
 
     boolean pingSupplicant();
 
-    boolean startScan();
+    boolean startScan(boolean forceActive);
 
     List<ScanResult> getScanResults();
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 7a15f27..1f73bec 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -476,9 +476,27 @@
      * on completion of the scan.
      * @return {@code true} if the operation succeeded, i.e., the scan was initiated
      */
-    public boolean  startScan() {
+    public boolean startScan() {
         try {
-            return mService.startScan();
+            return mService.startScan(false);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Request a scan for access points. Returns immediately. The availability
+     * of the results is made known later by means of an asynchronous event sent
+     * on completion of the scan.
+     * This is a variant of startScan that forces an active scan, even if passive
+     * scans are the current default
+     * @return {@code true} if the operation succeeded, i.e., the scan was initiated
+     *
+     * @hide
+     */
+    public boolean startScanActive() {
+        try {
+            return mService.startScan(true);
         } catch (RemoteException e) {
             return false;
         }
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 3851ac0..0799f5f 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -51,7 +51,7 @@
 
     public native static boolean pingCommand();
 
-    public native static boolean scanCommand();
+    public native static boolean scanCommand(boolean forceActive);
     
     public native static boolean setScanModeCommand(boolean setActive);
 
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 2fbc779..63687b3 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -1121,7 +1121,7 @@
                             } else {
                                 // In some situations, supplicant needs to be kickstarted to
                                 // start the background scanning
-                                WifiNative.scanCommand();
+                                WifiNative.scanCommand(true);
                             }
                         }
                     }