Finalize MEP functionality.

1) Finish plumbing of PULLING_CALL state.
2) Add new disconnect cause used when maximum number of calls across
all devices has been reached.
3) Add PII mask for toString of ImsExternalCallState.

Bug: 29522023
Change-Id: I78a0a9f3c3d846cfc58a1c5bcc6f105027602cbc
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 441efb7..52f75f6 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -1551,6 +1551,8 @@
                 return "RINGING";
             case STATE_DIALING:
                 return "DIALING";
+            case STATE_PULLING_CALL:
+                return "PULLING_CALL";
             case STATE_ACTIVE:
                 return "ACTIVE";
             case STATE_HOLDING:
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index fc7d741..0c75630c 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -556,6 +556,9 @@
                 case Connection.STATE_DIALING:
                     mAdapter.setDialing(id);
                     break;
+                case Connection.STATE_PULLING_CALL:
+                    mAdapter.setPulling(id);
+                    break;
                 case Connection.STATE_DISCONNECTED:
                     // Handled in onDisconnected()
                     break;
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index c8cd3c0..df7d539 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -143,6 +143,21 @@
     }
 
     /**
+     * Sets a call's state to pulling (e.g. a call with {@link Connection#PROPERTY_IS_EXTERNAL_CALL}
+     * is being pulled to the local device.
+     *
+     * @param callId The unique ID of the call whose state is changing to dialing.
+     */
+    void setPulling(String callId) {
+        for (IConnectionServiceAdapter adapter : mAdapters) {
+            try {
+                adapter.setPulling(callId);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /**
      * Sets a call's state to disconnected.
      *
      * @param callId The unique ID of the call whose state is changing to disconnected.
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index bf28feb..486f9d5 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -65,6 +65,7 @@
     private static final int MSG_REMOVE_EXTRAS = 25;
     private static final int MSG_ON_CONNECTION_EVENT = 26;
     private static final int MSG_SET_CONNECTION_PROPERTIES = 27;
+    private static final int MSG_SET_PULLING = 28;
 
     private final IConnectionServiceAdapter mDelegate;
 
@@ -101,6 +102,9 @@
                 case MSG_SET_DIALING:
                     mDelegate.setDialing((String) msg.obj);
                     break;
+                case MSG_SET_PULLING:
+                    mDelegate.setPulling((String) msg.obj);
+                    break;
                 case MSG_SET_DISCONNECTED: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
@@ -299,6 +303,11 @@
         }
 
         @Override
+        public void setPulling(String connectionId) {
+            mHandler.obtainMessage(MSG_SET_PULLING, connectionId).sendToTarget();
+        }
+
+        @Override
         public void setDisconnected(
                 String connectionId, DisconnectCause disconnectCause) {
             SomeArgs args = SomeArgs.obtain();
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index 21a7706..306b3c1 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -118,6 +118,12 @@
         }
 
         @Override
+        public void setPulling(String callId) {
+            findConnectionForAction(callId, "setPulling")
+                    .setState(Connection.STATE_PULLING_CALL);
+        }
+
+        @Override
         public void setDisconnected(String callId, DisconnectCause disconnectCause) {
             if (mConnectionById.containsKey(callId)) {
                 findConnectionForAction(callId, "setDisconnected")
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index 9bc8ffe..3bf83ae 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -47,6 +47,8 @@
 
     void setDialing(String callId);
 
+    void setPulling(String callId);
+
     void setDisconnected(String callId, in DisconnectCause disconnectCause);
 
     void setOnHold(String callId);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index a84f13e..2a95d3e 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -24,6 +24,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 
+import com.android.ims.ImsReasonInfo;
 import com.android.internal.telephony.ICarrierConfigLoader;
 
 /**
@@ -836,6 +837,25 @@
     public static final String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL =
             "allow_add_call_during_video_call";
 
+    /**
+     * Defines operator-specific {@link com.android.ims.ImsReasonInfo} mappings.
+     *
+     * Format: "ORIGINAL_CODE|MESSAGE|NEW_CODE"
+     * Where {@code ORIGINAL_CODE} corresponds to a {@link ImsReasonInfo#getCode()} code,
+     * {@code MESSAGE} corresponds to an expected {@link ImsReasonInfo#getExtraMessage()} string,
+     * and {@code NEW_CODE} is the new {@code ImsReasonInfo#CODE_*} which this combination of
+     * original code and message shall be remapped to.
+     *
+     * Example: "501|call completion elsewhere|1014"
+     * When the {@link ImsReasonInfo#getCode()} is {@link ImsReasonInfo#CODE_USER_TERMINATED} and
+     * the {@link ImsReasonInfo#getExtraMessage()} is {@code "call completion elsewhere"},
+     * {@link ImsReasonInfo#CODE_ANSWERED_ELSEWHERE} shall be used as the {@link ImsReasonInfo}
+     * code instead.
+     * @hide
+     */
+    public static final String KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY =
+            "ims_reasoninfo_mapping_string_array";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -992,6 +1012,8 @@
         sDefaults.putBoolean(KEY_DROP_VIDEO_CALL_WHEN_ANSWERING_AUDIO_CALL_BOOL, false);
         sDefaults.putBoolean(KEY_ALLOW_MERGE_WIFI_CALLS_WHEN_VOWIFI_OFF_BOOL, true);
         sDefaults.putBoolean(KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL, true);
+
+        sDefaults.putStringArray(KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY, null);
     }
 
     /**
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 80ae4af..d7d4e84 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -206,6 +206,12 @@
      */
     public static final int ANSWERED_ELSEWHERE = 52;
 
+    /**
+     * The call was terminated because the maximum allowable number of calls has been reached.
+     * {@hide}
+     */
+    public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 53;
+
     //*********************************************************************************************
     // When adding a disconnect type:
     // 1) Please assign the new type the next id value below.
@@ -214,14 +220,14 @@
     // 4) Update toString() with the newly added disconnect type.
     // 5) Update android.telecom.DisconnectCauseUtil with any mappings to a telecom.DisconnectCause.
     //
-    // NextId: 53
+    // NextId: 54
     //*********************************************************************************************
 
     /** Smallest valid value for call disconnect codes. */
     public static final int MINIMUM_VALID_VALUE = NOT_DISCONNECTED;
 
     /** Largest valid value for call disconnect codes. */
-    public static final int MAXIMUM_VALID_VALUE = ANSWERED_ELSEWHERE;
+    public static final int MAXIMUM_VALID_VALUE = MAXIMUM_NUMBER_OF_CALLS_REACHED;
 
     /** Private constructor to avoid class instantiation. */
     private DisconnectCause() {
@@ -335,6 +341,8 @@
             return "CALL_PULLED";
         case ANSWERED_ELSEWHERE:
             return "ANSWERED_ELSEWHERE";
+        case MAXIMUM_NUMBER_OF_CALLS_REACHED:
+            return "MAXIMUM_NUMER_OF_CALLS_REACHED";
         default:
             return "INVALID: " + cause;
         }
diff --git a/telephony/java/com/android/ims/ImsExternalCallState.java b/telephony/java/com/android/ims/ImsExternalCallState.java
index 71c1837..da26073 100644
--- a/telephony/java/com/android/ims/ImsExternalCallState.java
+++ b/telephony/java/com/android/ims/ImsExternalCallState.java
@@ -19,6 +19,7 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.telecom.Log;
 import android.telephony.Rlog;
 
 /*
@@ -130,7 +131,7 @@
     @Override
     public String toString() {
         return "ImsExternalCallState { mCallId = " + mCallId +
-                ", mAddress = " + mAddress +
+                ", mAddress = " + Log.pii(mAddress) +
                 ", mIsPullable = " + mIsPullable +
                 ", mCallState = " + mCallState +
                 ", mCallType = " + mCallType +
diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java
index 9369b20..408ad31 100644
--- a/telephony/java/com/android/ims/ImsReasonInfo.java
+++ b/telephony/java/com/android/ims/ImsReasonInfo.java
@@ -25,6 +25,7 @@
  * @hide
  */
 public class ImsReasonInfo implements Parcelable {
+
     /**
      * Specific code of each types
      */
@@ -284,6 +285,19 @@
     public static final int CODE_EPDG_TUNNEL_LOST_CONNECTION = 1402;
 
     /**
+     * The maximum number of calls allowed has been reached.  Used in a multi-endpoint scenario
+     * where the number of calls across all connected devices has reached the maximum.
+     */
+    public static final int CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED = 1403;
+
+    /**
+     * Similar to {@link #CODE_LOCAL_CALL_DECLINE}, except indicates that a remote device has
+     * declined the call.  Used in a multi-endpoint scenario where a remote device declined an
+     * incoming call.
+     */
+    public static final int CODE_REMOTE_CALL_DECLINE = 1404;
+
+    /**
      * Network string error messages.
      * mExtraMessage may have these values.
      */