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

Commit b11f7ed8 authored by Ravi Paluri's avatar Ravi Paluri Committed by android-build-merger
Browse files

Merge "Ims: Add support for Adhoc Conference calls"

am: b9072fec

Change-Id: I7da75abcbdc54a583126f232dfc02815e4d69337
parents f8117d6a b9072fec
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
public abstract class Connection {
    private static final String TAG = "Connection";

    public static final String ADHOC_CONFERENCE_ADDRESS = "tel:conf-factory";

    public interface PostDialListener {
        void onPostDialWait();
        void onPostDialChar(char c);
@@ -185,6 +187,8 @@ public abstract class Connection {
    protected String mAddress;     // MAY BE NULL!!!
    @UnsupportedAppUsage
    protected String mDialString;          // outgoing calls only
    protected String[] mParticipantsToDial;// outgoing calls only
    protected boolean mIsAdhocConference;
    @UnsupportedAppUsage
    protected int mNumberPresentation = PhoneConstants.PRESENTATION_ALLOWED;
    @UnsupportedAppUsage
@@ -313,6 +317,20 @@ public abstract class Connection {
        return mAddress;
    }

    /**
     * Gets the participants address (e.g. phone number) associated with connection.
     *
     * @return address or null if unavailable
     */
    public String[] getParticipantsToDial() {
        return mParticipantsToDial;
    }

    // return whether connection is AdhocConference or not
    public boolean isAdhocConference() {
        return mIsAdhocConference;
    }

    /**
     * Gets CNAP name associated with connection.
     * @return cnap name or null if unavailable
+33 −5
Original line number Diff line number Diff line
@@ -1221,6 +1221,38 @@ public class GsmCdmaPhone extends Phone {
                ringingCallState.isAlive());
    }

    private boolean useImsForCall(DialArgs dialArgs) {
        return isImsUseEnabled()
                && mImsPhone != null
                && (mImsPhone.isVolteEnabled() || mImsPhone.isWifiCallingEnabled() ||
                (mImsPhone.isVideoEnabled() && VideoProfile.isVideo(dialArgs.videoState)))
                && (mImsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE);
    }

    @Override
    public Connection startConference(String[] participantsToDial, DialArgs dialArgs)
            throws CallStateException {
        Phone imsPhone = mImsPhone;
        boolean useImsForCall = useImsForCall(dialArgs);
        logd("useImsForCall=" + useImsForCall);
        if (useImsForCall) {
            try {
                if (DBG) logd("Trying IMS PS Conference call");
                return imsPhone.startConference(participantsToDial, dialArgs);
            } catch (CallStateException e) {
                if (DBG) logd("IMS PS conference call exception " + e +
                        "useImsForCall =" + useImsForCall + ", imsPhone =" + imsPhone);
                 CallStateException ce = new CallStateException(e.getError(), e.getMessage());
                 ce.setStackTrace(e.getStackTrace());
                 throw ce;
            }
        } else {
            throw new CallStateException(
                CallStateException.ERROR_OUT_OF_SERVICE,
                "cannot dial conference call in out of service");
        }
    }

    @Override
    public Connection dial(String dialString, @NonNull DialArgs dialArgs)
            throws CallStateException {
@@ -1241,11 +1273,7 @@ public class GsmCdmaPhone extends Phone {
        boolean allowWpsOverIms = configManager.getConfigForSubId(getSubId())
                .getBoolean(CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL);

        boolean useImsForCall = isImsUseEnabled()
                 && imsPhone != null
                 && (imsPhone.isVolteEnabled() || imsPhone.isWifiCallingEnabled() ||
                 (imsPhone.isVideoEnabled() && VideoProfile.isVideo(dialArgs.videoState)))
                 && (imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
        boolean useImsForCall = useImsForCall(dialArgs)
                 && (isWpsCall ? allowWpsOverIms : true);

        boolean useImsForEmergency = imsPhone != null
+15 −0
Original line number Diff line number Diff line
@@ -434,6 +434,21 @@ public interface PhoneInternalInterface {
     */
    Connection dial(String dialString, @NonNull DialArgs dialArgs) throws CallStateException;

    /**
     * Initiate a new conference connection. This happens asynchronously, so you
     * cannot assume the audio path is connected (or a call index has been
     * assigned) until PhoneStateChanged notification has occurred.
     *
     * @param participantsToDial The participants to dial.
     * @param dialArgs Parameters to perform the start conference with.
     * @exception CallStateException if a new outgoing call is not currently
     *                possible because no more call slots exist or a call exists
     *                that is dialing, alerting, ringing, or waiting. Other
     *                errors are handled asynchronously.
     */
    Connection startConference(String[] participantsToDial, @NonNull DialArgs dialArgs)
            throws CallStateException;

    /**
     * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
     * without SEND (so <code>dial</code> is not appropriate).
+12 −0
Original line number Diff line number Diff line
@@ -875,6 +875,18 @@ public class ImsPhone extends ImsPhoneBase {
        mDefaultPhone.setRadioPower(on);
    }

    @Override
    public Connection startConference(String[] participantsToDial, DialArgs dialArgs)
            throws CallStateException {
         ImsDialArgs.Builder imsDialArgsBuilder;
         if (!(dialArgs instanceof ImsDialArgs)) {
             imsDialArgsBuilder = ImsDialArgs.Builder.from(dialArgs);
         } else {
             imsDialArgsBuilder = ImsDialArgs.Builder.from((ImsDialArgs) dialArgs);
         }
         return mCT.startConference(participantsToDial, imsDialArgsBuilder.build());
    }

    @Override
    public Connection dial(String dialString, DialArgs dialArgs) throws CallStateException {
        return dialInternal(dialString, dialArgs, null);
+98 −55
Original line number Diff line number Diff line
@@ -787,6 +787,91 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
        }
    }

    private boolean prepareForDialing(ImsPhone.ImsDialArgs dialArgs) throws CallStateException {
        boolean holdBeforeDial = false;
        // note that this triggers call state changed notif
        clearDisconnected();
        if (mImsManager == null) {
            throw new CallStateException("service not available");
        }
        // See if there are any issues which preclude placing a call; throw a CallStateException
        // if there is.
        checkForDialIssues();
        int videoState = dialArgs.videoState;
        if (!canAddVideoCallDuringImsAudioCall(videoState)) {
            throw new CallStateException("cannot dial in current state");
        }

        // The new call must be assigned to the foreground call.
        // That call must be idle, so place anything that's
        // there on hold
        if (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) {
            if (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE) {
                //we should have failed in checkForDialIssues above before we get here
                throw new CallStateException(CallStateException.ERROR_TOO_MANY_CALLS,
                        "Already too many ongoing calls.");
            }
            // foreground call is empty for the newly dialed connection
            holdBeforeDial = true;
            mPendingCallVideoState = videoState;
            mPendingIntentExtras = dialArgs.intentExtras;
            holdActiveCallForPendingMo();
        }

        ImsPhoneCall.State fgState = ImsPhoneCall.State.IDLE;
        ImsPhoneCall.State bgState = ImsPhoneCall.State.IDLE;

        synchronized (mSyncHold) {
            if (holdBeforeDial) {
                fgState = mForegroundCall.getState();
                bgState = mBackgroundCall.getState();
                //holding foreground call failed
                if (fgState == ImsPhoneCall.State.ACTIVE) {
                    throw new CallStateException("cannot dial in current state");
                }
                //holding foreground call succeeded
                if (bgState == ImsPhoneCall.State.HOLDING) {
                    holdBeforeDial = false;
                }
            }
        }
        return holdBeforeDial;
    }

    public Connection startConference(String[] participantsToDial, ImsPhone.ImsDialArgs dialArgs)
            throws CallStateException {

        int clirMode = dialArgs.clirMode;
        int videoState = dialArgs.videoState;

        if (DBG) log("dial clirMode=" + clirMode);
        boolean holdBeforeDial = prepareForDialing(dialArgs);

        mClirMode = clirMode;

        synchronized (mSyncHold) {
            mLastDialArgs = dialArgs;
            mPendingMO = new ImsPhoneConnection(mPhone,
                    participantsToDial, this, mForegroundCall,
                    false);
            mPendingMO.setVideoState(videoState);
            if (dialArgs.rttTextStream != null) {
                log("startConference: setting RTT stream on mPendingMO");
                mPendingMO.setCurrentRttTextStream(dialArgs.rttTextStream);
            }
        }
        addConnection(mPendingMO);

        if (!holdBeforeDial) {
            dialInternal(mPendingMO, clirMode, videoState, dialArgs.intentExtras);
        }

        updatePhoneState();
        mPhone.notifyPreciseCallStateChanged();

        return mPendingMO;
    }

    @UnsupportedAppUsage
    public Connection dial(String dialString, int videoState, Bundle intentExtras) throws
            CallStateException {
@@ -822,20 +907,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            dialString = convertNumberIfNecessary(mPhone, dialString);
        }

        // note that this triggers call state changed notif
        clearDisconnected();

        if (mImsManager == null) {
            throw new CallStateException("service not available");
        }

        // See if there are any issues which preclude placing a call; throw a CallStateException
        // if there is.
        checkForDialIssues();

        if (!canAddVideoCallDuringImsAudioCall(videoState)) {
            throw new CallStateException("cannot dial in current state");
        }
        mClirMode = clirMode;
        boolean holdBeforeDial = prepareForDialing(dialArgs);

        if (isPhoneInEcmMode && isEmergencyNumber) {
            handleEcmTimer(ImsPhone.CANCEL_ECM_TIMER);
@@ -849,46 +922,10 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            videoState = VideoProfile.STATE_AUDIO_ONLY;
        }

        boolean holdBeforeDial = false;

        // The new call must be assigned to the foreground call.
        // That call must be idle, so place anything that's
        // there on hold
        if (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) {
            if (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE) {
                //we should have failed in checkForDialIssues above before we get here
                throw new CallStateException(CallStateException.ERROR_TOO_MANY_CALLS,
                        "Already too many ongoing calls.");
            }
            // foreground call is empty for the newly dialed connection
            holdBeforeDial = true;
        // Cache the video state for pending MO call.
        mPendingCallVideoState = videoState;
            mPendingIntentExtras = dialArgs.intentExtras;
            holdActiveCallForPendingMo();
        }

        ImsPhoneCall.State fgState = ImsPhoneCall.State.IDLE;
        ImsPhoneCall.State bgState = ImsPhoneCall.State.IDLE;

        mClirMode = clirMode;

        synchronized (mSyncHold) {
            if (holdBeforeDial) {
                fgState = mForegroundCall.getState();
                bgState = mBackgroundCall.getState();

                //holding foreground call failed
                if (fgState == ImsPhoneCall.State.ACTIVE) {
                    throw new CallStateException("cannot dial in current state");
                }

                //holding foreground call succeeded
                if (bgState == ImsPhoneCall.State.HOLDING) {
                    holdBeforeDial = false;
                }
            }

            mLastDialString = dialString;
            mLastDialArgs = dialArgs;
            mPendingMO = new ImsPhoneConnection(mPhone,
@@ -1099,8 +1136,9 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            return;
        }

        if (conn.getAddress()== null || conn.getAddress().length() == 0
                || conn.getAddress().indexOf(PhoneNumberUtils.WILD) >= 0) {
        if (!conn.isAdhocConference() &&
                (conn.getAddress()== null || conn.getAddress().length() == 0
                || conn.getAddress().indexOf(PhoneNumberUtils.WILD) >= 0)) {
            // Phone number is invalid
            conn.setDisconnectCause(DisconnectCause.INVALID_NUMBER);
            sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
@@ -1119,6 +1157,9 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
        try {
            String[] callees = new String[] { conn.getAddress() };
            ImsCallProfile profile = mImsManager.createCallProfile(serviceType, callType);
            if (conn.isAdhocConference()) {
                profile.setCallExtraBoolean(ImsCallProfile.EXTRA_CONFERENCE, true);
            }
            profile.setCallExtraInt(ImsCallProfile.EXTRA_OIR, clirMode);

            if (isEmergencyCall) {
@@ -1158,7 +1199,9 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
                // being sent to the lower layers/to the network.
            }

            ImsCall imsCall = mImsManager.makeCall(profile, callees, mImsCallListener);
            ImsCall imsCall = mImsManager.makeCall(profile,
                    conn.isAdhocConference() ? conn.getParticipantsToDial() : callees,
                    mImsCallListener);
            conn.setImsCall(imsCall);

            mMetrics.writeOnImsCallStart(mPhone.getPhoneId(),
Loading