Merge "Restructure new outgoing call broadcast logic." into main
diff --git a/flags/telecom_api_flags.aconfig b/flags/telecom_api_flags.aconfig
index e956a38..4dbc03b 100644
--- a/flags/telecom_api_flags.aconfig
+++ b/flags/telecom_api_flags.aconfig
@@ -5,4 +5,11 @@
   namespace: "telecom"
   description: "When set, Telecom support for additional VOIP application actions is active."
   bug: "296934278"
+}
+
+flag {
+  name: "call_details_id_changes"
+  namespace: "telecom"
+  description: "When set, call details/extras id updates to Telecom APIs for Android V are active."
+  bug: "301713560"
 }
\ No newline at end of file
diff --git a/flags/telecom_default_phone_account_flags.aconfig b/flags/telecom_default_phone_account_flags.aconfig
index ca21a79..03f324c 100644
--- a/flags/telecom_default_phone_account_flags.aconfig
+++ b/flags/telecom_default_phone_account_flags.aconfig
@@ -1,6 +1,13 @@
 package: "com.android.server.telecom.flags"
 
 flag {
+  name: "only_update_telephony_on_valid_sub_ids"
+  namespace: "telecom"
+  description: "For testing purposes, only update Telephony when the default calling subId is non-zero"
+  bug: "234846282"
+}
+
+flag {
   name: "telephony_has_default_but_telecom_does_not"
   namespace: "telecom"
   description: "Telecom is requesting the user to select a sim account to place the outgoing call on but the user has a default account in the settings"
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index a4d1ddf..576cf3e 100755
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -5533,9 +5533,10 @@
             // We are going to place the new outgoing call, so disconnect any ongoing self-managed
             // calls which are ongoing at this time.
             disconnectSelfManagedCalls("outgoing call " + callId);
-
-            mPendingCallConfirm.complete(mPendingCall);
-            mPendingCallConfirm = null;
+            if (mPendingCallConfirm != null) {
+                mPendingCallConfirm.complete(mPendingCall);
+                mPendingCallConfirm = null;
+            }
             mPendingCall = null;
         }
     }
@@ -5554,8 +5555,10 @@
             markCallAsDisconnected(mPendingCall, new DisconnectCause(DisconnectCause.CANCELED));
             markCallAsRemoved(mPendingCall);
             mPendingCall = null;
-            mPendingCallConfirm.complete(null);
-            mPendingCallConfirm = null;
+            if (mPendingCallConfirm != null) {
+                mPendingCallConfirm.complete(null);
+                mPendingCallConfirm = null;
+            }
         }
     }
 
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index fe82bbc..5f23e4d 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -61,6 +61,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.XmlUtils;
 import com.android.modules.utils.ModifiedUtf8;
+import com.android.server.telecom.flags.Flags;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -389,26 +390,62 @@
                             account.getGroupId()));
         }
 
-        // Potentially update the default voice subid in SubscriptionManager.
+        // Potentially update the default voice subid in SubscriptionManager so that Telephony and
+        // Telecom are in sync.
         int newSubId = accountHandle == null ? SubscriptionManager.INVALID_SUBSCRIPTION_ID :
                 getSubscriptionIdForPhoneAccount(accountHandle);
-        if (isSimAccount || accountHandle == null) {
-            int currentVoiceSubId = mSubscriptionManager.getDefaultVoiceSubscriptionId();
-            if (newSubId != currentVoiceSubId) {
-                Log.i(this, "setUserSelectedOutgoingPhoneAccount: update voice sub; "
-                        + "account=%s, subId=%d", accountHandle, newSubId);
-                mSubscriptionManager.setDefaultVoiceSubscriptionId(newSubId);
+        if (Flags.onlyUpdateTelephonyOnValidSubIds()) {
+            if (shouldUpdateTelephonyDefaultVoiceSubId(accountHandle, isSimAccount, newSubId)) {
+                updateDefaultVoiceSubId(newSubId, accountHandle);
             } else {
-                Log.i(this, "setUserSelectedOutgoingPhoneAccount: no change to voice sub");
+                Log.i(this, "setUserSelectedOutgoingPhoneAccount: %s is not a sub", accountHandle);
             }
         } else {
-            Log.i(this, "setUserSelectedOutgoingPhoneAccount: %s is not a sub", accountHandle);
+            if (isSimAccount || accountHandle == null) {
+                updateDefaultVoiceSubId(newSubId, accountHandle);
+            } else {
+                Log.i(this, "setUserSelectedOutgoingPhoneAccount: %s is not a sub", accountHandle);
+            }
         }
-
         write();
         fireDefaultOutgoingChanged();
     }
 
+    private void updateDefaultVoiceSubId(int newSubId, PhoneAccountHandle accountHandle){
+        int currentVoiceSubId = mSubscriptionManager.getDefaultVoiceSubscriptionId();
+        if (newSubId != currentVoiceSubId) {
+            Log.i(this, "setUserSelectedOutgoingPhoneAccount: update voice sub; "
+                    + "account=%s, subId=%d", accountHandle, newSubId);
+            mSubscriptionManager.setDefaultVoiceSubscriptionId(newSubId);
+        } else {
+            Log.i(this, "setUserSelectedOutgoingPhoneAccount: no change to voice sub");
+        }
+    }
+
+    // This helper is important for CTS testing.  [PhoneAccount]s created by Telecom in CTS are
+    // assigned a  subId value of INVALID_SUBSCRIPTION_ID (-1) by Telephony.  However, when
+    // Telephony has a default outgoing calling voice account of -1, that translates to no default
+    // account (user should be prompted to select an acct when making MOs).  In order to avoid
+    // Telephony clearing out the newly changed default [PhoneAccount] in Telecom, Telephony should
+    // not be updated. This situation will never occur in production since [PhoneAccount]s in
+    // production are assigned non-negative subId values.
+    private boolean shouldUpdateTelephonyDefaultVoiceSubId(PhoneAccountHandle phoneAccountHandle,
+            boolean isSimAccount, int newSubId) {
+        // user requests no call preference
+        if (phoneAccountHandle == null) {
+            return true;
+        }
+        // do not update Telephony if the newSubId is invalid
+        if (newSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            Log.w(this, "shouldUpdateTelephonyDefaultVoiceSubId: "
+                            + "invalid subId scenario, not updating Telephony. "
+                            + "phoneAccountHandle=[%s], isSimAccount=[%b], newSubId=[%s]",
+                    phoneAccountHandle, isSimAccount, newSubId);
+            return false;
+        }
+        return isSimAccount;
+    }
+
     boolean isUserSelectedSmsPhoneAccount(PhoneAccountHandle accountHandle) {
         return getSubscriptionIdForPhoneAccount(accountHandle) ==
                 SubscriptionManager.getDefaultSmsSubscriptionId();