Merge "WifiStateMachinePrime: update interface management"
diff --git a/service/java/com/android/server/wifi/SavedNetworkEvaluator.java b/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
index 59d4ab2..97f6b6f 100644
--- a/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
+++ b/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
@@ -25,8 +25,6 @@
 import com.android.internal.R;
 import com.android.server.wifi.util.TelephonyUtil;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -242,96 +240,83 @@
 
         for (ScanDetail scanDetail : scanDetails) {
             ScanResult scanResult = scanDetail.getScanResult();
-            int highestScoreOfScanResult = Integer.MIN_VALUE;
-            int candidateIdOfScanResult = WifiConfiguration.INVALID_NETWORK_ID;
 
             // One ScanResult can be associated with more than one networks, hence we calculate all
             // the scores and use the highest one as the ScanResult's score.
-            List<WifiConfiguration> associatedConfigurations = null;
-            WifiConfiguration associatedConfiguration =
+            WifiConfiguration network =
                     mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail);
 
-            if (associatedConfiguration == null) {
+            if (network == null) {
                 continue;
-            } else {
-                associatedConfigurations =
-                    new ArrayList<>(Arrays.asList(associatedConfiguration));
             }
 
-            for (WifiConfiguration network : associatedConfigurations) {
-                /**
-                 * Ignore Passpoint and Ephemeral networks. They are configured networks,
-                 * but without being persisted to the storage. They are evaluated by
-                 * {@link PasspointNetworkEvaluator} and {@link ScoredNetworkEvaluator}
-                 * respectively.
-                 */
-                if (network.isPasspoint() || network.isEphemeral()) {
-                    continue;
-                }
+            /**
+             * Ignore Passpoint and Ephemeral networks. They are configured networks,
+             * but without being persisted to the storage. They are evaluated by
+             * {@link PasspointNetworkEvaluator} and {@link ScoredNetworkEvaluator}
+             * respectively.
+             */
+            if (network.isPasspoint() || network.isEphemeral()) {
+                continue;
+            }
 
-                WifiConfiguration.NetworkSelectionStatus status =
-                        network.getNetworkSelectionStatus();
-                status.setSeenInLastQualifiedNetworkSelection(true);
+            WifiConfiguration.NetworkSelectionStatus status =
+                    network.getNetworkSelectionStatus();
+            status.setSeenInLastQualifiedNetworkSelection(true);
 
-                if (!status.isNetworkEnabled()) {
-                    continue;
-                } else if (network.BSSID != null &&  !network.BSSID.equals("any")
-                        && !network.BSSID.equals(scanResult.BSSID)) {
-                    // App has specified the only BSSID to connect for this
-                    // configuration. So only the matching ScanResult can be a candidate.
-                    localLog("Network " + WifiNetworkSelector.toNetworkString(network)
-                            + " has specified BSSID " + network.BSSID + ". Skip "
-                            + scanResult.BSSID);
-                    continue;
-                } else if (TelephonyUtil.isSimConfig(network)
-                        && !mWifiConfigManager.isSimPresent()) {
-                    // Don't select if security type is EAP SIM/AKA/AKA' when SIM is not present.
-                    continue;
-                }
+            if (!status.isNetworkEnabled()) {
+                continue;
+            } else if (network.BSSID != null &&  !network.BSSID.equals("any")
+                    && !network.BSSID.equals(scanResult.BSSID)) {
+                // App has specified the only BSSID to connect for this
+                // configuration. So only the matching ScanResult can be a candidate.
+                localLog("Network " + WifiNetworkSelector.toNetworkString(network)
+                        + " has specified BSSID " + network.BSSID + ". Skip "
+                        + scanResult.BSSID);
+                continue;
+            } else if (TelephonyUtil.isSimConfig(network)
+                    && !mWifiConfigManager.isSimPresent()) {
+                // Don't select if security type is EAP SIM/AKA/AKA' when SIM is not present.
+                continue;
+            }
 
-                int score = calculateBssidScore(scanResult, network, currentNetwork, currentBssid,
-                        scoreHistory);
+            int score = calculateBssidScore(scanResult, network, currentNetwork, currentBssid,
+                    scoreHistory);
 
-                // Set candidate ScanResult for all saved networks to ensure that users can
-                // override network selection. See WifiNetworkSelector#setUserConnectChoice.
-                // TODO(b/36067705): consider alternative designs to push filtering/selecting of
-                // user connect choice networks to RecommendedNetworkEvaluator.
-                if (score > status.getCandidateScore() || (score == status.getCandidateScore()
-                        && status.getCandidate() != null
-                        && scanResult.level > status.getCandidate().level)) {
-                    mWifiConfigManager.setNetworkCandidateScanResult(
-                            network.networkId, scanResult, score);
-                }
+            // Set candidate ScanResult for all saved networks to ensure that users can
+            // override network selection. See WifiNetworkSelector#setUserConnectChoice.
+            // TODO(b/36067705): consider alternative designs to push filtering/selecting of
+            // user connect choice networks to RecommendedNetworkEvaluator.
+            if (score > status.getCandidateScore() || (score == status.getCandidateScore()
+                    && status.getCandidate() != null
+                    && scanResult.level > status.getCandidate().level)) {
+                mWifiConfigManager.setNetworkCandidateScanResult(
+                        network.networkId, scanResult, score);
+            }
 
-                // If the network is marked to use external scores, or is an open network with
-                // curate saved open networks enabled, do not consider it for network selection.
-                if (network.useExternalScores) {
-                    localLog("Network " + WifiNetworkSelector.toNetworkString(network)
-                            + " has external score.");
-                    continue;
-                }
-
-                if (score > highestScoreOfScanResult) {
-                    highestScoreOfScanResult = score;
-                    candidateIdOfScanResult = network.networkId;
-                }
+            // If the network is marked to use external scores, or is an open network with
+            // curate saved open networks enabled, do not consider it for network selection.
+            if (network.useExternalScores) {
+                localLog("Network " + WifiNetworkSelector.toNetworkString(network)
+                        + " has external score.");
+                continue;
             }
 
             if (connectableNetworks != null) {
                 connectableNetworks.add(Pair.create(scanDetail,
-                        mWifiConfigManager.getConfiguredNetwork(candidateIdOfScanResult)));
+                        mWifiConfigManager.getConfiguredNetwork(network.networkId)));
             }
 
-            if (highestScoreOfScanResult > highestScore
-                    || (highestScoreOfScanResult == highestScore
+            if (score > highestScore
+                    || (score == highestScore
                     && scanResultCandidate != null
                     && scanResult.level > scanResultCandidate.level)) {
-                highestScore = highestScoreOfScanResult;
+                highestScore = score;
                 scanResultCandidate = scanResult;
                 mWifiConfigManager.setNetworkCandidateScanResult(
-                        candidateIdOfScanResult, scanResultCandidate, highestScore);
+                        network.networkId, scanResultCandidate, highestScore);
                 // Reload the network config with the updated info.
-                candidate = mWifiConfigManager.getConfiguredNetwork(candidateIdOfScanResult);
+                candidate = mWifiConfigManager.getConfiguredNetwork(network.networkId);
             }
         }
 
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 429e3c3..b79c901 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -106,8 +106,6 @@
                          WifiApConfigStore wifiApConfigStore,
                          @NonNull SoftApModeConfiguration apConfig,
                          WifiMetrics wifiMetrics) {
-        mStateMachine = new SoftApStateMachine(looper);
-
         mContext = context;
         mWifiNative = wifiNative;
         mCountryCode = countryCode;
@@ -124,6 +122,7 @@
             mApConfig = config;
         }
         mWifiMetrics = wifiMetrics;
+        mStateMachine = new SoftApStateMachine(looper);
     }
 
     /**
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index f6770a5..0ed5b35 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -380,7 +380,7 @@
                                            @NonNull IApInterface apInterface,
                                            @NonNull String ifaceName,
                                            @NonNull SoftApModeConfiguration config) {
-        return new SoftApManager(mContext, mWifiServiceHandlerThread.getLooper(),
+        return new SoftApManager(mContext, mWifiStateMachineHandlerThread.getLooper(),
                                  mWifiNative, mCountryCode.getCountryCode(),
                                  listener, apInterface, ifaceName, nmService,
                                  mWifiApConfigStore, config, mWifiMetrics);
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 2f1b550..3118761 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -152,6 +152,105 @@
         }
     }
 
+    /**
+     * TODO(b/69426063): NEW API Surface for interface management. This will eventually
+     * deprecate the other interface management API's above. But, for now there will be
+     * some duplication to ease transition.
+     */
+    /**
+     * Initialize the native modules.
+     *
+     * @return true on success, false otherwise.
+     */
+    public boolean initialize() {
+        return false;
+    }
+
+    /**
+     * Callback to notify when the status of one of the native daemons
+     * (wificond, wpa_supplicant & vendor HAL) changes.
+     */
+    public interface StatusListener {
+        /**
+         * @param allReady Indicates if all the native daemons are ready for operation or not.
+         */
+        void onStatusChanged(boolean allReady);
+    }
+
+    /**
+     * Register a StatusListener to get notified about any status changes from the native daemons.
+     *
+     * It is safe to re-register the same callback object - duplicates are detected and only a
+     * single copy kept.
+     *
+     * @param listener StatusListener listener object.
+     */
+    public void registerStatusListener(@NonNull StatusListener listener) {
+    }
+
+    /**
+     * Callback to notify when the associated interface is destroyed, up or down.
+     */
+    public interface InterfaceCallback {
+        /**
+         * Interface destroyed by HalDeviceManager.
+         *
+         * @param ifaceName Name of the iface.
+         */
+        void onDestroyed(String ifaceName);
+
+        /**
+         * Interface is up.
+         *
+         * @param ifaceName Name of the iface.
+         */
+        void onUp(String ifaceName);
+
+        /**
+         * Interface is down.
+         *
+         * @param ifaceName Name of the iface.
+         */
+        void onDown(String ifaceName);
+    }
+
+    /**
+     * Setup an interface for Client mode operations.
+     *
+     * This method configures an interface in STA mode in all the native daemons
+     * (wificond, wpa_supplicant & vendor HAL).
+     *
+     * @param interfaceCallback Associated callback for notifying status changes for the iface.
+     * @return Returns the name of the allocated interface, will be null on failure.
+     */
+    public String setupInterfaceForClientMode(@NonNull InterfaceCallback interfaceCallback) {
+        return null;
+    }
+
+    /**
+     * Setup an interface for Soft AP mode operations.
+     *
+     * This method configures an interface in AP mode in all the native daemons
+     * (wificond, wpa_supplicant & vendor HAL).
+     *
+     * @param interfaceCallback Associated callback for notifying status changes for the iface.
+     * @return Returns the name of the allocated interface, will be null on failure.
+     */
+    public String setupInterfaceForSoftApMode(@NonNull InterfaceCallback interfaceCallback) {
+        return null;
+    }
+
+    /**
+     * Teardown an interface in Client/AP mode.
+     *
+     * This method tears down the associated interface from all the native daemons
+     * (wificond, wpa_supplicant & vendor HAL).
+     *
+     * @param ifaceName Name of the interface.
+     */
+    public void teardownInterface(@NonNull String ifaceName) {
+    }
+
     /********************************************************
      * Wificond operations
      ********************************************************/
diff --git a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
index 72a7a27..9afe061 100644
--- a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
@@ -35,7 +35,6 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -66,28 +65,16 @@
 
     private final Object mSettingsLock = new Object();
 
-    // Next scan settings to apply when the previous scan completes
-    private WifiNative.ScanSettings mPendingSingleScanSettings = null;
-    private WifiNative.ScanEventHandler mPendingSingleScanEventHandler = null;
-
     private ArrayList<ScanDetail> mNativeScanResults;
     private WifiScanner.ScanData mLatestSingleScanResult =
             new WifiScanner.ScanData(0, 0, new ScanResult[0]);
 
-    // Settings for the currently running scan, null if no scan active
+    // Settings for the currently running single scan, null if no scan active
     private LastScanSettings mLastScanSettings = null;
+    // Settings for the currently running pno scan, null if no scan active
+    private LastPnoScanSettings mLastPnoScanSettings = null;
 
-    // Pno related info.
-    private WifiNative.PnoSettings mPnoSettings = null;
-    private WifiNative.PnoEventHandler mPnoEventHandler;
     private final boolean mHwPnoScanSupported;
-    private final HwPnoDebouncer mHwPnoDebouncer;
-    private final HwPnoDebouncer.Listener mHwPnoDebouncerListener = new HwPnoDebouncer.Listener() {
-        public void onPnoScanFailed() {
-            Log.e(TAG, "Pno scan failure received");
-            reportPnoScanFailure();
-        }
-    };
 
     /**
      * Duration to wait before timing out a scan.
@@ -114,7 +101,6 @@
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         mEventHandler = new Handler(looper, this);
         mClock = clock;
-        mHwPnoDebouncer = new HwPnoDebouncer(mWifiNative, mAlarmManager, mEventHandler, mClock);
 
         // Check if the device supports HW PNO scans.
         mHwPnoScanSupported = mContext.getResources().getBoolean(
@@ -131,10 +117,9 @@
     @Override
     public void cleanup() {
         synchronized (mSettingsLock) {
-            mPendingSingleScanSettings = null;
-            mPendingSingleScanEventHandler = null;
             stopHwPnoScan();
             mLastScanSettings = null; // finally clear any active scan
+            mLastPnoScanSettings = null; // finally clear any active scan
         }
     }
 
@@ -162,14 +147,65 @@
             return false;
         }
         synchronized (mSettingsLock) {
-            if (mPendingSingleScanSettings != null
-                    || (mLastScanSettings != null && mLastScanSettings.singleScanActive)) {
+            if (mLastScanSettings != null) {
                 Log.w(TAG, "A single scan is already running");
                 return false;
             }
-            mPendingSingleScanSettings = settings;
-            mPendingSingleScanEventHandler = eventHandler;
-            processPendingScans();
+
+            ChannelCollection allFreqs = mChannelHelper.createChannelCollection();
+            boolean reportFullResults = false;
+
+            for (int i = 0; i < settings.num_buckets; ++i) {
+                WifiNative.BucketSettings bucketSettings = settings.buckets[i];
+                if ((bucketSettings.report_events
+                                & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0) {
+                    reportFullResults = true;
+                }
+                allFreqs.addChannels(bucketSettings);
+            }
+
+            Set<String> hiddenNetworkSSIDSet = new HashSet<>();
+            if (settings.hiddenNetworks != null) {
+                int numHiddenNetworks =
+                        Math.min(settings.hiddenNetworks.length, MAX_HIDDEN_NETWORK_IDS_PER_SCAN);
+                for (int i = 0; i < numHiddenNetworks; i++) {
+                    hiddenNetworkSSIDSet.add(settings.hiddenNetworks[i].ssid);
+                }
+            }
+            mLastScanSettings = new LastScanSettings(
+                        mClock.getElapsedSinceBootMillis(),
+                        reportFullResults, allFreqs, eventHandler);
+
+            boolean success = false;
+            Set<Integer> freqs;
+            if (!allFreqs.isEmpty()) {
+                freqs = allFreqs.getScanFreqs();
+                success = mWifiNative.scan(freqs, hiddenNetworkSSIDSet);
+                if (!success) {
+                    Log.e(TAG, "Failed to start scan, freqs=" + freqs);
+                }
+            } else {
+                // There is a scan request but no available channels could be scanned for.
+                // We regard it as a scan failure in this case.
+                Log.e(TAG, "Failed to start scan because there is no available channel to scan");
+            }
+            if (success) {
+                if (DBG) {
+                    Log.d(TAG, "Starting wifi scan for freqs=" + freqs);
+                }
+
+                mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                        mClock.getElapsedSinceBootMillis() + SCAN_TIMEOUT_MS,
+                        TIMEOUT_ALARM_TAG, mScanTimeoutListener, mEventHandler);
+            } else {
+                // indicate scan failure async
+                mEventHandler.post(new Runnable() {
+                        public void run() {
+                            reportScanFailure();
+                        }
+                    });
+            }
+
             return true;
         }
     }
@@ -204,123 +240,6 @@
     private void handleScanTimeout() {
         Log.e(TAG, "Timed out waiting for scan result from wificond");
         reportScanFailure();
-        processPendingScans();
-    }
-
-    private boolean isDifferentPnoScanSettings(LastScanSettings newScanSettings) {
-        return (mLastScanSettings == null || !Arrays.equals(
-                newScanSettings.pnoNetworkList, mLastScanSettings.pnoNetworkList));
-    }
-
-    private void processPendingScans() {
-        synchronized (mSettingsLock) {
-            // Wait for the active scan result to come back to reschedule other scans,
-            // unless if HW pno scan is running. Hw PNO scans are paused it if there
-            // are other pending scans,
-            if (mLastScanSettings != null && !mLastScanSettings.hwPnoScanActive) {
-                return;
-            }
-
-            ChannelCollection allFreqs = mChannelHelper.createChannelCollection();
-            Set<String> hiddenNetworkSSIDSet = new HashSet<>();
-            final LastScanSettings newScanSettings =
-                    new LastScanSettings(mClock.getElapsedSinceBootMillis());
-
-            if (mPendingSingleScanSettings != null) {
-                boolean reportFullResults = false;
-                ChannelCollection singleScanFreqs = mChannelHelper.createChannelCollection();
-                for (int i = 0; i < mPendingSingleScanSettings.num_buckets; ++i) {
-                    WifiNative.BucketSettings bucketSettings =
-                            mPendingSingleScanSettings.buckets[i];
-                    if ((bucketSettings.report_events
-                                    & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0) {
-                        reportFullResults = true;
-                    }
-                    singleScanFreqs.addChannels(bucketSettings);
-                    allFreqs.addChannels(bucketSettings);
-                }
-                newScanSettings.setSingleScan(reportFullResults, singleScanFreqs,
-                        mPendingSingleScanEventHandler);
-
-                WifiNative.HiddenNetwork[] hiddenNetworks =
-                        mPendingSingleScanSettings.hiddenNetworks;
-                if (hiddenNetworks != null) {
-                    int numHiddenNetworks =
-                            Math.min(hiddenNetworks.length, MAX_HIDDEN_NETWORK_IDS_PER_SCAN);
-                    for (int i = 0; i < numHiddenNetworks; i++) {
-                        hiddenNetworkSSIDSet.add(hiddenNetworks[i].ssid);
-                    }
-                }
-
-                mPendingSingleScanSettings = null;
-                mPendingSingleScanEventHandler = null;
-            }
-
-            if (newScanSettings.singleScanActive) {
-                boolean success = false;
-                Set<Integer> freqs;
-                if (!allFreqs.isEmpty()) {
-                    pauseHwPnoScan();
-                    freqs = allFreqs.getScanFreqs();
-                    success = mWifiNative.scan(freqs, hiddenNetworkSSIDSet);
-                    if (!success) {
-                        Log.e(TAG, "Failed to start scan, freqs=" + freqs);
-                    }
-                } else {
-                    // There is a scan request but no available channels could be scanned for.
-                    // We regard it as a scan failure in this case.
-                    Log.e(TAG, "Failed to start scan because there is "
-                            + "no available channel to scan for");
-                }
-                if (success) {
-                    // TODO handle scan timeout
-                    if (DBG) {
-                        Log.d(TAG, "Starting wifi scan for freqs=" + freqs
-                                + ", single=" + newScanSettings.singleScanActive);
-                    }
-                    mLastScanSettings = newScanSettings;
-                    mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                            mClock.getElapsedSinceBootMillis() + SCAN_TIMEOUT_MS,
-                            TIMEOUT_ALARM_TAG, mScanTimeoutListener, mEventHandler);
-                } else {
-                    // indicate scan failure async
-                    mEventHandler.post(new Runnable() {
-                            public void run() {
-                                if (newScanSettings.singleScanEventHandler != null) {
-                                    newScanSettings.singleScanEventHandler
-                                            .onScanStatus(WifiNative.WIFI_SCAN_FAILED);
-                                }
-                            }
-                        });
-                }
-            } else if (isHwPnoScanRequired()) {
-                newScanSettings.setHwPnoScan(mPnoSettings.networkList, mPnoEventHandler);
-                boolean status;
-                // If the PNO network list has changed from the previous request, ensure that
-                // we bypass the debounce logic and restart PNO scan.
-                if (isDifferentPnoScanSettings(newScanSettings)) {
-                    status = restartHwPnoScan(mPnoSettings);
-                } else {
-                    status = startHwPnoScan(mPnoSettings);
-                }
-                if (status) {
-                    mLastScanSettings = newScanSettings;
-                } else {
-                    Log.e(TAG, "Failed to start PNO scan");
-                    // indicate scan failure async
-                    mEventHandler.post(new Runnable() {
-                        public void run() {
-                            if (mPnoEventHandler != null) {
-                                mPnoEventHandler.onPnoScanFailed();
-                            }
-                            // Clean up PNO state, we don't want to continue PNO scanning.
-                            mPnoSettings = null;
-                            mPnoEventHandler = null;
-                        }
-                    });
-                }
-            }
-        }
     }
 
     @Override
@@ -330,16 +249,13 @@
                 Log.w(TAG, "Scan failed");
                 mAlarmManager.cancel(mScanTimeoutListener);
                 reportScanFailure();
-                processPendingScans();
                 break;
             case WifiMonitor.PNO_SCAN_RESULTS_EVENT:
                 pollLatestScanDataForPno();
-                processPendingScans();
                 break;
             case WifiMonitor.SCAN_RESULTS_EVENT:
                 mAlarmManager.cancel(mScanTimeoutListener);
                 pollLatestScanData();
-                processPendingScans();
                 break;
             default:
                 // ignore unknown event
@@ -361,21 +277,19 @@
 
     private void reportPnoScanFailure() {
         synchronized (mSettingsLock) {
-            if (mLastScanSettings != null && mLastScanSettings.hwPnoScanActive) {
-                if (mLastScanSettings.pnoScanEventHandler != null) {
-                    mLastScanSettings.pnoScanEventHandler.onPnoScanFailed();
+            if (mLastPnoScanSettings != null) {
+                if (mLastPnoScanSettings.pnoScanEventHandler != null) {
+                    mLastPnoScanSettings.pnoScanEventHandler.onPnoScanFailed();
                 }
                 // Clean up PNO state, we don't want to continue PNO scanning.
-                mPnoSettings = null;
-                mPnoEventHandler = null;
-                mLastScanSettings = null;
+                mLastPnoScanSettings = null;
             }
         }
     }
 
     private void pollLatestScanDataForPno() {
         synchronized (mSettingsLock) {
-            if (mLastScanSettings == null) {
+            if (mLastPnoScanSettings == null) {
                  // got a scan before we started scanning or after scan was canceled
                 return;
             }
@@ -385,10 +299,8 @@
             for (int i = 0; i < mNativeScanResults.size(); ++i) {
                 ScanResult result = mNativeScanResults.get(i).getScanResult();
                 long timestamp_ms = result.timestamp / 1000; // convert us -> ms
-                if (timestamp_ms > mLastScanSettings.startTime) {
-                    if (mLastScanSettings.hwPnoScanActive) {
-                        hwPnoScanResults.add(result);
-                    }
+                if (timestamp_ms > mLastPnoScanSettings.startTime) {
+                    hwPnoScanResults.add(result);
                 } else {
                     numFilteredScanResults++;
                 }
@@ -398,25 +310,11 @@
                 Log.d(TAG, "Filtering out " + numFilteredScanResults + " pno scan results.");
             }
 
-            if (mLastScanSettings.hwPnoScanActive
-                    && mLastScanSettings.pnoScanEventHandler != null) {
+            if (mLastPnoScanSettings.pnoScanEventHandler != null) {
                 ScanResult[] pnoScanResultsArray =
                         hwPnoScanResults.toArray(new ScanResult[hwPnoScanResults.size()]);
-                mLastScanSettings.pnoScanEventHandler.onPnoNetworkFound(pnoScanResultsArray);
+                mLastPnoScanSettings.pnoScanEventHandler.onPnoNetworkFound(pnoScanResultsArray);
             }
-            // On pno scan result event, we are expecting a mLastScanSettings for pno scan.
-            // However, if unlikey mLastScanSettings is for single scan, we need this part
-            // to protect from leaving WifiSingleScanStateMachine in a forever wait state.
-            if (mLastScanSettings.singleScanActive
-                    && mLastScanSettings.singleScanEventHandler != null) {
-                Log.w(TAG, "Polling pno scan result when single scan is active, reporting"
-                        + " single scan failure");
-                mLastScanSettings.singleScanEventHandler
-                        .onScanStatus(WifiNative.WIFI_SCAN_FAILED);
-            }
-            // mLastScanSettings is for either single/batched scan or pno scan.
-            // We can safely set it to null when pno scan finishes.
-            mLastScanSettings = null;
         }
     }
 
@@ -445,8 +343,7 @@
                 ScanResult result = mNativeScanResults.get(i).getScanResult();
                 long timestamp_ms = result.timestamp / 1000; // convert us -> ms
                 if (timestamp_ms > mLastScanSettings.startTime) {
-                    if (mLastScanSettings.singleScanActive
-                            && mLastScanSettings.singleScanFreqs.containsChannel(
+                    if (mLastScanSettings.singleScanFreqs.containsChannel(
                                     result.frequency)) {
                         singleScanResults.add(result);
                     }
@@ -458,8 +355,7 @@
                 Log.d(TAG, "Filtering out " + numFilteredScanResults + " scan results.");
             }
 
-            if (mLastScanSettings.singleScanActive
-                    && mLastScanSettings.singleScanEventHandler != null) {
+            if (mLastScanSettings.singleScanEventHandler != null) {
                 if (mLastScanSettings.reportSingleScanFullResults) {
                     for (ScanResult scanResult : singleScanResults) {
                         // ignore buckets scanned since there is only one bucket for a single scan
@@ -486,20 +382,11 @@
     }
 
     private boolean startHwPnoScan(WifiNative.PnoSettings pnoSettings) {
-        return mHwPnoDebouncer.startPnoScan(pnoSettings, mHwPnoDebouncerListener);
+        return mWifiNative.startPnoScan(pnoSettings);
     }
 
     private void stopHwPnoScan() {
-        mHwPnoDebouncer.stopPnoScan();
-    }
-
-    private void pauseHwPnoScan() {
-        mHwPnoDebouncer.forceStopPnoScan();
-    }
-
-    private boolean restartHwPnoScan(WifiNative.PnoSettings pnoSettings) {
-        mHwPnoDebouncer.forceStopPnoScan();
-        return mHwPnoDebouncer.startPnoScan(pnoSettings, mHwPnoDebouncerListener);
+        mWifiNative.stopPnoScan();
     }
 
     /**
@@ -511,26 +398,27 @@
         return (!isConnectedPno & mHwPnoScanSupported);
     }
 
-    private boolean isHwPnoScanRequired() {
-        synchronized (mSettingsLock) {
-            if (mPnoSettings == null) return false;
-            return isHwPnoScanRequired(mPnoSettings.isConnected);
-        }
-    }
-
     @Override
     public boolean setHwPnoList(WifiNative.PnoSettings settings,
             WifiNative.PnoEventHandler eventHandler) {
         synchronized (mSettingsLock) {
-            if (mPnoSettings != null) {
+            if (mLastPnoScanSettings != null) {
                 Log.w(TAG, "Already running a PNO scan");
                 return false;
             }
-            mPnoEventHandler = eventHandler;
-            mPnoSettings = settings;
+            if (!isHwPnoScanRequired(settings.isConnected)) {
+                return false;
+            }
 
-            // For wificond based PNO, we start the scan immediately when we set pno list.
-            processPendingScans();
+            if (startHwPnoScan(settings)) {
+                mLastPnoScanSettings = new LastPnoScanSettings(
+                            mClock.getElapsedSinceBootMillis(),
+                            settings.networkList, eventHandler);
+
+            } else {
+                Log.e(TAG, "Failed to start PNO scan");
+                reportPnoScanFailure();
+            }
             return true;
         }
     }
@@ -538,12 +426,11 @@
     @Override
     public boolean resetHwPnoList() {
         synchronized (mSettingsLock) {
-            if (mPnoSettings == null) {
+            if (mLastPnoScanSettings == null) {
                 Log.w(TAG, "No PNO scan running");
                 return false;
             }
-            mPnoEventHandler = null;
-            mPnoSettings = null;
+            mLastPnoScanSettings = null;
             // For wificond based PNO, we stop the scan immediately when we reset pno list.
             stopHwPnoScan();
             return true;
@@ -591,204 +478,36 @@
     }
 
     private static class LastScanSettings {
-        public long startTime;
-
-        LastScanSettings(long startTime) {
-            this.startTime = startTime;
-        }
-
-        // Single scan settings
-        public boolean singleScanActive = false;
-        public boolean reportSingleScanFullResults;
-        public ChannelCollection singleScanFreqs;
-        public WifiNative.ScanEventHandler singleScanEventHandler;
-
-        public void setSingleScan(boolean reportSingleScanFullResults,
+        LastScanSettings(long startTime,
+                boolean reportSingleScanFullResults,
                 ChannelCollection singleScanFreqs,
                 WifiNative.ScanEventHandler singleScanEventHandler) {
-            singleScanActive = true;
+            this.startTime = startTime;
             this.reportSingleScanFullResults = reportSingleScanFullResults;
             this.singleScanFreqs = singleScanFreqs;
             this.singleScanEventHandler = singleScanEventHandler;
         }
 
-        public boolean hwPnoScanActive = false;
-        public WifiNative.PnoNetwork[] pnoNetworkList;
-        public WifiNative.PnoEventHandler pnoScanEventHandler;
+        public long startTime;
+        public boolean reportSingleScanFullResults;
+        public ChannelCollection singleScanFreqs;
+        public WifiNative.ScanEventHandler singleScanEventHandler;
 
-        public void setHwPnoScan(
+    }
+
+    private static class LastPnoScanSettings {
+        LastPnoScanSettings(long startTime,
                 WifiNative.PnoNetwork[] pnoNetworkList,
                 WifiNative.PnoEventHandler pnoScanEventHandler) {
-            hwPnoScanActive = true;
+            this.startTime = startTime;
             this.pnoNetworkList = pnoNetworkList;
             this.pnoScanEventHandler = pnoScanEventHandler;
         }
+
+        public long startTime;
+        public WifiNative.PnoNetwork[] pnoNetworkList;
+        public WifiNative.PnoEventHandler pnoScanEventHandler;
+
     }
 
-    /**
-     * HW PNO Debouncer is used to debounce PNO requests. This guards against toggling the PNO
-     * state too often which is not handled very well by some drivers.
-     * Note: This is not thread safe!
-     */
-    public static class HwPnoDebouncer {
-        public static final String PNO_DEBOUNCER_ALARM_TAG = TAG + "Pno Monitor";
-        private static final int MINIMUM_PNO_GAP_MS = 5 * 1000;
-
-        private final WifiNative mWifiNative;
-        private final AlarmManager mAlarmManager;
-        private final Handler mEventHandler;
-        private final Clock mClock;
-        private long mLastPnoChangeTimeStamp = -1L;
-        private boolean mExpectedPnoState = false;
-        private boolean mCurrentPnoState = false;;
-        private boolean mWaitForTimer = false;
-        private Listener mListener;
-        private WifiNative.PnoSettings mPnoSettings;
-
-        /**
-         * Interface used to indicate PNO scan notifications.
-         */
-        public interface Listener {
-            /**
-             * Used to indicate a delayed PNO scan request failure.
-             */
-            void onPnoScanFailed();
-        }
-
-        public HwPnoDebouncer(WifiNative wifiNative, AlarmManager alarmManager,
-                Handler eventHandler, Clock clock) {
-            mWifiNative = wifiNative;
-            mAlarmManager = alarmManager;
-            mEventHandler = eventHandler;
-            mClock = clock;
-        }
-
-        /**
-         * Enable PNO state in wificond
-         */
-        private boolean startPnoScanInternal() {
-            if (mCurrentPnoState) {
-                if (DBG) Log.d(TAG, "PNO state is already enable");
-                return true;
-            }
-            if (mPnoSettings == null) {
-                Log.e(TAG, "PNO state change to enable failed, no available Pno settings");
-                return false;
-            }
-            mLastPnoChangeTimeStamp = mClock.getElapsedSinceBootMillis();
-            Log.d(TAG, "Remove all networks from supplicant before starting PNO scan");
-            mWifiNative.removeAllNetworks();
-            if (mWifiNative.startPnoScan(mPnoSettings)) {
-                Log.d(TAG, "Changed PNO state from " + mCurrentPnoState + " to enable");
-                mCurrentPnoState = true;
-                return true;
-            } else {
-                Log.e(TAG, "PNO state change to enable failed");
-                mCurrentPnoState = false;
-            }
-            return false;
-        }
-
-        /**
-         * Disable PNO state in wificond
-         */
-        private boolean stopPnoScanInternal() {
-            if (!mCurrentPnoState) {
-                if (DBG) Log.d(TAG, "PNO state is already disable");
-                return true;
-            }
-            mLastPnoChangeTimeStamp = mClock.getElapsedSinceBootMillis();
-            if (mWifiNative.stopPnoScan()) {
-                Log.d(TAG, "Changed PNO state from " + mCurrentPnoState + " to disable");
-                mCurrentPnoState = false;
-                return true;
-            } else {
-                Log.e(TAG, "PNO state change to disable failed");
-                mCurrentPnoState = false;
-            }
-            return false;
-        }
-
-        private final AlarmManager.OnAlarmListener mAlarmListener =
-                new AlarmManager.OnAlarmListener() {
-            public void onAlarm() {
-                if (DBG) Log.d(TAG, "PNO timer expired, expected state " + mExpectedPnoState);
-                if (mExpectedPnoState) {
-                    if (!startPnoScanInternal()) {
-                        if (mListener != null) {
-                            mListener.onPnoScanFailed();
-                        }
-                    }
-                } else {
-                    stopPnoScanInternal();
-                }
-                mWaitForTimer = false;
-            }
-        };
-
-        /**
-         * Enable/Disable PNO state. This method will debounce PNO scan requests.
-         * @param enable boolean indicating whether PNO is being enabled or disabled.
-         */
-        private boolean setPnoState(boolean enable) {
-            boolean isSuccess = true;
-            mExpectedPnoState = enable;
-            if (!mWaitForTimer) {
-                long timeDifference = mClock.getElapsedSinceBootMillis() - mLastPnoChangeTimeStamp;
-                if (timeDifference >= MINIMUM_PNO_GAP_MS) {
-                    if (enable) {
-                        isSuccess = startPnoScanInternal();
-                    } else {
-                        isSuccess = stopPnoScanInternal();
-                    }
-                } else {
-                    long alarmTimeout = MINIMUM_PNO_GAP_MS - timeDifference;
-                    Log.d(TAG, "Start PNO timer with delay " + alarmTimeout);
-                    mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                            mClock.getElapsedSinceBootMillis() + alarmTimeout,
-                            PNO_DEBOUNCER_ALARM_TAG,
-                            mAlarmListener, mEventHandler);
-                    mWaitForTimer = true;
-                }
-            }
-            return isSuccess;
-        }
-
-        /**
-         * Start PNO scan
-         */
-        public boolean startPnoScan(WifiNative.PnoSettings pnoSettings, Listener listener) {
-            if (DBG) Log.d(TAG, "Starting PNO scan");
-            mListener = listener;
-            mPnoSettings = pnoSettings;
-            if (!setPnoState(true)) {
-                mListener = null;
-                return false;
-            }
-            return true;
-        }
-
-        /**
-         * Stop PNO scan
-         */
-        public void stopPnoScan() {
-            if (DBG) Log.d(TAG, "Stopping PNO scan");
-            setPnoState(false);
-            mListener = null;
-        }
-
-        /**
-         * Force stop PNO scanning. This method will bypass the debounce logic and stop PNO
-         * scan immediately.
-         */
-        public void forceStopPnoScan() {
-            if (DBG) Log.d(TAG, "Force stopping Pno scan");
-            // Cancel the debounce timer and stop PNO scan.
-            if (mWaitForTimer) {
-                mAlarmManager.cancel(mAlarmListener);
-                mWaitForTimer = false;
-            }
-            stopPnoScanInternal();
-        }
-    }
 }
diff --git a/tests/wifitests/Android.mk b/tests/wifitests/Android.mk
index 11e508d..b5c5844 100644
--- a/tests/wifitests/Android.mk
+++ b/tests/wifitests/Android.mk
@@ -68,7 +68,9 @@
 	android.test.runner \
 	wifi-service \
 	services \
-	android.hidl.manager-V1.0-java
+	android.hidl.manager-V1.0-java \
+	android.test.base \
+	android.test.mock
 
 # These must be explicitly included because they are not normally accessible
 # from apps.
diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/WificondPnoScannerTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/WificondPnoScannerTest.java
index 73ea143..15dfccc 100644
--- a/tests/wifitests/src/com/android/server/wifi/scanner/WificondPnoScannerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/scanner/WificondPnoScannerTest.java
@@ -17,7 +17,6 @@
 package com.android.server.wifi.scanner;
 
 import static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder;
-import static com.android.server.wifi.ScanTestUtil.assertScanDataEquals;
 import static com.android.server.wifi.ScanTestUtil.setupMockChannels;
 
 import static org.junit.Assert.*;
@@ -45,7 +44,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.Arrays;
 import java.util.Set;
 
 /**
@@ -104,89 +102,6 @@
     }
 
     /**
-     * Verify that we pause & resume HW PNO scan when a single scan is scheduled and invokes the
-     * OnPnoNetworkFound callback when the scan results are received.
-     */
-    @Test
-    public void pauseResumeHwDisconnectedPnoScanForSingleScan() {
-        createScannerWithHwPnoScanSupport();
-
-        WifiNative.PnoEventHandler pnoEventHandler = mock(WifiNative.PnoEventHandler.class);
-        WifiNative.PnoSettings pnoSettings = createDummyPnoSettings(false);
-        WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
-        WifiNative.ScanSettings settings = createDummyScanSettings(false);
-        ScanResults scanResults = createDummyScanResults(false);
-
-        InOrder order = inOrder(eventHandler, mWifiNative);
-        // Start PNO scan
-        startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
-        // Start single scan
-        assertTrue(mScanner.startSingleScan(settings, eventHandler));
-        // Verify that the PNO scan was paused and single scan runs successfully
-        expectSuccessfulSingleScanWithHwPnoEnabled(order, eventHandler,
-                expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ), scanResults);
-        verifyNoMoreInteractions(eventHandler);
-
-        order = inOrder(pnoEventHandler, mWifiNative);
-        // Resume PNO scan after the single scan results are received and PNO monitor debounce
-        // alarm fires.
-        assertTrue("dispatch pno monitor alarm",
-                mAlarmManager.dispatch(
-                        WificondScannerImpl.HwPnoDebouncer.PNO_DEBOUNCER_ALARM_TAG));
-        assertEquals("dispatch message after alarm", 1, mLooper.dispatchAll());
-        // Now verify that PNO scan is resumed successfully
-        expectSuccessfulHwDisconnectedPnoScan(order, pnoSettings, pnoEventHandler, scanResults);
-        verifyNoMoreInteractions(pnoEventHandler);
-    }
-
-    /**
-     * Verify that the HW PNO delayed failure cleans up the scan settings cleanly.
-     * 1. Start Hw PNO.
-     * 2. Start Single Scan which should pause PNO scan.
-     * 3. Fail the PNO scan resume and verify that the OnPnoScanFailed callback is invoked.
-     * 4. Now restart a new PNO scan to ensure that the failure was cleanly handled.
-     */
-    @Test
-    public void delayedHwDisconnectedPnoScanFailure() {
-        createScannerWithHwPnoScanSupport();
-
-        WifiNative.PnoEventHandler pnoEventHandler = mock(WifiNative.PnoEventHandler.class);
-        WifiNative.PnoSettings pnoSettings = createDummyPnoSettings(false);
-        WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
-        WifiNative.ScanSettings settings = createDummyScanSettings(false);
-        ScanResults scanResults = createDummyScanResults(false);
-
-        InOrder order = inOrder(eventHandler, mWifiNative);
-        // Start PNO scan
-        startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
-        // Start single scan
-        assertTrue(mScanner.startSingleScan(settings, eventHandler));
-        // Verify that the PNO scan was paused and single scan runs successfully
-        expectSuccessfulSingleScanWithHwPnoEnabled(order, eventHandler,
-                expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ), scanResults);
-        verifyNoMoreInteractions(eventHandler);
-
-        // Fail the PNO resume and check that the OnPnoScanFailed callback is invoked.
-        order = inOrder(pnoEventHandler, mWifiNative);
-        when(mWifiNative.startPnoScan(any(WifiNative.PnoSettings.class))).thenReturn(false);
-        assertTrue("dispatch pno monitor alarm",
-                mAlarmManager.dispatch(
-                        WificondScannerImpl.HwPnoDebouncer.PNO_DEBOUNCER_ALARM_TAG));
-        assertEquals("dispatch message after alarm", 1, mLooper.dispatchAll());
-        order.verify(pnoEventHandler).onPnoScanFailed();
-        verifyNoMoreInteractions(pnoEventHandler);
-
-        // Add a new PNO scan request
-        startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
-        assertTrue("dispatch pno monitor alarm",
-                mAlarmManager.dispatch(
-                        WificondScannerImpl.HwPnoDebouncer.PNO_DEBOUNCER_ALARM_TAG));
-        assertEquals("dispatch message after alarm", 1, mLooper.dispatchAll());
-        expectSuccessfulHwDisconnectedPnoScan(order, pnoSettings, pnoEventHandler, scanResults);
-        verifyNoMoreInteractions(pnoEventHandler);
-    }
-
-    /**
      * Verify that the HW PNO scan stop failure still resets the PNO scan state.
      * 1. Start Hw PNO.
      * 2. Stop Hw PNO scan which raises a stop command to WifiNative which is failed.
@@ -205,17 +120,11 @@
         // Fail the PNO stop.
         when(mWifiNative.stopPnoScan()).thenReturn(false);
         assertTrue(mScanner.resetHwPnoList());
-        assertTrue("dispatch pno monitor alarm",
-                mAlarmManager.dispatch(
-                        WificondScannerImpl.HwPnoDebouncer.PNO_DEBOUNCER_ALARM_TAG));
         mLooper.dispatchAll();
         verify(mWifiNative).stopPnoScan();
 
         // Add a new PNO scan request and ensure it runs successfully.
         startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
-        assertTrue("dispatch pno monitor alarm",
-                mAlarmManager.dispatch(
-                        WificondScannerImpl.HwPnoDebouncer.PNO_DEBOUNCER_ALARM_TAG));
         mLooper.dispatchAll();
         InOrder order = inOrder(pnoEventHandler, mWifiNative);
         ScanResults scanResults = createDummyScanResults(false);
@@ -223,84 +132,6 @@
         verifyNoMoreInteractions(pnoEventHandler);
     }
 
-    /**
-     * Verify that the HW PNO scan is forcefully stopped (bypass debounce logic) and restarted when
-     * settings change.
-     * 1. Start Hw PNO.
-     * 2. Stop Hw PNO .
-     * 3. Now restart a new PNO scan with different settings.
-     * 4. Ensure that the stop was issued before we start again.
-     */
-    @Test
-    public void forceRestartHwDisconnectedPnoScanWhenSettingsChange() {
-        createScannerWithHwPnoScanSupport();
-
-        WifiNative.PnoEventHandler pnoEventHandler = mock(WifiNative.PnoEventHandler.class);
-        WifiNative.PnoSettings pnoSettings = createDummyPnoSettings(false);
-        InOrder order = inOrder(pnoEventHandler, mWifiNative);
-
-        // Start PNO scan
-        startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
-        expectHwDisconnectedPnoScanStart(order, pnoSettings);
-
-        // Stop PNO now. This should trigger the debounce timer and not stop PNO.
-        assertTrue(mScanner.resetHwPnoList());
-        assertTrue(mAlarmManager.isPending(
-                WificondScannerImpl.HwPnoDebouncer.PNO_DEBOUNCER_ALARM_TAG));
-        order.verify(mWifiNative, never()).stopPnoScan();
-
-        // Now restart PNO scan with an extra network in settings.
-        pnoSettings.networkList =
-                Arrays.copyOf(pnoSettings.networkList, pnoSettings.networkList.length + 1);
-        pnoSettings.networkList[pnoSettings.networkList.length - 1] =
-                createDummyPnoNetwork("ssid_pno_new");
-        startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
-
-        // This should bypass the debounce timer and stop PNO scan immediately and then start
-        // a new debounce timer for the start.
-        order.verify(mWifiNative).stopPnoScan();
-
-        // Trigger the debounce timer and ensure we start PNO scan again.
-        mAlarmManager.dispatch(WificondScannerImpl.HwPnoDebouncer.PNO_DEBOUNCER_ALARM_TAG);
-        mLooper.dispatchAll();
-        order.verify(mWifiNative).startPnoScan(pnoSettings);
-    }
-
-    /**
-     * Verify that the HW PNO scan is not forcefully stopped (bypass debounce logic) when
-     * settings don't change.
-     * 1. Start Hw PNO.
-     * 2. Stop Hw PNO .
-     * 3. Now restart a new PNO scan with same settings.
-     * 4. Ensure that the stop was never issued.
-     */
-    @Test
-    public void noForceRestartHwDisconnectedPnoScanWhenNoSettingsChange() {
-        createScannerWithHwPnoScanSupport();
-
-        WifiNative.PnoEventHandler pnoEventHandler = mock(WifiNative.PnoEventHandler.class);
-        WifiNative.PnoSettings pnoSettings = createDummyPnoSettings(false);
-        InOrder order = inOrder(pnoEventHandler, mWifiNative);
-
-        // Start PNO scan
-        startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
-        expectHwDisconnectedPnoScanStart(order, pnoSettings);
-
-        // Stop PNO now. This should trigger the debounce timer and not stop PNO.
-        assertTrue(mScanner.resetHwPnoList());
-        assertTrue(mAlarmManager.isPending(
-                WificondScannerImpl.HwPnoDebouncer.PNO_DEBOUNCER_ALARM_TAG));
-        order.verify(mWifiNative, never()).stopPnoScan();
-
-        // Now restart PNO scan with the same settings.
-        startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
-
-        // Trigger the debounce timer and ensure that we neither stop/start.
-        mLooper.dispatchAll();
-        order.verify(mWifiNative, never()).startPnoScan(any(WifiNative.PnoSettings.class));
-        order.verify(mWifiNative, never()).stopPnoScan();
-    }
-
     private void createScannerWithHwPnoScanSupport() {
         mResources.setBoolean(R.bool.config_wifi_background_scan_support, true);
         mScanner = new WificondScannerImpl(mContext, mWifiNative, mWifiMonitor,
@@ -389,27 +220,4 @@
         order.verify(eventHandler).onPnoNetworkFound(scanResults.getRawScanResults());
     }
 
-    /**
-     * Verify that the single scan results were delivered and that the PNO scan was paused and
-     * resumed either side of it.
-     */
-    private void expectSuccessfulSingleScanWithHwPnoEnabled(InOrder order,
-            WifiNative.ScanEventHandler eventHandler, Set<Integer> expectedScanFreqs,
-            ScanResults scanResults) {
-        // Pause PNO scan first
-        order.verify(mWifiNative).stopPnoScan();
-
-        order.verify(mWifiNative).scan(eq(expectedScanFreqs), any(Set.class));
-
-        when(mWifiNative.getPnoScanResults()).thenReturn(scanResults.getScanDetailArrayList());
-        when(mWifiNative.getScanResults()).thenReturn(scanResults.getScanDetailArrayList());
-
-        // Notify scan has finished
-        mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_RESULTS_EVENT);
-        assertEquals("dispatch message after results event", 1, mLooper.dispatchAll());
-
-        order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
-        assertScanDataEquals(scanResults.getScanData(), mScanner.getLatestSingleScanResults());
-    }
-
 }