Merge "Do not use hidden PhoneStateListener.mSubId"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 34c67a4..3f24251 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -34,7 +34,6 @@
     <protected-broadcast android:name="android.intent.action.ANY_DATA_STATE" />
     <protected-broadcast android:name="android.intent.action.DATA_STALL_DETECTED" />
     <protected-broadcast android:name="android.intent.action.SIM_STATE_CHANGED" />
-    <protected-broadcast android:name="android.telephony.action.NETWORK_SET_TIME" />
     <protected-broadcast android:name="com.android.internal.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS" />
     <protected-broadcast android:name="android.intent.action.ACTION_MDN_STATE_CHANGED" />
     <protected-broadcast android:name="android.provider.Telephony.SPN_STRINGS_UPDATED" />
diff --git a/res/layout/emergency_dialer.xml b/res/layout/emergency_dialer.xml
index d14a679..ab32c62 100644
--- a/res/layout/emergency_dialer.xml
+++ b/res/layout/emergency_dialer.xml
@@ -58,8 +58,6 @@
         android:accessibilityPaneTitle="@string/pane_title_emergency_dialpad"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:paddingLeft="36dp"
-        android:paddingRight="36dp"
         android:paddingBottom="@dimen/dialpad_bottom_padding"
         android:visibility="visible">
         <LinearLayout
@@ -73,6 +71,7 @@
                 android:id="@+id/emergency_action_group"
                 android:layout_height="64dp"
                 android:layout_width="match_parent"
+                android:layout_marginHorizontal="36dp"
                 android:layout_marginTop="16dp"
                 android:layout_marginBottom="24dp">
 
@@ -155,8 +154,14 @@
                 </FrameLayout>
 
             </com.android.phone.EmergencyActionGroup>
-
+            <Space
+                android:id="@+id/emergency_info_dialpad_spacer"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"/>
             <include layout="@layout/dialpad_view_unthemed"
+                     android:layout_height="wrap_content"
+                     android:layout_width="match_parent"
                      android:theme="?attr/dialpadTheme" />
 
         </LinearLayout>
diff --git a/res/values-h500dp/dimens.xml b/res/values-h500dp/dimens.xml
index 2c7c797..d74f0a1 100644
--- a/res/values-h500dp/dimens.xml
+++ b/res/values-h500dp/dimens.xml
@@ -16,5 +16,5 @@
   -->
 
 <resources>
-    <dimen name="dialpad_bottom_padding">36dp</dimen>
+    <dimen name="dialpad_bottom_padding">16dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/res/values/styles.xml b/res/values/styles.xml
index d131bd8..e8a0bed 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -260,7 +260,7 @@
         <item name="android:navigationBarColor">@android:color/transparent</item>
         <item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
         <item name="emergencyButtonBackgroundColor">#3cffffff</item>
-        <item name="dialpadTheme">@style/Dialpad_DarkTransparent</item>
+        <item name="dialpadTheme">@style/Dialpad_DarkTransparent.Emergency</item>
     </style>
 
     <style name="EmergencyDialerThemeDark" parent="@style/EmergencyDialerTheme">
@@ -268,7 +268,15 @@
         <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
         <item name="emergencyButtonBackgroundColor">#19414549</item>
         <item name="android:colorControlHighlight">#40000000</item>
-        <item name="dialpadTheme">@style/Dialpad_LightTransparent</item>
+        <item name="dialpadTheme">@style/Dialpad_LightTransparent.Emergency</item>
+    </style>
+
+    <style name="Dialpad_LightTransparent.Emergency">
+        <item name="dialpad_delete_padding">16dp</item>
+    </style>
+
+    <style name="Dialpad_DarkTransparent.Emergency">
+        <item name="dialpad_delete_padding">16dp</item>
     </style>
 
     <style name="EmergencyDialerAlertDialogTheme"
diff --git a/src/com/android/phone/CallBarringEditPreference.java b/src/com/android/phone/CallBarringEditPreference.java
index edff1e3..4b89cd9 100644
--- a/src/com/android/phone/CallBarringEditPreference.java
+++ b/src/com/android/phone/CallBarringEditPreference.java
@@ -77,9 +77,9 @@
         super(context, attrs);
         // Get the summary settings, use CheckBoxPreference as the standard.
         TypedArray typedArray = context.obtainStyledAttributes(attrs,
-                android.R.styleable.CheckBoxPreference, 0, 0);
-        mSummaryOn = typedArray.getString(android.R.styleable.CheckBoxPreference_summaryOn);
-        mSummaryOff = typedArray.getString(android.R.styleable.CheckBoxPreference_summaryOff);
+                R.styleable.CheckBoxPreference, 0, 0);
+        mSummaryOn = typedArray.getString(R.styleable.CheckBoxPreference_summaryOn);
+        mSummaryOff = typedArray.getString(R.styleable.CheckBoxPreference_summaryOff);
         mDisableText = context.getText(R.string.disable);
         mEnableText = context.getText(R.string.enable);
         typedArray.recycle();
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index 7531aca..119c71b 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -45,7 +45,7 @@
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneNumberUtils;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 859131f..7303c7f 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -84,7 +84,7 @@
 import android.telephony.PhoneNumberRange;
 import android.telephony.RadioAccessFamily;
 import android.telephony.RadioAccessSpecifier;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
@@ -110,6 +110,7 @@
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.feature.RcsFeature;
 import android.telephony.ims.stub.ImsConfigImplBase;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.text.TextUtils;
@@ -2677,7 +2678,8 @@
      */
     @Override
     public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
-        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
+        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+                mApp, subId, "setVoiceMailNumber");
 
         final long identity = Binder.clearCallingIdentity();
         try {
@@ -2926,7 +2928,7 @@
         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
         String defaultDialer = tm.getDefaultDialerPackage();
         if (!TextUtils.equals(callingPackage, defaultDialer)) {
-            TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+            TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
                     getDefaultSubscription(), "sendDialerSpecialCode");
         }
 
@@ -3449,6 +3451,91 @@
         }
     }
 
+
+    private void checkModifyPhoneStatePermission(int subId, String message) {
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
+                message);
+    }
+
+    private boolean isImsProvisioningRequired(int subId, int capability,
+            boolean isMmtelCapability) {
+        Phone phone = getPhone(subId);
+        if (phone == null) {
+            loge("phone instance null for subid " + subId);
+            return false;
+        }
+        if (isMmtelCapability) {
+            if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
+                return false;
+            }
+        } else {
+            if (!doesRcsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void setRcsProvisioningStatusForCapability(int subId, int capability,
+            boolean isProvisioned) {
+        checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
+            if (!isImsProvisioningRequired(subId, capability, false)) {
+                return;
+            }
+
+            // this capability requires provisioning, route to the correct API.
+            ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
+            switch (capability) {
+                case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
+                case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
+                    ims.setEabProvisioned(isProvisioned);
+                    break;
+                default: {
+                    throw new IllegalArgumentException("Tried to set provisioning for "
+                            + "rcs capability '" + capability + "', which does not require "
+                            + "provisioning.");
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+
+    }
+
+
+    @Override
+    public boolean getRcsProvisioningStatusForCapability(int subId, int capability) {
+        enforceReadPrivilegedPermission("getRcsProvisioningStatusForCapability");
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
+            if (!isImsProvisioningRequired(subId, capability, false)) {
+                return true;
+            }
+
+            ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
+            switch (capability) {
+                case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
+                case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
+                    return ims.isEabProvisionedOnDevice();
+
+                default: {
+                    throw new IllegalArgumentException("Tried to get rcs provisioning for "
+                            + "capability '" + capability + "', which does not require "
+                            + "provisioning.");
+                }
+            }
+
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     @Override
     public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
             boolean isProvisioned) {
@@ -3456,18 +3543,11 @@
                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
         }
-        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
-                "setProvisioningStatusForCapability");
+        checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
         final long identity = Binder.clearCallingIdentity();
         try {
             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
-            Phone phone = getPhone(subId);
-            if (phone == null) {
-                loge("setImsProvisioningStatusForCapability: phone instance null for subid "
-                        + subId);
-                return;
-            }
-            if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
+            if (!isImsProvisioningRequired(subId, capability, true)) {
                 return;
             }
 
@@ -3505,8 +3585,9 @@
                     break;
                 }
                 default: {
-                    throw new IllegalArgumentException("Tried to set provisioning for capability '"
-                            + capability + "', which does not require provisioning.");
+                    throw new IllegalArgumentException("Tried to set provisioning for "
+                            + "MmTel capability '" + capability + "', which does not require "
+                            + "provisioning. ");
                 }
             }
 
@@ -3525,16 +3606,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
-            Phone phone = getPhone(subId);
-            if (phone == null) {
-                loge("getImsProvisioningStatusForCapability: phone instance null for subid "
-                        + subId);
-                // We will fail with "true" as the provisioning status because this is the default
-                // if we do not require provisioning.
-                return true;
-            }
-
-            if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
+            if (!isImsProvisioningRequired(subId, capability, true)) {
                 return true;
             }
 
@@ -3560,8 +3632,9 @@
                     return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
                 }
                 default: {
-                    throw new IllegalArgumentException("Tried to get provisioning for capability '"
-                            + capability + "', which does not require provisioning.");
+                    throw new IllegalArgumentException(
+                            "Tried to get provisioning for MmTel capability '" + capability
+                                    + "', which does not require provisioning.");
                 }
             }
 
@@ -3670,6 +3743,29 @@
         return false;
     }
 
+    private boolean doesRcsCapabilityRequireProvisioning(Context context, int subId,
+            int capability) {
+        CarrierConfigManager configManager = new CarrierConfigManager(context);
+        PersistableBundle c = configManager.getConfigForSubId(subId);
+
+        boolean requireRcsProvisioning = c.getBoolean(
+                CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, false);
+
+        // First check to make sure that the capability requires provisioning.
+        switch (capability) {
+            case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
+                // intentional fallthrough
+            case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE: {
+                if (requireRcsProvisioning) {
+                    // OPTION or PRESENCE requires provisioning
+                    return true;
+                }
+                break;
+            }
+        }
+        return false;
+    }
+
     @Override
     public int getImsProvisioningInt(int subId, int key) {
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -5177,6 +5273,7 @@
 
     @Override
     public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
+        enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
         final Phone phone = getPhone(subId);
         if (phone == null) {
             loge("getCarrierPrivilegeStatusForUid: Invalid subId");
@@ -5189,8 +5286,8 @@
             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
         }
         return getCarrierPrivilegeStatusFromCarrierConfigRules(
-            profile.getCarrierPrivilegeStatusForUid(
-                phone.getContext().getPackageManager(), uid), phone);
+                profile.getCarrierPrivilegeStatusForUid(
+                        phone.getContext().getPackageManager(), uid), phone);
     }
 
     @Override
@@ -5312,7 +5409,7 @@
     @Override
     public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
             String number) {
-        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
                 subId, "setLine1NumberForDisplayForSubscriber");
 
         final long identity = Binder.clearCallingIdentity();
@@ -5540,7 +5637,7 @@
 
     @Override
     public boolean setOperatorBrandOverride(int subId, String brand) {
-        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
                 subId, "setOperatorBrandOverride");
 
         final long identity = Binder.clearCallingIdentity();
@@ -5556,7 +5653,8 @@
     public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
             List<String> cdmaNonRoamingList) {
-        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
+        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+                mApp, subId, "setRoamingOverride");
 
         final long identity = Binder.clearCallingIdentity();
         try {
@@ -7716,4 +7814,28 @@
             Binder.restoreCallingIdentity(identity);
         }
     }
+
+    /**
+     * Notify that an RCS autoconfiguration XML file has been received for provisioning.
+     *
+     * @param config       The XML file to be read. ASCII/UTF8 encoded text if not compressed.
+     * @param isCompressed The XML file is compressed in gzip format and must be decompressed
+     *                     before being read.
+     */
+    @Override
+    public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
+            isCompressed) {
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "notifyRcsAutoConfigurationReceived");
+        try {
+            IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
+            if (configBinder == null) {
+                Rlog.e(LOG_TAG, "null result for getImsConfig");
+            } else {
+                configBinder.notifyRcsAutoConfigurationReceived(config, isCompressed);
+            }
+        } catch (RemoteException e) {
+            Rlog.e(LOG_TAG, "fail to getImsConfig " + e.getMessage());
+        }
+    }
 }
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index c865f14..20a818e 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -31,7 +31,7 @@
 import android.telecom.VideoProfile;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneNumberUtils;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.SubscriptionManager;
 import android.text.TextUtils;
 import android.util.Log;
diff --git a/src/com/android/services/telephony/ConferenceParticipantConnection.java b/src/com/android/services/telephony/ConferenceParticipantConnection.java
index ed92e7f..ac3928f 100644
--- a/src/com/android/services/telephony/ConferenceParticipantConnection.java
+++ b/src/com/android/services/telephony/ConferenceParticipantConnection.java
@@ -19,7 +19,7 @@
 import android.net.Uri;
 import android.telecom.Connection;
 import android.telecom.DisconnectCause;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.SubscriptionInfo;
 import android.text.TextUtils;
 
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 4c3f9c9..e8386e8 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -30,7 +30,7 @@
 import android.telecom.VideoProfile;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneNumberUtils;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.util.Pair;
 
 import com.android.ims.internal.ConferenceParticipant;
diff --git a/src/com/android/services/telephony/ImsConferenceController.java b/src/com/android/services/telephony/ImsConferenceController.java
index 1e10055..5445cc4 100644
--- a/src/com/android/services/telephony/ImsConferenceController.java
+++ b/src/com/android/services/telephony/ImsConferenceController.java
@@ -22,7 +22,7 @@
 import android.telecom.ConnectionService;
 import android.telecom.DisconnectCause;
 import android.telecom.PhoneAccountHandle;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
diff --git a/src/com/android/services/telephony/PstnIncomingCallNotifier.java b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
index 2dfeaed..b99be81 100644
--- a/src/com/android/services/telephony/PstnIncomingCallNotifier.java
+++ b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
@@ -25,7 +25,7 @@
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.Call;
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 5a1e6a6..90512b6 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -41,7 +41,7 @@
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneStateListener;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 14f0cb8..7d7b72b 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -40,7 +40,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.ServiceState.RilRadioTechnology;
 import android.telephony.SubscriptionManager;
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 2aba682..bac4793 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -1471,6 +1471,12 @@
                                                     .OUTGOING_EMERGENCY_CALL_PLACED);
                                 }
                             }
+                            for (Conference c : getAllConferences()) {
+                                if (c.getState() != Connection.STATE_DISCONNECTED
+                                        && c instanceof Conference) {
+                                    ((Conference) c).onDisconnect();
+                                }
+                            }
                         } else if (!isVideoCallHoldAllowed(phone)) {
                             // If we do not support holding ongoing video call for an outgoing
                             // emergency call, disconnect the ongoing video call.