Prevent turning on airplane mode when in network identified e-call.

When the device is in a network-identified emergency call, prevent the
user from toggling on airplane mode.  Instead of relying on old
PhoneUtils code to see if there is an emergency call, rely on Telecom
which knows of all calls.

Test: Used new test intent to identify call as ecall and verified user is
not able to turn on airplane mode.
Test: Set outgoing number as emergency number using ril.ecclist property
and verify user is not able to turn on airplane mode.
Bug: 77565333

Change-Id: Idb8d4745a1651097c7276233bc06cc8cb254ac96
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index b1e061f..d0b236f 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -41,6 +41,7 @@
 import android.os.UserManager;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
+import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
@@ -665,7 +666,9 @@
         if (isAirplaneNewlyOn) {
             // If we are trying to turn off the radio, make sure there are no active
             // emergency calls.  If there are, switch airplane mode back to off.
-            if (PhoneUtils.isInEmergencyCall(mCM)) {
+            TelecomManager tm = (TelecomManager) context.getSystemService(TELECOM_SERVICE);
+
+            if (tm != null && tm.isInEmergencyCall()) {
                 // Switch airplane mode back to off.
                 ConnectivityManager.from(this).setAirplaneMode(false);
                 Toast.makeText(this, R.string.radio_off_during_emergency_call, Toast.LENGTH_LONG)
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index c5625e9..9ede914 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -1330,20 +1330,6 @@
         return audioManager.isSpeakerphoneOn();
     }
 
-    static boolean isInEmergencyCall(CallManager cm) {
-        Call fgCall = cm.getActiveFgCall();
-        // isIdle includes checks for the DISCONNECTING/DISCONNECTED state.
-        if(!fgCall.isIdle()) {
-            for (Connection cn : fgCall.getConnections()) {
-                if (PhoneNumberUtils.isLocalEmergencyNumber(PhoneGlobals.getInstance(),
-                        cn.getAddress())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     /**
      * Get the mute state of foreground phone, which has the current
      * foreground call
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 7d25767..440a504 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -602,6 +602,11 @@
                 com.android.internal.telephony.Connection newConnection) {
             setOriginalConnection(newConnection);
         }
+
+        @Override
+        public void onIsNetworkEmergencyCallChanged(boolean isEmergencyCall) {
+            setIsNetworkIdentifiedEmergencyCall(isEmergencyCall);
+        }
     };
 
     protected com.android.internal.telephony.Connection mOriginalConnection;
@@ -640,6 +645,15 @@
     private boolean mTreatAsEmergencyCall;
 
     /**
+     * Indicates whether the network has identified this call as an emergency call.  Where
+     * {@link #mTreatAsEmergencyCall} is based on comparing dialed numbers to a list of known
+     * emergency numbers, this property is based on whether the network itself has identified the
+     * call as an emergency call (which can be the case for an incoming call from emergency
+     * services).
+     */
+    private boolean mIsNetworkIdentifiedEmergencyCall;
+
+    /**
      * For video calls, indicates whether the outgoing video for the call can be paused using
      * the {@link android.telecom.VideoProfile#STATE_PAUSED} VideoState.
      */
@@ -1058,6 +1072,8 @@
         newProperties = changeBitmask(newProperties, PROPERTY_ASSISTED_DIALING_USED,
                 mIsUsingAssistedDialing);
         newProperties = changeBitmask(newProperties, PROPERTY_IS_RTT, isRtt());
+        newProperties = changeBitmask(newProperties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL,
+                isNetworkIdentifiedEmergencyCall());
 
         if (getConnectionProperties() != newProperties) {
             setConnectionProperties(newProperties);
@@ -1137,6 +1153,7 @@
         // Set video state and capabilities
         setVideoState(mOriginalConnection.getVideoState());
         setOriginalConnectionCapabilities(mOriginalConnection.getConnectionCapabilities());
+        setIsNetworkIdentifiedEmergencyCall(mOriginalConnection.isNetworkIdentifiedEmergencyCall());
         setAudioModeIsVoip(mOriginalConnection.getAudioModeIsVoip());
         setVideoProvider(mOriginalConnection.getVideoProvider());
         setAudioQuality(mOriginalConnection.getAudioQuality());
@@ -1859,6 +1876,27 @@
     }
 
     /**
+     * Sets whether this call has been identified by the network as an emergency call.
+     * @param isNetworkIdentifiedEmergencyCall {@code true} if the network has identified this call
+     * as an emergency call, {@code false} otherwise.
+     */
+    public void setIsNetworkIdentifiedEmergencyCall(boolean isNetworkIdentifiedEmergencyCall) {
+        Log.d(this, "setIsNetworkIdentifiedEmergencyCall; callId=%s, "
+                + "isNetworkIdentifiedEmergencyCall=%b", getTelecomCallId(),
+                isNetworkIdentifiedEmergencyCall);
+        mIsNetworkIdentifiedEmergencyCall = isNetworkIdentifiedEmergencyCall;
+        updateConnectionProperties();
+    }
+
+    /**
+     * @return {@code true} if the network has identified this call as an emergency call,
+     * {@code false} otherwise.
+     */
+    public boolean isNetworkIdentifiedEmergencyCall() {
+        return mIsNetworkIdentifiedEmergencyCall;
+    }
+
+    /**
      * @return {@code true} if this is an outgoing call, {@code false} otherwise.
      */
     boolean isOutgoingCall() {