Wifi: Ingore miracast scan from connectivity manager

When WFD session is active, wifi scans will impact WFD performance,
so at least ignore scans triggered internally by ConnectityManager.
Meanwhile we still allow connectivity scans initiated by other work
source.

Also, if the user toggles wifi we should resume scanning since it's
an indication that the user wants internet. Also add additional
checks to make sure that Wifi Direct is actually on before ignoring
connectivity scan.

CRs-Fixed: 2995795
Change-Id: I81793f0703807c0af464a250f8ba1f93e61bb749
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 08e93bd..6407307 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -5112,7 +5112,18 @@
                     }
                     break;
                 }
+                case WifiP2pServiceImpl.SET_MIRACAST_MODE:
+                    if (mVerboseLoggingEnabled) logd("SET_MIRACAST_MODE: " + (int)message.arg1);
+                    mWifiConnectivityManager.saveMiracastMode((int)message.arg1);
+                    break;
                 case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED:
+                    NetworkInfo info = (NetworkInfo) message.obj;
+                    if (info != null) {
+                        NetworkInfo.DetailedState detailedState = info.getDetailedState();
+                        mWifiConnectivityManager.saveP2pGroupStarted(
+                                detailedState == NetworkInfo.DetailedState.CONNECTED);
+                    }
+                    break;
                 case CMD_RESET_SIM_NETWORKS:
                 case WifiMonitor.NETWORK_CONNECTION_EVENT:
                 case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 03e0ac0..1b1d43d 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -43,6 +43,7 @@
 import android.net.wifi.WifiNetworkSelectionConfig;
 import android.net.wifi.WifiNetworkSuggestion;
 import android.net.wifi.WifiScanner;
+import android.net.wifi.p2p.WifiP2pManager;
 import android.net.wifi.WifiScanner.PnoSettings;
 import android.net.wifi.WifiScanner.ScanSettings;
 import android.net.wifi.WifiSsid;
@@ -197,6 +198,8 @@
     private boolean mAutoJoinEnabled = false; // disabled by default, enabled by external triggers
     private boolean mRunning = false;
     private boolean mScreenOn = false;
+    private int mMiracastMode = WifiP2pManager.MIRACAST_DISABLED;
+    private boolean mP2pGroupStarted = false;
     private int mWifiState = WIFI_STATE_UNKNOWN;
     private int mInitialScanState = INITIAL_SCAN_STATE_COMPLETE;
     private boolean mAutoJoinEnabledExternal = true; // enabled by default
@@ -2444,6 +2447,17 @@
     // Start a single scan
     private void startForcedSingleScan(boolean isFullBandScan, WorkSource workSource,
             int scanType) {
+        // Any scans will impact wifi performance including WFD performance,
+        // So at least ignore scans triggered internally by ConnectivityManager
+        // when WFD session is active. We still allow connectivity scans initiated
+        // by other work source.
+        if (WIFI_WORK_SOURCE.equals(workSource) && mP2pGroupStarted &&
+                (mMiracastMode == WifiP2pManager.MIRACAST_SOURCE ||
+                mMiracastMode == WifiP2pManager.MIRACAST_SINK)) {
+            Log.d(TAG, "ignore connectivity scan, MiracastMode: " + mMiracastMode);
+            return;
+        }
+
         mPnoScanListener.resetLowRssiNetworkRetryDelay();
 
         ScanSettings settings = new ScanSettings();
@@ -3020,6 +3034,23 @@
     }
 
     /**
+     * Save current miracast mode, it will be used to ignore
+     * connectivity scan during the time when miracast is enabled.
+     */
+    public void saveMiracastMode(int mode) {
+        Log.d(TAG, "saveMiracastMode: mode=" + mode);
+        mMiracastMode = mode;
+    }
+
+    /**
+     * Save current p2p group started or not.
+     */
+    public void saveP2pGroupStarted(boolean started) {
+        Log.d(TAG, "saveP2pGroupStarted: started=" + started);
+        mP2pGroupStarted = started;
+    }
+
+    /**
      * Helper function that converts the WIFI_STATE_XXX constants to string
      */
     private static String stateToString(int state) {
@@ -3620,6 +3651,8 @@
         if (mEnablePnoScanAfterWifiToggle) {
             mPnoScanEnabledByFramework = true;
         }
+        saveMiracastMode(WifiP2pManager.MIRACAST_DISABLED);
+        saveP2pGroupStarted(false);
     }
 
     /**
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index 05a21be..a07e3e7 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -1146,6 +1146,11 @@
     public void setMiracastMode(int mode) {
         checkConfigureWifiDisplayPermission();
         mP2pStateMachine.sendMessage(SET_MIRACAST_MODE, mode);
+        if (mWifiChannel != null) {
+            mWifiChannel.sendMessage(WifiP2pServiceImpl.SET_MIRACAST_MODE, mode);
+        } else {
+            Log.e(TAG, "setMiracastMode(): WifiChannel is null");
+        }
     }
 
     @Override