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

Commit 52b8b17e authored by Tyler Gunn's avatar Tyler Gunn Committed by android-build-merger
Browse files

Handle video capability changes mid-call. am: d2280477

am: df6beac5

Change-Id: I1b1518a8e983eb6f5f8c45f804af8a2b647ddcb7
parents cfd950a8 df6beac5
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -1250,6 +1250,23 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        return mIsVideoCallingSupportedByPhoneAccount;
    }

    /**
     * Sets whether video calling is supported by the current phone account. Since video support
     * can change during a call, this method facilitates updating call video state.
     * @param isVideoCallingSupported Sets whether video calling is supported.
     */
    public void setVideoCallingSupportedByPhoneAccount(boolean isVideoCallingSupported) {
        if (mIsVideoCallingSupportedByPhoneAccount == isVideoCallingSupported) {
            return;
        }
        Log.i(this, "setVideoCallingSupportedByPhoneAccount: isSupp=%b", isVideoCallingSupported);
        mIsVideoCallingSupportedByPhoneAccount = isVideoCallingSupported;

        // Force an update of the connection capabilities so that the dialer is informed of the new
        // video capabilities based on the phone account's support for video.
        setConnectionCapabilities(getConnectionCapabilities(), true /* force */);
    }

    /**
     * @return {@code true} if the {@link Call} locally supports video.
     */
@@ -1363,8 +1380,8 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        }
        PhoneAccount phoneAccount =
                phoneAccountRegistrar.getPhoneAccountUnchecked(mTargetPhoneAccountHandle);
        mIsVideoCallingSupportedByPhoneAccount = phoneAccount != null && phoneAccount.hasCapabilities(
                    PhoneAccount.CAPABILITY_VIDEO_CALLING);
        mIsVideoCallingSupportedByPhoneAccount = phoneAccount != null &&
                phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_VIDEO_CALLING);

        if (!mIsVideoCallingSupportedByPhoneAccount && VideoProfile.isVideo(getVideoState())) {
            // The PhoneAccount for the Call was set to one which does not support video calling,
@@ -1455,7 +1472,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        mConnectElapsedTimeMillis = connectElapsedTimeMillis;
    }

    int getConnectionCapabilities() {
    public int getConnectionCapabilities() {
        return mConnectionCapabilities;
    }

@@ -1463,7 +1480,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        return mConnectionProperties;
    }

    void setConnectionCapabilities(int connectionCapabilities) {
    public void setConnectionCapabilities(int connectionCapabilities) {
        setConnectionCapabilities(connectionCapabilities, false /* forceUpdate */);
    }

+30 −0
Original line number Diff line number Diff line
@@ -340,6 +340,12 @@ public class CallsManager extends Call.ListenerBase
                                               PhoneAccountHandle handle) {
            broadcastUnregisterIntent(handle);
        }

        @Override
        public void onPhoneAccountChanged(PhoneAccountRegistrar registrar,
                PhoneAccount phoneAccount) {
            handlePhoneAccountChanged(registrar, phoneAccount);
        }
    };

    /**
@@ -924,6 +930,11 @@ public class CallsManager extends Call.ListenerBase
        return mEmergencyCallHelper;
    }

    @VisibleForTesting
    public PhoneAccountRegistrar.Listener getPhoneAccountListener() {
        return mPhoneAccountListener;
    }

    @VisibleForTesting
    public boolean hasEmergencyCall() {
        for (Call call : mCalls) {
@@ -4461,4 +4472,23 @@ public class CallsManager extends Call.ListenerBase
        errorIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mContext.startActivityAsUser(errorIntent, UserHandle.CURRENT);
    }

    /**
     * Handles changes to a {@link PhoneAccount}.
     *
     * Checks for changes to video calling availability and updates whether calls for that phone
     * account are video capable.
     *
     * @param registrar The {@link PhoneAccountRegistrar} originating the change.
     * @param phoneAccount The {@link PhoneAccount} which changed.
     */
    private void handlePhoneAccountChanged(PhoneAccountRegistrar registrar,
            PhoneAccount phoneAccount) {
        Log.i(this, "handlePhoneAccountChanged: phoneAccount=%s", phoneAccount);
        boolean isVideoNowSupported = phoneAccount.hasCapabilities(
                PhoneAccount.CAPABILITY_VIDEO_CALLING);
        mCalls.stream()
                .filter(c -> phoneAccount.getAccountHandle().equals(c.getTargetPhoneAccount()))
                .forEach(c -> c.setVideoCallingSupportedByPhoneAccount(isVideoNowSupported));
    }
}
+10 −0
Original line number Diff line number Diff line
@@ -126,6 +126,8 @@ public class PhoneAccountRegistrar {
                                             PhoneAccountHandle handle) {}
        public void onPhoneAccountUnRegistered(PhoneAccountRegistrar registrar,
                                             PhoneAccountHandle handle) {}
        public void onPhoneAccountChanged(PhoneAccountRegistrar registrar,
                PhoneAccount phoneAccount) {}
    }

    /**
@@ -743,6 +745,8 @@ public class PhoneAccountRegistrar {
        fireAccountsChanged();
        if (isNewAccount) {
            fireAccountRegistered(account.getAccountHandle());
        } else {
            fireAccountChanged(account);
        }
    }

@@ -804,6 +808,12 @@ public class PhoneAccountRegistrar {
        }
    }

    private void fireAccountChanged(PhoneAccount account) {
        for (Listener l : mListeners) {
            l.onPhoneAccountChanged(this, account);
        }
    }

    private void fireAccountUnRegistered(PhoneAccountHandle handle) {
        for (Listener l : mListeners) {
            l.onPhoneAccountUnRegistered(this, handle);
+66 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.telecom.tests;

import static junit.framework.TestCase.fail;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -102,9 +104,12 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

@RunWith(JUnit4.class)
public class CallsManagerTest extends TelecomTestCase {
    private static final int TEST_TIMEOUT = 5000;  // milliseconds
    private static final PhoneAccountHandle SIM_1_HANDLE = new PhoneAccountHandle(
            ComponentName.unflattenFromString("com.foo/.Blah"), "Sim1");
    private static final PhoneAccountHandle SIM_2_HANDLE = new PhoneAccountHandle(
@@ -960,6 +965,67 @@ public class CallsManagerTest extends TelecomTestCase {
        assertTrue(mCallsManager.isInEmergencyCall());
    }

    /**
     * Verifies that changes to a {@link PhoneAccount}'s
     * {@link PhoneAccount#CAPABILITY_VIDEO_CALLING} capability will be reflected on a call.
     * @throws Exception
     */
    @SmallTest
    @Test
    public void testPhoneAccountVideoAvailability() throws InterruptedException {
        Call ongoingCall = addSpyCall(); // adds to SIM_2_ACCT
        LinkedBlockingQueue<Integer> capabilitiesQueue = new LinkedBlockingQueue<>(1);
        ongoingCall.addListener(new Call.ListenerBase() {
            @Override
            public void onConnectionCapabilitiesChanged(Call call) {
                try {
                    Log.i("TYLER", "Listener got " + call.getConnectionCapabilities());
                    capabilitiesQueue.put(call.getConnectionCapabilities());
                } catch (InterruptedException e) {
                    fail();
                }
            }
        });

        // Lets make the phone account video capable.
        PhoneAccount videoCapableAccount = new PhoneAccount.Builder(SIM_2_ACCOUNT)
                .setCapabilities(SIM_2_ACCOUNT.getCapabilities()
                        | PhoneAccount.CAPABILITY_VIDEO_CALLING)
                .build();
        mCallsManager.getPhoneAccountListener().onPhoneAccountChanged(mPhoneAccountRegistrar,
                videoCapableAccount);
        // Absorb first update; it'll be from when phone account changed initially (since we force
        // a capabilities update.
        int newCapabilities = capabilitiesQueue.poll(TEST_TIMEOUT, TimeUnit.MILLISECONDS);

        // Lets pretend the ConnectionService made it video capable as well.
        ongoingCall.setConnectionCapabilities(
                Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
        newCapabilities = capabilitiesQueue.poll(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
        assertTrue(Connection.can(newCapabilities,
                Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL));
        assertTrue(ongoingCall.isVideoCallingSupportedByPhoneAccount());

        // Fire a changed event for the phone account making it not capable.
        mCallsManager.getPhoneAccountListener().onPhoneAccountChanged(mPhoneAccountRegistrar,
                SIM_2_ACCOUNT);
        newCapabilities = capabilitiesQueue.poll(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
        assertFalse(Connection.can(newCapabilities,
                Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL));
        assertFalse(ongoingCall.isVideoCallingSupportedByPhoneAccount());

        // Fire a change for an unrelated phone account.
        PhoneAccount anotherVideoCapableAcct = new PhoneAccount.Builder(SIM_1_ACCOUNT)
                .setCapabilities(SIM_2_ACCOUNT.getCapabilities()
                        | PhoneAccount.CAPABILITY_VIDEO_CALLING)
                .build();
        mCallsManager.getPhoneAccountListener().onPhoneAccountChanged(mPhoneAccountRegistrar,
                anotherVideoCapableAcct);
        // Call still should not be video capable
        assertFalse(Connection.can(ongoingCall.getConnectionCapabilities(),
                Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL));
    }

    private Call addSpyCallWithConnectionService(ConnectionServiceWrapper connSvr) {
        Call call = addSpyCall();
        doReturn(connSvr).when(call).getConnectionService();