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

Commit 0c0e3fa5 authored by Chen Xu's avatar Chen Xu Committed by Android Partner Code Review
Browse files

Merge "ImsPhoneConnection Unit Test" into mm-wireless-dev

parents c629786a f9b150b2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ abstract class ImsPhoneBase extends Phone {
        super.notifyPreciseCallStateChangedP();
    }

    void notifyDisconnect(Connection cn) {
    public void notifyDisconnect(Connection cn) {
        mDisconnectRegistrants.notifyResult(cn);
    }

+8 −15
Original line number Diff line number Diff line
@@ -66,8 +66,7 @@ public class ImsPhoneCall extends Call {
        mCallContext = CONTEXT_UNKNOWN;
    }

    /*package*/
    ImsPhoneCall(ImsPhoneCallTracker owner, String context) {
    public ImsPhoneCall(ImsPhoneCallTracker owner, String context) {
        mOwner = owner;
        mCallContext = context;
    }
@@ -151,8 +150,7 @@ public class ImsPhoneCall extends Call {

    //***** Called from ImsPhoneConnection

    /*package*/ void
    attach(Connection conn) {
    public void attach(Connection conn) {
        if (VDBG) {
            Rlog.v(LOG_TAG, "attach : " + mCallContext + " conn = " + conn);
        }
@@ -162,8 +160,7 @@ public class ImsPhoneCall extends Call {
        mOwner.logState();
    }

    /*package*/ void
    attach(Connection conn, State state) {
    public void attach(Connection conn, State state) {
        if (VDBG) {
            Rlog.v(LOG_TAG, "attach : " + mCallContext + " state = " +
                    state.toString());
@@ -172,16 +169,14 @@ public class ImsPhoneCall extends Call {
        mState = state;
    }

    /*package*/ void
    attachFake(Connection conn, State state) {
    public void attachFake(Connection conn, State state) {
        attach(conn, state);
    }

    /**
     * Called by ImsPhoneConnection when it has disconnected
     */
    boolean
    connectionDisconnected(ImsPhoneConnection conn) {
    public boolean connectionDisconnected(ImsPhoneConnection conn) {
        if (mState != State.DISCONNECTED) {
            /* If only disconnected connections remain, we are disconnected*/

@@ -203,8 +198,7 @@ public class ImsPhoneCall extends Call {
        return false;
    }

    /*package*/ void
    detach(ImsPhoneConnection conn) {
    public void detach(ImsPhoneConnection conn) {
        if (VDBG) {
            Rlog.v(LOG_TAG, "detach : " + mCallContext + " conn = " + conn);
        }
@@ -305,8 +299,7 @@ public class ImsPhoneCall extends Call {
                ? true : false;
    }

    /*package*/ boolean
    update (ImsPhoneConnection conn, ImsCall imsCall, State state) {
    public boolean update (ImsPhoneConnection conn, ImsCall imsCall, State state) {
        State newState = state;
        boolean changed = false;

@@ -342,7 +335,7 @@ public class ImsPhoneCall extends Call {
        return (ImsPhoneConnection) getEarliestConnection();
    }

    void switchWith(ImsPhoneCall that) {
    public void switchWith(ImsPhoneCall that) {
        if (VDBG) {
            Rlog.v(LOG_TAG, "switchWith : switchCall = " + this + " withCall = " + that);
        }
+4 −6
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ import com.android.internal.telephony.gsm.SuppServiceNotification;
/**
 * {@hide}
 */
public final class ImsPhoneCallTracker extends CallTracker {
public class ImsPhoneCallTracker extends CallTracker {
    static final String LOG_TAG = "ImsPhoneCallTracker";

    private static final boolean DBG = true;
@@ -814,7 +814,7 @@ public final class ImsPhoneCallTracker extends CallTracker {
        return mDesiredMute;
    }

    /* package */ void sendDtmf(char c, Message result) {
    public void sendDtmf(char c, Message result) {
        if (DBG) log("sendDtmf");

        ImsCall imscall = mForegroundCall.getImsCall();
@@ -849,8 +849,7 @@ public final class ImsPhoneCallTracker extends CallTracker {

    //***** Called from ImsPhoneConnection

    /*package*/ void
    hangup (ImsPhoneConnection conn) throws CallStateException {
    public void hangup (ImsPhoneConnection conn) throws CallStateException {
        if (DBG) log("hangup connection");

        if (conn.getOwner() != this) {
@@ -863,8 +862,7 @@ public final class ImsPhoneCallTracker extends CallTracker {

    //***** Called from ImsPhoneCall

    /* package */ void
    hangup (ImsPhoneCall call) throws CallStateException {
    public void hangup (ImsPhoneCall call) throws CallStateException {
        if (DBG) log("hangup call");

        if (call.getConnections().size() == 0) {
+7 −10
Original line number Diff line number Diff line
@@ -140,8 +140,7 @@ public class ImsPhoneConnection extends Connection {
    //***** Constructors

    /** This is probably an MT call */
    /*package*/
    ImsPhoneConnection(Phone phone, ImsCall imsCall, ImsPhoneCallTracker ct,
    public ImsPhoneConnection(Phone phone, ImsCall imsCall, ImsPhoneCallTracker ct,
           ImsPhoneCall parent, boolean isUnknown) {
        super(PhoneConstants.PHONE_TYPE_IMS);
        createWakeLock(phone.getContext());
@@ -183,8 +182,7 @@ public class ImsPhoneConnection extends Connection {
    }

    /** This is an MO call, created when dialing */
    /*package*/
    ImsPhoneConnection(Phone phone, String dialString, ImsPhoneCallTracker ct,
    public ImsPhoneConnection(Phone phone, String dialString, ImsPhoneCallTracker ct,
            ImsPhoneCall parent, boolean isEmergency) {
        super(PhoneConstants.PHONE_TYPE_IMS);
        createWakeLock(phone.getContext());
@@ -393,8 +391,7 @@ public class ImsPhoneConnection extends Connection {
        return onDisconnect();
    }

    /*package*/ boolean
    onDisconnect() {
    public boolean onDisconnect() {
        boolean changed = false;

        if (!mDisconnected) {
@@ -632,15 +629,15 @@ public class ImsPhoneConnection extends Connection {
        return !isConferenceHost();
    }

    /*package*/ ImsCall getImsCall() {
    public ImsCall getImsCall() {
        return mImsCall;
    }

    /*package*/ void setImsCall(ImsCall imsCall) {
    public void setImsCall(ImsCall imsCall) {
        mImsCall = imsCall;
    }

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

@@ -648,7 +645,7 @@ public class ImsPhoneConnection extends Connection {
     * @return {@code true} if the {@link ImsPhoneConnection} or its media capabilities have been
     *     changed, and {@code false} otherwise.
     */
    /*package*/ boolean update(ImsCall imsCall, ImsPhoneCall.State state) {
    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
+243 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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;

import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.telephony.DisconnectCause;

import com.android.ims.ImsCall;
import com.android.ims.ImsCallProfile;
import com.android.internal.telephony.imsphone.ImsPhoneCall;
import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
import com.android.internal.telephony.imsphone.ImsPhoneConnection;
import static org.mockito.Mockito.doAnswer;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.lang.reflect.Field;

import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;

public class ImsPhoneConnectionTest extends TelephonyTest {
    private ImsPhoneConnection mConnectionUT;
    private Bundle mBundle = new Bundle();
    @Mock
    private ImsPhoneCall mForeGroundCall;
    @Mock
    private ImsPhoneCall mBackGroundCall;
    @Mock
    private ImsPhoneCall mRingGroundCall;

    @Before
    public void setUp() throws Exception {
        super.setUp(getClass().getSimpleName());
        replaceInstance(Handler.class, "mLooper", mImsCT, Looper.getMainLooper());
        replaceInstance(ImsPhoneCallTracker.class, "mForegroundCall", mImsCT, mForeGroundCall);
        replaceInstance(ImsPhoneCallTracker.class, "mBackgroundCall", mImsCT, mBackGroundCall);
        replaceInstance(ImsPhoneCallTracker.class, "mRingingCall", mImsCT, mRingGroundCall);
        replaceInstance(ImsPhoneCallTracker.class, "mPhone", mImsCT, mImsPhone);

        mImsCallProfile.mCallExtras = mBundle;
        doReturn(ImsPhoneCall.State.IDLE).when(mForeGroundCall).getState();
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Test
    @SmallTest
    public void testImsConnectionSanity() {
        logd("Testing initial state of MT ImsPhoneConnection");
        mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);

        assertEquals(ImsPhoneCall.State.IDLE, mConnectionUT.getState());
        assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getNumberPresentation());
        assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getCnapNamePresentation());
        assertEquals(Connection.PostDialState.NOT_STARTED, mConnectionUT.getPostDialState());
        assertEquals(0, mConnectionUT.getDisconnectTime());
        assertEquals(0, mConnectionUT.getHoldDurationMillis());
        assertNull(mConnectionUT.getOrigDialString());
        assertFalse(mConnectionUT.isMultiparty());
        assertFalse(mConnectionUT.isConferenceHost());
        verify(mForeGroundCall, times(1)).attach((Connection) any(),
                eq(ImsPhoneCall.State.INCOMING));

        logd("Testing initial state of MO ImsPhoneConnection");
        mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
                PhoneNumberUtils.PAUSE), mImsCT, mForeGroundCall, false);
        assertEquals(PhoneConstants.PRESENTATION_ALLOWED, mConnectionUT.getNumberPresentation());
        assertEquals(PhoneConstants.PRESENTATION_ALLOWED, mConnectionUT.getCnapNamePresentation());
        assertEquals("+1 (700).555-41NN,1234", mConnectionUT.getOrigDialString());
        verify(mForeGroundCall, times(1)).attachFake((Connection) any(),
                eq(ImsPhoneCall.State.DIALING));
    }

    @Test
    @SmallTest
    public void testImsUpdateStateForeGround() {
        // MO Foreground Connection dailing -> active
        mConnectionUT = new ImsPhoneConnection(mImsPhone, "+1 (700).555-41NN1234", mImsCT,
                mForeGroundCall, false);
        // initially in dialing state
        doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
        assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
        // for Ringing/Dialing upadte postDialState
        assertEquals(Connection.PostDialState.COMPLETE, mConnectionUT.getPostDialState());
        verify(mForeGroundCall, times(1)).update(eq(mConnectionUT), eq(mImsCall),
                eq(Call.State.ACTIVE));
    }

    @Test
    @SmallTest
    public void testImsUpdateStateBackGround() {
        // MT background Connection dialing -> active
        mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mBackGroundCall, false);
        doReturn(Call.State.HOLDING).when(mBackGroundCall).getState();
        assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
        verify(mBackGroundCall, times(1)).detach(eq(mConnectionUT));
        verify(mForeGroundCall, times(1)).attach(eq(mConnectionUT));
        verify(mForeGroundCall, times(1)).update(eq(mConnectionUT), eq(mImsCall),
                eq(Call.State.ACTIVE));
        assertEquals(Connection.PostDialState.NOT_STARTED, mConnectionUT.getPostDialState());
    }

    @Test
    @SmallTest
    public void testImsUpdateStatePendingHold() {
        mConnectionUT = new ImsPhoneConnection(mImsPhone, "+1 (700).555-41NN1234", mImsCT,
                mForeGroundCall, false);
        doReturn(true).when(mImsCall).isPendingHold();
        assertFalse(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
        verify(mForeGroundCall, times(0)).update(eq(mConnectionUT), eq(mImsCall),
                eq(Call.State.ACTIVE));
        assertEquals(Connection.PostDialState.NOT_STARTED, mConnectionUT.getPostDialState());
    }

    @Test
    @SmallTest
    public void testUpdateAddressDisplay() {
        mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
        assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getNumberPresentation());
        assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getCnapNamePresentation());
        doReturn(ImsCallProfile.OIR_PRESENTATION_PAYPHONE).when(mImsCallProfile)
                .getCallExtraInt(eq(ImsCallProfile.EXTRA_CNAP));
        doReturn(ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED).when(mImsCallProfile)
                .getCallExtraInt(eq(ImsCallProfile.EXTRA_OIR));

        mConnectionUT.updateAddressDisplay(mImsCall);
        assertEquals(ImsCallProfile.OIRToPresentation(ImsCallProfile.OIR_PRESENTATION_PAYPHONE),
                mConnectionUT.getCnapNamePresentation());
        assertEquals(ImsCallProfile.OIRToPresentation(
                        ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED),
                mConnectionUT.getNumberPresentation());
    }

    @Test
    @SmallTest
    public void testConnectionDisconnect() {
        //Mock we have an active connection
        testImsUpdateStateForeGround();
        waitForMs(50);
        mConnectionUT.onDisconnect(DisconnectCause.LOCAL);
        assertEquals(DisconnectCause.LOCAL, mConnectionUT.getDisconnectCause());
        assertEquals(GsmCdmaCall.State.DISCONNECTED, mConnectionUT.getState());
        assertTrue(mConnectionUT.getDisconnectTime() <= System.currentTimeMillis());
        assertTrue(mConnectionUT.getDurationMillis() >= 50);
    }

    @Test
    @SmallTest
    public void testPostDialWait() {
        mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
                PhoneNumberUtils.WAIT), mImsCT, mForeGroundCall, false);
        doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
        doAnswer(new Answer() {
            @Override
            public Void answer(InvocationOnMock invocation) throws Throwable {
                Message msg = (Message) invocation.getArguments()[1];
                AsyncResult.forMessage(msg);
                msg.sendToTarget();
                return  null;
            }
        }).when(mImsCT).sendDtmf(anyChar(), (Message) any());
        // process post dial string during update
        assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
        assertEquals(Connection.PostDialState.WAIT, mConnectionUT.getPostDialState());
        mConnectionUT.proceedAfterWaitChar();
        waitForMs(50);
        assertEquals(Connection.PostDialState.COMPLETE, mConnectionUT.getPostDialState());
    }

    @Test
    @MediumTest
    public void testPostDialPause() {
        mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
                PhoneNumberUtils.PAUSE), mImsCT, mForeGroundCall, false);
        doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
        doAnswer(new Answer() {
            @Override
            public Void answer(InvocationOnMock invocation) throws Throwable {
                Message msg = (Message) invocation.getArguments()[1];
                AsyncResult.forMessage(msg);
                msg.sendToTarget();
                return null;
            }
        }).when(mImsCT).sendDtmf(anyChar(), (Message) any());

        // process post dial string during update
        assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
        assertEquals(Connection.PostDialState.STARTED, mConnectionUT.getPostDialState());
        try {
            Field field = ImsPhoneConnection.class.getDeclaredField("PAUSE_DELAY_MILLIS");
            field.setAccessible(true);
            waitForMs((Integer) field.get(null) + 50);
        } catch (Exception ex) {
            Assert.fail("unexpected exception thrown" + ex.getMessage());
        }
        assertEquals(Connection.PostDialState.COMPLETE, mConnectionUT.getPostDialState());
    }

    @Test
    @SmallTest
    public void testSetWifi() {
        mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
        assertFalse(mConnectionUT.isWifi());
        mBundle.putString(ImsCallProfile.EXTRA_CALL_RAT_TYPE,
                ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN + "");
        assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
        assertTrue(mConnectionUT.isWifi());
        //keep using the wifi state from extra, not update
        assertFalse(mConnectionUT.updateWifiState());
    }
}
Loading