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

Commit 81e8a25a authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Restrict calling in favor of emergency calling - Incoming Cases

The first series of CLs (1/2) that allow for better interactions
between emergency calls and incoming call types. This includes:
1) Disconnecting incoming calls and marking them as MISSED if an
outgoing emergency call is placed before the call is set to active.
2) Not allowing the pulling of external calls while an emergency
call is active and showing a Toast.
3) If a call is in AUDIO_PROCESSING state, hang it up in favor of
a new outgoing emergency call (and mark disconnected call as
MISSED if this is during an initial call screen).
4) If a call is in SIMULATED_RINGING state, hang it up in favor of
a new outgoing emergency call.

Bug: 138741228
Test: manual; atest TelecomUnitTests; atest CtsTelecomTestCases
Change-Id: I74d2b174121fb9c6402caf806d20eb6c5226873a
parent 29cbb62d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ android_test {
        "androidx.legacy_legacy-support-core-utils",
        "androidx.core_core",
        "androidx.fragment_fragment",
        "androidx.test.ext.junit"
    ],
    srcs: [
        "tests/src/**/*.java",
+5 −0
Original line number Diff line number Diff line
@@ -335,6 +335,11 @@
    <string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt">Call Blocking has been disabled to allow emergency responders to contact you.</string>
    <!-- Window title used for the Telecom Developer Menu -->
    <string name="developer_title">Telecom Developer Menu</string>
    <!-- Some carriers allow an "external" call that has been placed on another device (another
    tablet, phone, etc...) to be transferred to this device and taken as a call. In
    the situation that we are already in an emergency call, notify the user that the call can not
    be taken at this time.-->
    <string name="toast_emergency_can_not_pull_call">Calls can not be taken while in an emergency call.</string>
    <!-- Label for a switch in the Telecom Developer Menu which is used to enable the enhanced call
         blocking functionality (for test purposes).
         DO NOT TRANSLATE -->
+47 −6
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import android.widget.Toast;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telecom.IVideoProvider;
import com.android.internal.util.Preconditions;
import com.android.server.telecom.ui.ToastFactory;

import java.io.IOException;
import java.text.SimpleDateFormat;
@@ -435,6 +436,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
    private final Context mContext;
    private final CallsManager mCallsManager;
    private final ClockProxy mClockProxy;
    private final ToastFactory mToastFactory;
    private final TelecomSystem.SyncRoot mLock;
    private final String mId;
    private String mConnectionId;
@@ -559,6 +561,17 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
     */
    private boolean mIsUsingCallFiltering = false;

    /**
     * Indicates whether or not this call has been active before. This is helpful in detecting
     * situations where we have moved into {@link CallState#SIMULATED_RINGING} or
     * {@link CallState#AUDIO_PROCESSING} again after being active. If a call has moved into one
     * of these states again after being active and the user dials an emergency call, we want to
     * log these calls normally instead of considering them MISSED. If the emergency call was
     * dialed during initial screening however, we want to treat those calls as MISSED (because the
     * user never got the chance to explicitly reject).
     */
    private boolean mHasGoneActiveBefore = false;

    /**
     * Persists the specified parameters and initializes the new instance.
     * @param context The context.
@@ -589,7 +602,8 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
            int callDirection,
            boolean shouldAttachToExistingConnection,
            boolean isConference,
            ClockProxy clockProxy) {
            ClockProxy clockProxy,
            ToastFactory toastFactory) {
        mId = callId;
        mConnectionId = callId;
        mState = isConference ? CallState.ACTIVE : CallState.NEW;
@@ -610,6 +624,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
                || callDirection == CALL_DIRECTION_INCOMING;
        maybeLoadCannedSmsResponses();
        mClockProxy = clockProxy;
        mToastFactory = toastFactory;
        mCreationTimeMillis = mClockProxy.currentTimeMillis();
    }

@@ -647,11 +662,12 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
            boolean isConference,
            long connectTimeMillis,
            long connectElapsedTimeMillis,
            ClockProxy clockProxy) {
            ClockProxy clockProxy,
            ToastFactory toastFactory) {
        this(callId, context, callsManager, lock, repository,
                phoneNumberUtilsAdapter, handle, gatewayInfo,
                connectionManagerPhoneAccountHandle, targetPhoneAccountHandle, callDirection,
                shouldAttachToExistingConnection, isConference, clockProxy);
                shouldAttachToExistingConnection, isConference, clockProxy, toastFactory);

        mConnectTimeMillis = connectTimeMillis;
        mConnectElapsedTimeMillis = connectElapsedTimeMillis;
@@ -943,6 +959,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
                // We're clearly not disconnected, so reset the disconnected time.
                mDisconnectTimeMillis = 0;
                mDisconnectElapsedTimeMillis = 0;
                mHasGoneActiveBefore = true;
            } else if (mState == CallState.DISCONNECTED) {
                mDisconnectTimeMillis = mClockProxy.currentTimeMillis();
                mDisconnectElapsedTimeMillis = mClockProxy.elapsedRealtime();
@@ -1944,10 +1961,11 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
            Log.v(this, "Aborting call %s", this);
            abort(disconnectionTimeout);
        } else if (mState != CallState.ABORTED && mState != CallState.DISCONNECTED) {
            if (mState == CallState.AUDIO_PROCESSING) {
            if (mState == CallState.AUDIO_PROCESSING && !hasGoneActiveBefore()) {
                mOverrideDisconnectCauseCode = DisconnectCause.REJECTED;
            } else if (mState == CallState.SIMULATED_RINGING) {
                // This is the case where the dialer calls disconnect() because the call timed out
                // or an emergency call was dialed while in this state.
                // Override the disconnect cause to MISSED
                mOverrideDisconnectCauseCode = DisconnectCause.MISSED;
            }
@@ -2389,6 +2407,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
     * device, so will issue a request to pull the call to the second device.
     * <p>
     * Requests to pull a call which is not external, or a call which is not pullable are ignored.
     * If there is an ongoing emergency call, pull requests are also ignored.
     */
    public void pullExternalCall() {
        if (mConnectionService == null) {
@@ -2404,6 +2423,15 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
            Log.w(this, "pullExternalCall - call %s is external but cannot be pulled.", mId);
            return;
        }

        if (mCallsManager.isInEmergencyCall()) {
            Log.w(this, "pullExternalCall = pullExternalCall - call %s is external but can not be"
                    + " pulled while an emergency call is in progress.", mId);
            mToastFactory.makeText(mContext, R.string.toast_emergency_can_not_pull_call,
                    Toast.LENGTH_LONG).show();
            return;
        }

        Log.addEvent(this, LogUtils.Events.REQUEST_PULL);
        mConnectionService.pullExternalCall(this);
    }
@@ -2438,8 +2466,9 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(mContext, "WARNING: Event-based handover APIs are deprecated "
                                            + "and will no longer function in Android Q.",
                            mToastFactory.makeText(mContext,
                                    "WARNING: Event-based handover APIs are deprecated and will no"
                                            + " longer function in Android Q.",
                                    Toast.LENGTH_LONG).show();
                        }
                    });
@@ -3316,6 +3345,18 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        mIsUsingCallFiltering = isUsingCallFiltering;
    }

    /**
     * In some cases, we need to know if this call has ever gone active (for example, the case
     * when the call was put into the {@link CallState#AUDIO_PROCESSING} state after being active)
     * for call logging purposes.
     *
     * @return {@code true} if this call has gone active before (even if it isn't now), false if it
     * has never gone active.
     */
    public boolean hasGoneActiveBefore() {
        return mHasGoneActiveBefore;
    }

    /**
     * When upgrading a call to video via
     * {@link VideoProviderProxy#onSendSessionModifyRequest(VideoProfile, VideoProfile)}, if the
+2 −2
Original line number Diff line number Diff line
@@ -363,7 +363,7 @@ public class CallAudioManager extends CallsManagerListenerBase {
    @VisibleForTesting
    public void toggleMute() {
        // Don't mute if there are any emergency calls.
        if (mCallsManager.hasEmergencyCall()) {
        if (mCallsManager.isInEmergencyCall()) {
            Log.v(this, "ignoring toggleMute for emergency call");
            return;
        }
@@ -382,7 +382,7 @@ public class CallAudioManager extends CallsManagerListenerBase {
        Log.v(this, "mute, shouldMute: %b", shouldMute);

        // Don't mute if there are any emergency calls.
        if (mCallsManager.hasEmergencyCall()) {
        if (mCallsManager.isInEmergencyCall()) {
            shouldMute = false;
            Log.v(this, "ignoring mute for emergency call");
        }
+1 −1
Original line number Diff line number Diff line
@@ -1278,7 +1278,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
            Log.startSession("CARSM.mCR");
            try {
                if (AudioManager.ACTION_MICROPHONE_MUTE_CHANGED.equals(intent.getAction())) {
                    if (mCallsManager.hasEmergencyCall()) {
                    if (mCallsManager.isInEmergencyCall()) {
                        Log.i(this, "Mute was externally changed when there's an emergency call. " +
                                "Forcing mute back off.");
                        sendInternalMessage(MUTE_OFF);
Loading