Merge "Updated owners"
diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
index ffac202..48300c9 100644
--- a/src/com/android/phone/ImsRcsController.java
+++ b/src/com/android/phone/ImsRcsController.java
@@ -20,6 +20,7 @@
 import android.os.Binder;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.ims.ImsException;
 import android.telephony.ims.RegistrationManager;
@@ -260,12 +261,15 @@
     @Override
     public boolean isUceSettingEnabled(int subId) {
         enforceReadPrivilegedPermission("isUceSettingEnabled");
-        return false;
+        return SubscriptionManager.getBooleanSubscriptionProperty(subId,
+                SubscriptionManager.IMS_RCS_UCE_ENABLED, false /*defaultValue*/, mApp);
     }
 
     @Override
     public void setUceSettingEnabled(int subId, boolean isEnabled) {
         enforceModifyPermission();
+        SubscriptionManager.setSubscriptionProperty(subId, SubscriptionManager.IMS_RCS_UCE_ENABLED,
+                (isEnabled ? "1" : "0"));
     }
 
     /**
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 919d3b2..fdf302c 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -1009,7 +1009,7 @@
      * @param handle The {@link PhoneAccountHandle}.
      * @return {@code True} if merging calls is supported.
      */
-    boolean isMergeCallSupported(PhoneAccountHandle handle) {
+    public boolean isMergeCallSupported(PhoneAccountHandle handle) {
         synchronized (mAccountsLock) {
             for (AccountEntry entry : mAccounts) {
                 if (entry.getPhoneAccountHandle().equals(handle)) {
@@ -1027,7 +1027,7 @@
      * @param handle The {@link PhoneAccountHandle}.
      * @return {@code True} if video conferencing is supported.
      */
-    boolean isVideoConferencingSupported(PhoneAccountHandle handle) {
+    public boolean isVideoConferencingSupported(PhoneAccountHandle handle) {
         synchronized (mAccountsLock) {
             for (AccountEntry entry : mAccounts) {
                 if (entry.getPhoneAccountHandle().equals(handle)) {
@@ -1045,7 +1045,7 @@
      * @param handle The {@link PhoneAccountHandle}.
      * @return {@code True} if merging of wifi calls is allowed when VoWIFI is disabled.
      */
-    boolean isMergeOfWifiCallsAllowedWhenVoWifiOff(final PhoneAccountHandle handle) {
+    public boolean isMergeOfWifiCallsAllowedWhenVoWifiOff(final PhoneAccountHandle handle) {
         synchronized (mAccountsLock) {
             Optional<AccountEntry> result = mAccounts.stream().filter(
                     entry -> entry.getPhoneAccountHandle().equals(handle)).findFirst();
@@ -1065,7 +1065,7 @@
      * @param handle The {@link PhoneAccountHandle}.
      * @return {@code True} if merging IMS calls is supported.
      */
-    boolean isMergeImsCallSupported(PhoneAccountHandle handle) {
+    public boolean isMergeImsCallSupported(PhoneAccountHandle handle) {
         synchronized (mAccountsLock) {
             for (AccountEntry entry : mAccounts) {
                 if (entry.getPhoneAccountHandle().equals(handle)) {
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index f2b2244..95f4a04 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -2465,8 +2465,8 @@
         PhoneAccountHandle phoneAccountHandle = isIms ? PhoneUtils
                 .makePstnPhoneAccountHandle(phone.getDefaultPhone())
                 : PhoneUtils.makePstnPhoneAccountHandle(phone);
-        TelecomAccountRegistry telecomAccountRegistry = TelecomAccountRegistry
-                .getInstance(getPhone().getContext());
+        TelecomAccountRegistry telecomAccountRegistry = getTelecomAccountRegistry(
+                getPhone().getContext());
         boolean isConferencingSupported = telecomAccountRegistry
                 .isMergeCallSupported(phoneAccountHandle);
         boolean isImsConferencingSupported = telecomAccountRegistry
@@ -2475,6 +2475,17 @@
                 .isVideoConferencingSupported(phoneAccountHandle);
         boolean isMergeOfWifiCallsAllowedWhenVoWifiOff = telecomAccountRegistry
                 .isMergeOfWifiCallsAllowedWhenVoWifiOff(phoneAccountHandle);
+        ImsCall imsCall = ((ImsPhoneConnection) getOriginalConnection()).getImsCall();
+        CarrierConfigManager configManager = (CarrierConfigManager) phone.getContext()
+                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        boolean downGradedVideoCall = false;
+        if (configManager != null) {
+            PersistableBundle config = configManager.getConfigForSubId(phone.getSubId());
+            if (config != null) {
+                downGradedVideoCall = config.getBoolean(
+                        CarrierConfigManager.KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL);
+            }
+        }
 
         Log.v(this, "refreshConferenceSupported : isConfSupp=%b, isImsConfSupp=%b, " +
                 "isVidConfSupp=%b, isMergeOfWifiAllowed=%b, " +
@@ -2495,6 +2506,12 @@
         } else if (isVideoCall && !mIsCarrierVideoConferencingSupported) {
             isConferenceSupported = false;
             Log.d(this, "refreshConferenceSupported = false; video conf not supported.");
+        } else if ((imsCall.wasVideoCall() && downGradedVideoCall)
+                && !mIsCarrierVideoConferencingSupported) {
+            isConferenceSupported = false;
+            Log.d(this,
+                    "refreshConferenceSupported = false;"
+                            + " video conf not supported for downgraded audio call.");
         } else if (!isMergeOfWifiCallsAllowedWhenVoWifiOff && isWifi() && !isVoWifiEnabled) {
             isConferenceSupported = false;
             Log.d(this,
@@ -2937,4 +2954,8 @@
             listener.onStatusHintsChanged(this, statusHints);
         }
     }
+
+    public TelecomAccountRegistry getTelecomAccountRegistry(Context context) {
+        return TelecomAccountRegistry.getInstance(context);
+    }
 }
diff --git a/tests/src/com/android/phone/ServiceStateProviderTest.java b/tests/src/com/android/phone/ServiceStateProviderTest.java
index 574c0c9..32e5f26 100644
--- a/tests/src/com/android/phone/ServiceStateProviderTest.java
+++ b/tests/src/com/android/phone/ServiceStateProviderTest.java
@@ -60,27 +60,27 @@
     private final String[] mTestProjection =
     {
         ServiceStateTable.VOICE_REG_STATE,
-        ServiceStateTable.DATA_REG_STATE,
-        ServiceStateTable.VOICE_OPERATOR_ALPHA_LONG,
-        ServiceStateTable.VOICE_OPERATOR_ALPHA_SHORT,
+        ServiceStateProvider.DATA_REG_STATE,
+        ServiceStateProvider.VOICE_OPERATOR_ALPHA_LONG,
+        ServiceStateProvider.VOICE_OPERATOR_ALPHA_SHORT,
         ServiceStateTable.VOICE_OPERATOR_NUMERIC,
-        ServiceStateTable.DATA_OPERATOR_ALPHA_LONG,
-        ServiceStateTable.DATA_OPERATOR_ALPHA_SHORT,
-        ServiceStateTable.DATA_OPERATOR_NUMERIC,
+        ServiceStateProvider.DATA_OPERATOR_ALPHA_LONG,
+        ServiceStateProvider.DATA_OPERATOR_ALPHA_SHORT,
+        ServiceStateProvider.DATA_OPERATOR_NUMERIC,
         ServiceStateTable.IS_MANUAL_NETWORK_SELECTION,
-        ServiceStateTable.RIL_VOICE_RADIO_TECHNOLOGY,
-        ServiceStateTable.RIL_DATA_RADIO_TECHNOLOGY,
-        ServiceStateTable.CSS_INDICATOR,
-        ServiceStateTable.NETWORK_ID,
-        ServiceStateTable.SYSTEM_ID,
-        ServiceStateTable.CDMA_ROAMING_INDICATOR,
-        ServiceStateTable.CDMA_DEFAULT_ROAMING_INDICATOR,
-        ServiceStateTable.CDMA_ERI_ICON_INDEX,
-        ServiceStateTable.CDMA_ERI_ICON_MODE,
-        ServiceStateTable.IS_EMERGENCY_ONLY,
-        ServiceStateTable.IS_USING_CARRIER_AGGREGATION,
-        ServiceStateTable.OPERATOR_ALPHA_LONG_RAW,
-        ServiceStateTable.OPERATOR_ALPHA_SHORT_RAW,
+        ServiceStateProvider.RIL_VOICE_RADIO_TECHNOLOGY,
+        ServiceStateProvider.RIL_DATA_RADIO_TECHNOLOGY,
+        ServiceStateProvider.CSS_INDICATOR,
+        ServiceStateProvider.NETWORK_ID,
+        ServiceStateProvider.SYSTEM_ID,
+        ServiceStateProvider.CDMA_ROAMING_INDICATOR,
+        ServiceStateProvider.CDMA_DEFAULT_ROAMING_INDICATOR,
+        ServiceStateProvider.CDMA_ERI_ICON_INDEX,
+        ServiceStateProvider.CDMA_ERI_ICON_MODE,
+        ServiceStateProvider.IS_EMERGENCY_ONLY,
+        ServiceStateProvider.IS_USING_CARRIER_AGGREGATION,
+        ServiceStateProvider.OPERATOR_ALPHA_LONG_RAW,
+        ServiceStateProvider.OPERATOR_ALPHA_SHORT_RAW,
     };
 
     @Before
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
index 7d15680..6f5e5c9 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
@@ -1,15 +1,17 @@
 package com.android.services.telephony;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertFalse;
 
 import android.os.Bundle;
 import android.telecom.Connection;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import androidx.test.runner.AndroidJUnit4;
-
 @RunWith(AndroidJUnit4.class)
 public class TelephonyConnectionTest {
 
@@ -22,4 +24,17 @@
         assertEquals(codec, Connection.AUDIO_CODEC_AMR);
     }
 
+    @Test
+    public void testConferenceNotSupportedForDownGradedVideoCall() {
+        TestTelephonyConnection c = new TestTelephonyConnection();
+        c.setIsImsConnection(true);
+        c.setIsVideoCall(false);
+        c.setWasVideoCall(true);
+        c.setDownGradeVideoCall(true);
+        c.refreshConferenceSupported();
+        assertFalse(c.isConferenceSupported());
+        c.setDownGradeVideoCall(false);
+        c.refreshConferenceSupported();
+        assertTrue(c.isConferenceSupported());
+    }
 }
diff --git a/tests/src/com/android/services/telephony/TestTelephonyConnection.java b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
index 5b31c0f..d42ef5e 100644
--- a/tests/src/com/android/services/telephony/TestTelephonyConnection.java
+++ b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
@@ -16,24 +16,29 @@
 
 package com.android.services.telephony;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.PersistableBundle;
 import android.telecom.PhoneAccountHandle;
+import android.telecom.VideoProfile;
+import android.telephony.CarrierConfigManager;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
+import com.android.ims.ImsCall;
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.Connection;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+import com.android.internal.telephony.imsphone.ImsPhoneConnection;
 
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -62,23 +67,45 @@
     @Mock
     EmergencyNumberTracker mEmergencyNumberTracker;
 
+    @Mock
+    ImsPhoneConnection mImsPhoneConnection;
+
+    @Mock
+    ImsCall mImsCall;
+
+    @Mock
+    TelecomAccountRegistry mTelecomAccountRegistry;
+
+    @Mock
+    CarrierConfigManager mCarrierConfigManager;
+
+    private boolean mIsImsConnection;
+    private boolean mIsConferenceSupported = true;
     private Phone mMockPhone;
     private int mNotifyPhoneAccountChangedCount = 0;
     private List<String> mLastConnectionEvents = new ArrayList<>();
     private List<Bundle> mLastConnectionEventExtras = new ArrayList<>();
+    private Object mLock = new Object();
 
     @Override
     public com.android.internal.telephony.Connection getOriginalConnection() {
-        return mMockRadioConnection;
+        if (mIsImsConnection) {
+            return mImsPhoneConnection;
+        } else {
+            return mMockRadioConnection;
+        }
     }
 
     public TestTelephonyConnection() {
         super(null, null, false);
         MockitoAnnotations.initMocks(this);
 
+        mIsImsConnection = false;
         mMockPhone = mock(Phone.class);
         mMockContext = mock(Context.class);
         mOriginalConnection = mock(Connection.class);
+        mTelecomAccountRegistry = mock(TelecomAccountRegistry.class);
+
         // Set up mMockRadioConnection and mMockPhone to contain an active call
         when(mMockRadioConnection.getState()).thenReturn(Call.State.ACTIVE);
         when(mOriginalConnection.getState()).thenReturn(Call.State.ACTIVE);
@@ -100,11 +127,17 @@
         when(mMockPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_IMS);
         when(mMockCall.getState()).thenReturn(Call.State.ACTIVE);
         when(mMockCall.getPhone()).thenReturn(mMockPhone);
-    }
-
-    @Override
-    public boolean isConferenceSupported() {
-        return true;
+        when(mMockPhone.getDefaultPhone()).thenReturn(mMockPhone);
+        when(mImsPhoneConnection.getImsCall()).thenReturn(mImsCall);
+        when(mTelecomAccountRegistry.isMergeCallSupported(notNull(PhoneAccountHandle.class)))
+                .thenReturn(mIsConferenceSupported);
+        when(mTelecomAccountRegistry.isMergeImsCallSupported(notNull(PhoneAccountHandle.class)))
+                .thenReturn(mIsImsConnection);
+        when(mTelecomAccountRegistry
+                .isVideoConferencingSupported(notNull(PhoneAccountHandle.class))).thenReturn(false);
+        when(mTelecomAccountRegistry
+                .isMergeOfWifiCallsAllowedWhenVoWifiOff(notNull(PhoneAccountHandle.class)))
+                .thenReturn(false);
     }
 
     public void setMockPhone(Phone newPhone) {
@@ -144,6 +177,13 @@
     }
 
     @Override
+    public void refreshConferenceSupported() {
+        if (mIsImsConnection) {
+            super.refreshConferenceSupported();
+        }
+    }
+
+    @Override
     public CharSequence getResourceText(int messageId) {
         return "TEST";
     }
@@ -154,8 +194,30 @@
     }
 
     @Override
-    void refreshConferenceSupported() {
-        // Requires ImsManager dependencies, do not implement during testing.
+    public void setConferenceSupported(boolean conferenceSupported) {
+        mIsConferenceSupported = conferenceSupported;
+    }
+
+    @Override
+    public boolean isConferenceSupported() {
+        return mIsConferenceSupported;
+    }
+
+    @Override
+    public TelecomAccountRegistry getTelecomAccountRegistry(Context context) {
+        return mTelecomAccountRegistry;
+    }
+
+    public void setIsVideoCall(boolean isVideoCall) {
+        if (isVideoCall) {
+            setVideoState(VideoProfile.STATE_TX_ENABLED);
+        } else {
+            setVideoState(VideoProfile.STATE_AUDIO_ONLY);
+        }
+    }
+
+    public void setWasVideoCall(boolean wasVideoCall) {
+        when(mImsCall.wasVideoCall()).thenReturn(wasVideoCall);
     }
 
     public int getNotifyPhoneAccountChangedCount() {
@@ -169,4 +231,19 @@
     public List<Bundle> getLastConnectionEventExtras() {
         return mLastConnectionEventExtras;
     }
+
+    public void setIsImsConnection(boolean isImsConnection) {
+        mIsImsConnection = isImsConnection;
+        when(mTelecomAccountRegistry.isMergeImsCallSupported(notNull(PhoneAccountHandle.class)))
+                .thenReturn(isImsConnection && mIsConferenceSupported);
+    }
+
+    public void setDownGradeVideoCall(boolean downgrade) {
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putBoolean(CarrierConfigManager.KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL,
+                downgrade);
+        when(mMockContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
+                .thenReturn(mCarrierConfigManager);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+    }
 }