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

Commit 6c296d3b authored by Tyler Gunn's avatar Tyler Gunn Committed by Nathan Harold
Browse files

[DO NOT MERGE] Add "acceptRingingCall()" API which accepts a videoState.

- Added acceptRingingCall API which accepts a videostate to complement the
existing API.
- Added unit test for acceptRingingCall APIs.

Bug: 20159300
Change-Id: I4166a8b7c470632d0ffc0e75504b081ffeea733d
parent 4a6e9613
Loading
Loading
Loading
Loading
+45 −3
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.telecom.DefaultDialerManager;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -62,6 +63,7 @@ import java.util.List;
public class TelecomServiceImpl {
    private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION =
            "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION";
    private static final int DEFAULT_VIDEO_STATE = -1;

    private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
        @Override
@@ -584,7 +586,25 @@ public class TelecomServiceImpl {

                long token = Binder.clearCallingIdentity();
                try {
                    acceptRingingCallInternal();
                    acceptRingingCallInternal(DEFAULT_VIDEO_STATE);
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
            }
        }

        /**
         * @see android.telecom.TelecomManager#acceptRingingCall(int)
         *
         */
        @Override
        public void acceptRingingCallWithVideoState(int videoState) {
            synchronized (mLock) {
                enforceModifyPermission();

                long token = Binder.clearCallingIdentity();
                try {
                    acceptRingingCallInternal(videoState);
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
@@ -1038,10 +1058,13 @@ public class TelecomServiceImpl {
        return false;
    }

    private void acceptRingingCallInternal() {
    private void acceptRingingCallInternal(int videoState) {
        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
        if (call != null) {
            call.answer(call.getVideoState());
            if (videoState == DEFAULT_VIDEO_STATE || !isValidAcceptVideoState(videoState)) {
                videoState = call.getVideoState();
            }
            call.answer(videoState);
        }
    }

@@ -1204,4 +1227,23 @@ public class TelecomServiceImpl {
    private TelephonyManager getTelephonyManager() {
        return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
    }

    /**
     * Determines if a video state is valid for accepting an incoming call.
     * For the purpose of accepting a call, states {@link VideoProfile#STATE_AUDIO_ONLY}, and
     * any combination of {@link VideoProfile#STATE_RX_ENABLED} and
     * {@link VideoProfile#STATE_TX_ENABLED} are considered valid.
     *
     * @param videoState The video state.
     * @return {@code true} if the video state is valid, {@code false} otherwise.
     */
    private boolean isValidAcceptVideoState(int videoState) {
        // Given a video state input, turn off TX and RX so that we can determine if those were the
        // only bits set.
        int remainingState = videoState & ~VideoProfile.STATE_TX_ENABLED;
        remainingState = remainingState & ~VideoProfile.STATE_RX_ENABLED;

        // If only TX or RX were set (or neither), the video state is valid.
        return remainingState == 0;
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
    <uses-permission android:name="android.permission.MANAGE_USERS" />

    <!-- Used to access TelephonyManager APIs -->
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />

    <application android:label="@string/app_name"
                 android:debuggable="true">
        <uses-library android:name="android.test.runner" />
+107 −0
Original line number Diff line number Diff line
@@ -351,6 +351,15 @@ public class TelecomSystemTest extends TelecomTestCase {
            String number,
            PhoneAccountHandle phoneAccountHandle,
            final ConnectionServiceFixture connectionServiceFixture) throws Exception {
        return startIncomingPhoneCall(number, phoneAccountHandle, VideoProfile.STATE_AUDIO_ONLY,
                connectionServiceFixture);
    }

    private IdPair startIncomingPhoneCall(
            String number,
            PhoneAccountHandle phoneAccountHandle,
            int videoState,
            final ConnectionServiceFixture connectionServiceFixture) throws Exception {
        reset(
                connectionServiceFixture.getTestDouble(),
                mInCallServiceFixtureX.getTestDouble(),
@@ -381,10 +390,15 @@ public class TelecomSystemTest extends TelecomTestCase {
                eq(true),
                eq(false));

        mConnectionServiceFixtureA.mConnectionById.get(
                connectionServiceFixture.mLatestConnectionId).videoState = videoState;

        connectionServiceFixture.sendHandleCreateConnectionComplete(
                connectionServiceFixture.mLatestConnectionId);
        connectionServiceFixture.sendSetRinging(
                connectionServiceFixture.mLatestConnectionId);
        connectionServiceFixture.sendSetVideoState(
                connectionServiceFixture.mLatestConnectionId);

        // For the case of incoming calls, Telecom connecting the InCall services and adding the
        // Call is triggered by the async completion of the CallerInfoAsyncQuery. Once the Call
@@ -537,6 +551,99 @@ public class TelecomSystemTest extends TelecomTestCase {
                mInCallServiceFixtureY.getCall(ids.mCallId).getState());
    }

    /**
     * Tests the {@link TelecomManager#acceptRingingCall()} API.  Tests simple case of an incoming
     * audio-only call.
     *
     * @throws Exception
     */
    public void testTelecomManagerAcceptRingingCall() throws Exception {
        IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
                mConnectionServiceFixtureA);

        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());

        // Use TelecomManager API to answer the ringing call.
        TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
                .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
        telecomManager.acceptRingingCall();

        verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
                .answer(ids.mCallId);
    }

    /**
     * Tests the {@link TelecomManager#acceptRingingCall()} API.  Tests simple case of an incoming
     * video call, which should be answered as video.
     *
     * @throws Exception
     */
    public void testTelecomManagerAcceptRingingVideoCall() throws Exception {
        IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
                VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA);

        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());

        // Use TelecomManager API to answer the ringing call; the default expected behavior is to
        // answer using whatever video state the ringing call requests.
        TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
                .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
        telecomManager.acceptRingingCall();

        // Answer video API should be called
        verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
                .answerVideo(eq(ids.mCallId), eq(VideoProfile.STATE_BIDIRECTIONAL));
    }

    /**
     * Tests the {@link TelecomManager#acceptRingingCall(int)} API.  Tests answering a video call
     * as an audio call.
     *
     * @throws Exception
     */
    public void testTelecomManagerAcceptRingingVideoCallAsAudio() throws Exception {
        IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
                VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA);

        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());

        // Use TelecomManager API to answer the ringing call.
        TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
                .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
        telecomManager.acceptRingingCall(VideoProfile.STATE_AUDIO_ONLY);

        // The generic answer method on the ConnectionService is used to answer audio-only calls.
        verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
                .answer(eq(ids.mCallId));
    }

    /**
     * Tests the {@link TelecomManager#acceptRingingCall()} API.  Tests simple case of an incoming
     * video call, where an attempt is made to answer with an invalid video state.
     *
     * @throws Exception
     */
    public void testTelecomManagerAcceptRingingInvalidVideoState() throws Exception {
        IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
                VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA);

        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());

        // Use TelecomManager API to answer the ringing call; the default expected behavior is to
        // answer using whatever video state the ringing call requests.
        TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
                .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
        telecomManager.acceptRingingCall(999 /* invalid videostate */);

        // Answer video API should be called
        verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
                .answerVideo(eq(ids.mCallId), eq(VideoProfile.STATE_BIDIRECTIONAL));
    }

    // A simple incoming call, similar in scope to the previous test
    private IdPair startAndMakeActiveIncomingCall(
            String number,