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

Commit c2c6c619 authored by Aishwarya Mallampati's avatar Aishwarya Mallampati
Browse files

Timeout is not needed for E911 call if carrier is not in service.

Bug: 323896984
Test: atest CreateConnectionProcessorTest
Test Request Bugs: 324922010, 324921263, 324955710

Change-Id: I32a1f73bbc56e405e11b4b9653cf37e6357b2e33
Merged-In: I32a1f73bbc56e405e11b4b9653cf37e6357b2e33
parent 09c82ab9
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -16,21 +16,27 @@

package com.android.server.telecom;

import static com.android.internal.telephony.flags.Flags.carrierEnabledSatelliteFlag;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.telecom.Log;
import android.telecom.Logging.Runnable;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telephony.TelephonyManager;

import com.android.internal.annotations.VisibleForTesting;

import java.util.Collection;
import java.util.Objects;

/**
 * Registers a timeout for a call and disconnects the call when the timeout expires.
 */
final class CreateConnectionTimeout extends Runnable {
@VisibleForTesting
public final class CreateConnectionTimeout extends Runnable {
    private final Context mContext;
    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
    private final ConnectionServiceWrapper mConnectionService;
@@ -39,7 +45,8 @@ final class CreateConnectionTimeout extends Runnable {
    private boolean mIsRegistered;
    private boolean mIsCallTimedOut;

    CreateConnectionTimeout(Context context, PhoneAccountRegistrar phoneAccountRegistrar,
    @VisibleForTesting
    public CreateConnectionTimeout(Context context, PhoneAccountRegistrar phoneAccountRegistrar,
            ConnectionServiceWrapper service, Call call) {
        super("CCT", null /*lock*/);
        mContext = context;
@@ -48,7 +55,8 @@ final class CreateConnectionTimeout extends Runnable {
        mCall = call;
    }

    boolean isTimeoutNeededForCall(Collection<PhoneAccountHandle> accounts,
    @VisibleForTesting
    public boolean isTimeoutNeededForCall(Collection<PhoneAccountHandle> accounts,
            PhoneAccountHandle currentAccount) {
        // Non-emergency calls timeout automatically at the radio layer. No need for a timeout here.
        if (!mCall.isEmergencyCall()) {
@@ -75,6 +83,17 @@ final class CreateConnectionTimeout extends Runnable {
            return false;
        }

        // Timeout is not required if carrier is not in service.
        if (carrierEnabledSatelliteFlag() && connectionManager != null) {
            PhoneAccount account = mPhoneAccountRegistrar.getPhoneAccount(connectionManager,
                    connectionManager.getUserHandle());
            if (account.hasCapabilities(PhoneAccount.CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS)
                    && !account.hasCapabilities(PhoneAccount.CAPABILITY_VOICE_CALLING_AVAILABLE)) {
                Log.d(this, "isTimeoutNeededForCall, carrier is not in service.");
                return false;
            }
        }

        Log.i(this, "isTimeoutNeededForCall, returning true");
        return true;
    }
+117 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.server.telecom.tests;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;

import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyList;
@@ -35,6 +38,7 @@ import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Binder;
import android.os.UserHandle;
import android.platform.test.flag.junit.SetFlagsRule;
import android.telecom.DisconnectCause;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
@@ -42,6 +46,7 @@ import android.telephony.SubscriptionManager;

import androidx.test.filters.SmallTest;

import com.android.internal.telephony.flags.Flags;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallIdMapper;
import com.android.server.telecom.ConnectionServiceFocusManager;
@@ -49,11 +54,13 @@ import com.android.server.telecom.ConnectionServiceRepository;
import com.android.server.telecom.ConnectionServiceWrapper;
import com.android.server.telecom.CreateConnectionProcessor;
import com.android.server.telecom.CreateConnectionResponse;
import com.android.server.telecom.CreateConnectionTimeout;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.flags.FeatureFlags;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -73,6 +80,7 @@ import java.util.UUID;
 */
@RunWith(JUnit4.class)
public class CreateConnectionProcessorTest extends TelecomTestCase {
    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    private static final String TEST_PACKAGE = "com.android.server.telecom.tests";
    private static final String TEST_CLASS =
@@ -91,6 +99,7 @@ public class CreateConnectionProcessorTest extends TelecomTestCase {
    ConnectionServiceFocusManager mConnectionServiceFocusManager;

    CreateConnectionProcessor mTestCreateConnectionProcessor;
    CreateConnectionTimeout mTestCreateConnectionTimeout;

    private ArrayList<PhoneAccount> phoneAccounts;
    private HashMap<Integer,Integer> mSubToSlot;
@@ -144,6 +153,11 @@ public class CreateConnectionProcessorTest extends TelecomTestCase {
                .thenReturn(phoneAccounts);
        when(mMockCall.getAssociatedUser()).
                thenReturn(Binder.getCallingUserHandle());

        mTestCreateConnectionTimeout = new CreateConnectionTimeout(mContext, mMockAccountRegistrar,
                makeConnectionServiceWrapper(), mMockCall);

        mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG);
    }

    @Override
@@ -707,6 +721,109 @@ public class CreateConnectionProcessorTest extends TelecomTestCase {
        }
    }

    @Test
    public void testIsTimeoutNeededForCall_nonEmergencyCall() {
        when(mMockCall.isEmergencyCall()).thenReturn(false);

        assertFalse(mTestCreateConnectionTimeout.isTimeoutNeededForCall(null, null));
    }

    @Test
    public void testIsTimeoutNeededForCall_noConnectionManager() {
        when(mMockCall.isEmergencyCall()).thenReturn(true);
        List<PhoneAccountHandle> phoneAccountHandles = new ArrayList<>();
        // Put in a regular phone account handle
        PhoneAccount regularAccount = makePhoneAccount("tel_acct1",
                PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION);
        phoneAccountHandles.add(regularAccount.getAccountHandle());
        // Create a connection manager for the call and do not include in phoneAccountHandles
        createNewConnectionManagerPhoneAccountForCall(mMockCall, "cm_acct", 0);

        assertFalse(mTestCreateConnectionTimeout.isTimeoutNeededForCall(phoneAccountHandles, null));
    }

    @Test
    public void testIsTimeoutNeededForCall_usingConnectionManager() {
        when(mMockCall.isEmergencyCall()).thenReturn(true);
        List<PhoneAccountHandle> phoneAccountHandles = new ArrayList<>();
        // Put in a regular phone account handle
        PhoneAccount regularAccount = makePhoneAccount("tel_acct1",
                PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION);
        phoneAccountHandles.add(regularAccount.getAccountHandle());
        // Create a connection manager for the call and include it in phoneAccountHandles
        PhoneAccount callManagerPA = createNewConnectionManagerPhoneAccountForCall(mMockCall,
                "cm_acct", 0);
        phoneAccountHandles.add(callManagerPA.getAccountHandle());

        assertFalse(mTestCreateConnectionTimeout.isTimeoutNeededForCall(
                phoneAccountHandles, callManagerPA.getAccountHandle()));
    }

    @Test
    public void testIsTimeoutNeededForCall_NotSystemSimCallManager() {
        when(mMockCall.isEmergencyCall()).thenReturn(true);
        List<PhoneAccountHandle> phoneAccountHandles = new ArrayList<>();
        // Put in a regular phone account handle
        PhoneAccount regularAccount = makePhoneAccount("tel_acct1",
                PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION);
        phoneAccountHandles.add(regularAccount.getAccountHandle());
        // Create a connection manager for the call and include it in phoneAccountHandles
        PhoneAccount callManagerPA = createNewConnectionManagerPhoneAccountForCall(mMockCall,
                "cm_acct", 0);
        phoneAccountHandles.add(callManagerPA.getAccountHandle());

        assertFalse(mTestCreateConnectionTimeout.isTimeoutNeededForCall(phoneAccountHandles, null));
    }

    @Test
    public void testIsTimeoutNeededForCall_carrierNotInService() {
        when(mMockCall.isEmergencyCall()).thenReturn(true);
        when(mMockAccountRegistrar.getSystemSimCallManagerComponent()).thenReturn(
                new ComponentName(TEST_PACKAGE, TEST_CLASS));

        List<PhoneAccountHandle> phoneAccountHandles = new ArrayList<>();
        // Put in a regular phone account handle
        PhoneAccount regularAccount = makePhoneAccount("tel_acct1",
                PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION);
        phoneAccountHandles.add(regularAccount.getAccountHandle());
        // Create a connection manager for the call and include it in phoneAccountHandles
        int capability = PhoneAccount.CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS;
        PhoneAccount callManagerPA = createNewConnectionManagerPhoneAccountForCall(mMockCall,
                "cm_acct", capability);
        PhoneAccount phoneAccountWithoutService = makeQuickAccount("cm_acct", capability, null);
        when(mMockAccountRegistrar.getPhoneAccount(callManagerPA.getAccountHandle(),
                callManagerPA.getAccountHandle().getUserHandle()))
                .thenReturn(phoneAccountWithoutService);
        phoneAccountHandles.add(callManagerPA.getAccountHandle());

        assertFalse(mTestCreateConnectionTimeout.isTimeoutNeededForCall(phoneAccountHandles, null));
    }

    @Test
    public void testIsTimeoutNeededForCall() {
        when(mMockCall.isEmergencyCall()).thenReturn(true);
        when(mMockAccountRegistrar.getSystemSimCallManagerComponent()).thenReturn(
                new ComponentName(TEST_PACKAGE, TEST_CLASS));

        List<PhoneAccountHandle> phoneAccountHandles = new ArrayList<>();
        // Put in a regular phone account handle
        PhoneAccount regularAccount = makePhoneAccount("tel_acct1",
                PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION);
        phoneAccountHandles.add(regularAccount.getAccountHandle());
        // Create a connection manager for the call and include it in phoneAccountHandles
        int capability = PhoneAccount.CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS
                | PhoneAccount.CAPABILITY_VOICE_CALLING_AVAILABLE;
        PhoneAccount callManagerPA = createNewConnectionManagerPhoneAccountForCall(mMockCall,
                "cm_acct", capability);
        PhoneAccount phoneAccountWithService = makeQuickAccount("cm_acct", capability, null);
        when(mMockAccountRegistrar.getPhoneAccount(callManagerPA.getAccountHandle(),
                callManagerPA.getAccountHandle().getUserHandle()))
                .thenReturn(phoneAccountWithService);
        phoneAccountHandles.add(callManagerPA.getAccountHandle());

        assertTrue(mTestCreateConnectionTimeout.isTimeoutNeededForCall(phoneAccountHandles, null));
    }

    /**
     * Generates random phone accounts.
     * @param seed random seed to use for random UUIDs; passed in for determinism.