summaryrefslogtreecommitdiff
path: root/java/com/android/incallui/videotech
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/incallui/videotech')
-rw-r--r--java/com/android/incallui/videotech/VideoTech.java38
-rw-r--r--java/com/android/incallui/videotech/empty/EmptyVideoTech.java18
-rw-r--r--java/com/android/incallui/videotech/ims/ImsVideoCallCallback.java28
-rw-r--r--java/com/android/incallui/videotech/ims/ImsVideoTech.java38
-rw-r--r--java/com/android/incallui/videotech/rcs/RcsVideoShare.java200
-rw-r--r--java/com/android/incallui/videotech/utils/SessionModificationState.java46
-rw-r--r--java/com/android/incallui/videotech/utils/VideoUtils.java60
7 files changed, 171 insertions, 257 deletions
diff --git a/java/com/android/incallui/videotech/VideoTech.java b/java/com/android/incallui/videotech/VideoTech.java
index bd957b699..5ecdc1d56 100644
--- a/java/com/android/incallui/videotech/VideoTech.java
+++ b/java/com/android/incallui/videotech/VideoTech.java
@@ -16,9 +16,10 @@
package com.android.incallui.videotech;
-import android.support.annotation.IntDef;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import android.content.Context;
+import com.android.incallui.video.protocol.VideoCallScreen;
+import com.android.incallui.video.protocol.VideoCallScreenDelegate;
+import com.android.incallui.videotech.utils.SessionModificationState;
/** Video calling interface. */
public interface VideoTech {
@@ -33,6 +34,11 @@ public interface VideoTech {
*/
boolean isSelfManagedCamera();
+ boolean shouldUseSurfaceView();
+
+ VideoCallScreenDelegate createVideoCallScreenDelegate(
+ Context context, VideoCallScreen videoCallScreen);
+
void onCallStateChanged(int newState);
@SessionModificationState
@@ -73,30 +79,4 @@ public interface VideoTech {
void onVideoUpgradeRequestReceived();
}
-
- /**
- * Defines different states of session modify requests, which are used to upgrade to video, or
- * downgrade to audio.
- */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({
- SESSION_MODIFICATION_STATE_NO_REQUEST,
- SESSION_MODIFICATION_STATE_WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE,
- SESSION_MODIFICATION_STATE_REQUEST_FAILED,
- SESSION_MODIFICATION_STATE_RECEIVED_UPGRADE_TO_VIDEO_REQUEST,
- SESSION_MODIFICATION_STATE_UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT,
- SESSION_MODIFICATION_STATE_UPGRADE_TO_VIDEO_REQUEST_FAILED,
- SESSION_MODIFICATION_STATE_REQUEST_REJECTED,
- SESSION_MODIFICATION_STATE_WAITING_FOR_RESPONSE
- })
- @interface SessionModificationState {}
-
- int SESSION_MODIFICATION_STATE_NO_REQUEST = 0;
- int SESSION_MODIFICATION_STATE_WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE = 1;
- int SESSION_MODIFICATION_STATE_REQUEST_FAILED = 2;
- int SESSION_MODIFICATION_STATE_RECEIVED_UPGRADE_TO_VIDEO_REQUEST = 3;
- int SESSION_MODIFICATION_STATE_UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT = 4;
- int SESSION_MODIFICATION_STATE_UPGRADE_TO_VIDEO_REQUEST_FAILED = 5;
- int SESSION_MODIFICATION_STATE_REQUEST_REJECTED = 6;
- int SESSION_MODIFICATION_STATE_WAITING_FOR_RESPONSE = 7;
}
diff --git a/java/com/android/incallui/videotech/empty/EmptyVideoTech.java b/java/com/android/incallui/videotech/empty/EmptyVideoTech.java
index c76043540..58c680935 100644
--- a/java/com/android/incallui/videotech/empty/EmptyVideoTech.java
+++ b/java/com/android/incallui/videotech/empty/EmptyVideoTech.java
@@ -16,7 +16,12 @@
package com.android.incallui.videotech.empty;
+import android.content.Context;
+import com.android.dialer.common.Assert;
+import com.android.incallui.video.protocol.VideoCallScreen;
+import com.android.incallui.video.protocol.VideoCallScreenDelegate;
import com.android.incallui.videotech.VideoTech;
+import com.android.incallui.videotech.utils.SessionModificationState;
/** Default video tech that is always available but doesn't do anything. */
public class EmptyVideoTech implements VideoTech {
@@ -37,11 +42,22 @@ public class EmptyVideoTech implements VideoTech {
}
@Override
+ public boolean shouldUseSurfaceView() {
+ return false;
+ }
+
+ @Override
+ public VideoCallScreenDelegate createVideoCallScreenDelegate(
+ Context context, VideoCallScreen videoCallScreen) {
+ throw Assert.createUnsupportedOperationFailException();
+ }
+
+ @Override
public void onCallStateChanged(int newState) {}
@Override
public int getSessionModificationState() {
- return VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST;
+ return SessionModificationState.NO_REQUEST;
}
@Override
diff --git a/java/com/android/incallui/videotech/ims/ImsVideoCallCallback.java b/java/com/android/incallui/videotech/ims/ImsVideoCallCallback.java
index 0a15f7e65..9b5222e10 100644
--- a/java/com/android/incallui/videotech/ims/ImsVideoCallCallback.java
+++ b/java/com/android/incallui/videotech/ims/ImsVideoCallCallback.java
@@ -24,9 +24,8 @@ import android.telecom.InCallService.VideoCall;
import android.telecom.VideoProfile;
import android.telecom.VideoProfile.CameraCapabilities;
import com.android.dialer.common.LogUtil;
-import com.android.incallui.videotech.VideoTech;
-import com.android.incallui.videotech.VideoTech.SessionModificationState;
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 {
@@ -60,7 +59,7 @@ public class ImsVideoCallCallback extends VideoCall.Callback {
} else if (previousVideoState != newVideoState) {
requestedVideoState = newVideoState;
videoTech.setSessionModificationState(
- VideoTech.SESSION_MODIFICATION_STATE_RECEIVED_UPGRADE_TO_VIDEO_REQUEST);
+ SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST);
listener.onVideoUpgradeRequestReceived();
}
}
@@ -84,7 +83,7 @@ public class ImsVideoCallCallback extends VideoCall.Callback {
videoTech.getSessionModificationState());
if (videoTech.getSessionModificationState()
- == VideoTech.SESSION_MODIFICATION_STATE_WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE) {
+ == SessionModificationState.WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE) {
handler.removeCallbacksAndMessages(null); // Clear everything
final int newSessionModificationState = getSessionModificationStateFromTelecomStatus(status);
@@ -103,8 +102,7 @@ public class ImsVideoCallCallback extends VideoCall.Callback {
() -> {
if (videoTech.getSessionModificationState() == newSessionModificationState) {
LogUtil.i("ImsVideoCallCallback.onSessionModifyResponseReceived", "clearing state");
- videoTech.setSessionModificationState(
- VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST);
+ videoTech.setSessionModificationState(SessionModificationState.NO_REQUEST);
} else {
LogUtil.i(
"ImsVideoCallCallback.onSessionModifyResponseReceived",
@@ -113,10 +111,10 @@ public class ImsVideoCallCallback extends VideoCall.Callback {
},
CLEAR_FAILED_REQUEST_TIMEOUT_MILLIS);
} else if (videoTech.getSessionModificationState()
- == VideoTech.SESSION_MODIFICATION_STATE_RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
- videoTech.setSessionModificationState(VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST);
+ == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
+ videoTech.setSessionModificationState(SessionModificationState.NO_REQUEST);
} else if (videoTech.getSessionModificationState()
- == VideoTech.SESSION_MODIFICATION_STATE_WAITING_FOR_RESPONSE) {
+ == SessionModificationState.WAITING_FOR_RESPONSE) {
videoTech.setSessionModificationState(getSessionModificationStateFromTelecomStatus(status));
} else {
LogUtil.i(
@@ -129,25 +127,25 @@ public class ImsVideoCallCallback extends VideoCall.Callback {
private int getSessionModificationStateFromTelecomStatus(int telecomStatus) {
switch (telecomStatus) {
case VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS:
- return VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST;
+ 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 VideoTech.SESSION_MODIFICATION_STATE_REQUEST_FAILED;
+ return SessionModificationState.REQUEST_FAILED;
} else {
- return VideoTech.SESSION_MODIFICATION_STATE_UPGRADE_TO_VIDEO_REQUEST_FAILED;
+ return SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_FAILED;
}
case VideoProvider.SESSION_MODIFY_REQUEST_TIMED_OUT:
- return VideoTech.SESSION_MODIFICATION_STATE_UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT;
+ return SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT;
case VideoProvider.SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE:
- return VideoTech.SESSION_MODIFICATION_STATE_REQUEST_REJECTED;
+ return SessionModificationState.REQUEST_REJECTED;
default:
LogUtil.e(
"ImsVideoCallCallback.getSessionModificationStateFromTelecomStatus",
"unknown status: %d",
telecomStatus);
- return VideoTech.SESSION_MODIFICATION_STATE_REQUEST_FAILED;
+ return SessionModificationState.REQUEST_FAILED;
}
}
diff --git a/java/com/android/incallui/videotech/ims/ImsVideoTech.java b/java/com/android/incallui/videotech/ims/ImsVideoTech.java
index a37500c3b..8c2ca151a 100644
--- a/java/com/android/incallui/videotech/ims/ImsVideoTech.java
+++ b/java/com/android/incallui/videotech/ims/ImsVideoTech.java
@@ -16,13 +16,17 @@
package com.android.incallui.videotech.ims;
+import android.content.Context;
import android.os.Build;
import android.telecom.Call;
import android.telecom.Call.Details;
import android.telecom.VideoProfile;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
+import com.android.incallui.video.protocol.VideoCallScreen;
+import com.android.incallui.video.protocol.VideoCallScreenDelegate;
import com.android.incallui.videotech.VideoTech;
+import com.android.incallui.videotech.utils.SessionModificationState;
/** ViLTE implementation */
public class ImsVideoTech implements VideoTech {
@@ -30,7 +34,7 @@ public class ImsVideoTech implements VideoTech {
private final VideoTechListener listener;
private ImsVideoCallCallback callback;
private @SessionModificationState int sessionModificationState =
- VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST;
+ SessionModificationState.NO_REQUEST;
private int previousVideoState = VideoProfile.STATE_AUDIO_ONLY;
public ImsVideoTech(VideoTechListener listener, Call call) {
@@ -65,6 +69,18 @@ public class ImsVideoTech implements VideoTech {
}
@Override
+ public boolean shouldUseSurfaceView() {
+ return false;
+ }
+
+ @Override
+ public VideoCallScreenDelegate createVideoCallScreenDelegate(
+ Context context, VideoCallScreen videoCallScreen) {
+ // TODO move creating VideoCallPresenter here
+ throw Assert.createUnsupportedOperationFailException();
+ }
+
+ @Override
public void onCallStateChanged(int newState) {
if (!isAvailable()) {
return;
@@ -76,7 +92,7 @@ public class ImsVideoTech implements VideoTech {
}
if (getSessionModificationState()
- == VideoTech.SESSION_MODIFICATION_STATE_WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE
+ == SessionModificationState.WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE
&& isTransmittingOrReceiving()) {
// We don't clear the session modification state right away when we find out the video upgrade
// request was accepted to avoid having the UI switch from video to voice to video.
@@ -84,17 +100,16 @@ public class ImsVideoTech implements VideoTech {
LogUtil.i(
"ImsVideoTech.onCallStateChanged",
"upgraded to video, clearing session modification state");
- setSessionModificationState(VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST);
+ setSessionModificationState(SessionModificationState.NO_REQUEST);
}
// Determines if a received upgrade to video request should be cancelled. This can happen if
// another InCall UI responds to the upgrade to video request.
int newVideoState = call.getDetails().getVideoState();
if (newVideoState != previousVideoState
- && sessionModificationState
- == VideoTech.SESSION_MODIFICATION_STATE_RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
+ && sessionModificationState == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
LogUtil.i("ImsVideoTech.onCallStateChanged", "cancelling upgrade notification");
- setSessionModificationState(VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST);
+ setSessionModificationState(SessionModificationState.NO_REQUEST);
}
previousVideoState = newVideoState;
}
@@ -121,8 +136,7 @@ public class ImsVideoTech implements VideoTech {
call.getVideoCall()
.sendSessionModifyRequest(
new VideoProfile(unpausedVideoState | VideoProfile.STATE_BIDIRECTIONAL));
- setSessionModificationState(
- VideoTech.SESSION_MODIFICATION_STATE_WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE);
+ setSessionModificationState(SessionModificationState.WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE);
}
@Override
@@ -131,14 +145,14 @@ public class ImsVideoTech implements VideoTech {
Assert.checkArgument(requestedVideoState != VideoProfile.STATE_AUDIO_ONLY);
LogUtil.i("ImsVideoTech.acceptUpgradeRequest", "videoState: " + requestedVideoState);
call.getVideoCall().sendSessionModifyResponse(new VideoProfile(requestedVideoState));
- setSessionModificationState(VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST);
+ setSessionModificationState(SessionModificationState.NO_REQUEST);
}
@Override
public void acceptVideoRequestAsAudio() {
LogUtil.enterBlock("ImsVideoTech.acceptVideoRequestAsAudio");
call.getVideoCall().sendSessionModifyResponse(new VideoProfile(VideoProfile.STATE_AUDIO_ONLY));
- setSessionModificationState(VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST);
+ setSessionModificationState(SessionModificationState.NO_REQUEST);
}
@Override
@@ -146,7 +160,7 @@ public class ImsVideoTech implements VideoTech {
LogUtil.enterBlock("ImsVideoTech.declineUpgradeRequest");
call.getVideoCall()
.sendSessionModifyResponse(new VideoProfile(call.getDetails().getVideoState()));
- setSessionModificationState(VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST);
+ setSessionModificationState(SessionModificationState.NO_REQUEST);
}
@Override
@@ -172,7 +186,7 @@ public class ImsVideoTech implements VideoTech {
call.getVideoCall()
.sendSessionModifyRequest(
new VideoProfile(unpausedVideoState | VideoProfile.STATE_TX_ENABLED));
- setSessionModificationState(VideoTech.SESSION_MODIFICATION_STATE_WAITING_FOR_RESPONSE);
+ setSessionModificationState(SessionModificationState.WAITING_FOR_RESPONSE);
}
@Override
diff --git a/java/com/android/incallui/videotech/rcs/RcsVideoShare.java b/java/com/android/incallui/videotech/rcs/RcsVideoShare.java
deleted file mode 100644
index 1e951408c..000000000
--- a/java/com/android/incallui/videotech/rcs/RcsVideoShare.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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.rcs;
-
-import android.support.annotation.NonNull;
-import android.telecom.Call;
-import com.android.dialer.common.Assert;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.enrichedcall.EnrichedCallCapabilities;
-import com.android.dialer.enrichedcall.EnrichedCallManager;
-import com.android.dialer.enrichedcall.EnrichedCallManager.CapabilitiesListener;
-import com.android.dialer.enrichedcall.Session;
-import com.android.dialer.enrichedcall.videoshare.VideoShareListener;
-import com.android.incallui.videotech.VideoTech;
-
-/** Allows the in-call UI to make video calls over RCS. */
-public class RcsVideoShare implements VideoTech, CapabilitiesListener, VideoShareListener {
- private final EnrichedCallManager enrichedCallManager;
- private final VideoTechListener listener;
- private final String callingNumber;
- private int previousCallState = Call.STATE_NEW;
- private long inviteSessionId = Session.NO_SESSION_ID;
- private long transmittingSessionId = Session.NO_SESSION_ID;
- private long receivingSessionId = Session.NO_SESSION_ID;
-
- private @SessionModificationState int sessionModificationState =
- VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST;
-
- public RcsVideoShare(
- @NonNull EnrichedCallManager enrichedCallManager,
- @NonNull VideoTechListener listener,
- @NonNull String callingNumber) {
- this.enrichedCallManager = Assert.isNotNull(enrichedCallManager);
- this.listener = Assert.isNotNull(listener);
- this.callingNumber = Assert.isNotNull(callingNumber);
-
- enrichedCallManager.registerCapabilitiesListener(this);
- enrichedCallManager.registerVideoShareListener(this);
- }
-
- @Override
- public boolean isAvailable() {
- EnrichedCallCapabilities capabilities = enrichedCallManager.getCapabilities(callingNumber);
- return capabilities != null && capabilities.supportsVideoShare();
- }
-
- @Override
- public boolean isTransmittingOrReceiving() {
- return transmittingSessionId != Session.NO_SESSION_ID
- || receivingSessionId != Session.NO_SESSION_ID;
- }
-
- @Override
- public boolean isSelfManagedCamera() {
- return true;
- }
-
- @Override
- public void onCallStateChanged(int newState) {
- if (newState == Call.STATE_DISCONNECTING) {
- enrichedCallManager.unregisterVideoShareListener(this);
- enrichedCallManager.unregisterCapabilitiesListener(this);
- }
-
- if (newState != previousCallState && newState == Call.STATE_ACTIVE) {
- // Per spec, request capabilities when the call becomes active
- enrichedCallManager.requestCapabilities(callingNumber);
- }
-
- previousCallState = newState;
- }
-
- @Override
- public int getSessionModificationState() {
- return sessionModificationState;
- }
-
- private void setSessionModificationState(@SessionModificationState int state) {
- if (state != sessionModificationState) {
- LogUtil.i(
- "RcsVideoShare.setSessionModificationState", "%d -> %d", sessionModificationState, state);
- sessionModificationState = state;
- listener.onSessionModificationStateChanged();
- }
- }
-
- @Override
- public void upgradeToVideo() {
- LogUtil.enterBlock("RcsVideoShare.upgradeToVideo");
- transmittingSessionId = enrichedCallManager.startVideoShareSession(callingNumber);
- if (transmittingSessionId != Session.NO_SESSION_ID) {
- setSessionModificationState(
- VideoTech.SESSION_MODIFICATION_STATE_WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE);
- }
- }
-
- @Override
- public void acceptVideoRequest() {
- LogUtil.enterBlock("RcsVideoShare.acceptVideoRequest");
- if (enrichedCallManager.acceptVideoShareSession(inviteSessionId)) {
- receivingSessionId = inviteSessionId;
- }
- inviteSessionId = Session.NO_SESSION_ID;
- setSessionModificationState(VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST);
- }
-
- @Override
- public void acceptVideoRequestAsAudio() {
- throw Assert.createUnsupportedOperationFailException();
- }
-
- @Override
- public void declineVideoRequest() {
- LogUtil.enterBlock("RcsVideoTech.declineUpgradeRequest");
- enrichedCallManager.endVideoShareSession(
- enrichedCallManager.getVideoShareInviteSessionId(callingNumber));
- inviteSessionId = Session.NO_SESSION_ID;
- setSessionModificationState(VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST);
- }
-
- @Override
- public boolean isTransmitting() {
- return transmittingSessionId != Session.NO_SESSION_ID;
- }
-
- @Override
- public void stopTransmission() {
- LogUtil.enterBlock("RcsVideoTech.stopTransmission");
- }
-
- @Override
- public void resumeTransmission() {
- LogUtil.enterBlock("RcsVideoTech.resumeTransmission");
- }
-
- @Override
- public void pause() {}
-
- @Override
- public void unpause() {}
-
- @Override
- public void setCamera(String cameraId) {}
-
- @Override
- public void setDeviceOrientation(int rotation) {}
-
- @Override
- public void onCapabilitiesUpdated() {
- listener.onVideoTechStateChanged();
- }
-
- @Override
- public void onVideoShareChanged() {
- long existingInviteSessionId = inviteSessionId;
-
- inviteSessionId = enrichedCallManager.getVideoShareInviteSessionId(callingNumber);
- if (inviteSessionId != Session.NO_SESSION_ID) {
- if (existingInviteSessionId == Session.NO_SESSION_ID) {
- // This is a new invite
- setSessionModificationState(
- VideoTech.SESSION_MODIFICATION_STATE_RECEIVED_UPGRADE_TO_VIDEO_REQUEST);
- listener.onVideoUpgradeRequestReceived();
- }
- } else {
- setSessionModificationState(VideoTech.SESSION_MODIFICATION_STATE_NO_REQUEST);
- }
-
- if (sessionIsClosed(transmittingSessionId)) {
- LogUtil.i("RcsVideoShare.onSessionClosed", "transmitting session closed");
- transmittingSessionId = Session.NO_SESSION_ID;
- }
-
- if (sessionIsClosed(receivingSessionId)) {
- LogUtil.i("RcsVideoShare.onSessionClosed", "receiving session closed");
- receivingSessionId = Session.NO_SESSION_ID;
- }
-
- listener.onVideoTechStateChanged();
- }
-
- private boolean sessionIsClosed(long sessionId) {
- return sessionId != Session.NO_SESSION_ID
- && enrichedCallManager.getVideoShareSession(sessionId) == null;
- }
-}
diff --git a/java/com/android/incallui/videotech/utils/SessionModificationState.java b/java/com/android/incallui/videotech/utils/SessionModificationState.java
new file mode 100644
index 000000000..24b0ca369
--- /dev/null
+++ b/java/com/android/incallui/videotech/utils/SessionModificationState.java
@@ -0,0 +1,46 @@
+/*
+ * 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.utils;
+
+import android.support.annotation.IntDef;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Defines different states of session modify requests, which are used to upgrade to video, or
+ * downgrade to audio.
+ */
+@Retention(RetentionPolicy.SOURCE)
+@IntDef({
+ SessionModificationState.NO_REQUEST,
+ SessionModificationState.WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE,
+ SessionModificationState.REQUEST_FAILED,
+ SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST,
+ SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT,
+ SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_FAILED,
+ SessionModificationState.REQUEST_REJECTED,
+ SessionModificationState.WAITING_FOR_RESPONSE
+})
+public @interface SessionModificationState {
+ int NO_REQUEST = 0;
+ int WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE = 1;
+ int REQUEST_FAILED = 2;
+ int RECEIVED_UPGRADE_TO_VIDEO_REQUEST = 3;
+ int UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT = 4;
+ int UPGRADE_TO_VIDEO_REQUEST_FAILED = 5;
+ int REQUEST_REJECTED = 6;
+ int WAITING_FOR_RESPONSE = 7;
+}
diff --git a/java/com/android/incallui/videotech/utils/VideoUtils.java b/java/com/android/incallui/videotech/utils/VideoUtils.java
new file mode 100644
index 000000000..527654030
--- /dev/null
+++ b/java/com/android/incallui/videotech/utils/VideoUtils.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 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.utils;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.support.annotation.NonNull;
+import android.support.v4.content.ContextCompat;
+import com.android.dialer.util.DialerUtils;
+
+public class VideoUtils {
+
+ private static final String PREFERENCE_CAMERA_ALLOWED_BY_USER = "camera_allowed_by_user";
+
+ public static boolean hasSentVideoUpgradeRequest(@SessionModificationState int state) {
+ return state == SessionModificationState.WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE
+ || state == SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_FAILED
+ || state == SessionModificationState.REQUEST_REJECTED
+ || state == SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT;
+ }
+
+ public static boolean hasReceivedVideoUpgradeRequest(@SessionModificationState int state) {
+ return state == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST;
+ }
+
+ public static boolean hasCameraPermissionAndAllowedByUser(@NonNull Context context) {
+ return isCameraAllowedByUser(context) && hasCameraPermission(context);
+ }
+
+ public static boolean hasCameraPermission(@NonNull Context context) {
+ return ContextCompat.checkSelfPermission(context, android.Manifest.permission.CAMERA)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ public static boolean isCameraAllowedByUser(@NonNull Context context) {
+ return DialerUtils.getDefaultSharedPreferenceForDeviceProtectedStorageContext(context)
+ .getBoolean(PREFERENCE_CAMERA_ALLOWED_BY_USER, false);
+ }
+
+ public static void setCameraAllowedByUser(@NonNull Context context) {
+ DialerUtils.getDefaultSharedPreferenceForDeviceProtectedStorageContext(context)
+ .edit()
+ .putBoolean(PREFERENCE_CAMERA_ALLOWED_BY_USER, true)
+ .apply();
+ }
+}