Merge "Revert "Add wake lock that is acquired during full wifi scans"" into mnc-dev
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index dde3020..652899e 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -1279,6 +1279,7 @@
             /* create a temporary SSID with providerFriendlyName */
             Long csum = getChecksum(config.FQDN);
             config.SSID = csum.toString();
+            config.enterpriseConfig.setDomainSuffixMatch(config.FQDN);
         }
 
         NetworkUpdateResult result = addOrUpdateNetworkNative(config, uid);
@@ -2332,6 +2333,9 @@
                 } else if (config != null) {
                     switch (key) {
                         case SSID_KEY:
+                            if (config.isPasspoint()) {
+                                break;
+                            }
                             ssid = value;
                             if (config.SSID != null && !config.SSID.equals(ssid)) {
                                 loge("Error parsing network history file, mismatched SSIDs");
@@ -4174,16 +4178,11 @@
         WifiConfiguration config = mConfiguredNetworks.get(netId);
         if (config != null) {
             if (enabled) {
-                loge("SSID re-enabled for  " + config.configKey() +
+                loge("Ignoring SSID re-enabled from supplicant:  " + config.configKey() +
                         " had autoJoinStatus=" + Integer.toString(config.autoJoinStatus)
                         + " self added " + config.selfAdded + " ephemeral " + config.ephemeral);
-                //TODO: http://b/16381983 Fix Wifi Network Blacklisting
-                //TODO: really I don't know if re-enabling is right but we
-                //TODO: should err on the side of trying to connect
-                //TODO: even if the attempt will fail
-                if (config.autoJoinStatus == WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE) {
-                    config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED);
-                }
+                //We should not re-enable the BSSID based on Supplicant reanable.
+                // Framework will re-enable it after its own blacklist timer expires
             } else {
                 loge("SSID temp disabled for  " + config.configKey() +
                         " had autoJoinStatus=" + Integer.toString(config.autoJoinStatus)
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 84bb38e..46058ad 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -444,7 +444,15 @@
             if (mInIdleMode) {
                 // Need to send an immediate scan result broadcast in case the
                 // caller is waiting for a result ..
-                mWifiStateMachine.sendScanResultsAvailableBroadcast(/* scanSucceeded = */ false);
+
+                // clear calling identity to send broadcast
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    mWifiStateMachine.sendScanResultsAvailableBroadcast(/* scanSucceeded = */ false);
+                } finally {
+                    // restore calling identity
+                    Binder.restoreCallingIdentity(callingIdentity);
+                }
                 mScanPending = true;
                 return;
             }
@@ -966,7 +974,7 @@
                 return new ArrayList<ScanResult>();
             }
             if (!canReadPeerMacAddresses && !isActiveNetworkScorer
-                    && !checkCallerHasLocationPermission(callingPackage, uid)) {
+                    && !checkCallerCanAccessScanResults(callingPackage, uid)) {
                 return new ArrayList<ScanResult>();
             }
             if (mAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, uid, callingPackage)
@@ -2035,7 +2043,7 @@
      * Checks that calling process has android.Manifest.permission.ACCESS_COARSE_LOCATION or
      * android.Manifest.permission.ACCESS_FINE_LOCATION and a corresponding app op is allowed
      */
-    private boolean checkCallerHasLocationPermission(String callingPackage, int uid) {
+    private boolean checkCallerCanAccessScanResults(String callingPackage, int uid) {
         if (ActivityManager.checkUidPermission(Manifest.permission.ACCESS_FINE_LOCATION, uid)
                 == PackageManager.PERMISSION_GRANTED
                 && isAppOppAllowed(AppOpsManager.OP_FINE_LOCATION, callingPackage, uid)) {
@@ -2058,10 +2066,13 @@
         if (enforceLocationPermission) {
             throw new SecurityException("Need ACCESS_COARSE_LOCATION or "
                     + "ACCESS_FINE_LOCATION permission to get scan results");
-        } else {
-            Log.e(TAG, "Permission denial: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION "
-                    + "permission to get scan results");
         }
+        // Pre-M apps running in the foreground should continue getting scan results
+        if (isForegroundApp(callingPackage)) {
+            return true;
+        }
+        Log.e(TAG, "Permission denial: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION "
+                + "permission to get scan results");
         return false;
     }
 
@@ -2069,4 +2080,15 @@
         return mAppOps.noteOp(op, uid, callingPackage) == AppOpsManager.MODE_ALLOWED;
     }
 
+    /**
+     * Return true if the specified package name is a foreground app.
+     *
+     * @param pkgName application package name.
+     */
+    private boolean isForegroundApp(String pkgName) {
+        ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
+        return !tasks.isEmpty() && pkgName.equals(tasks.get(0).topActivity.getPackageName());
+    }
+
 }
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 883f1aa..4bc62b3 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -3604,9 +3604,19 @@
     private void setFrequencyBand() {
         int band = Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.WIFI_FREQUENCY_BAND, WifiManager.WIFI_FREQUENCY_BAND_AUTO);
-        setFrequencyBand(band, false);
+
+        if (mWifiNative.setBand(band)) {
+            mFrequencyBand.set(band);
+            if (PDBG) {
+                logd("done set frequency band " + band);
+            }
+        } else {
+            loge("Failed to set frequency band " + band);
+        }
     }
 
+
+
     private void setSuspendOptimizationsNative(int reason, boolean enabled) {
         if (DBG) {
             log("setSuspendOptimizationsNative: " + reason + " " + enabled
@@ -4460,8 +4470,13 @@
         final boolean linkChanged = !newLp.equals(mLinkProperties);
         final boolean wasProvisioned = isProvisioned(mLinkProperties);
         final boolean isProvisioned = isProvisioned(newLp);
-        final boolean lostIPv4Provisioning =
-                mLinkProperties.hasIPv4Address() && !newLp.hasIPv4Address();
+        // TODO: Teach LinkProperties how to understand static assignment
+        // and simplify all this provisioning change detection logic by
+        // unifying it under LinkProperties.compareProvisioning().
+        final boolean lostProvisioning =
+                (wasProvisioned && !isProvisioned) ||
+                (mLinkProperties.hasIPv4Address() && !newLp.hasIPv4Address()) ||
+                (mLinkProperties.isIPv6Provisioned() && !newLp.isIPv6Provisioned());
         final DetailedState detailedState = getNetworkDetailedState();
 
         if (linkChanged) {
@@ -4476,6 +4491,12 @@
             if (mNetworkAgent != null) mNetworkAgent.sendLinkProperties(mLinkProperties);
         }
 
+        if (lostProvisioning) {
+            log("Lost IP layer provisioning!" +
+                    " was: " + mLinkProperties +
+                    " now: " + newLp);
+        }
+
         if (DBG) {
             StringBuilder sb = new StringBuilder();
             sb.append("updateLinkProperties nid: " + mLastNetworkId);
@@ -4532,7 +4553,7 @@
                 // DHCP failed. If we're not already provisioned, or we had IPv4 and now lost it,
                 // give up and disconnect.
                 // If we're already provisioned (e.g., IPv6-only network), stay connected.
-                if (!isProvisioned || lostIPv4Provisioning) {
+                if (!isProvisioned || lostProvisioning) {
                     sendMessage(CMD_IP_CONFIGURATION_LOST);
                 } else {
                     // DHCP failed, but we're provisioned (e.g., if we're on an IPv6-only network).
@@ -4563,7 +4584,7 @@
 
             case CMD_UPDATE_LINKPROPERTIES:
                 // IP addresses, DNS servers, etc. changed. Act accordingly.
-                if (wasProvisioned && !isProvisioned) {
+                if (lostProvisioning) {
                     // We no longer have a usable network configuration. Disconnect.
                     sendMessage(CMD_IP_CONFIGURATION_LOST);
                 } else if (!wasProvisioned && isProvisioned) {
@@ -5754,6 +5775,8 @@
                     mLastSignalLevel = -1;
 
                     mWifiInfo.setMacAddress(mWifiNative.getMacAddress());
+                    /* set frequency band of operation */
+                    setFrequencyBand();
                     mWifiNative.enableSaveConfig();
                     mWifiConfigStore.loadAndEnableAllNetworks();
                     if (mWifiConfigStore.enableVerboseLogging.get() > 0) {
@@ -6092,8 +6115,6 @@
              * driver are changed to reduce interference with bluetooth
              */
             mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
-            /* set frequency band of operation */
-            setFrequencyBand();
             /* initialize network state */
             setNetworkDetailedState(DetailedState.DISCONNECTED);
 
diff --git a/service/java/com/android/server/wifi/anqp/IPAddressTypeAvailabilityElement.java b/service/java/com/android/server/wifi/anqp/IPAddressTypeAvailabilityElement.java
index 26ed721..8d71a3b 100644
--- a/service/java/com/android/server/wifi/anqp/IPAddressTypeAvailabilityElement.java
+++ b/service/java/com/android/server/wifi/anqp/IPAddressTypeAvailabilityElement.java
@@ -29,7 +29,7 @@
         mV6Availability = IPv6Availability.values()[ipField & 0x3];
 
         ipField = (ipField >> 2) & 0x3f;
-        mV4Availability = ipField <= IPv4Availability.values().length ?
+        mV4Availability = ipField < IPv4Availability.values().length ?
                 IPv4Availability.values()[ipField] :
                 IPv4Availability.Unknown;
     }
diff --git a/service/java/com/android/server/wifi/configparse/ConfigBuilder.java b/service/java/com/android/server/wifi/configparse/ConfigBuilder.java
index d9259a3..e8e5e6a 100644
--- a/service/java/com/android/server/wifi/configparse/ConfigBuilder.java
+++ b/service/java/com/android/server/wifi/configparse/ConfigBuilder.java
@@ -203,7 +203,6 @@
         enterpriseConfig.setCaCertificate(caCert);
         enterpriseConfig.setAnonymousIdentity("anonymous@" + credential.getRealm());
         enterpriseConfig.setRealm(credential.getRealm());
-        enterpriseConfig.setDomainSuffixMatch(homeSP.getFQDN());
 
         return config;
     }