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

Commit 0d10f467 authored by Xin Li's avatar Xin Li
Browse files

Merge UP1A.230905.019

Merged-In: I9cc11eb11b59eb04b706a4bd6f61c1b7240a50c2
Change-Id: I36ebb7dfb787df39b1754cf7a24ef784ad6db23d
parents 1b97dc21 70a60418
Loading
Loading
Loading
Loading
+22 −20
Original line number Diff line number Diff line
@@ -1741,7 +1741,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
        final boolean hasAnyCalls = mCallsManager.hasAnyCalls();
        // These APIs are all via two-way binder calls so can potentially block Telecom.  Since none
        // of this has to happen in the Telecom lock we'll offload it to the async executor.
        mAsyncTaskExecutor.execute(() -> {

        AudioDeviceInfo speakerDevice = null;
        for (AudioDeviceInfo info : mAudioManager.getAvailableCommunicationDevices()) {
            if (info.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
@@ -1762,7 +1762,9 @@ public class CallAudioRouteStateMachine extends StateMachine {
                mAudioManager.clearCommunicationDevice();
            }
        }
            mStatusBarNotifier.notifySpeakerphone(hasAnyCalls && speakerOn);
        final boolean isSpeakerOn = speakerOn;
        mAsyncTaskExecutor.execute(() -> {
            mStatusBarNotifier.notifySpeakerphone(hasAnyCalls && isSpeakerOn);
        });
    }

+8 −1
Original line number Diff line number Diff line
@@ -1572,7 +1572,14 @@ public class CallsManager extends Call.ListenerBase
        // Check if the target phone account is possibly in ECBM.
        call.setIsInECBM(getEmergencyCallHelper()
                .isLastOutgoingEmergencyCallPAH(call.getTargetPhoneAccount()));
        if (mUserManager.isQuietModeEnabled(call.getAssociatedUser())
        // If the phone account user profile is paused or the call isn't visible to the secondary/
        // guest user, reject the non-emergency incoming call. When the current user is the admin,
        // we need to allow the calls to go through if the work profile isn't paused. We should
        // always allow emergency calls and also allow non-emergency calls when ECBM is active for
        // the phone account.
        if ((mUserManager.isQuietModeEnabled(call.getAssociatedUser())
                || (!mUserManager.isUserAdmin(mCurrentUserHandle.getIdentifier())
                && !isCallVisibleForUser(call, mCurrentUserHandle)))
                && !call.isEmergencyCall() && !call.isInECBM()) {
            Log.d(TAG, "Rejecting non-emergency call because the owner %s is not running.",
                    phoneAccountHandle.getUserHandle());
+21 −48
Original line number Diff line number Diff line
@@ -23,16 +23,11 @@ import android.media.session.MediaSession;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.telecom.CallAudioState;
import android.telecom.CallEndpoint;
import android.telecom.Log;
import android.util.ArraySet;
import android.view.KeyEvent;

import com.android.internal.annotations.VisibleForTesting;

import java.util.Set;

/**
 * Static class to handle listening to the headset media buttons.
 */
@@ -154,10 +149,8 @@ public class HeadsetMediaButton extends CallsManagerListenerBase {
    private final Context mContext;
    private final CallsManager mCallsManager;
    private final TelecomSystem.SyncRoot mLock;
    private final Set<Call> mCalls = new ArraySet<>();
    private MediaSessionAdapter mSession;
    private KeyEvent mLastHookEvent;
    private @CallEndpoint.EndpointType int mCurrentEndpointType;

    /**
     * Constructor used for testing purposes to initialize a {@link HeadsetMediaButton} with a
@@ -219,7 +212,7 @@ public class HeadsetMediaButton extends CallsManagerListenerBase {
            return mCallsManager.onMediaButton(LONG_PRESS);
        } else if (event.getAction() == KeyEvent.ACTION_UP) {
            // We should not judge SHORT_PRESS by ACTION_UP event repeatCount, because it always
            // returns 0.
            // return 0.
            // Actually ACTION_DOWN event repeatCount only increases when LONG_PRESS performed.
            if (mLastHookEvent != null && mLastHookEvent.getRepeatCount() == 0) {
                return mCallsManager.onMediaButton(SHORT_PRESS);
@@ -233,70 +226,50 @@ public class HeadsetMediaButton extends CallsManagerListenerBase {
        return true;
    }

    @Override
    public void onCallEndpointChanged(CallEndpoint callEndpoint) {
        mCurrentEndpointType = callEndpoint.getEndpointType();
        Log.i(this, "onCallEndpointChanged: endPoint=%s", callEndpoint);
        maybeChangeSessionState();
    }

    /** ${inheritDoc} */
    @Override
    public void onCallAdded(Call call) {
        handleCallAddition(call);
        if (call.isExternalCall()) {
            return;
        }

    /**
     * Triggers session activation due to call addition.
     */
    private void handleCallAddition(Call call) {
        mCalls.add(call);
        maybeChangeSessionState();
        handleCallAddition();
    }

    /**
     * Based on whether there are tracked calls and the audio is routed to a wired headset,
     * potentially activate or deactive the media session.
     * Triggers session activation due to call addition.
     */
    private void maybeChangeSessionState() {
        boolean hasNonExternalCalls = !mCalls.isEmpty()
                && mCalls.stream().anyMatch(c -> !c.isExternalCall());
        if (hasNonExternalCalls && mCurrentEndpointType == CallEndpoint.TYPE_WIRED_HEADSET) {
            Log.i(this, "maybeChangeSessionState: hasCalls=%b, currentEndpointType=%s, ACTIVATE",
                    hasNonExternalCalls, CallEndpoint.endpointTypeToString(mCurrentEndpointType));
    private void handleCallAddition() {
        mMediaSessionHandler.obtainMessage(MSG_MEDIA_SESSION_SET_ACTIVE, 1, 0).sendToTarget();
        } else {
            Log.i(this, "maybeChangeSessionState: hasCalls=%b, currentEndpointType=%s, DEACTIVATE",
                    hasNonExternalCalls, CallEndpoint.endpointTypeToString(mCurrentEndpointType));
            mMediaSessionHandler.obtainMessage(MSG_MEDIA_SESSION_SET_ACTIVE, 0, 0).sendToTarget();
        }
    }

    /** ${inheritDoc} */
    @Override
    public void onCallRemoved(Call call) {
        handleCallRemoval(call);
        if (call.isExternalCall()) {
            return;
        }
        handleCallRemoval();
    }

    /**
     * Triggers session deactivation due to call removal.
     */
    private void handleCallRemoval(Call call) {
        // If we were tracking the call, potentially change session state.
        if (mCalls.remove(call)) {
            if (mCalls.isEmpty()) {
                // When there are no calls, don't cache that we previously had a wired headset
                // connected; we'll be updated on the next call.
                mCurrentEndpointType = CallEndpoint.TYPE_UNKNOWN;
            }
            maybeChangeSessionState();
    private void handleCallRemoval() {
        if (!mCallsManager.hasAnyCalls()) {
            mMediaSessionHandler.obtainMessage(MSG_MEDIA_SESSION_SET_ACTIVE, 0, 0).sendToTarget();
        }
    }

    /** ${inheritDoc} */
    @Override
    public void onExternalCallChanged(Call call, boolean isExternalCall) {
        maybeChangeSessionState();
        // Note: We don't use the onCallAdded/onCallRemoved methods here since they do checks to see
        // if the call is external or not and would skip the session activation/deactivation.
        if (isExternalCall) {
            handleCallRemoval();
        } else {
            handleCallAddition();
        }
    }

    @VisibleForTesting
+5 −1
Original line number Diff line number Diff line
@@ -2875,7 +2875,11 @@ public class InCallController extends CallsManagerListenerBase implements
            // Emergency call should never be blocked, so if the user associated with call is in
            // quite mode, use the primary user for the emergency call.
            if ((call.isEmergencyCall() || call.isInECBM())
                    && userManager.isQuietModeEnabled(userFromCall)) {
                    && (userManager.isQuietModeEnabled(userFromCall)
                    // We should also account for secondary/guest users where the profile may not
                    // necessarily be paused.
                    || !userManager.isUserAdmin(mCallsManager.getCurrentUserHandle()
                    .getIdentifier()))) {
                return mCallsManager.getCurrentUserHandle();
            }
            return userFromCall;
+63 −1
Original line number Diff line number Diff line
@@ -174,6 +174,8 @@ public class CallsManagerTest extends TelecomTestCase {
            ComponentName.unflattenFromString("com.baz/.Self"), "Self");
    private static final PhoneAccountHandle SELF_MANAGED_2_HANDLE = new PhoneAccountHandle(
            ComponentName.unflattenFromString("com.baz/.Self2"), "Self2");
    private static final PhoneAccountHandle WORK_HANDLE = new PhoneAccountHandle(
            ComponentName.unflattenFromString("com.foo/.Blah"), "work", new UserHandle(10));
    private static final PhoneAccountHandle SELF_MANAGED_W_CUSTOM_HANDLE = new PhoneAccountHandle(
            new ComponentName(TEST_PACKAGE_NAME, "class"), "1", TEST_USER_HANDLE);
    private static final PhoneAccount SIM_1_ACCOUNT = new PhoneAccount.Builder(SIM_1_HANDLE, "Sim1")
@@ -205,11 +207,19 @@ public class CallsManagerTest extends TelecomTestCase {
            .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
            .setIsEnabled(true)
            .build();
    private static final PhoneAccount WORK_ACCOUNT = new PhoneAccount.Builder(
            WORK_HANDLE, "work")
            .setCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION
                    | PhoneAccount.CAPABILITY_CALL_PROVIDER
                    | PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)
            .setIsEnabled(true)
            .build();
    private static final PhoneAccount SM_W_DIFFERENT_PACKAGE_AND_USER = new PhoneAccount.Builder(
            SELF_MANAGED_W_CUSTOM_HANDLE, "Self")
            .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
            .setIsEnabled(true)
            .build();

    private static final Uri TEST_ADDRESS = Uri.parse("tel:555-1212");
    private static final Uri TEST_ADDRESS2 = Uri.parse("tel:555-1213");
    private static final Uri TEST_ADDRESS3 = Uri.parse("tel:555-1214");
@@ -346,6 +356,8 @@ public class CallsManagerTest extends TelecomTestCase {
                eq(SIM_1_HANDLE), any())).thenReturn(SIM_1_ACCOUNT);
        when(mPhoneAccountRegistrar.getPhoneAccount(
                eq(SIM_2_HANDLE), any())).thenReturn(SIM_2_ACCOUNT);
        when(mPhoneAccountRegistrar.getPhoneAccount(
                eq(WORK_HANDLE), any())).thenReturn(WORK_ACCOUNT);
        when(mToastFactory.makeText(any(), anyInt(), anyInt())).thenReturn(mToast);
        when(mToastFactory.makeText(any(), any(), anyInt())).thenReturn(mToast);
    }
@@ -2490,7 +2502,30 @@ public class CallsManagerTest extends TelecomTestCase {

    @SmallTest
    @Test
    public void testRejectIncomingCallOnPAHInactive() throws Exception {
    public void testRejectIncomingCallOnPAHInactive_SecondaryUser() throws Exception {
        ConnectionServiceWrapper service = mock(ConnectionServiceWrapper.class);
        doReturn(WORK_HANDLE.getComponentName()).when(service).getComponentName();
        mCallsManager.addConnectionServiceRepositoryCache(WORK_HANDLE.getComponentName(),
                WORK_HANDLE.getUserHandle(), service);

        UserManager um = mContext.getSystemService(UserManager.class);
        UserHandle newUser = new UserHandle(11);
        when(mCallsManager.getCurrentUserHandle()).thenReturn(newUser);
        when(um.isUserAdmin(eq(newUser.getIdentifier()))).thenReturn(false);
        when(um.isQuietModeEnabled(eq(WORK_HANDLE.getUserHandle()))).thenReturn(false);
        when(mPhoneAccountRegistrar.getPhoneAccountUnchecked(eq(WORK_HANDLE)))
                .thenReturn(WORK_ACCOUNT);
        Call newCall = mCallsManager.processIncomingCallIntent(
                WORK_HANDLE, new Bundle(), false);

        verify(service, timeout(TEST_TIMEOUT)).createConnectionFailed(any());
        assertFalse(newCall.isInECBM());
        assertEquals(USER_MISSED_NOT_RUNNING, newCall.getMissedReason());
    }

    @SmallTest
    @Test
    public void testRejectIncomingCallOnPAHInactive_ProfilePaused() throws Exception {
        ConnectionServiceWrapper service = mock(ConnectionServiceWrapper.class);
        doReturn(SIM_2_HANDLE.getComponentName()).when(service).getComponentName();
        mCallsManager.addConnectionServiceRepositoryCache(SIM_2_HANDLE.getComponentName(),
@@ -2525,6 +2560,30 @@ public class CallsManagerTest extends TelecomTestCase {
        verify(service, timeout(TEST_TIMEOUT).times(0)).createConnectionFailed(any());
    }

    @SmallTest
    @Test
    public void testAcceptIncomingCallOnPAHInactiveAndECBMActive_SecondaryUser() throws Exception {
        ConnectionServiceWrapper service = mock(ConnectionServiceWrapper.class);
        doReturn(WORK_HANDLE.getComponentName()).when(service).getComponentName();
        mCallsManager.addConnectionServiceRepositoryCache(SIM_2_HANDLE.getComponentName(),
                WORK_HANDLE.getUserHandle(), service);

        when(mEmergencyCallHelper.isLastOutgoingEmergencyCallPAH(eq(WORK_HANDLE)))
                .thenReturn(true);
        UserManager um = mContext.getSystemService(UserManager.class);
        UserHandle newUser = new UserHandle(11);
        when(mCallsManager.getCurrentUserHandle()).thenReturn(newUser);
        when(um.isUserAdmin(eq(newUser.getIdentifier()))).thenReturn(false);
        when(um.isQuietModeEnabled(eq(WORK_HANDLE.getUserHandle()))).thenReturn(false);
        when(mPhoneAccountRegistrar.getPhoneAccountUnchecked(eq(WORK_HANDLE)))
                .thenReturn(WORK_ACCOUNT);
        Call newCall = mCallsManager.processIncomingCallIntent(
                WORK_HANDLE, new Bundle(), false);

        assertTrue(newCall.isInECBM());
        verify(service, timeout(TEST_TIMEOUT).times(0)).createConnectionFailed(any());
    }

    @SmallTest
    @Test
    public void testAcceptIncomingEmergencyCallOnPAHInactive() throws Exception {
@@ -3100,6 +3159,9 @@ public class CallsManagerTest extends TelecomTestCase {
        // WHEN
        when(mPhoneAccountRegistrar.getPhoneAccountUnchecked(any()))
                .thenReturn(SM_W_DIFFERENT_PACKAGE_AND_USER);
        UserManager um = mContext.getSystemService(UserManager.class);
        when(um.isUserAdmin(eq(mCallsManager.getCurrentUserHandle().getIdentifier())))
                .thenReturn(true);

        // THEN
        mCallsManager.processIncomingCallIntent(SELF_MANAGED_W_CUSTOM_HANDLE, new Bundle(), false);
Loading