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

Commit 9f767b48 authored by Tyler Gunn's avatar Tyler Gunn
Browse files

Wiring up RTP Transport for D2D Communication.

- Adding configuration class in ImsPhoneCallTracker which is injected from
packages/services/Telephony to enable D2D comms.
- Set offered RTP header extensions when D2D comms enabled.
- Add some logging to track sending of D2D messages.

Test: Added unit test to verify ImsPhoneCallTracker sets the offered
RTP header extension types when D2D enabled.
Test: Added unit test to verify IPCT does not set offered RTP header
extensions whens D2D not enabled.
Test: Manual end to end test using adb shell command added for sending
D2D messages.
Bug: 163085177

Change-Id: I482cee19be369dc3d022c2fa57072f0cd63f87f8
parent 8e14fdc4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.telephony.d2d;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.telecom.Connection;
import android.telecom.Log;

import java.util.ArrayList;
import java.util.List;
@@ -175,6 +176,7 @@ public class Communicator implements TransportProtocol.Callback {
     */
    public void sendMessages(@NonNull Set<Message> messages) {
        if (mActiveTransport == null || !mIsNegotiated) {
            Log.w(this, "sendMessages: no active transport");
            return;
        }

+25 −0
Original line number Diff line number Diff line
@@ -70,6 +70,31 @@ public class RtpTransport implements TransportProtocol, RtpAdapter.Callback {
    public static Uri CALL_STATE_RTP_HEADER_EXTENSION =
            Uri.parse("http://develop.android.com/122020/d2dcomm#call-state");

    /**
     * Default local identifier for device state RTP header extensions.
     */
    public static int DEVICE_STATE_LOCAL_IDENTIFIER = 10;

    /**
     * Default local identifier for call state RTP header extensions.
     */
    public static int CALL_STATE_LOCAL_IDENTIFIER = 11;

    /**
     * {@link RtpHeaderExtensionType} for device state communication.
     */
    public static RtpHeaderExtensionType DEVICE_STATE_RTP_HEADER_EXTENSION_TYPE =
            new RtpHeaderExtensionType(DEVICE_STATE_LOCAL_IDENTIFIER,
                    DEVICE_STATE_RTP_HEADER_EXTENSION);

    /**
     * {@link RtpHeaderExtensionType} for call state communication.
     */
    public static RtpHeaderExtensionType CALL_STATE_RTP_HEADER_EXTENSION_TYPE =
            new RtpHeaderExtensionType(CALL_STATE_LOCAL_IDENTIFIER,
                    CALL_STATE_RTP_HEADER_EXTENSION);


    /**
     * See {@link #generateRtpHeaderExtension(Communicator.Message)} for more information; indicates
     * the offset of the parameter value in the RTP header extension payload.
+44 −0
Original line number Diff line number Diff line
@@ -71,11 +71,13 @@ import android.telephony.ims.ImsStreamMediaProfile;
import android.telephony.ims.ImsSuppServiceNotification;
import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.RtpHeaderExtension;
import android.telephony.ims.RtpHeaderExtensionType;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Log;
import android.util.Pair;
@@ -109,6 +111,7 @@ import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.d2d.RtpTransport;
import com.android.internal.telephony.dataconnection.DataEnabledSettings;
import com.android.internal.telephony.dataconnection.DataEnabledSettings.DataEnabledChangedReason;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
@@ -144,6 +147,20 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
    static final String LOG_TAG = "ImsPhoneCallTracker";
    static final String VERBOSE_STATE_TAG = "IPCTState";

    /**
     * Class which contains configuration items obtained from the config.xml in
     * packages/services/Telephony which are injected in the ImsPhoneCallTracker at phone creation
     * time.
     */
    public static class Config {
        /**
         * The value for config.xml/config_use_device_to_device_communication.
         * When {@code true}, the device supports device to device communication using both DTMF
         * and RTP header extensions.
         */
        public boolean isD2DCommunicationSupported;
    }

    public interface PhoneStateListener {
        void onPhoneStateChanged(PhoneConstants.State oldState, PhoneConstants.State newState);
    }
@@ -357,6 +374,11 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
     */
    private boolean mIsConferenceEventPackageEnabled = true;

    /**
     * The Telephony config.xml values pertinent to ImsPhoneCallTracker.
     */
    private Config mConfig = null;

    /**
     * Network callback used to schedule the handover check when a wireless network connects.
     */
@@ -1004,6 +1026,17 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
                    EVENT_SUPP_SERVICE_INDICATION, null);
        }

        // Where device to device communication is available, ensure that the
        // supported RTP header extension types defined in {@link RtpTransport} are
        // set as the offered RTP header extensions for this device.
        if (mConfig != null && mConfig.isD2DCommunicationSupported) {
            ArraySet<RtpHeaderExtensionType> types = new ArraySet<>();
            types.add(RtpTransport.CALL_STATE_RTP_HEADER_EXTENSION_TYPE);
            types.add(RtpTransport.DEVICE_STATE_RTP_HEADER_EXTENSION_TYPE);
            logi("connectionReady: set offered RTP header extension types");
            mImsManager.setOfferedRtpHeaderExtensionTypes(types);
        }

        if (mCarrierConfigLoaded) {
            mImsManager.updateImsServiceConfig();
        }
@@ -4329,6 +4362,9 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
        pw.println(" mCallQualityMetricsHistory=" + mCallQualityMetricsHistory);
        pw.println(" mIsConferenceEventPackageHandlingEnabled=" + mIsConferenceEventPackageEnabled);
        pw.println(" mSupportCepOnPeer=" + mSupportCepOnPeer);
        if (mConfig != null) {
            pw.println(" isDeviceToDeviceCommsSupported= " + mConfig.isD2DCommunicationSupported);
        }
        pw.println(" Event Log:");
        pw.increaseIndent();
        mOperationLocalLog.dump(pw);
@@ -5048,6 +5084,14 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
        return mConnections;
    }

    /**
     * Set up static configuration from package/services/Telephony's config.xml.
     * @param config the config.
     */
    public void setConfig(@NonNull Config config) {
        mConfig = config;
    }

    private void handleConferenceFailed(ImsPhoneConnection fgConnection,
            ImsPhoneConnection bgConnection) {
        if (fgConnection != null) {
+1 −0
Original line number Diff line number Diff line
@@ -1541,6 +1541,7 @@ public class ImsPhoneConnection extends Connection implements
     */
    public void sendRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> rtpHeaderExtensions) {
        if (mImsCall == null) {
            Rlog.w(LOG_TAG, "sendRtpHeaderExtensions: Not an IMS call");
            return;
        }
        Rlog.i(LOG_TAG, "sendRtpHeaderExtensions: numExtensions = " + rtpHeaderExtensions.size());
+46 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ import android.telephony.ims.ImsConferenceState;
import android.telephony.ims.ImsMmTelManager;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsStreamMediaProfile;
import android.telephony.ims.RtpHeaderExtensionType;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -91,6 +92,7 @@ import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.d2d.RtpTransport;
import com.android.internal.telephony.imsphone.ImsPhoneCallTracker.VtDataUsageProvider;

import org.junit.After;
@@ -100,10 +102,13 @@ import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.util.Set;

@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class ImsPhoneCallTrackerTest extends TelephonyTest {
@@ -132,6 +137,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
    private ImsPhoneCallTracker.ConnectorFactory mConnectorFactory;
    @Mock
    private FeatureConnector<ImsManager> mMockConnector;
    @Captor
    private ArgumentCaptor<Set<RtpHeaderExtensionType>> mRtpHeaderExtensionTypeCaptor;

    private void imsCallMocking(final ImsCall imsCall) throws Exception {

@@ -1275,6 +1282,45 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
        assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
    }

    /**
     * Ensures when D2D communication is supported that we register the expected D2D RTP header
     * extension types.
     * @throws Exception
     */
    @Test
    @SmallTest
    public void testConfigureRtpHeaderExtensionTypes() throws Exception {
        ImsPhoneCallTracker.Config config = new ImsPhoneCallTracker.Config();
        config.isD2DCommunicationSupported = true;
        mCTUT.setConfig(config);
        mConnectorListener.connectionReady(mImsManager);

        // Expect to get offered header extensions since d2d is supported.
        verify(mImsManager).setOfferedRtpHeaderExtensionTypes(
                mRtpHeaderExtensionTypeCaptor.capture());
        Set<RtpHeaderExtensionType> types = mRtpHeaderExtensionTypeCaptor.getValue();
        assertEquals(2, types.size());
        assertTrue(types.contains(RtpTransport.CALL_STATE_RTP_HEADER_EXTENSION_TYPE));
        assertTrue(types.contains(RtpTransport.DEVICE_STATE_RTP_HEADER_EXTENSION_TYPE));
    }

    /**
     * Ensures when D2D communication is not supported that we don't register the D2D RTP header
     * extension types.
     * @throws Exception
     */
    @Test
    @SmallTest
    public void testDontConfigureRtpHeaderExtensionTypes() throws Exception {
        ImsPhoneCallTracker.Config config = new ImsPhoneCallTracker.Config();
        config.isD2DCommunicationSupported = false;
        mCTUT.setConfig(config);
        mConnectorListener.connectionReady(mImsManager);

        // Expect no offered header extensions since d2d is not supported.
        verify(mImsManager, never()).setOfferedRtpHeaderExtensionTypes(any());
    }

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