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

Commit db5b6a50 authored by Tyler Gunn's avatar Tyler Gunn
Browse files

Handle video session modify responses while paused.

There is a limitation in the modem implementation whereby when the remote
party has paused video (eg sent dialer to the background) any session
modify requests which are sent are responded to, but the video state of
the connection is NOT updated until the video state becomes unpaused
again.

To handle this, ImsPhoneConnection will now listen for session modify
responses received via the VideoProvider.  When paused, valid
responses to requests will be used to update the current video state of
the ImsPhoneConnection.  When the video becomes unpaused, we will resume
using the modem reported video state.

Bug: 29381561
Change-Id: I1ac854dbc292affb3bc0bb9ce98b2fea33014cbb
parent cdcdab38
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ import com.android.ims.ImsServiceClass;
import com.android.ims.ImsSuppServiceNotification;
import com.android.ims.ImsUtInterface;
import com.android.ims.internal.IImsVideoCallProvider;
import com.android.ims.internal.ImsVideoCallProvider;
import com.android.ims.internal.ImsVideoCallProviderWrapper;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
@@ -1452,6 +1453,15 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            ImsPhoneConnection conn = findConnection(imsCall);
            if (DBG) log("cause = " + cause + " conn = " + conn);

            if (conn != null) {
                android.telecom.Connection.VideoProvider videoProvider = conn.getVideoProvider();
                if (videoProvider instanceof ImsVideoCallProviderWrapper) {
                    ImsVideoCallProviderWrapper wrapper = (ImsVideoCallProviderWrapper)
                            videoProvider;

                    wrapper.removeImsVideoProviderCallback(conn);
                }
            }
            if (mOnHoldToneId == System.identityHashCode(conn)) {
                if (conn != null && mOnHoldToneStarted) {
                    mPhone.stopOnHoldTone(conn);
@@ -2325,6 +2335,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            conn.setVideoProvider(imsVideoCallProviderWrapper);
            imsVideoCallProviderWrapper.registerForDataUsageUpdate
                    (this, EVENT_VT_DATA_USAGE_UPDATE, imsCall);
            imsVideoCallProviderWrapper.addImsVideoProviderCallback(conn);
        }
    }

+87 −3
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.PowerManager;
import android.os.Registrant;
import android.os.SystemClock;
import android.telecom.Log;
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
@@ -37,6 +38,7 @@ import android.text.TextUtils;

import com.android.ims.ImsException;
import com.android.ims.ImsStreamMediaProfile;
import com.android.ims.internal.ImsVideoCallProviderWrapper;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;
@@ -51,7 +53,9 @@ import java.util.Objects;
/**
 * {@hide}
 */
public class ImsPhoneConnection extends Connection {
public class ImsPhoneConnection extends Connection implements
        ImsVideoCallProviderWrapper.ImsVideoProviderWrapperCallback {

    private static final String LOG_TAG = "ImsPhoneConnection";
    private static final boolean DBG = true;

@@ -88,6 +92,15 @@ public class ImsPhoneConnection extends Connection {

    private boolean mIsEmergency = false;

    /**
     * Used to indicate that video state changes detected by
     * {@link #updateMediaCapabilities(ImsCall)} should be ignored.  When a video state change from
     * unpaused to paused occurs, we set this flag and then update the existing video state when
     * new {@link #onReceiveSessionModifyResponse(int, VideoProfile, VideoProfile)} callbacks come
     * in.  When the video un-pauses we continue receiving the video state updates.
     */
    private boolean mShouldIgnoreVideoStateChanges = false;

    /**
     * Used to indicate whether the wifi state is based on
     * {@link com.android.ims.ImsConnectionStateListener#
@@ -792,8 +805,35 @@ public class ImsPhoneConnection extends Connection {
                        .getVideoStateFromImsCallProfile(negotiatedCallProfile);

                if (oldVideoState != newVideoState) {
                    // The video state has changed.  See also code in onReceiveSessionModifyResponse
                    // below.  When the video enters a paused state, subsequent changes to the video
                    // state will not be reported by the modem.  In onReceiveSessionModifyResponse
                    // we will be updating the current video state while paused to include any
                    // changes the modem reports via the video provider.  When the video enters an
                    // unpaused state, we will resume passing the video states from the modem as is.
                    if (VideoProfile.isPaused(oldVideoState) &&
                            !VideoProfile.isPaused(newVideoState)) {
                        // Video entered un-paused state; recognize updates from now on; we want to
                        // ensure that the new un-paused state is propagated to Telecom, so change
                        // this now.
                        mShouldIgnoreVideoStateChanges = false;
                    }

                    if (!mShouldIgnoreVideoStateChanges) {
                        setVideoState(newVideoState);
                        changed = true;
                    } else {
                        Rlog.d(LOG_TAG, "updateMediaCapabilities - ignoring video state change " +
                                "due to paused state.");
                    }

                    if (!VideoProfile.isPaused(oldVideoState) &&
                            VideoProfile.isPaused(newVideoState)) {
                        // Video entered pause state; ignore updates until un-paused.  We do this
                        // after setVideoState is called above to ensure Telecom is notified that
                        // the device has entered paused state.
                        mShouldIgnoreVideoStateChanges = true;
                    }
                }
            }

@@ -1000,4 +1040,48 @@ public class ImsPhoneConnection extends Connection {
    protected boolean isEmergency() {
        return mIsEmergency;
    }

    /**
     * Handles notifications from the {@link ImsVideoCallProviderWrapper} of session modification
     * responses received.
     *
     * @param status The status of the original request.
     * @param requestProfile The requested video profile.
     * @param responseProfile The response upon video profile.
     */
    @Override
    public void onReceiveSessionModifyResponse(int status, VideoProfile requestProfile,
            VideoProfile responseProfile) {
        if (status == android.telecom.Connection.VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS &&
                mShouldIgnoreVideoStateChanges) {
            int currentVideoState = getVideoState();
            int newVideoState = responseProfile.getVideoState();

            // If the current video state is paused, the modem will not send us any changes to
            // the TX and RX bits of the video state.  Until the video is un-paused we will
            // "fake out" the video state by applying the changes that the modem reports via a
            // response.

            // First, find out whether there was a change to the TX or RX bits:
            int changedBits = currentVideoState ^ newVideoState;
            changedBits &= VideoProfile.STATE_BIDIRECTIONAL;
            if (changedBits == 0) {
                // No applicable change, bail out.
                return;
            }

            // Turn off any existing bits that changed.
            currentVideoState &= ~(changedBits & currentVideoState);
            // Turn on any new bits that turned on.
            currentVideoState |= changedBits & newVideoState;

            Rlog.d(LOG_TAG, "onReceiveSessionModifyResponse : received " +
                    VideoProfile.videoStateToString(requestProfile.getVideoState()) +
                    " / " +
                    VideoProfile.videoStateToString(responseProfile.getVideoState()) +
                    " while paused ; sending new videoState = " +
                    VideoProfile.videoStateToString(currentVideoState));
            setVideoState(currentVideoState);
        }
    }
}