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

Commit 4a05d5cc authored by Tyler Gunn's avatar Tyler Gunn
Browse files

DO NOT MERGE Ensure TelecomManager#isIncall returns true when in phone acct selection.

Cherry-pick from AOSP-Master.

am: baf105bf am: 82fafefe am: 75256f10
am: f6318dda

Test: Manual
Bug: 34469716
Merged-In: Iec7e77bfbf2f0e493d8cc21187baca6a0a7d032d
Change-Id: Iec7e77bfbf2f0e493d8cc21187baca6a0a7d032d
(cherry picked from commit 44c54a2e)
parent 3a04bdbd
Loading
Loading
Loading
Loading
+80 −7
Original line number Diff line number Diff line
@@ -125,6 +125,27 @@ public class CallsManager extends Call.ListenerBase
    private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION =
            "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION";

    /**
     * Call filter specifier used with
     * {@link #getNumCallsWithState(int, Call, PhoneAccountHandle, int...)} to indicate only
     * self-managed calls should be included.
     */
    private static final int CALL_FILTER_SELF_MANAGED = 1;

    /**
     * Call filter specifier used with
     * {@link #getNumCallsWithState(int, Call, PhoneAccountHandle, int...)} to indicate only
     * managed calls should be included.
     */
    private static final int CALL_FILTER_MANAGED = 2;

    /**
     * Call filter specifier used with
     * {@link #getNumCallsWithState(int, Call, PhoneAccountHandle, int...)} to indicate both managed
     * and self-managed calls should be included.
     */
    private static final int CALL_FILTER_ALL = 3;

    private static final int HANDLER_WAIT_TIMEOUT = 10000;
    private static final int MAXIMUM_LIVE_CALLS = 1;
    private static final int MAXIMUM_HOLD_CALLS = 1;
@@ -138,10 +159,25 @@ public class CallsManager extends Call.ListenerBase
            {CallState.CONNECTING, CallState.SELECT_PHONE_ACCOUNT, CallState.DIALING,
                    CallState.PULLING};

    /**
     * These states are used by {@link #makeRoomForOutgoingCall(Call, boolean)} to determine which
     * call should be ended first to make room for a new outgoing call.
     */
    private static final int[] LIVE_CALL_STATES =
            {CallState.CONNECTING, CallState.SELECT_PHONE_ACCOUNT, CallState.DIALING,
                    CallState.PULLING, CallState.ACTIVE};

    /**
     * These states determine which calls will cause {@link TelecomManager#isInCall()} or
     * {@link TelecomManager#isInManagedCall()} to return true.
     *
     * See also {@link PhoneStateBroadcaster}, which considers a similar set of states as being
     * off-hook.
     */
    public static final int[] ONGOING_CALL_STATES =
            {CallState.SELECT_PHONE_ACCOUNT, CallState.DIALING, CallState.PULLING, CallState.ACTIVE,
                    CallState.ON_HOLD, CallState.RINGING};

    private static final int[] ANY_CALL_STATE =
            {CallState.NEW, CallState.CONNECTING, CallState.SELECT_PHONE_ACCOUNT, CallState.DIALING,
                    CallState.RINGING, CallState.ACTIVE, CallState.ON_HOLD, CallState.DISCONNECTED,
@@ -2133,15 +2169,39 @@ public class CallsManager extends Call.ListenerBase
    @VisibleForTesting
    public int getNumCallsWithState(final boolean isSelfManaged, Call excludeCall,
                                    PhoneAccountHandle phoneAccountHandle, int... states) {
        return getNumCallsWithState(isSelfManaged ? CALL_FILTER_SELF_MANAGED : CALL_FILTER_MANAGED,
                excludeCall, phoneAccountHandle, states);
    }

    /**
     * Determines the number of calls matching the specified criteria.
     * @param callFilter indicates whether to include just managed calls
     *                   ({@link #CALL_FILTER_MANAGED}), self-managed calls
     *                   ({@link #CALL_FILTER_SELF_MANAGED}), or all calls
     *                   ({@link #CALL_FILTER_ALL}).
     * @param excludeCall Where {@code non-null}, this call is excluded from the count.
     * @param phoneAccountHandle Where {@code non-null}, calls for this {@link PhoneAccountHandle}
     *                           are excluded from the count.
     * @param states The list of {@link CallState}s to include in the count.
     * @return Count of calls matching criteria.
     */
    @VisibleForTesting
    public int getNumCallsWithState(final int callFilter, Call excludeCall,
                                    PhoneAccountHandle phoneAccountHandle, int... states) {

        Set<Integer> desiredStates = IntStream.of(states).boxed().collect(Collectors.toSet());

        Stream<Call> callsStream = mCalls.stream()
                .filter(call -> desiredStates.contains(call.getState()) &&
                        call.getParentCall() == null && !call.isExternalCall() &&
                        call.isSelfManaged() == isSelfManaged);
                        call.getParentCall() == null && !call.isExternalCall());

        if (callFilter == CALL_FILTER_MANAGED) {
            callsStream = callsStream.filter(call -> !call.isSelfManaged());
        } else if (callFilter == CALL_FILTER_SELF_MANAGED) {
            callsStream = callsStream.filter(call -> call.isSelfManaged());
        }

        // If a call to exclude was specifeid, filter it out.
        // If a call to exclude was specified, filter it out.
        if (excludeCall != null) {
            callsStream = callsStream.filter(call -> call != excludeCall);
        }
@@ -2231,19 +2291,32 @@ public class CallsManager extends Call.ListenerBase
        return mCalls.stream().filter(call -> call.isSelfManaged()).count() > 0;
    }

    /**
     * Determines if there are any ongoing managed or self-managed calls.
     * Note: The {@link #ONGOING_CALL_STATES} are
     * @return {@code true} if there are ongoing managed or self-managed calls, {@code false}
     *      otherwise.
     */
    public boolean hasOngoingCalls() {
        return getNumCallsWithState(
                CALL_FILTER_ALL, null /* excludeCall */,
                null /* phoneAccountHandle */,
                ONGOING_CALL_STATES) > 0;
    }

    /**
     * Determines if there are any ongoing managed calls.
     * @return {@code true} if there are ongoing managed calls, {@code false} otherwise.
     */
    public boolean hasOngoingManagedCalls() {
        return getNumCallsWithState(
                false /* isSelfManaged */, null /* excludeCall */,
                CALL_FILTER_MANAGED, null /* excludeCall */,
                null /* phoneAccountHandle */,
                LIVE_CALL_STATES) > 0;
                ONGOING_CALL_STATES) > 0;
    }

    /**
     * Deteremines if the system incoming call UI should be shown.
     * Determines if the system incoming call UI should be shown.
     * The system incoming call UI will be shown if the new incoming call is self-managed, and there
     * are ongoing calls for another PhoneAccount.
     * @param incomingCall The incoming call.
+1 −3
Original line number Diff line number Diff line
@@ -637,9 +637,7 @@ public class TelecomServiceImpl {
                }

                synchronized (mLock) {
                    final int callState = mCallsManager.getCallState();
                    return callState == TelephonyManager.CALL_STATE_OFFHOOK
                            || callState == TelephonyManager.CALL_STATE_RINGING;
                    return mCallsManager.hasOngoingCalls();
                }
            } finally {
                Log.endSession();
+50 −0
Original line number Diff line number Diff line
@@ -878,6 +878,56 @@ public class TelecomServiceImplTest extends TelecomTestCase {
        verify(call).answer(realVideoState);
    }

    @SmallTest
    public void testIsInCall() throws Exception {
        when(mFakeCallsManager.hasOngoingCalls()).thenReturn(true);
        assertTrue(mTSIBinder.isInCall(DEFAULT_DIALER_PACKAGE));
    }

    @SmallTest
    public void testNotIsInCall() throws Exception {
        when(mFakeCallsManager.hasOngoingCalls()).thenReturn(false);
        assertFalse(mTSIBinder.isInCall(DEFAULT_DIALER_PACKAGE));
    }

    @SmallTest
    public void testIsInCallFail() throws Exception {
        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
                anyString(), any());
        try {
            mTSIBinder.isInCall("blah");
            fail();
        } catch (SecurityException e) {
            // desired result
        }
        verify(mFakeCallsManager, never()).hasOngoingCalls();
    }

    @SmallTest
    public void testIsInManagedCall() throws Exception {
        when(mFakeCallsManager.hasOngoingManagedCalls()).thenReturn(true);
        assertTrue(mTSIBinder.isInManagedCall(DEFAULT_DIALER_PACKAGE));
    }

    @SmallTest
    public void testNotIsInManagedCall() throws Exception {
        when(mFakeCallsManager.hasOngoingManagedCalls()).thenReturn(false);
        assertFalse(mTSIBinder.isInManagedCall(DEFAULT_DIALER_PACKAGE));
    }

    @SmallTest
    public void testIsInManagedCallFail() throws Exception {
        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
                anyString(), any());
        try {
            mTSIBinder.isInManagedCall("blah");
            fail();
        } catch (SecurityException e) {
            // desired result
        }
        verify(mFakeCallsManager, never()).hasOngoingCalls();
    }

    /**
     * Register phone accounts for the supplied PhoneAccountHandles to make them
     * visible to all users (via the isVisibleToCaller method in TelecomServiceImpl.