Allow turning off Wi-Fi when emergency call is made [DO NOT MERGE]

Bug: 24147407

Change-Id: I52db1b34df318d0754b1c316806712a61fc3a1f5
diff --git a/service/java/com/android/server/wifi/WifiController.java b/service/java/com/android/server/wifi/WifiController.java
index 9a8967b..7841a13 100644
--- a/service/java/com/android/server/wifi/WifiController.java
+++ b/service/java/com/android/server/wifi/WifiController.java
@@ -102,19 +102,20 @@
 
     private static final int BASE = Protocol.BASE_WIFI_CONTROLLER;
 
-    static final int CMD_EMERGENCY_MODE_CHANGED     = BASE + 1;
-    static final int CMD_SCREEN_ON                  = BASE + 2;
-    static final int CMD_SCREEN_OFF                 = BASE + 3;
-    static final int CMD_BATTERY_CHANGED            = BASE + 4;
-    static final int CMD_DEVICE_IDLE                = BASE + 5;
-    static final int CMD_LOCKS_CHANGED              = BASE + 6;
-    static final int CMD_SCAN_ALWAYS_MODE_CHANGED   = BASE + 7;
-    static final int CMD_WIFI_TOGGLED               = BASE + 8;
-    static final int CMD_AIRPLANE_TOGGLED           = BASE + 9;
-    static final int CMD_SET_AP                     = BASE + 10;
-    static final int CMD_DEFERRED_TOGGLE            = BASE + 11;
-    static final int CMD_USER_PRESENT               = BASE + 12;
-    static final int CMD_AP_START_FAILURE           = BASE + 13;
+    static final int CMD_EMERGENCY_MODE_CHANGED       = BASE + 1;
+    static final int CMD_SCREEN_ON                    = BASE + 2;
+    static final int CMD_SCREEN_OFF                   = BASE + 3;
+    static final int CMD_BATTERY_CHANGED              = BASE + 4;
+    static final int CMD_DEVICE_IDLE                  = BASE + 5;
+    static final int CMD_LOCKS_CHANGED                = BASE + 6;
+    static final int CMD_SCAN_ALWAYS_MODE_CHANGED     = BASE + 7;
+    static final int CMD_WIFI_TOGGLED                 = BASE + 8;
+    static final int CMD_AIRPLANE_TOGGLED             = BASE + 9;
+    static final int CMD_SET_AP                       = BASE + 10;
+    static final int CMD_DEFERRED_TOGGLE              = BASE + 11;
+    static final int CMD_USER_PRESENT                 = BASE + 12;
+    static final int CMD_AP_START_FAILURE             = BASE + 13;
+    static final int CMD_EMERGENCY_CALL_STATE_CHANGED = BASE + 14;
 
     private static final int WIFI_DISABLED = 0;
     private static final int WIFI_ENABLED = 1;
@@ -384,6 +385,7 @@
                 case CMD_WIFI_TOGGLED:
                 case CMD_AIRPLANE_TOGGLED:
                 case CMD_EMERGENCY_MODE_CHANGED:
+                case CMD_EMERGENCY_CALL_STATE_CHANGED:
                 case CMD_AP_START_FAILURE:
                     break;
                 case CMD_USER_PRESENT:
@@ -511,6 +513,7 @@
                         transitionTo(mApStaDisabledState);
                     }
                     break;
+                case CMD_EMERGENCY_CALL_STATE_CHANGED:
                 case CMD_EMERGENCY_MODE_CHANGED:
                     if (msg.arg1 == 1) {
                         transitionTo(mEcmState);
@@ -650,6 +653,7 @@
                         }
                     }
                     break;
+                case CMD_EMERGENCY_CALL_STATE_CHANGED:
                 case CMD_EMERGENCY_MODE_CHANGED:
                     if (msg.arg1 == 1) {
                         mWifiStateMachine.setHostApRunning(null, false);
@@ -670,15 +674,55 @@
     }
 
     class EcmState extends State {
+        // we can enter EcmState either because an emergency call started or because
+        // emergency callback mode started. This count keeps track of how many such
+        // events happened; so we can exit after all are undone
+
+        private int mEcmEntryCount;
         @Override
         public void enter() {
             mWifiStateMachine.setSupplicantRunning(false);
             mWifiStateMachine.clearANQPCache();
+            mEcmEntryCount = 1;
         }
 
         @Override
         public boolean processMessage(Message msg) {
-            if (msg.what == CMD_EMERGENCY_MODE_CHANGED && msg.arg1 == 0) {
+            if (msg.what == CMD_EMERGENCY_CALL_STATE_CHANGED) {
+                if (msg.arg1 == 1) {
+                    // nothing to do - just says emergency call started
+                    mEcmEntryCount++;
+                } else if (msg.arg1 == 0) {
+                    // emergency call ended
+                    decrementCountAndReturnToAppropriateState();
+                }
+                return HANDLED;
+            } else if (msg.what == CMD_EMERGENCY_MODE_CHANGED) {
+
+                if (msg.arg1 == 1) {
+                    // Transitioned into emergency callback mode
+                    mEcmEntryCount++;
+                } else if (msg.arg1 == 0) {
+                    // out of emergency callback mode
+                    decrementCountAndReturnToAppropriateState();
+                }
+                return HANDLED;
+            } else {
+                return NOT_HANDLED;
+            }
+        }
+
+        private void decrementCountAndReturnToAppropriateState() {
+            boolean exitEcm = false;
+
+            if (mEcmEntryCount == 0) {
+                loge("mEcmEntryCount is 0; exiting Ecm");
+                exitEcm = true;
+            } else if (--mEcmEntryCount == 0) {
+                exitEcm = true;
+            }
+
+            if (exitEcm) {
                 if (mSettingsStore.isWifiToggleEnabled()) {
                     if (mDeviceIdle == false) {
                         transitionTo(mDeviceActiveState);
@@ -690,9 +734,6 @@
                 } else {
                     transitionTo(mApStaDisabledState);
                 }
-                return HANDLED;
-            } else {
-                return NOT_HANDLED;
             }
         }
     }
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 5ab035c..55c6040 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -70,6 +70,7 @@
 import com.android.internal.R;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.AsyncChannel;
 import com.android.server.am.BatteryStatsService;
@@ -99,6 +100,7 @@
 
 import static com.android.server.wifi.WifiController.CMD_AIRPLANE_TOGGLED;
 import static com.android.server.wifi.WifiController.CMD_BATTERY_CHANGED;
+import static com.android.server.wifi.WifiController.CMD_EMERGENCY_CALL_STATE_CHANGED;
 import static com.android.server.wifi.WifiController.CMD_EMERGENCY_MODE_CHANGED;
 import static com.android.server.wifi.WifiController.CMD_LOCKS_CHANGED;
 import static com.android.server.wifi.WifiController.CMD_SCAN_ALWAYS_MODE_CHANGED;
@@ -1394,6 +1396,9 @@
             } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
                 boolean emergencyMode = intent.getBooleanExtra("phoneinECMState", false);
                 mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, emergencyMode ? 1 : 0, 0);
+            } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED)) {
+                boolean inCall = intent.getBooleanExtra(PhoneConstants.PHONE_IN_EMERGENCY_CALL, false);
+                mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, inCall ? 1 : 0, 0);
             } else if (action.equals(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) {
                 handleIdleModeChanged();
             }
@@ -1427,6 +1432,13 @@
         intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
         intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
         intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
+
+        boolean trackEmergencyCallState = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_wifi_turn_off_during_emergency_call);
+        if (trackEmergencyCallState) {
+            intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED);
+        }
+
         mContext.registerReceiver(mReceiver, intentFilter);
     }