Merge "Fix issue where system rings even if default dialer can play ringtone."
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index ca41974..76eed40 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -50,6 +50,7 @@
import android.text.TextUtils;
import android.util.StatsLog;
import android.os.UserHandle;
+import android.widget.Toast;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telecom.IVideoProvider;
@@ -461,7 +462,7 @@
* Indicates whether the {@link PhoneAccount} associated with this call supports video calling.
* {@code True} if the phone account supports video calling, {@code false} otherwise.
*/
- private boolean mIsVideoCallingSupported = false;
+ private boolean mIsVideoCallingSupportedByPhoneAccount = false;
private PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter;
@@ -1229,8 +1230,19 @@
return mUseCallRecordingTone;
}
- public boolean isVideoCallingSupported() {
- return mIsVideoCallingSupported;
+ /**
+ * @return {@code true} if the {@link Call}'s {@link #getTargetPhoneAccount()} supports video.
+ */
+ public boolean isVideoCallingSupportedByPhoneAccount() {
+ return mIsVideoCallingSupportedByPhoneAccount;
+ }
+
+ /**
+ * @return {@code true} if the {@link Call} locally supports video.
+ */
+ public boolean isLocallyVideoCapable() {
+ return (getConnectionCapabilities() & Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)
+ == Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL;
}
public boolean isSelfManaged() {
@@ -1332,16 +1344,16 @@
if (mTargetPhoneAccountHandle == null) {
// If no target phone account handle is specified, assume we can potentially perform a
// video call; once the phone account is set, we can confirm that it is video capable.
- mIsVideoCallingSupported = true;
+ mIsVideoCallingSupportedByPhoneAccount = true;
Log.d(this, "checkIfVideoCapable: no phone account selected; assume video capable.");
return;
}
PhoneAccount phoneAccount =
phoneAccountRegistrar.getPhoneAccountUnchecked(mTargetPhoneAccountHandle);
- mIsVideoCallingSupported = phoneAccount != null && phoneAccount.hasCapabilities(
+ mIsVideoCallingSupportedByPhoneAccount = phoneAccount != null && phoneAccount.hasCapabilities(
PhoneAccount.CAPABILITY_VIDEO_CALLING);
- if (!mIsVideoCallingSupported && VideoProfile.isVideo(getVideoState())) {
+ if (!mIsVideoCallingSupportedByPhoneAccount && VideoProfile.isVideo(getVideoState())) {
// The PhoneAccount for the Call was set to one which does not support video calling,
// and the current call is configured to be a video call; downgrade to audio-only.
setVideoState(VideoProfile.STATE_AUDIO_ONLY);
@@ -1444,7 +1456,8 @@
if (forceUpdate || mConnectionCapabilities != connectionCapabilities) {
// If the phone account does not support video calling, and the connection capabilities
// passed in indicate that the call supports video, remove those video capabilities.
- if (!isVideoCallingSupported() && doesCallSupportVideo(connectionCapabilities)) {
+ if (!isVideoCallingSupportedByPhoneAccount()
+ && doesCallSupportVideo(connectionCapabilities)) {
Log.w(this, "setConnectionCapabilities: attempt to set connection as video " +
"capable when not supported by the phone account.");
connectionCapabilities = removeVideoCapabilities(connectionCapabilities);
@@ -1880,7 +1893,7 @@
// Check to verify that the call is still in the ringing state. A call can change states
// between the time the user hits 'answer' and Telecom receives the command.
if (isRinging("answer")) {
- if (!isVideoCallingSupported() && VideoProfile.isVideo(videoState)) {
+ if (!isVideoCallingSupportedByPhoneAccount() && VideoProfile.isVideo(videoState)) {
// Video calling is not supported, yet the InCallService is attempting to answer as
// video. We will simply answer as audio-only.
videoState = VideoProfile.STATE_AUDIO_ONLY;
@@ -2260,10 +2273,20 @@
public void sendCallEvent(String event, int targetSdkVer, Bundle extras) {
if (mConnectionService != null) {
if (android.telecom.Call.EVENT_REQUEST_HANDOVER.equals(event)) {
- if (targetSdkVer > Build.VERSION_CODES.O_MR1) {
+ if (targetSdkVer > Build.VERSION_CODES.P) {
Log.e(this, new Exception(), "sendCallEvent failed. Use public api handoverTo" +
- " for API > 27(O-MR1)");
- // TODO: Add "return" after DUO team adds new API support for handover
+ " for API > 28(P)");
+ // Event-based Handover APIs are deprecated, so inform the user.
+ 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.",
+ Toast.LENGTH_LONG).show();
+ }
+ });
+
+ // Uncomment and remove toast at feature complete: return;
}
// Handover requests are targeted at Telecom, not the ConnectionService.
@@ -2784,7 +2807,7 @@
public void setVideoState(int videoState) {
// If the phone account associated with this call does not support video calling, then we
// will automatically set the video state to audio-only.
- if (!isVideoCallingSupported()) {
+ if (!isVideoCallingSupportedByPhoneAccount()) {
Log.d(this, "setVideoState: videoState=%s defaulted to audio (video not supported)",
VideoProfile.videoStateToString(videoState));
videoState = VideoProfile.STATE_AUDIO_ONLY;
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 1575cc4..7b318c3 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -577,9 +577,14 @@
rejectCallAndLog(incomingCall);
}
} else if (hasMaximumManagedDialingCalls(incomingCall)) {
- Log.i(this, "onCallFilteringCompleted: Call rejected! Exceeds maximum number of " +
- "dialing calls.");
- rejectCallAndLog(incomingCall);
+ if (shouldSilenceInsteadOfReject(incomingCall)) {
+ incomingCall.silence();
+ } else {
+
+ Log.i(this, "onCallFilteringCompleted: Call rejected! Exceeds maximum number of " +
+ "dialing calls.");
+ rejectCallAndLog(incomingCall);
+ }
} else {
addCall(incomingCall);
}
@@ -604,8 +609,10 @@
}
/**
- * Whether allow (silence rather than reject) the incoming call if it has a different source
- * (connection service) from the existing ringing call when reaching maximum ringing calls.
+ * In the event that the maximum supported calls of a given type is reached, the
+ * default behavior is to reject any additional calls of that type. This checks
+ * if the device is configured to silence instead of reject the call, provided
+ * that the incoming call is from a different source (connection service).
*/
private boolean shouldSilenceInsteadOfReject(Call incomingCall) {
if (!mContext.getResources().getBoolean(
@@ -613,8 +620,6 @@
return false;
}
- Call ringingCall = null;
-
for (Call call : mCalls) {
// Only operate on top-level calls
if (call.getParentCall() != null) {
@@ -625,8 +630,7 @@
continue;
}
- if (CallState.RINGING == call.getState() &&
- call.getConnectionService() == incomingCall.getConnectionService()) {
+ if (call.getConnectionService() == incomingCall.getConnectionService()) {
return false;
}
}
@@ -3559,6 +3563,10 @@
mCallAudioManager.getCallAudioState());
Call handoverToCall = startOutgoingCall(handoverFromCall.getHandle(), handoverToHandle,
extras, getCurrentUserHandle(), null /* originalIntent */);
+ if (handoverToCall == null) {
+ handoverFromCall.sendCallEvent(android.telecom.Call.EVENT_HANDOVER_FAILED, null);
+ return;
+ }
Log.addEvent(handoverFromCall, LogUtils.Events.START_HANDOVER,
"handOverFrom=%s, handOverTo=%s", handoverFromCall.getId(), handoverToCall.getId());
handoverFromCall.setHandoverDestinationCall(handoverToCall);
diff --git a/src/com/android/server/telecom/VideoProviderProxy.java b/src/com/android/server/telecom/VideoProviderProxy.java
index 7d90a6d..6e1f01d 100644
--- a/src/com/android/server/telecom/VideoProviderProxy.java
+++ b/src/com/android/server/telecom/VideoProviderProxy.java
@@ -20,7 +20,6 @@
import android.app.AppOpsManager;
import android.content.Context;
import android.net.Uri;
-import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.Looper;
@@ -33,6 +32,7 @@
import android.text.TextUtils;
import android.view.Surface;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telecom.IVideoCallback;
import com.android.internal.telecom.IVideoProvider;
@@ -40,8 +40,6 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import static android.Manifest.permission.CALL_PHONE;
-
/**
* Proxies video provider messages from {@link InCallService.VideoCall}
* implementations to the underlying {@link Connection.VideoProvider} implementation. Also proxies
@@ -55,7 +53,7 @@
/**
* Listener for Telecom components interested in callbacks from the video provider.
*/
- interface Listener {
+ public interface Listener {
void onSessionModifyRequestReceived(Call call, VideoProfile videoProfile);
}
@@ -112,7 +110,7 @@
* @param call The current call.
* @throws RemoteException Remote exception.
*/
- VideoProviderProxy(TelecomSystem.SyncRoot lock,
+ public VideoProviderProxy(TelecomSystem.SyncRoot lock,
IVideoProvider videoProvider, Call call, CurrentUserProxy currentUserProxy)
throws RemoteException {
@@ -136,11 +134,16 @@
}
}
+ @VisibleForTesting
+ public VideoCallListenerBinder getVideoCallListenerBinder() {
+ return mVideoCallListenerBinder;
+ }
+
/**
* IVideoCallback stub implementation. An instance of this class receives callbacks from the
* {@code ConnectionService}'s video provider.
*/
- private final class VideoCallListenerBinder extends IVideoCallback.Stub {
+ public final class VideoCallListenerBinder extends IVideoCallback.Stub {
/**
* Proxies a request from the {@link #mConectionServiceVideoProvider} to the
* {@link InCallService} when a session modification request is received.
@@ -160,13 +163,14 @@
Analytics.RECEIVE_REMOTE_SESSION_MODIFY_REQUEST,
videoProfile.getVideoState());
- if (!mCall.isVideoCallingSupported() &&
- VideoProfile.isVideo(videoProfile.getVideoState())) {
- // If video calling is not supported by the phone account, and we receive
- // a request to upgrade to video, automatically reject it without informing
- // the InCallService.
-
- Log.addEvent(mCall, LogUtils.Events.SEND_VIDEO_RESPONSE, "video not supported");
+ if ((!mCall.isVideoCallingSupportedByPhoneAccount()
+ || !mCall.isLocallyVideoCapable())
+ && VideoProfile.isVideo(videoProfile.getVideoState())) {
+ // If video calling is not supported by the phone account, or is not
+ // locally video capable and we receive a request to upgrade to video,
+ // automatically reject it without informing the InCallService.
+ Log.addEvent(mCall, LogUtils.Events.SEND_VIDEO_RESPONSE,
+ "video not supported");
VideoProfile responseProfile = new VideoProfile(
VideoProfile.STATE_AUDIO_ONLY);
try {
diff --git a/testapps/AndroidManifest.xml b/testapps/AndroidManifest.xml
index 48451d1..02443ba 100644
--- a/testapps/AndroidManifest.xml
+++ b/testapps/AndroidManifest.xml
@@ -19,9 +19,10 @@
package="com.android.server.telecom.testapps">
<uses-sdk
- android:minSdkVersion="23"
- android:targetSdkVersion="23" />
+ android:minSdkVersion="28"
+ android:targetSdkVersion="28" />
+ <uses-permission android:name="android.permission.ACCEPT_HANDOVER" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CALL_PHONE" />
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
index 93a2c7f..959b855 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
@@ -119,12 +119,12 @@
mPlaceIncomingCallButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- placeIncomingCall(false /* isHandoverFrom */);
+ placeIncomingCall();
}
});
mHandoverFrom = (Button) findViewById(R.id.handoverFrom);
mHandoverFrom.setOnClickListener((v -> {
- placeIncomingCall(true /* isHandoverFrom */);
+ initiateHandover();
}));
mUseAcct1Button = findViewById(R.id.useAcct1Button);
@@ -176,7 +176,14 @@
tm.placeCall(Uri.parse(mNumber.getText().toString()), extras);
}
- private void placeIncomingCall(boolean isHandoverFrom) {
+ private void initiateHandover() {
+ TelecomManager tm = TelecomManager.from(this);
+ PhoneAccountHandle phoneAccountHandle = getSelectedPhoneAccountHandle();
+ Uri address = Uri.parse(mNumber.getText().toString());
+ tm.acceptHandover(address, VideoProfile.STATE_BIDIRECTIONAL, phoneAccountHandle);
+ }
+
+ private void placeIncomingCall() {
TelecomManager tm = TelecomManager.from(this);
PhoneAccountHandle phoneAccountHandle = getSelectedPhoneAccountHandle();
@@ -196,9 +203,6 @@
extras.putInt(TelecomManager.EXTRA_INCOMING_VIDEO_STATE,
VideoProfile.STATE_BIDIRECTIONAL);
}
- if (isHandoverFrom) {
- extras.putBoolean(TelecomManager.EXTRA_IS_HANDOVER, true);
- }
tm.addNewIncomingCall(getSelectedPhoneAccountHandle(), extras);
}
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedConnectionService.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedConnectionService.java
index fca05dc..f2b6496 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedConnectionService.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedConnectionService.java
@@ -24,9 +24,7 @@
import android.telecom.Log;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
-import android.telecom.VideoProfile;
-import java.util.Objects;
import java.util.Random;
/**
@@ -45,13 +43,25 @@
PhoneAccountHandle connectionManagerAccount,
final ConnectionRequest request) {
- return createSelfManagedConnection(request, false);
+ return createSelfManagedConnection(request, false, false /* isHandover */);
}
@Override
public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
ConnectionRequest request) {
- return createSelfManagedConnection(request, true);
+ return createSelfManagedConnection(request, true, false /* isHandover */);
+ }
+
+ @Override
+ public Connection onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
+ ConnectionRequest request) {
+ return createSelfManagedConnection(request, false, true /* isHandover */);
+ }
+
+ @Override
+ public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
+ ConnectionRequest request) {
+ return createSelfManagedConnection(request, true, true /* isHandover */);
}
@Override
@@ -77,7 +87,8 @@
mCallList.notifyConnectionServiceFocusGained();
}
- private Connection createSelfManagedConnection(ConnectionRequest request, boolean isIncoming) {
+ private Connection createSelfManagedConnection(ConnectionRequest request, boolean isIncoming,
+ boolean isHandover) {
SelfManagedConnection connection = new SelfManagedConnection(mCallList,
getApplicationContext(), isIncoming);
connection.setListener(mCallList.getConnectionListener());
@@ -98,11 +109,10 @@
if (requestExtras != null) {
boolean isHoldable = requestExtras.getBoolean(EXTRA_HOLDABLE, false);
Log.i(this, "createConnection: isHandover=%b, handoverFrom=%s, holdable=%b",
- requestExtras.getBoolean(TelecomManager.EXTRA_IS_HANDOVER),
+ isHandover,
requestExtras.getString(TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT),
isHoldable);
- connection.setIsHandover(requestExtras.getBoolean(TelecomManager.EXTRA_IS_HANDOVER,
- false));
+ connection.setIsHandover(isHandover);
if (isHoldable) {
connection.setConnectionCapabilities(connection.getConnectionCapabilities() |
Connection.CAPABILITY_HOLD | Connection.CAPABILITY_SUPPORT_HOLD);
diff --git a/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java b/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java
index 9851253..2a5b33a 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestInCallUI.java
@@ -18,6 +18,7 @@
import android.app.Activity;
import android.bluetooth.BluetoothDevice;
+import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.telecom.Call;
@@ -209,11 +210,8 @@
handoverButton.setOnClickListener((v) -> {
Call call = mCallList.getCall(0);
- Bundle extras = new Bundle();
- extras.putParcelable(Call.EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE,
- getHandoverToPhoneAccountHandle());
- extras.putInt(Call.EXTRA_HANDOVER_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL);
- call.sendCallEvent(Call.EVENT_REQUEST_HANDOVER, extras);
+ call.handoverTo(getHandoverToPhoneAccountHandle(), VideoProfile.STATE_BIDIRECTIONAL,
+ null);
});
}
@@ -263,17 +261,8 @@
}
private PhoneAccountHandle getHandoverToPhoneAccountHandle() {
- TelecomManager tm = TelecomManager.from(this);
-
- List<PhoneAccountHandle> handles = tm.getAllPhoneAccountHandles();
- Optional<PhoneAccountHandle> found = handles.stream().filter(h -> {
- PhoneAccount account = tm.getPhoneAccount(h);
- Bundle extras = account.getExtras();
- return extras != null && extras.getBoolean(PhoneAccount.EXTRA_SUPPORTS_HANDOVER_TO);
- }).findFirst();
- PhoneAccountHandle foundHandle = found.orElse(null);
- Log.i(TestInCallUI.class.getSimpleName(), "getHandoverToPhoneAccountHandle() = " +
- foundHandle);
- return foundHandle;
+ return new PhoneAccountHandle(new ComponentName(
+ SelfManagedCallList.class.getPackage().getName(),
+ SelfManagedConnectionService.class.getName()), "1");
}
}
diff --git a/tests/src/com/android/server/telecom/tests/BasicCallTests.java b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
index 9240199..c7c5675 100644
--- a/tests/src/com/android/server/telecom/tests/BasicCallTests.java
+++ b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
@@ -26,7 +26,6 @@
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
-import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
@@ -921,12 +920,12 @@
Process.myUserHandle(), VideoProfile.STATE_BIDIRECTIONAL);
com.android.server.telecom.Call call = mTelecomSystem.getCallsManager().getCalls()
.iterator().next();
- assert(call.isVideoCallingSupported());
+ assert(call.isVideoCallingSupportedByPhoneAccount());
assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState());
// Change the phone account to one which supports video calling.
call.setTargetPhoneAccount(mPhoneAccountA1.getAccountHandle());
- assert(call.isVideoCallingSupported());
+ assert(call.isVideoCallingSupportedByPhoneAccount());
assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState());
}
@@ -944,12 +943,12 @@
Process.myUserHandle(), VideoProfile.STATE_BIDIRECTIONAL);
com.android.server.telecom.Call call = mTelecomSystem.getCallsManager().getCalls()
.iterator().next();
- assert(call.isVideoCallingSupported());
+ assert(call.isVideoCallingSupportedByPhoneAccount());
assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState());
// Change the phone account to one which does not support video calling.
call.setTargetPhoneAccount(mPhoneAccountA2.getAccountHandle());
- assert(!call.isVideoCallingSupported());
+ assert(!call.isVideoCallingSupportedByPhoneAccount());
assertEquals(VideoProfile.STATE_AUDIO_ONLY, call.getVideoState());
}
diff --git a/tests/src/com/android/server/telecom/tests/VideoProviderProxyTest.java b/tests/src/com/android/server/telecom/tests/VideoProviderProxyTest.java
new file mode 100644
index 0000000..a6eecf7
--- /dev/null
+++ b/tests/src/com/android/server/telecom/tests/VideoProviderProxyTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.telecom.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.IBinder;
+import android.telecom.VideoProfile;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.internal.telecom.IVideoProvider;
+import com.android.server.telecom.Analytics;
+import com.android.server.telecom.Call;
+import com.android.server.telecom.CurrentUserProxy;
+import com.android.server.telecom.TelecomSystem;
+import com.android.server.telecom.VideoProviderProxy;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class VideoProviderProxyTest extends TelecomTestCase {
+
+ private TelecomSystem.SyncRoot mLock;
+ private VideoProviderProxy mVideoProviderProxy;
+ @Mock private IVideoProvider mVideoProvider;
+ @Mock private IBinder mIBinder;
+ @Mock private Call mCall;
+ @Mock private Analytics.CallInfo mCallInfo;
+ @Mock private CurrentUserProxy mCurrentUserProxy;
+ @Mock private VideoProviderProxy.Listener mListener;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ MockitoAnnotations.initMocks(this);
+ mLock = new TelecomSystem.SyncRoot() { };
+
+ when(mVideoProvider.asBinder()).thenReturn(mIBinder);
+ doNothing().when(mIBinder).linkToDeath(any(), anyInt());
+ when(mCall.getAnalytics()).thenReturn(mCallInfo);
+ doNothing().when(mCallInfo).addVideoEvent(anyInt(), anyInt());
+ mVideoProviderProxy = new VideoProviderProxy(mLock, mVideoProvider, mCall,
+ mCurrentUserProxy);
+ mVideoProviderProxy.addListener(mListener);
+ }
+
+ /**
+ * Tests the case where we receive a request to upgrade to video, except:
+ * 1. Phone account says we support video.
+ * 2. Call says we don't support video.
+ *
+ * Ensures that we send back a response immediately to indicate the call should remain as
+ * audio-only.
+ * @throws Exception
+ */
+ @SmallTest
+ @Test
+ public void testReceiveUpgradeRequestWhenLocalDoesntSupportVideo() throws Exception {
+ // Given a call which supports video at the phone account level, but is not currently
+ // marked as supporting video locally.
+ when(mCall.isLocallyVideoCapable()).thenReturn(false);
+ when(mCall.isVideoCallingSupportedByPhoneAccount()).thenReturn(true);
+
+ // Simulate receiving a request to upgrade to video.
+ mVideoProviderProxy.getVideoCallListenerBinder().receiveSessionModifyRequest(
+ new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL));
+
+ // Make sure that we send back a response rejecting the request.
+ ArgumentCaptor<VideoProfile> capturedProfile = ArgumentCaptor.forClass(VideoProfile.class);
+ verify(mVideoProvider).sendSessionModifyResponse(capturedProfile.capture());
+ assertEquals(VideoProfile.STATE_AUDIO_ONLY, capturedProfile.getValue().getVideoState());
+ }
+
+ /**
+ * Tests the case where we receive a request to upgrade to video and video is supported.
+ * @throws Exception
+ */
+ @SmallTest
+ @Test
+ public void testReceiveUpgradeRequestWhenVideoIsSupported() throws Exception {
+ // Given a call which supports video at the phone account level, and is currently marked as
+ // supporting video locally.
+ when(mCall.isLocallyVideoCapable()).thenReturn(true);
+ when(mCall.isVideoCallingSupportedByPhoneAccount()).thenReturn(true);
+
+ // Simulate receiving a request to upgrade to video.
+ mVideoProviderProxy.getVideoCallListenerBinder().receiveSessionModifyRequest(
+ new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL));
+
+ // Ensure it gets proxied back to the caller.
+
+ ArgumentCaptor<VideoProfile> capturedProfile = ArgumentCaptor.forClass(VideoProfile.class);
+ verify(mListener).onSessionModifyRequestReceived(any(), capturedProfile.capture());
+ assertEquals(VideoProfile.STATE_BIDIRECTIONAL, capturedProfile.getValue().getVideoState());
+ }
+}