Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 255bd10c authored by Brad Ebinger's avatar Brad Ebinger Committed by Automerger Merge Worker
Browse files

Merge changes I18caf795,Ic2e2a177 am: a9f6eb41 am: 2b2cc70c

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/1977274

Change-Id: Ibb1635500b22a90394d67a7a619e49f539846610
parents 743a1b6f 2b2cc70c
Loading
Loading
Loading
Loading
+74 −39
Original line number Diff line number Diff line
@@ -132,6 +132,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -188,15 +189,21 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
    private final Map<String, CallQualityMetrics> mCallQualityMetrics = new ConcurrentHashMap<>();
    private final ConcurrentLinkedQueue<CallQualityMetrics> mCallQualityMetricsHistory =
            new ConcurrentLinkedQueue<>();
    // True if there is a carrier config loaded for a specific subscrption (and not the default
    // True if there is a carrier config loaded for a specific subscription (and not the default
    // configuration).
    private boolean mCarrierConfigLoadedForSubscription = false;
    // Cache a carrier config for a subscription that is still pending a connection to the
    // ImsService.
    private Pair<Integer, PersistableBundle> mPendingCarrierConfigForSubId = null;
    // The subId of the last ImsService attached to this tracker or empty if there has not been
    // an attached ImsService yet.
    private Optional<Integer> mCurrentlyConnectedSubId = Optional.empty();

    private final MmTelFeatureListener mMmTelFeatureListener = new MmTelFeatureListener();
    private class MmTelFeatureListener extends MmTelFeature.Listener {

        private void processIncomingCall(IImsCallSession c, Bundle extras) {
            if (DBG) log("onReceive : incoming call intent");
            if (DBG) log("processIncomingCall: incoming call intent");
            mOperationLocalLog.log("onIncomingCall Received");

            if (extras == null) extras = new Bundle();
@@ -208,7 +215,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
                // For compatibility purposes with older vendor implmentations.
                isUssd |= extras.getBoolean(ImsManager.EXTRA_USSD, false);
                if (isUssd) {
                    if (DBG) log("onReceive : USSD");
                    if (DBG) log("processIncomingCall: USSD");
                    mUssdSession = mImsManager.takeCall(c, mImsUssdListener);
                    if (mUssdSession != null) {
                        mUssdSession.accept(ImsCallProfile.CALL_TYPE_VOICE);
@@ -220,7 +227,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
                // For compatibility purposes with older vendor implmentations.
                isUnknown |= extras.getBoolean(ImsManager.EXTRA_IS_UNKNOWN_CALL, false);
                if (DBG) {
                    log("onReceive : isUnknown = " + isUnknown
                    log("processIncomingCall: isUnknown = " + isUnknown
                            + " fg = " + mForegroundCall.getState()
                            + " bg = " + mBackgroundCall.getState());
                }
@@ -290,7 +297,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
                updatePhoneState();
                mPhone.notifyPreciseCallStateChanged();
            } catch (ImsException e) {
                loge("onReceive : exception " + e);
                loge("processIncomingCall: exception " + e);
            } catch (RemoteException e) {
            }
        }
@@ -359,7 +366,30 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (TelecomManager.ACTION_DEFAULT_DIALER_CHANGED.equals(intent.getAction())) {
            if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
                int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
                int phoneId = intent.getIntExtra(CarrierConfigManager.EXTRA_SLOT_INDEX,
                        SubscriptionManager.INVALID_PHONE_INDEX);
                if (mPhone.getPhoneId() != phoneId) {
                    log("onReceive: Skipping indication for other phoneId: " + phoneId);
                    return;
                }
                PersistableBundle carrierConfig = getCarrierConfigBundle(subId);
                if (!mCurrentlyConnectedSubId.isEmpty()
                        && subId == mCurrentlyConnectedSubId.get()) {
                    log("onReceive: Applying carrier config for subId: " + subId);
                    // Reset pending config state
                    mPendingCarrierConfigForSubId = null;
                    updateCarrierConfiguration(subId, carrierConfig);
                } else {
                    // cache the latest config update until ImsService connects for this subId.
                    // Once it has connected, startListeningForCalls will apply the pending config.
                    mPendingCarrierConfigForSubId = new Pair<>(subId, carrierConfig);
                    log("onReceive: caching carrier config until ImsService connects for subId: "
                            + subId);
                }
            } else if (TelecomManager.ACTION_DEFAULT_DIALER_CHANGED.equals(intent.getAction())) {
                mDefaultDialerUid.set(getPackageUid(context, intent.getStringExtra(
                        TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME)));
            }
@@ -939,9 +969,10 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
        mMetrics = TelephonyMetrics.getInstance();

        IntentFilter intentfilter = new IntentFilter();
        intentfilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        intentfilter.addAction(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED);
        mPhone.getContext().registerReceiver(mReceiver, intentfilter);
        updateCarrierConfiguration(mPhone.getSubId());
        updateCarrierConfiguration(mPhone.getSubId(), getCarrierConfigBundle(mPhone.getSubId()));

        mPhone.getDefaultPhone().getDataEnabledSettings().registerForDataEnabledChanged(
                this, EVENT_DATA_ENABLED_CHANGED, null);
@@ -964,18 +995,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
                    public void connectionReady(ImsManager manager, int subId) throws ImsException {
                        mImsManager = manager;
                        log("connectionReady for subId = " + subId);
                        if (subId != mPhone.getSubId()) {
                            // this means we are behind the ImsService that is actually connected,
                            // skip setting up the ImsService connection so that we do not send the
                            // wrong state information to that subscription.
                            // We will get another connectionReady with the up to date info once
                            // the ImsResolver has caught up.
                            loge("connectionReady: skipping, connection to ImsService for "
                                    + "subId = " + subId + " does not match the ImsPhone's current "
                                    + "subId = " + mPhone.getSubId());
                            return;

                        }
                        startListeningForCalls(subId);
                    }

@@ -1053,9 +1072,18 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            mUtInterface.registerForSuppServiceIndication(this, EVENT_SUPP_SERVICE_INDICATION,
                    null);
        }
        updateCarrierConfiguration(subId);

        if (mPendingCarrierConfigForSubId != null && mPendingCarrierConfigForSubId.first == subId) {
            // The carrier configuration was received by CarrierConfigManager before the indication
            // that the ImsService was connected.
            updateCarrierConfiguration(subId, mPendingCarrierConfigForSubId.second);
        } else {
            log("startListeningForCalls - waiting for the first carrier config indication for this "
                    + "subscription");
        }
        // For compatibility with apps that still use deprecated intent
        sendImsServiceStateIntent(ImsManager.ACTION_IMS_SERVICE_UP);
        mCurrentlyConnectedSubId = Optional.of(subId);
    }

    /**
@@ -1115,7 +1143,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            mUtInterface.unregisterForSuppServiceIndication(this);
            mUtInterface = null;
        }

        mCurrentlyConnectedSubId = Optional.empty();
        resetImsCapabilities();
        hangupAllOrphanedConnections(DisconnectCause.LOST_SIGNAL);
        // For compatibility with apps that still use deprecated intent
@@ -1468,17 +1496,10 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
     * @param subId The sub id to use to update configuration, may be invalid if a SIM has been
     *              removed.
     */
    private void updateCarrierConfiguration(int subId) {
    private void updateCarrierConfiguration(int subId, PersistableBundle carrierConfig) {
        // start by assuming the carrier config is not loaded for the provided subscription.
        mCarrierConfigLoadedForSubscription = false;

        CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
        if (carrierConfigManager == null) {
            loge("updateCarrierConfiguration: No carrier config service found");
            return;
        }
        PersistableBundle carrierConfig = carrierConfigManager.getConfigForSubId(subId);
        if (carrierConfig == null) {
            loge("updateCarrierConfiguration: carrier config is null, skipping.");
            return;
@@ -1520,6 +1541,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {

        // Only update the ImsService configurations for the case where a new subscription has been
        // loaded and is active.
        logi("updateCarrierConfiguration: Updating ImsService configs.");
        mCarrierConfigLoadedForSubscription = true;
        updateImsServiceConfig();
    }
@@ -4642,6 +4664,27 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
        return mMmTelCapabilities.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT);
    }

    /**
     *
     * @param subId The subId to get the carrier config for.
     * @return The PersistableBundle containing the carrier config  from
     * {@link CarrierConfigManager} for the subId specified.
     */
    private PersistableBundle getCarrierConfigBundle(int subId) {
        CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
        if (carrierConfigManager == null) {
            loge("getCarrierConfigBundle: No carrier config service found");
            return null;
        }
        PersistableBundle carrierConfig = carrierConfigManager.getConfigForSubId(subId);
        if (carrierConfig == null) {
            loge("getCarrierConfigBundle: carrier config is null, skipping.");
            return null;
        }
        return carrierConfig;
    }

    /**
     * Given a call subject, removes any characters considered by the current carrier to be
     * invalid, as well as escaping (using \) any characters which the carrier requires to be
@@ -4655,15 +4698,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            return callSubject;
        }

        // Get the carrier config for the current sub.
        CarrierConfigManager configMgr = (CarrierConfigManager)
                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
        // Bail if we can't find the carrier config service.
        if (configMgr == null) {
            return callSubject;
        }

        PersistableBundle carrierConfig = configMgr.getConfigForSubId(mPhone.getSubId());
        PersistableBundle carrierConfig = getCarrierConfigBundle(mPhone.getSubId());
        // Bail if no carrier config found.
        if (carrierConfig == null) {
            return callSubject;
+90 −8
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import static org.mockito.Mockito.when;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.NetworkStats;
@@ -92,6 +93,7 @@ import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.d2d.RtpTransport;
@@ -364,16 +366,85 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
        // updateCarrierConfiguration. Since the carrier config is not report carrier identified
        // config, we should not see updateImsServiceConfig called yet.
        verify(mImsManager, never()).updateImsServiceConfig();
        // Send disconnected indication
        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);

        // Receive a subscription loaded and IMS connection ready indication.
        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
        bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
        mContextFixture.getCarrierConfigBundle().putBoolean(
                CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
        sendCarrierConfigChanged();
        // CarrierConfigLoader has signalled that the carrier config has been applied for a specific
        // subscription. This will trigger unavailable -> ready indications.
        mConnectorListener.connectionReady(mImsManager, SUB_0);
        processAllMessages();
        verify(mImsManager).updateImsServiceConfig();
    }

    @Test
    @SmallTest
    public void testCarrierConfigSentLocked() throws Exception {
        // move to ImsService unavailable state.
        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
        mContextFixture.getCarrierConfigBundle().putBoolean(
                CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);

        sendCarrierConfigChanged();
        // No ImsService connected, so this will cache the config.
        verify(mImsManager, never()).updateImsServiceConfig();

        // Connect to ImsService, but sim is locked, so ensure we do not send configs yet
        doReturn(mIccCard).when(mPhone).getIccCard();
        doReturn(IccCardConstants.State.PIN_REQUIRED).when(mIccCard).getState();
        mConnectorListener.connectionReady(mImsManager, SUB_0);
        processAllMessages();
        verify(mImsManager, never()).updateImsServiceConfig();

        // Now move to ready and simulate carrier config change in response to SIM state change.
        doReturn(IccCardConstants.State.READY).when(mIccCard).getState();
        sendCarrierConfigChanged();
        verify(mImsManager).updateImsServiceConfig();
    }

    @Test
    @SmallTest
    public void testCarrierConfigSentAfterReady() throws Exception {
        verify(mImsManager, never()).updateImsServiceConfig();

        // Receive a subscription loaded and IMS connection ready indication.
        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
        mContextFixture.getCarrierConfigBundle().putBoolean(
                CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
        // CarrierConfigLoader has signalled that the carrier config has been applied for a specific
        // subscription. This will trigger unavailable -> ready indications.
        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
        mConnectorListener.connectionReady(mImsManager, SUB_0);
        processAllMessages();
        // Did not receive carrier config changed yet
        verify(mImsManager, never()).updateImsServiceConfig();
        sendCarrierConfigChanged();
        processAllMessages();
        verify(mImsManager).updateImsServiceConfig();
    }

    @Test
    @SmallTest
    public void testCarrierConfigSentBeforeReady() throws Exception {
        // move to ImsService unavailable state.
        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
        mContextFixture.getCarrierConfigBundle().putBoolean(
                CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);

        sendCarrierConfigChanged();
        // No ImsService connected, so this will cache the config.
        verify(mImsManager, never()).updateImsServiceConfig();

        // Connect to ImsService and ensure that the pending carrier config change is processed
        // properly.
        mConnectorListener.connectionReady(mImsManager, SUB_0);
        processAllMessages();
        verify(mImsManager).updateImsServiceConfig();
    }

@@ -1433,15 +1504,15 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testConfigureRtpHeaderExtensionTypes() throws Exception {

        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
        mContextFixture.getCarrierConfigBundle().putBoolean(
                CarrierConfigManager.KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL,
                true);
        mContextFixture.getCarrierConfigBundle().putBoolean(
                CarrierConfigManager.KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL,
                true);
        // Hacky but ImsPhoneCallTracker caches carrier config, so necessary.
        mCTUT.updateCarrierConfigCache(mContextFixture.getCarrierConfigBundle());
        sendCarrierConfigChanged();

        ImsPhoneCallTracker.Config config = new ImsPhoneCallTracker.Config();
        config.isD2DCommunicationSupported = true;
@@ -1464,15 +1535,15 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testRtpButNoSdp() throws Exception {

        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
        mContextFixture.getCarrierConfigBundle().putBoolean(
                CarrierConfigManager.KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL,
                true);
        mContextFixture.getCarrierConfigBundle().putBoolean(
                CarrierConfigManager.KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL,
                false);
        // Hacky but ImsPhoneCallTracker caches carrier config, so necessary.
        mCTUT.updateCarrierConfigCache(mContextFixture.getCarrierConfigBundle());
        sendCarrierConfigChanged();

        ImsPhoneCallTracker.Config config = new ImsPhoneCallTracker.Config();
        config.isD2DCommunicationSupported = true;
@@ -1494,6 +1565,9 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testDontConfigureRtpHeaderExtensionTypes() throws Exception {
        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
        sendCarrierConfigChanged();
        ImsPhoneCallTracker.Config config = new ImsPhoneCallTracker.Config();
        config.isD2DCommunicationSupported = false;
        mCTUT.setConfig(config);
@@ -1503,6 +1577,14 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
        verify(mImsManager, never()).setOfferedRtpHeaderExtensionTypes(any());
    }

    private void sendCarrierConfigChanged() {
        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        intent.putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
        intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, mPhone.getPhoneId());
        mBroadcastReceiver.onReceive(mContext, intent);
        processAllMessages();
    }

    private void assertVtDataUsageUpdated(int expectedToken, long rxBytes, long txBytes)
            throws RemoteException {
        final ArgumentCaptor<NetworkStats> ifaceStatsCaptor = ArgumentCaptor.forClass(