/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony.imsphone;

import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.PersistableBundle;
import android.os.PowerManager;
import android.os.Registrant;
import android.os.SystemClock;
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.ims.ImsCallProfile;
import android.telephony.ims.ImsStreamMediaProfile;
import android.text.TextUtils;

import com.android.ims.ImsCall;
import com.android.ims.ImsException;
import com.android.ims.internal.ImsVideoCallProviderWrapper;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.UUSInfo;
import com.android.internal.telephony.metrics.TelephonyMetrics;

import java.util.Objects;

/**
 * {@hide}
 */
public class ImsPhoneConnection extends Connection implements
        ImsVideoCallProviderWrapper.ImsVideoProviderWrapperCallback {

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

    //***** Instance Variables

    @UnsupportedAppUsage
    private ImsPhoneCallTracker mOwner;
    @UnsupportedAppUsage
    private ImsPhoneCall mParent;
    private ImsCall mImsCall;
    private Bundle mExtras = new Bundle();
    private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();

    @UnsupportedAppUsage
    private boolean mDisconnected;

    /*
    int mIndex;          // index in ImsPhoneCallTracker.connections[], -1 if unassigned
                        // The GSM index is 1 + this
    */

    /*
     * These time/timespan values are based on System.currentTimeMillis(),
     * i.e., "wall clock" time.
     */
    private long mDisconnectTime;

    private UUSInfo mUusInfo;
    private Handler mHandler;
    private final Messenger mHandlerMessenger;

    private PowerManager.WakeLock mPartialWakeLock;

    // The cached connect time of the connection when it turns into a conference.
    private long mConferenceConnectTime = 0;

    // The cached delay to be used between DTMF tones fetched from carrier config.
    private int mDtmfToneDelay = 0;

    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;

    private ImsVideoCallProviderWrapper mImsVideoCallProviderWrapper;

    private int mPreciseDisconnectCause = 0;

    private ImsRttTextHandler mRttTextHandler;
    private android.telecom.Connection.RttTextStream mRttTextStream;
    // This reflects the RTT status as reported to us by the IMS stack via the media profile.
    private boolean mIsRttEnabledForCall = false;

    /**
     * Used to indicate that this call is in the midst of being merged into a conference.
     */
    private boolean mIsMergeInProcess = false;

    /**
     * Used as an override to determine whether video is locally available for this call.
     * This allows video availability to be overridden in the case that the modem says video is
     * currently available, but mobile data is off and the carrier is metering data for video
     * calls.
     */
    private boolean mIsLocalVideoCapable = true;

    // Store the current audio codec
    private int mAudioCodec = ImsStreamMediaProfile.AUDIO_QUALITY_NONE;

    //***** Event Constants
    private static final int EVENT_DTMF_DONE = 1;
    private static final int EVENT_PAUSE_DONE = 2;
    private static final int EVENT_NEXT_POST_DIAL = 3;
    private static final int EVENT_WAKE_LOCK_TIMEOUT = 4;
    private static final int EVENT_DTMF_DELAY_DONE = 5;

    //***** Constants
    private static final int PAUSE_DELAY_MILLIS = 3 * 1000;
    private static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000;

    //***** Inner Classes

    class MyHandler extends Handler {
        MyHandler(Looper l) {super(l);}

        @Override
        public void
        handleMessage(Message msg) {

            switch (msg.what) {
                case EVENT_NEXT_POST_DIAL:
                case EVENT_DTMF_DELAY_DONE:
                case EVENT_PAUSE_DONE:
                    processNextPostDialChar();
                    break;
                case EVENT_WAKE_LOCK_TIMEOUT:
                    releaseWakeLock();
                    break;
                case EVENT_DTMF_DONE:
                    // We may need to add a delay specified by carrier between DTMF tones that are
                    // sent out.
                    mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_DTMF_DELAY_DONE),
                            mDtmfToneDelay);
                    break;
            }
        }
    }

    //***** Constructors

    /** This is probably an MT call */
    public ImsPhoneConnection(Phone phone, ImsCall imsCall, ImsPhoneCallTracker ct,
           ImsPhoneCall parent, boolean isUnknown) {
        super(PhoneConstants.PHONE_TYPE_IMS);
        createWakeLock(phone.getContext());
        acquireWakeLock();

        mOwner = ct;
        mHandler = new MyHandler(mOwner.getLooper());
        mHandlerMessenger = new Messenger(mHandler);
        mImsCall = imsCall;

        if ((imsCall != null) && (imsCall.getCallProfile() != null)) {
            mAddress = imsCall.getCallProfile().getCallExtra(ImsCallProfile.EXTRA_OI);
            mCnapName = imsCall.getCallProfile().getCallExtra(ImsCallProfile.EXTRA_CNA);
            mNumberPresentation = ImsCallProfile.OIRToPresentation(
                    imsCall.getCallProfile().getCallExtraInt(ImsCallProfile.EXTRA_OIR));
            mCnapNamePresentation = ImsCallProfile.OIRToPresentation(
                    imsCall.getCallProfile().getCallExtraInt(ImsCallProfile.EXTRA_CNAP));
            updateMediaCapabilities(imsCall);
        } else {
            mNumberPresentation = PhoneConstants.PRESENTATION_UNKNOWN;
            mCnapNamePresentation = PhoneConstants.PRESENTATION_UNKNOWN;
        }

        mIsIncoming = !isUnknown;
        mCreateTime = System.currentTimeMillis();
        mUusInfo = null;

        // Ensure any extras set on the ImsCallProfile at the start of the call are cached locally
        // in the ImsPhoneConnection.  This isn't going to inform any listeners (since the original
        // connection is not likely to be associated with a TelephonyConnection yet).
        updateExtras(imsCall);

        mParent = parent;
        mParent.attach(this,
                (mIsIncoming? ImsPhoneCall.State.INCOMING: ImsPhoneCall.State.DIALING));

        fetchDtmfToneDelay(phone);

        if (phone.getContext().getResources().getBoolean(
                com.android.internal.R.bool.config_use_voip_mode_for_ims)) {
            setAudioModeIsVoip(true);
        }
    }

    /** This is an MO call, created when dialing */
    public ImsPhoneConnection(Phone phone, String dialString, ImsPhoneCallTracker ct,
            ImsPhoneCall parent, boolean isEmergency) {
        super(PhoneConstants.PHONE_TYPE_IMS);
        createWakeLock(phone.getContext());
        acquireWakeLock();

        mOwner = ct;
        mHandler = new MyHandler(mOwner.getLooper());
        mHandlerMessenger = new Messenger(mHandler);

        mDialString = dialString;

        mAddress = PhoneNumberUtils.extractNetworkPortionAlt(dialString);
        mPostDialString = PhoneNumberUtils.extractPostDialPortion(dialString);

        //mIndex = -1;

        mIsIncoming = false;
        mCnapName = null;
        mCnapNamePresentation = PhoneConstants.PRESENTATION_ALLOWED;
        mNumberPresentation = PhoneConstants.PRESENTATION_ALLOWED;
        mCreateTime = System.currentTimeMillis();

        mParent = parent;
        parent.attachFake(this, ImsPhoneCall.State.DIALING);

        mIsEmergency = isEmergency;
        if (isEmergency) {
            setEmergencyCallInfo(mOwner);
        }

        fetchDtmfToneDelay(phone);

        if (phone.getContext().getResources().getBoolean(
                com.android.internal.R.bool.config_use_voip_mode_for_ims)) {
            setAudioModeIsVoip(true);
        }
    }

    public void dispose() {
    }

    static boolean
    equalsHandlesNulls (Object a, Object b) {
        return (a == null) ? (b == null) : a.equals (b);
    }

    static boolean
    equalsBaseDialString (String a, String b) {
        return (a == null) ? (b == null) : (b != null && a.startsWith (b));
    }

    private int applyLocalCallCapabilities(ImsCallProfile localProfile, int capabilities) {
        Rlog.i(LOG_TAG, "applyLocalCallCapabilities - localProfile = " + localProfile);
        capabilities = removeCapability(capabilities,
                Connection.Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL);

        if (!mIsLocalVideoCapable) {
            Rlog.i(LOG_TAG, "applyLocalCallCapabilities - disabling video (overidden)");
            return capabilities;
        }
        switch (localProfile.mCallType) {
            case ImsCallProfile.CALL_TYPE_VT:
                // Fall-through
            case ImsCallProfile.CALL_TYPE_VIDEO_N_VOICE:
                capabilities = addCapability(capabilities,
                        Connection.Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
                break;
        }
        return capabilities;
    }

    private static int applyRemoteCallCapabilities(ImsCallProfile remoteProfile, int capabilities) {
        Rlog.w(LOG_TAG, "applyRemoteCallCapabilities - remoteProfile = "+remoteProfile);
        capabilities = removeCapability(capabilities,
                Connection.Capability.SUPPORTS_VT_REMOTE_BIDIRECTIONAL);

        switch (remoteProfile.mCallType) {
            case ImsCallProfile.CALL_TYPE_VT:
                // fall-through
            case ImsCallProfile.CALL_TYPE_VIDEO_N_VOICE:
                capabilities = addCapability(capabilities,
                        Connection.Capability.SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
                break;
        }
        return capabilities;
    }

    @Override
    public String getOrigDialString(){
        return mDialString;
    }

    @UnsupportedAppUsage
    @Override
    public ImsPhoneCall getCall() {
        return mParent;
    }

    @Override
    public long getDisconnectTime() {
        return mDisconnectTime;
    }

    @Override
    public long getHoldingStartTime() {
        return mHoldingStartTime;
    }

    @Override
    public long getHoldDurationMillis() {
        if (getState() != ImsPhoneCall.State.HOLDING) {
            // If not holding, return 0
            return 0;
        } else {
            return SystemClock.elapsedRealtime() - mHoldingStartTime;
        }
    }

    public void setDisconnectCause(int cause) {
        mCause = cause;
    }

    @Override
    public String getVendorDisconnectCause() {
      return null;
    }

    @UnsupportedAppUsage
    public ImsPhoneCallTracker getOwner () {
        return mOwner;
    }

    @Override
    public ImsPhoneCall.State getState() {
        if (mDisconnected) {
            return ImsPhoneCall.State.DISCONNECTED;
        } else {
            return super.getState();
        }
    }

    @Override
    public void deflect(String number) throws CallStateException {
        if (mParent.getState().isRinging()) {
            try {
                if (mImsCall != null) {
                    mImsCall.deflect(number);
                } else {
                    throw new CallStateException("no valid ims call to deflect");
                }
            } catch (ImsException e) {
                throw new CallStateException("cannot deflect call");
            }
        } else {
            throw new CallStateException("phone not ringing");
        }
    }

    @Override
    public void hangup() throws CallStateException {
        if (!mDisconnected) {
            mOwner.hangup(this);
        } else {
            throw new CallStateException ("disconnected");
        }
    }

    @Override
    public void separate() throws CallStateException {
        throw new CallStateException ("not supported");
    }

    @Override
    public void proceedAfterWaitChar() {
        if (mPostDialState != PostDialState.WAIT) {
            Rlog.w(LOG_TAG, "ImsPhoneConnection.proceedAfterWaitChar(): Expected "
                    + "getPostDialState() to be WAIT but was " + mPostDialState);
            return;
        }

        setPostDialState(PostDialState.STARTED);

        processNextPostDialChar();
    }

    @Override
    public void proceedAfterWildChar(String str) {
        if (mPostDialState != PostDialState.WILD) {
            Rlog.w(LOG_TAG, "ImsPhoneConnection.proceedAfterWaitChar(): Expected "
                    + "getPostDialState() to be WILD but was " + mPostDialState);
            return;
        }

        setPostDialState(PostDialState.STARTED);

        // make a new postDialString, with the wild char replacement string
        // at the beginning, followed by the remaining postDialString.

        StringBuilder buf = new StringBuilder(str);
        buf.append(mPostDialString.substring(mNextPostDialChar));
        mPostDialString = buf.toString();
        mNextPostDialChar = 0;
        if (Phone.DEBUG_PHONE) {
            Rlog.d(LOG_TAG, "proceedAfterWildChar: new postDialString is " +
                    mPostDialString);
        }

        processNextPostDialChar();
    }

    @Override
    public void cancelPostDial() {
        setPostDialState(PostDialState.CANCELLED);
    }

    /**
     * Called when this Connection is being hung up locally (eg, user pressed "end")
     */
    void
    onHangupLocal() {
        mCause = DisconnectCause.LOCAL;
    }

    /** Called when the connection has been disconnected */
    @Override
    public boolean onDisconnect(int cause) {
        Rlog.d(LOG_TAG, "onDisconnect: cause=" + cause);
        if (mCause != DisconnectCause.LOCAL || cause == DisconnectCause.INCOMING_REJECTED) {
            mCause = cause;
        }
        return onDisconnect();
    }

    @UnsupportedAppUsage
    public boolean onDisconnect() {
        boolean changed = false;

        if (!mDisconnected) {
            //mIndex = -1;

            mDisconnectTime = System.currentTimeMillis();
            mDuration = SystemClock.elapsedRealtime() - mConnectTimeReal;
            mDisconnected = true;

            mOwner.mPhone.notifyDisconnect(this);
            notifyDisconnect(mCause);

            if (mParent != null) {
                changed = mParent.connectionDisconnected(this);
            } else {
                Rlog.d(LOG_TAG, "onDisconnect: no parent");
            }
            synchronized (this) {
                if (mRttTextHandler != null) {
                    mRttTextHandler.tearDown();
                }
                if (mImsCall != null) mImsCall.close();
                mImsCall = null;
            }
        }
        releaseWakeLock();
        return changed;
    }

    /**
     * An incoming or outgoing call has connected
     */
    void
    onConnectedInOrOut() {
        mConnectTime = System.currentTimeMillis();
        mConnectTimeReal = SystemClock.elapsedRealtime();
        mDuration = 0;

        if (Phone.DEBUG_PHONE) {
            Rlog.d(LOG_TAG, "onConnectedInOrOut: connectTime=" + mConnectTime);
        }

        if (!mIsIncoming) {
            // outgoing calls only
            processNextPostDialChar();
        }
        releaseWakeLock();
    }

    /*package*/ void
    onStartedHolding() {
        mHoldingStartTime = SystemClock.elapsedRealtime();
    }
    /**
     * Performs the appropriate action for a post-dial char, but does not
     * notify application. returns false if the character is invalid and
     * should be ignored
     */
    private boolean
    processPostDialChar(char c) {
        if (PhoneNumberUtils.is12Key(c)) {
            Message dtmfComplete = mHandler.obtainMessage(EVENT_DTMF_DONE);
            dtmfComplete.replyTo = mHandlerMessenger;
            mOwner.sendDtmf(c, dtmfComplete);
        } else if (c == PhoneNumberUtils.PAUSE) {
            // From TS 22.101:
            // It continues...
            // Upon the called party answering the UE shall send the DTMF digits
            // automatically to the network after a delay of 3 seconds( 20 ).
            // The digits shall be sent according to the procedures and timing
            // specified in 3GPP TS 24.008 [13]. The first occurrence of the
            // "DTMF Control Digits Separator" shall be used by the ME to
            // distinguish between the addressing digits (i.e. the phone number)
            // and the DTMF digits. Upon subsequent occurrences of the
            // separator,
            // the UE shall pause again for 3 seconds ( 20 ) before sending
            // any further DTMF digits.
            mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_PAUSE_DONE),
                    PAUSE_DELAY_MILLIS);
        } else if (c == PhoneNumberUtils.WAIT) {
            setPostDialState(PostDialState.WAIT);
        } else if (c == PhoneNumberUtils.WILD) {
            setPostDialState(PostDialState.WILD);
        } else {
            return false;
        }

        return true;
    }

    @Override
    protected void finalize() {
        releaseWakeLock();
    }

    private void
    processNextPostDialChar() {
        char c = 0;
        Registrant postDialHandler;

        if (mPostDialState == PostDialState.CANCELLED) {
            //Rlog.d(LOG_TAG, "##### processNextPostDialChar: postDialState == CANCELLED, bail");
            return;
        }

        if (mPostDialString == null || mPostDialString.length() <= mNextPostDialChar) {
            setPostDialState(PostDialState.COMPLETE);

            // notifyMessage.arg1 is 0 on complete
            c = 0;
        } else {
            boolean isValid;

            setPostDialState(PostDialState.STARTED);

            c = mPostDialString.charAt(mNextPostDialChar++);

            isValid = processPostDialChar(c);

            if (!isValid) {
                // Will call processNextPostDialChar
                mHandler.obtainMessage(EVENT_NEXT_POST_DIAL).sendToTarget();
                // Don't notify application
                Rlog.e(LOG_TAG, "processNextPostDialChar: c=" + c + " isn't valid!");
                return;
            }
        }

        notifyPostDialListenersNextChar(c);

        // TODO: remove the following code since the handler no longer executes anything.
        postDialHandler = mOwner.mPhone.getPostDialHandler();

        Message notifyMessage;

        if (postDialHandler != null
                && (notifyMessage = postDialHandler.messageForRegistrant()) != null) {
            // The AsyncResult.result is the Connection object
            PostDialState state = mPostDialState;
            AsyncResult ar = AsyncResult.forMessage(notifyMessage);
            ar.result = this;
            ar.userObj = state;

            // arg1 is the character that was/is being processed
            notifyMessage.arg1 = c;

            //Rlog.v(LOG_TAG,
            //      "##### processNextPostDialChar: send msg to postDialHandler, arg1=" + c);
            notifyMessage.sendToTarget();
        }
    }

    /**
     * Set post dial state and acquire wake lock while switching to "started"
     * state, the wake lock will be released if state switches out of "started"
     * state or after WAKE_LOCK_TIMEOUT_MILLIS.
     * @param s new PostDialState
     */
    private void setPostDialState(PostDialState s) {
        if (mPostDialState != PostDialState.STARTED
                && s == PostDialState.STARTED) {
            acquireWakeLock();
            Message msg = mHandler.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
            mHandler.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS);
        } else if (mPostDialState == PostDialState.STARTED
                && s != PostDialState.STARTED) {
            mHandler.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
            releaseWakeLock();
        }
        mPostDialState = s;
        notifyPostDialListeners();
    }

    @UnsupportedAppUsage
    private void
    createWakeLock(Context context) {
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
    }

    @UnsupportedAppUsage
    private void
    acquireWakeLock() {
        Rlog.d(LOG_TAG, "acquireWakeLock");
        mPartialWakeLock.acquire();
    }

    void
    releaseWakeLock() {
        if (mPartialWakeLock != null) {
            synchronized (mPartialWakeLock) {
                if (mPartialWakeLock.isHeld()) {
                    Rlog.d(LOG_TAG, "releaseWakeLock");
                    mPartialWakeLock.release();
                }
            }
        }
    }

    private void fetchDtmfToneDelay(Phone phone) {
        CarrierConfigManager configMgr = (CarrierConfigManager)
                phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
        PersistableBundle b = configMgr.getConfigForSubId(phone.getSubId());
        if (b != null) {
            mDtmfToneDelay = b.getInt(CarrierConfigManager.KEY_IMS_DTMF_TONE_DELAY_INT);
        }
    }

    @Override
    public int getNumberPresentation() {
        return mNumberPresentation;
    }

    @Override
    public UUSInfo getUUSInfo() {
        return mUusInfo;
    }

    @Override
    public Connection getOrigConnection() {
        return null;
    }

    @UnsupportedAppUsage
    @Override
    public synchronized boolean isMultiparty() {
        return mImsCall != null && mImsCall.isMultiparty();
    }

    /**
     * Where {@link #isMultiparty()} is {@code true}, determines if this {@link ImsCall} is the
     * origin of the conference call (i.e. {@code #isConferenceHost()} is {@code true}), or if this
     * {@link ImsCall} is a member of a conference hosted on another device.
     *
     * @return {@code true} if this call is the origin of the conference call it is a member of,
     *      {@code false} otherwise.
     */
    @Override
    public synchronized boolean isConferenceHost() {
        return mImsCall != null && mImsCall.isConferenceHost();
    }

    @Override
    public boolean isMemberOfPeerConference() {
        return !isConferenceHost();
    }

    public synchronized ImsCall getImsCall() {
        return mImsCall;
    }

    public synchronized void setImsCall(ImsCall imsCall) {
        mImsCall = imsCall;
    }

    public void changeParent(ImsPhoneCall parent) {
        mParent = parent;
    }

    /**
     * @return {@code true} if the {@link ImsPhoneConnection} or its media capabilities have been
     *     changed, and {@code false} otherwise.
     */
    public boolean update(ImsCall imsCall, ImsPhoneCall.State state) {
        if (state == ImsPhoneCall.State.ACTIVE) {
            // If the state of the call is active, but there is a pending request to the RIL to hold
            // the call, we will skip this update.  This is really a signalling delay or failure
            // from the RIL, but we will prevent it from going through as we will end up erroneously
            // making this call active when really it should be on hold.
            if (imsCall.isPendingHold()) {
                Rlog.w(LOG_TAG, "update : state is ACTIVE, but call is pending hold, skipping");
                return false;
            }

            if (mParent.getState().isRinging() || mParent.getState().isDialing()) {
                onConnectedInOrOut();
            }

            if (mParent.getState().isRinging() || mParent == mOwner.mBackgroundCall) {
                //mForegroundCall should be IDLE
                //when accepting WAITING call
                //before accept WAITING call,
                //the ACTIVE call should be held ahead
                mParent.detach(this);
                mParent = mOwner.mForegroundCall;
                mParent.attach(this);
            }
        } else if (state == ImsPhoneCall.State.HOLDING) {
            onStartedHolding();
        }

        boolean updateParent = mParent.update(this, imsCall, state);
        boolean updateAddressDisplay = updateAddressDisplay(imsCall);
        boolean updateMediaCapabilities = updateMediaCapabilities(imsCall);
        boolean updateExtras = updateExtras(imsCall);

        return updateParent || updateAddressDisplay || updateMediaCapabilities || updateExtras;
    }

    @Override
    public int getPreciseDisconnectCause() {
        return mPreciseDisconnectCause;
    }

    public void setPreciseDisconnectCause(int cause) {
        mPreciseDisconnectCause = cause;
    }

    /**
     * Notifies this Connection of a request to disconnect a participant of the conference managed
     * by the connection.
     *
     * @param endpoint the {@link android.net.Uri} of the participant to disconnect.
     */
    @Override
    public void onDisconnectConferenceParticipant(Uri endpoint) {
        ImsCall imsCall = getImsCall();
        if (imsCall == null) {
            return;
        }
        try {
            imsCall.removeParticipants(new String[]{endpoint.toString()});
        } catch (ImsException e) {
            // No session in place -- no change
            Rlog.e(LOG_TAG, "onDisconnectConferenceParticipant: no session in place. "+
                    "Failed to disconnect endpoint = " + endpoint);
        }
    }

    /**
     * Sets the conference connect time.  Used when an {@code ImsConference} is created to out of
     * this phone connection.
     *
     * @param conferenceConnectTime The conference connect time.
     */
    public void setConferenceConnectTime(long conferenceConnectTime) {
        mConferenceConnectTime = conferenceConnectTime;
    }

    /**
     * @return The conference connect time.
     */
    public long getConferenceConnectTime() {
        return mConferenceConnectTime;
    }

    /**
     * Check for a change in the address display related fields for the {@link ImsCall}, and
     * update the {@link ImsPhoneConnection} with this information.
     *
     * @param imsCall The call to check for changes in address display fields.
     * @return Whether the address display fields have been changed.
     */
    public boolean updateAddressDisplay(ImsCall imsCall) {
        if (imsCall == null) {
            return false;
        }

        boolean changed = false;
        ImsCallProfile callProfile = imsCall.getCallProfile();
        if (callProfile != null && isIncoming()) {
            // Only look for changes to the address for incoming calls.  The originating identity
            // can change for outgoing calls due to, for example, a call being forwarded to
            // voicemail.  This address change does not need to be presented to the user.
            String address = callProfile.getCallExtra(ImsCallProfile.EXTRA_OI);
            String name = callProfile.getCallExtra(ImsCallProfile.EXTRA_CNA);
            int nump = ImsCallProfile.OIRToPresentation(
                    callProfile.getCallExtraInt(ImsCallProfile.EXTRA_OIR));
            int namep = ImsCallProfile.OIRToPresentation(
                    callProfile.getCallExtraInt(ImsCallProfile.EXTRA_CNAP));
            if (Phone.DEBUG_PHONE) {
                Rlog.d(LOG_TAG, "updateAddressDisplay: callId = " + getTelecomCallId()
                        + " address = " + Rlog.pii(LOG_TAG, address) + " name = "
                        + Rlog.pii(LOG_TAG, name) + " nump = " + nump + " namep = " + namep);
            }
            if (!mIsMergeInProcess) {
                // Only process changes to the name and address when a merge is not in process.
                // When call A initiated a merge with call B to form a conference C, there is a
                // point in time when the ImsCall transfers the conference call session into A,
                // at which point the ImsConferenceController creates the conference in Telecom.
                // For some carriers C will have a unique conference URI address.  Swapping the
                // conference session into A, which is about to be disconnected, to be logged to
                // the call log using the conference address.  To prevent this we suppress updates
                // to the call address while a merge is in process.
                if (!equalsBaseDialString(mAddress, address)) {
                    mAddress = address;
                    changed = true;
                }
                if (TextUtils.isEmpty(name)) {
                    if (!TextUtils.isEmpty(mCnapName)) {
                        mCnapName = "";
                        changed = true;
                    }
                } else if (!name.equals(mCnapName)) {
                    mCnapName = name;
                    changed = true;
                }
                if (mNumberPresentation != nump) {
                    mNumberPresentation = nump;
                    changed = true;
                }
                if (mCnapNamePresentation != namep) {
                    mCnapNamePresentation = namep;
                    changed = true;
                }
            }
        }
        return changed;
    }

    /**
     * Check for a change in the video capabilities and audio quality for the {@link ImsCall}, and
     * update the {@link ImsPhoneConnection} with this information.
     *
     * @param imsCall The call to check for changes in media capabilities.
     * @return Whether the media capabilities have been changed.
     */
    public boolean updateMediaCapabilities(ImsCall imsCall) {
        if (imsCall == null) {
            return false;
        }

        boolean changed = false;

        try {
            // The actual call profile (negotiated between local and peer).
            ImsCallProfile negotiatedCallProfile = imsCall.getCallProfile();

            if (negotiatedCallProfile != null) {
                int oldVideoState = getVideoState();
                int newVideoState = ImsCallProfile
                        .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) {
                        updateVideoState(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;
                    }
                }

                if (negotiatedCallProfile.mMediaProfile != null) {
                    mIsRttEnabledForCall = negotiatedCallProfile.mMediaProfile.isRttCall();

                    if (mIsRttEnabledForCall && mRttTextHandler == null) {
                        Rlog.d(LOG_TAG, "updateMediaCapabilities -- turning RTT on, profile="
                                + negotiatedCallProfile);
                        startRttTextProcessing();
                        onRttInitiated();
                        changed = true;
                    } else if (!mIsRttEnabledForCall && mRttTextHandler != null) {
                        Rlog.d(LOG_TAG, "updateMediaCapabilities -- turning RTT off, profile="
                                + negotiatedCallProfile);
                        mRttTextHandler.tearDown();
                        mRttTextHandler = null;
                        onRttTerminated();
                        changed = true;
                    }
                }
            }

            // Check for a change in the capabilities for the call and update
            // {@link ImsPhoneConnection} with this information.
            int capabilities = getConnectionCapabilities();

            // Use carrier config to determine if downgrading directly to audio-only is supported.
            if (mOwner.isCarrierDowngradeOfVtCallSupported()) {
                capabilities = addCapability(capabilities,
                        Connection.Capability.SUPPORTS_DOWNGRADE_TO_VOICE_REMOTE |
                                Capability.SUPPORTS_DOWNGRADE_TO_VOICE_LOCAL);
            } else {
                capabilities = removeCapability(capabilities,
                        Connection.Capability.SUPPORTS_DOWNGRADE_TO_VOICE_REMOTE |
                                Capability.SUPPORTS_DOWNGRADE_TO_VOICE_LOCAL);
            }

            // Get the current local call capabilities which might be voice or video or both.
            ImsCallProfile localCallProfile = imsCall.getLocalCallProfile();
            Rlog.v(LOG_TAG, "update localCallProfile=" + localCallProfile);
            if (localCallProfile != null) {
                capabilities = applyLocalCallCapabilities(localCallProfile, capabilities);
            }

            // Get the current remote call capabilities which might be voice or video or both.
            ImsCallProfile remoteCallProfile = imsCall.getRemoteCallProfile();
            Rlog.v(LOG_TAG, "update remoteCallProfile=" + remoteCallProfile);
            if (remoteCallProfile != null) {
                capabilities = applyRemoteCallCapabilities(remoteCallProfile, capabilities);
            }
            if (getConnectionCapabilities() != capabilities) {
                setConnectionCapabilities(capabilities);
                changed = true;
            }

            if (!mOwner.isViLteDataMetered()) {
                Rlog.v(LOG_TAG, "data is not metered");
            } else {
                if (mImsVideoCallProviderWrapper != null) {
                    mImsVideoCallProviderWrapper.setIsVideoEnabled(
                            hasCapabilities(Connection.Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL));
                }
            }

            // Metrics for audio codec
            if (localCallProfile != null
                    && localCallProfile.mMediaProfile.mAudioQuality != mAudioCodec) {
                mAudioCodec = localCallProfile.mMediaProfile.mAudioQuality;
                mMetrics.writeAudioCodecIms(mOwner.mPhone.getPhoneId(), imsCall.getCallSession());
            }

            int newAudioQuality =
                    getAudioQualityFromCallProfile(localCallProfile, remoteCallProfile);
            if (getAudioQuality() != newAudioQuality) {
                setAudioQuality(newAudioQuality);
                changed = true;
            }
        } catch (ImsException e) {
            // No session in place -- no change
        }

        return changed;
    }

    private void updateVideoState(int newVideoState) {
        if (mImsVideoCallProviderWrapper != null) {
            mImsVideoCallProviderWrapper.onVideoStateChanged(newVideoState);
        }
        setVideoState(newVideoState);
    }


    /**
     * Send a RTT upgrade request to the remote party.
     * @param textStream RTT text stream to use
     */
    public void startRtt(android.telecom.Connection.RttTextStream textStream) {
        ImsCall imsCall = getImsCall();
        if (imsCall != null) {
            getImsCall().sendRttModifyRequest(true);
            setCurrentRttTextStream(textStream);
        }
    }

    /**
     * Terminate the current RTT session.
     */
    public void stopRtt() {
        getImsCall().sendRttModifyRequest(false);
    }

    /**
     * Sends the user's response to a remotely-issued RTT upgrade request
     *
     * @param textStream A valid {@link android.telecom.Connection.RttTextStream} if the user
     *                   accepts, {@code null} if not.
     */
    public void sendRttModifyResponse(android.telecom.Connection.RttTextStream textStream) {
        boolean accept = textStream != null;
        ImsCall imsCall = getImsCall();

        if (imsCall != null) {
            imsCall.sendRttModifyResponse(accept);
            if (accept) {
                setCurrentRttTextStream(textStream);
            } else {
                Rlog.e(LOG_TAG, "sendRttModifyResponse: foreground call has no connections");
            }
        }
    }

    public void onRttMessageReceived(String message) {
        synchronized (this) {
            if (mRttTextHandler == null) {
                Rlog.w(LOG_TAG, "onRttMessageReceived: RTT text handler not available."
                        + " Attempting to create one.");
                if (mRttTextStream == null) {
                    Rlog.e(LOG_TAG, "onRttMessageReceived:"
                            + " Unable to process incoming message. No textstream available");
                    return;
                }
                createRttTextHandler();
            }
        }
        mRttTextHandler.sendToInCall(message);
    }

    public void onRttAudioIndicatorChanged(ImsStreamMediaProfile profile) {
        Bundle extras = new Bundle();
        extras.putBoolean(android.telecom.Connection.EXTRA_IS_RTT_AUDIO_PRESENT,
                profile.isReceivingRttAudio());
        onConnectionEvent(android.telecom.Connection.EVENT_RTT_AUDIO_INDICATION_CHANGED,
                extras);
    }

    public void setCurrentRttTextStream(android.telecom.Connection.RttTextStream rttTextStream) {
        synchronized (this) {
            mRttTextStream = rttTextStream;
            if (mRttTextHandler == null && mIsRttEnabledForCall) {
                Rlog.i(LOG_TAG, "setCurrentRttTextStream: Creating a text handler");
                createRttTextHandler();
            }
        }
    }

    public boolean hasRttTextStream() {
        return mRttTextStream != null;
    }

    public boolean isRttEnabledForCall() {
        return mIsRttEnabledForCall;
    }

    public void startRttTextProcessing() {
        synchronized (this) {
            if (mRttTextStream == null) {
                Rlog.w(LOG_TAG, "startRttTextProcessing: no RTT text stream. Ignoring.");
                return;
            }
            if (mRttTextHandler != null) {
                Rlog.w(LOG_TAG, "startRttTextProcessing: RTT text handler already exists");
                return;
            }
            createRttTextHandler();
        }
    }

    // Make sure to synchronize on ImsPhoneConnection.this before calling.
    private void createRttTextHandler() {
        mRttTextHandler = new ImsRttTextHandler(Looper.getMainLooper(),
                (message) -> {
                    ImsCall imsCall = getImsCall();
                    if (imsCall != null) {
                        imsCall.sendRttMessage(message);
                    }
                });
        mRttTextHandler.initialize(mRttTextStream);
    }

    /**
     * Updates the IMS call rat based on the {@link ImsCallProfile#EXTRA_CALL_RAT_TYPE}.
     *
     * @param extras The ImsCallProfile extras.
     */
    private void updateImsCallRatFromExtras(Bundle extras) {
        if (extras.containsKey(ImsCallProfile.EXTRA_CALL_RAT_TYPE) ||
                extras.containsKey(ImsCallProfile.EXTRA_CALL_RAT_TYPE_ALT)) {

            ImsCall call = getImsCall();
            int callTech = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
            if (call != null) {
                callTech = call.getRadioTechnology();
            }

            // Report any changes for call tech change
            setCallRadioTech(callTech);
        }
    }

    private void updateEmergencyCallFromExtras(Bundle extras) {
        if (extras.getBoolean(ImsCallProfile.EXTRA_EMERGENCY_CALL)) {
            setIsNetworkIdentifiedEmergencyCall(true);
        }
    }

    /**
     * Check for a change in call extras of {@link ImsCall}, and
     * update the {@link ImsPhoneConnection} accordingly.
     *
     * @param imsCall The call to check for changes in extras.
     * @return Whether the extras fields have been changed.
     */
     boolean updateExtras(ImsCall imsCall) {
        if (imsCall == null) {
            return false;
        }

        final ImsCallProfile callProfile = imsCall.getCallProfile();
        final Bundle extras = callProfile != null ? callProfile.mCallExtras : null;
        if (extras == null && DBG) {
            Rlog.d(LOG_TAG, "Call profile extras are null.");
        }

        final boolean changed = !areBundlesEqual(extras, mExtras);
        if (changed) {
            updateImsCallRatFromExtras(extras);
            updateEmergencyCallFromExtras(extras);
            mExtras.clear();
            mExtras.putAll(extras);
            setConnectionExtras(mExtras);
        }
        return changed;
    }

    private static boolean areBundlesEqual(Bundle extras, Bundle newExtras) {
        if (extras == null || newExtras == null) {
            return extras == newExtras;
        }

        if (extras.size() != newExtras.size()) {
            return false;
        }

        for(String key : extras.keySet()) {
            if (key != null) {
                final Object value = extras.get(key);
                final Object newValue = newExtras.get(key);
                if (!Objects.equals(value, newValue)) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * Determines the {@link ImsPhoneConnection} audio quality based on the local and remote
     * {@link ImsCallProfile}. Indicate a HD audio call if the local stream profile
     * is AMR_WB, EVRC_WB, EVS_WB, EVS_SWB, EVS_FB and
     * there is no remote restrict cause.
     *
     * @param localCallProfile The local call profile.
     * @param remoteCallProfile The remote call profile.
     * @return The audio quality.
     */
    private int getAudioQualityFromCallProfile(
            ImsCallProfile localCallProfile, ImsCallProfile remoteCallProfile) {
        if (localCallProfile == null || remoteCallProfile == null
                || localCallProfile.mMediaProfile == null) {
            return AUDIO_QUALITY_STANDARD;
        }

        final boolean isEvsCodecHighDef = (localCallProfile.mMediaProfile.mAudioQuality
                        == ImsStreamMediaProfile.AUDIO_QUALITY_EVS_WB
                || localCallProfile.mMediaProfile.mAudioQuality
                        == ImsStreamMediaProfile.AUDIO_QUALITY_EVS_SWB
                || localCallProfile.mMediaProfile.mAudioQuality
                        == ImsStreamMediaProfile.AUDIO_QUALITY_EVS_FB);

        final boolean isHighDef = (localCallProfile.mMediaProfile.mAudioQuality
                        == ImsStreamMediaProfile.AUDIO_QUALITY_AMR_WB
                || localCallProfile.mMediaProfile.mAudioQuality
                        == ImsStreamMediaProfile.AUDIO_QUALITY_EVRC_WB
                || isEvsCodecHighDef)
                && remoteCallProfile.getRestrictCause() == ImsCallProfile.CALL_RESTRICT_CAUSE_NONE;
        return isHighDef ? AUDIO_QUALITY_HIGH_DEFINITION : AUDIO_QUALITY_STANDARD;
    }

    /**
     * Provides a string representation of the {@link ImsPhoneConnection}.  Primarily intended for
     * use in log statements.
     *
     * @return String representation of call.
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[ImsPhoneConnection objId: ");
        sb.append(System.identityHashCode(this));
        sb.append(" telecomCallID: ");
        sb.append(getTelecomCallId());
        sb.append(" address: ");
        sb.append(Rlog.pii(LOG_TAG, getAddress()));
        sb.append(" ImsCall: ");
        synchronized (this) {
            if (mImsCall == null) {
                sb.append("null");
            } else {
                sb.append(mImsCall);
            }
        }
        sb.append("]");
        return sb.toString();
    }

    @Override
    public void setVideoProvider(android.telecom.Connection.VideoProvider videoProvider) {
        super.setVideoProvider(videoProvider);

        if (videoProvider instanceof ImsVideoCallProviderWrapper) {
            mImsVideoCallProviderWrapper = (ImsVideoCallProviderWrapper) videoProvider;
        }
    }

    /**
     * Indicates whether current phone connection is emergency or not
     * @return boolean: true if emergency, false otherwise
     */
    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);
        }
    }

    /**
     * Issues a request to pause the video using {@link VideoProfile#STATE_PAUSED} from a source
     * other than the InCall UI.
     *
     * @param source The source of the pause request.
     */
    public void pauseVideo(int source) {
        if (mImsVideoCallProviderWrapper == null) {
            return;
        }

        mImsVideoCallProviderWrapper.pauseVideo(getVideoState(), source);
    }

    /**
     * Issues a request to resume the video using {@link VideoProfile#STATE_PAUSED} from a source
     * other than the InCall UI.
     *
     * @param source The source of the resume request.
     */
    public void resumeVideo(int source) {
        if (mImsVideoCallProviderWrapper == null) {
            return;
        }

        mImsVideoCallProviderWrapper.resumeVideo(getVideoState(), source);
    }

    /**
     * Determines if a specified source has issued a pause request.
     *
     * @param source The source.
     * @return {@code true} if the source issued a pause request, {@code false} otherwise.
     */
    public boolean wasVideoPausedFromSource(int source) {
        if (mImsVideoCallProviderWrapper == null) {
            return false;
        }

        return mImsVideoCallProviderWrapper.wasVideoPausedFromSource(source);
    }

    /**
     * Mark the call as in the process of being merged and inform the UI of the merge start.
     */
    public void handleMergeStart() {
        mIsMergeInProcess = true;
        onConnectionEvent(android.telecom.Connection.EVENT_MERGE_START, null);
    }

    /**
     * Mark the call as done merging and inform the UI of the merge start.
     */
    public void handleMergeComplete() {
        mIsMergeInProcess = false;
        onConnectionEvent(android.telecom.Connection.EVENT_MERGE_COMPLETE, null);
    }

    public void changeToPausedState() {
        int newVideoState = getVideoState() | VideoProfile.STATE_PAUSED;
        Rlog.i(LOG_TAG, "ImsPhoneConnection: changeToPausedState - setting paused bit; "
                + "newVideoState=" + VideoProfile.videoStateToString(newVideoState));
        updateVideoState(newVideoState);
        mShouldIgnoreVideoStateChanges = true;
    }

    public void changeToUnPausedState() {
        int newVideoState = getVideoState() & ~VideoProfile.STATE_PAUSED;
        Rlog.i(LOG_TAG, "ImsPhoneConnection: changeToUnPausedState - unsetting paused bit; "
                + "newVideoState=" + VideoProfile.videoStateToString(newVideoState));
        updateVideoState(newVideoState);
        mShouldIgnoreVideoStateChanges = false;
    }

    public void setLocalVideoCapable(boolean isVideoEnabled) {
        mIsLocalVideoCapable = isVideoEnabled;
        Rlog.i(LOG_TAG, "setLocalVideoCapable: mIsLocalVideoCapable = " + mIsLocalVideoCapable
                + "; updating local video availability.");
        updateMediaCapabilities(getImsCall());
    }
}
