summaryrefslogtreecommitdiff
path: root/java/com/android/incallui/videotech/ims/ImsVideoCallCallback.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/incallui/videotech/ims/ImsVideoCallCallback.java')
-rw-r--r--java/com/android/incallui/videotech/ims/ImsVideoCallCallback.java211
1 files changed, 211 insertions, 0 deletions
diff --git a/java/com/android/incallui/videotech/ims/ImsVideoCallCallback.java b/java/com/android/incallui/videotech/ims/ImsVideoCallCallback.java
new file mode 100644
index 000000000..17c2e6518
--- /dev/null
+++ b/java/com/android/incallui/videotech/ims/ImsVideoCallCallback.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2017 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.incallui.videotech.ims;
+
+import android.os.Handler;
+import android.telecom.Call;
+import android.telecom.Connection;
+import android.telecom.Connection.VideoProvider;
+import android.telecom.InCallService.VideoCall;
+import android.telecom.VideoProfile;
+import android.telecom.VideoProfile.CameraCapabilities;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.logging.DialerImpression;
+import com.android.dialer.logging.LoggingBindings;
+import com.android.incallui.videotech.VideoTech.VideoTechListener;
+import com.android.incallui.videotech.utils.SessionModificationState;
+
+/** Receives IMS video call state updates. */
+public class ImsVideoCallCallback extends VideoCall.Callback {
+ private static final int CLEAR_FAILED_REQUEST_TIMEOUT_MILLIS = 4000;
+ private final Handler handler = new Handler();
+ private final LoggingBindings logger;
+ private final Call call;
+ private final ImsVideoTech videoTech;
+ private final VideoTechListener listener;
+ private int requestedVideoState = VideoProfile.STATE_AUDIO_ONLY;
+
+ ImsVideoCallCallback(
+ final LoggingBindings logger,
+ final Call call,
+ ImsVideoTech videoTech,
+ VideoTechListener listener) {
+ this.logger = logger;
+ this.call = call;
+ this.videoTech = videoTech;
+ this.listener = listener;
+ }
+
+ @Override
+ public void onSessionModifyRequestReceived(VideoProfile videoProfile) {
+ LogUtil.i(
+ "ImsVideoCallCallback.onSessionModifyRequestReceived", "videoProfile: " + videoProfile);
+
+ int previousVideoState = ImsVideoTech.getUnpausedVideoState(call.getDetails().getVideoState());
+ int newVideoState = ImsVideoTech.getUnpausedVideoState(videoProfile.getVideoState());
+
+ boolean wasVideoCall = VideoProfile.isVideo(previousVideoState);
+ boolean isVideoCall = VideoProfile.isVideo(newVideoState);
+
+ if (wasVideoCall && !isVideoCall) {
+ LogUtil.i(
+ "ImsVideoTech.onSessionModifyRequestReceived", "call downgraded to %d", newVideoState);
+ } else if (previousVideoState != newVideoState) {
+ requestedVideoState = newVideoState;
+ videoTech.setSessionModificationState(
+ SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST);
+ listener.onVideoUpgradeRequestReceived();
+ logger.logImpression(DialerImpression.Type.IMS_VIDEO_REQUEST_RECEIVED);
+ }
+ }
+
+ /**
+ * @param status Status of the session modify request. Valid values are {@link
+ * Connection.VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS}, {@link
+ * Connection.VideoProvider#SESSION_MODIFY_REQUEST_FAIL}, {@link
+ * Connection.VideoProvider#SESSION_MODIFY_REQUEST_INVALID}
+ * @param responseProfile The actual profile changes made by the peer device.
+ */
+ @Override
+ public void onSessionModifyResponseReceived(
+ int status, VideoProfile requestedProfile, VideoProfile responseProfile) {
+ LogUtil.i(
+ "ImsVideoCallCallback.onSessionModifyResponseReceived",
+ "status: %d, requestedProfile: %s, responseProfile: %s, session modification state: %d",
+ status,
+ requestedProfile,
+ responseProfile,
+ videoTech.getSessionModificationState());
+
+ if (videoTech.getSessionModificationState()
+ == SessionModificationState.WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE) {
+ handler.removeCallbacksAndMessages(null); // Clear everything
+
+ final int newSessionModificationState = getSessionModificationStateFromTelecomStatus(status);
+ if (status == VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS) {
+ // Telecom manages audio route for us
+ listener.onUpgradedToVideo(false /* switchToSpeaker */);
+ } else {
+ // This will update the video UI to display the error message.
+ videoTech.setSessionModificationState(newSessionModificationState);
+ }
+
+ // Wait for 4 seconds and then clean the session modification state. This allows the video UI
+ // to stay up so that the user can read the error message.
+ //
+ // If the other person accepted the upgrade request then this will keep the video UI up until
+ // the call's video state change. Without this we would switch to the voice call and then
+ // switch back to video UI.
+ handler.postDelayed(
+ () -> {
+ if (videoTech.getSessionModificationState() == newSessionModificationState) {
+ LogUtil.i("ImsVideoCallCallback.onSessionModifyResponseReceived", "clearing state");
+ videoTech.setSessionModificationState(SessionModificationState.NO_REQUEST);
+ } else {
+ LogUtil.i(
+ "ImsVideoCallCallback.onSessionModifyResponseReceived",
+ "session modification state has changed, not clearing state");
+ }
+ },
+ CLEAR_FAILED_REQUEST_TIMEOUT_MILLIS);
+ } else if (videoTech.getSessionModificationState()
+ == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
+ videoTech.setSessionModificationState(SessionModificationState.NO_REQUEST);
+ } else if (videoTech.getSessionModificationState()
+ == SessionModificationState.WAITING_FOR_RESPONSE) {
+ videoTech.setSessionModificationState(getSessionModificationStateFromTelecomStatus(status));
+ } else {
+ LogUtil.i(
+ "ImsVideoCallCallback.onSessionModifyResponseReceived",
+ "call is not waiting for response, doing nothing");
+ }
+ }
+
+ @SessionModificationState
+ private int getSessionModificationStateFromTelecomStatus(int telecomStatus) {
+ switch (telecomStatus) {
+ case VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS:
+ return SessionModificationState.NO_REQUEST;
+ case VideoProvider.SESSION_MODIFY_REQUEST_FAIL:
+ case VideoProvider.SESSION_MODIFY_REQUEST_INVALID:
+ // Check if it's already video call, which means the request is not video upgrade request.
+ if (VideoProfile.isVideo(call.getDetails().getVideoState())) {
+ return SessionModificationState.REQUEST_FAILED;
+ } else {
+ return SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_FAILED;
+ }
+ case VideoProvider.SESSION_MODIFY_REQUEST_TIMED_OUT:
+ return SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT;
+ case VideoProvider.SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE:
+ return SessionModificationState.REQUEST_REJECTED;
+ default:
+ LogUtil.e(
+ "ImsVideoCallCallback.getSessionModificationStateFromTelecomStatus",
+ "unknown status: %d",
+ telecomStatus);
+ return SessionModificationState.REQUEST_FAILED;
+ }
+ }
+
+ @Override
+ public void onCallSessionEvent(int event) {
+ switch (event) {
+ case Connection.VideoProvider.SESSION_EVENT_RX_PAUSE:
+ LogUtil.i("ImsVideoCallCallback.onCallSessionEvent", "rx_pause");
+ break;
+ case Connection.VideoProvider.SESSION_EVENT_RX_RESUME:
+ LogUtil.i("ImsVideoCallCallback.onCallSessionEvent", "rx_resume");
+ break;
+ case Connection.VideoProvider.SESSION_EVENT_CAMERA_FAILURE:
+ LogUtil.i("ImsVideoCallCallback.onCallSessionEvent", "camera_failure");
+ break;
+ case Connection.VideoProvider.SESSION_EVENT_CAMERA_READY:
+ LogUtil.i("ImsVideoCallCallback.onCallSessionEvent", "camera_ready");
+ break;
+ default:
+ LogUtil.i("ImsVideoCallCallback.onCallSessionEvent", "unknown event = : " + event);
+ break;
+ }
+ }
+
+ @Override
+ public void onPeerDimensionsChanged(int width, int height) {
+ listener.onPeerDimensionsChanged(width, height);
+ }
+
+ @Override
+ public void onVideoQualityChanged(int videoQuality) {
+ LogUtil.i("ImsVideoCallCallback.onVideoQualityChanged", "videoQuality: %d", videoQuality);
+ }
+
+ @Override
+ public void onCallDataUsageChanged(long dataUsage) {
+ LogUtil.i("ImsVideoCallCallback.onCallDataUsageChanged", "dataUsage: %d", dataUsage);
+ }
+
+ @Override
+ public void onCameraCapabilitiesChanged(CameraCapabilities cameraCapabilities) {
+ if (cameraCapabilities != null) {
+ listener.onCameraDimensionsChanged(
+ cameraCapabilities.getWidth(), cameraCapabilities.getHeight());
+ }
+ }
+
+ int getRequestedVideoState() {
+ return requestedVideoState;
+ }
+}