summaryrefslogtreecommitdiff
path: root/InCallUI
diff options
context:
space:
mode:
authorTyler Gunn <tgunn@google.com>2015-04-08 10:41:57 -0700
committerTyler Gunn <tgunn@google.com>2015-04-08 10:41:57 -0700
commit3570e970a2812b95ed82bf8e232d1e22f71f118e (patch)
tree3a0a1140be967b6e18b6edf4f943eea1897aacab /InCallUI
parentda9a49ceb7b50c9139218c06120ae64d48abf714 (diff)
Cleanup of Video Call pause functionality.
Whether the paused videoState is available is dependent on the carrier's implementation of the VT spec. The original VT implementation assumed that this was stored in a system property accessed via InCall; these CLs move this to a Call/Connection capability which will ultimately support multisim video capable devices. - Made some general cleanups in VideoPauseController (comments, some minor logic changes, renamed a few methods). - Removed access of system property to see if pause is supported and instead key in on the call capability. - Changed video call presenter to hide incoming video surface when a pause signal is received. Bug: 16680364 Bug: 19820114 Change-Id: I6d1a7789925c69e4022846f8d847b8bb1274c06b
Diffstat (limited to 'InCallUI')
-rw-r--r--InCallUI/src/com/android/incallui/VideoCallPresenter.java14
-rw-r--r--InCallUI/src/com/android/incallui/VideoPauseController.java239
2 files changed, 170 insertions, 83 deletions
diff --git a/InCallUI/src/com/android/incallui/VideoCallPresenter.java b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
index 486a38da3..3f8a827c3 100644
--- a/InCallUI/src/com/android/incallui/VideoCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
@@ -412,7 +412,9 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
+ " hasVideoStateChanged=" +
hasVideoStateChanged + " isVideoMode=" + isVideoMode());
- if (!hasVideoStateChanged) { return;}
+ if (!hasVideoStateChanged) {
+ return;
+ }
updateCameraSelection(call);
@@ -705,7 +707,9 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
}
/**
- * Show video Ui depends on video state.
+ * Show video Ui depends on video state. Where the video state includes
+ * {@link VideoProfile.VideoState#PAUSED}, hide the incoming video surface so that the peer's
+ * contact photo shows.
*/
private void showVideoUi(int videoState) {
VideoCallUi ui = getUi();
@@ -713,13 +717,13 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
Log.e(this, "showVideoUi, VideoCallUi is null returning");
return;
}
-
+ boolean isPaused = VideoProfile.VideoState.isPaused(videoState);
if (VideoProfile.VideoState.isBidirectional(videoState)) {
- ui.showVideoViews(true, true);
+ ui.showVideoViews(true, !isPaused);
} else if (VideoProfile.VideoState.isTransmissionEnabled(videoState)) {
ui.showVideoViews(true, false);
} else if (VideoProfile.VideoState.isReceptionEnabled(videoState)) {
- ui.showVideoViews(false, true);
+ ui.showVideoViews(false, !isPaused);
} else {
ui.hideVideoUi();
}
diff --git a/InCallUI/src/com/android/incallui/VideoPauseController.java b/InCallUI/src/com/android/incallui/VideoPauseController.java
index 727780e8f..4b8ad7562 100644
--- a/InCallUI/src/com/android/incallui/VideoPauseController.java
+++ b/InCallUI/src/com/android/incallui/VideoPauseController.java
@@ -38,12 +38,16 @@ import com.android.incallui.InCallVideoCallListenerNotifier.SessionModificationL
import com.android.internal.util.Preconditions;
/**
- * The class is responsible for generating video pause/resume request.
+ * This class is responsible for generating video pause/resume requests when the InCall UI is sent
+ * to the background and subsequently brought back to the foreground.
*/
class VideoPauseController implements InCallStateListener, IncomingCallListener,
SessionModificationListener {
- private static final String TAG = "VideoCallPauseController:";
+ private static final String TAG = "VideoPauseController:";
+ /**
+ * Keeps track of the current active/foreground call.
+ */
private class CallContext {
public CallContext(Call call) {
Preconditions.checkNotNull(call);
@@ -53,7 +57,6 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
public void update(Call call) {
mCall = Preconditions.checkNotNull(call);
mState = call.getState();
- mId = call.getId();
mVideoState = call.getVideoState();
}
@@ -61,17 +64,13 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
return mState;
}
- public String getId() {
- return mId;
- }
-
public int getVideoState() {
return mVideoState;
}
public String toString() {
- return String.format("CallContext {CallId=%s, State=%s, VideoState=",
- mId, mState, mVideoState);
+ return String.format("CallContext {CallId=%s, State=%s, VideoState=%d}",
+ mCall.getId(), mState, mVideoState);
}
public Call getCall() {
@@ -79,7 +78,6 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
}
private int mState = State.INVALID;
- private String mId;
private int mVideoState;
private Call mCall;
}
@@ -87,27 +85,21 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
private InCallPresenter mInCallPresenter;
private static VideoPauseController sVideoPauseController;
- private CallContext mPrimaryCallContext = null; // Context of primary call, if any.
- private boolean mIsInBackground = false; // True if UI is not visible, false otherwise.
- private int mVideoPauseMode = VIDEO_PAUSE_MODE_DISABLED;
+ /**
+ * The current call context, if applicable.
+ */
+ private CallContext mPrimaryCallContext = null;
/**
- * Stores current video pause mode.
- * 0 - Video Pause is disabled.
- * 1 - Video Pause is enabled.
+ * Tracks whether the application is in the background. {@code True} if the application is in
+ * the background, {@code false} otherwise.
*/
- private static final String PROPERTY_VIDEO_PAUSE_MODE = "persist.radio.videopause.mode";
- private static int VIDEO_PAUSE_MODE_DISABLED = 0;
- private static int VIDEO_PAUSE_MODE_ENABLED = 1;
-
- private VideoPauseController() {
- mVideoPauseMode = SystemProperties.getInt(PROPERTY_VIDEO_PAUSE_MODE,
- VIDEO_PAUSE_MODE_DISABLED);
- if (mVideoPauseMode != VIDEO_PAUSE_MODE_ENABLED) { // Validate the mode before using.
- mVideoPauseMode = VIDEO_PAUSE_MODE_DISABLED;
- }
- }
+ private boolean mIsInBackground = false;
+ /**
+ * Singleton accessor for the {@link VideoPauseController}.
+ * @return Singleton instance of the {@link VideoPauseController}.
+ */
/*package*/
static synchronized VideoPauseController getInstance() {
if (sVideoPauseController == null) {
@@ -116,23 +108,25 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
return sVideoPauseController;
}
+ /**
+ * Configures the {@link VideoPauseController} to listen to call events. Configured via the
+ * {@link com.android.incallui.InCallPresenter}.
+ *
+ * @param inCallPresenter The {@link com.android.incallui.InCallPresenter}.
+ */
public void setUp(InCallPresenter inCallPresenter) {
- if (!isVideoPausedEnabled()) {
- return;
- }
-
- log("setUp...");
+ log("setUp");
mInCallPresenter = Preconditions.checkNotNull(inCallPresenter);
mInCallPresenter.addListener(this);
mInCallPresenter.addIncomingCallListener(this);
InCallVideoCallListenerNotifier.getInstance().addSessionModificationListener(this);
}
+ /**
+ * Cleans up the {@link VideoPauseController} by removing all listeners and clearing its
+ * internal state. Called from {@link com.android.incallui.InCallPresenter}.
+ */
public void tearDown() {
- if (!isVideoPausedEnabled()) {
- return;
- }
-
log("tearDown...");
InCallVideoCallListenerNotifier.getInstance().removeSessionModificationListener(this);
mInCallPresenter.removeListener(this);
@@ -140,6 +134,9 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
clear();
}
+ /**
+ * Clears the internal state for the {@link VideoPauseController}.
+ */
private void clear() {
mInCallPresenter = null;
mPrimaryCallContext = null;
@@ -147,8 +144,11 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
}
/**
- * The function gets called when call state changes.
- * @param state Phone state.
+ * Handles changes in the {@link InCallState}. Triggers pause and resumption of video for the
+ * current foreground call.
+ *
+ * @param oldState The previous {@link InCallState}.
+ * @param newState The current {@link InCallState}.
* @param callList List of current call.
*/
@Override
@@ -179,7 +179,7 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
return;
}
- if (isOutgoing(mPrimaryCallContext) && canVideoPause && mIsInBackground) {
+ if (isDialing(mPrimaryCallContext) && canVideoPause && mIsInBackground) {
// Bring UI to foreground if outgoing request becomes active while UI is in
// background.
bringToForeground();
@@ -192,6 +192,15 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
updatePrimaryCallContext(call);
}
+ /**
+ * Handles a change to the primary call.
+ * <p>
+ * Reject incoming or hangup dialing call: Where the previous call was an incoming call or a
+ * call in dialing state, resume the new primary call.
+ * Call swap: Where the new primary call is incoming, pause video on the previous primary call.
+ *
+ * @param call The new primary call.
+ */
private void onPrimaryCallChanged(Call call) {
log("onPrimaryCallChanged: New call = " + call);
log("onPrimaryCallChanged: Old call = " + mPrimaryCallContext);
@@ -200,25 +209,26 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
Preconditions.checkState(!areSame(call, mPrimaryCallContext));
final boolean canVideoPause = CallUtils.canVideoPause(call);
- if (isWaitingCall(mPrimaryCallContext) && canVideoPause && !mIsInBackground) {
- // Send resume request for the active call, if user rejects incoming
- // call and UI is in foreground.
+ if ((isIncomingCall(mPrimaryCallContext) || isDialing(mPrimaryCallContext))
+ && canVideoPause && !mIsInBackground) {
+ // Send resume request for the active call, if user rejects incoming call or ends
+ // dialing call and UI is in the foreground.
sendRequest(call, true);
- } else if (isWaitingCall(call) && canVideoPause(mPrimaryCallContext)) {
+ } else if (isIncomingCall(call) && canVideoPause(mPrimaryCallContext)) {
// Send pause request if there is an active video call, and we just received a new
// incoming call.
sendRequest(mPrimaryCallContext.getCall(), false);
- } else if (isOutgoing(mPrimaryCallContext) && canVideoPause && !mIsInBackground) {
- // Send resume request for the active call, if user ends outgoing call
- // and UI is in foreground.
- sendRequest(call, true);
}
updatePrimaryCallContext(call);
}
/**
- * The function gets called when InCallUI receives a new incoming call.
+ * Handles new incoming calls by triggering a change in the primary call.
+ *
+ * @param oldState the old {@link InCallState}.
+ * @param newState the new {@link InCallState}.
+ * @param call the incoming call.
*/
@Override
public void onIncomingCall(InCallState oldState, InCallState newState, Call call) {
@@ -231,6 +241,11 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
onPrimaryCallChanged(call);
}
+ /**
+ * Caches a reference to the primary call and stores its previous state.
+ *
+ * @param call The new primary call.
+ */
private void updatePrimaryCallContext(Call call) {
if (call == null) {
mPrimaryCallContext = null;
@@ -246,43 +261,67 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
* @param showing true if UI is in the foreground, false otherwise.
*/
public void onUiShowing(boolean showing) {
- if (!isVideoPausedEnabled() || mInCallPresenter == null) {
+ // Only send pause/unpause requests if we are in the INCALL state.
+ if (mInCallPresenter == null || mInCallPresenter.getInCallState() != InCallState.INCALL) {
return;
}
- final boolean notify = mInCallPresenter.getInCallState() == InCallState.INCALL;
if (showing) {
- onResume(notify);
+ onResume();
} else {
- onPause(notify);
+ onPause();
}
}
+ /**
+ * Handles requests to upgrade to video.
+ *
+ * @param call The call the request was received for.
+ * @param videoState The video state that the request wants to upgrade to.
+ */
@Override
public void onUpgradeToVideoRequest(Call call, int videoState) {
+ // Not used.
}
+ /**
+ * Handles successful upgrades to video.
+ * @param call The call the request was successful for.
+ */
@Override
public void onUpgradeToVideoSuccess(Call call) {
+ // Not used.
}
+ /**
+ * Handles a failure to upgrade a call to video.
+ *
+ * @param status The failure status.
+ * @param call The call the request was successful for.
+ */
@Override
public void onUpgradeToVideoFail(int status, Call call) {
// TODO (ims-vt) Automatically bring in call ui to foreground.
}
+ /**
+ * Handles a downgrade of a call to audio-only.
+ *
+ * @param call The call which was downgraded to audio-only.
+ */
@Override
public void onDowngradeToAudio(Call call) {
}
/**
- * Called when UI becomes visible. This will send resume request for current video call, if any.
+ * Called when UI is brought to the foreground. Sends a session modification request to resume
+ * the outgoing video.
*/
- private void onResume(boolean notify) {
- log("onResume: notify=" + notify);
+ private void onResume() {
+ log("onResume");
mIsInBackground = false;
- if (canVideoPause(mPrimaryCallContext) && notify) {
+ if (canVideoPause(mPrimaryCallContext)) {
sendRequest(mPrimaryCallContext.getCall(), true);
} else {
log("onResume. Ignoring...");
@@ -290,13 +329,14 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
}
/**
- * Called when UI becomes invisible. This will send pause request for current video call, if any.
+ * Called when UI is sent to the background. Sends a session modification request to pause the
+ * outgoing video.
*/
- private void onPause(boolean notify) {
- log("onPause: notify=" + notify);
+ private void onPause() {
+ log("onPause");
mIsInBackground = true;
- if (canVideoPause(mPrimaryCallContext) && notify) {
+ if (canVideoPause(mPrimaryCallContext)) {
sendRequest(mPrimaryCallContext.getCall(), false);
} else {
log("onPause, Ignoring...");
@@ -314,75 +354,118 @@ class VideoPauseController implements InCallStateListener, IncomingCallListener,
/**
* Sends Pause/Resume request.
+ *
* @param call Call to be paused/resumed.
* @param resume If true resume request will be sent, otherwise pause request.
*/
private void sendRequest(Call call, boolean resume) {
+ // Check if this call supports pause/un-pause.
+ if (!call.can(android.telecom.Call.Details.CAPABILITY_CAN_PAUSE_VIDEO)) {
+ return;
+ }
+
if (resume) {
log("sending resume request, call=" + call);
- call.getVideoCall().sendSessionModifyRequest(CallUtils.makeVideoUnPauseProfile(call));
+ call.getVideoCall()
+ .sendSessionModifyRequest(CallUtils.makeVideoUnPauseProfile(call));
} else {
log("sending pause request, call=" + call);
call.getVideoCall().sendSessionModifyRequest(CallUtils.makeVideoPauseProfile(call));
}
}
- private boolean isVideoPausedEnabled() {
- return mVideoPauseMode != VIDEO_PAUSE_MODE_DISABLED;
- }
-
+ /**
+ * Determines if a given call is the same one stored in a {@link CallContext}.
+ *
+ * @param call The call.
+ * @param callContext The call context.
+ * @return {@code true} if the {@link Call} is the same as the one referenced in the
+ * {@link CallContext}.
+ */
private static boolean areSame(Call call, CallContext callContext) {
if (call == null && callContext == null) {
return true;
} else if (call == null || callContext == null) {
return false;
}
- return call.getId().equals(callContext.getId());
- }
-
- private static boolean areSame(CallContext callContext, Call call) {
- return areSame(call, callContext);
+ return call.equals(callContext.getCall());
}
+ /**
+ * Determines if a video call can be paused. Only a video call which is active can be paused.
+ *
+ * @param callContext The call context to check.
+ * @return {@code true} if the call is an active video call.
+ */
private static boolean canVideoPause(CallContext callContext) {
return isVideoCall(callContext) && callContext.getState() == Call.State.ACTIVE;
}
+ /**
+ * Determines if a call referenced by a {@link CallContext} is a video call.
+ *
+ * @param callContext The call context.
+ * @return {@code true} if the call is a video call, {@code false} otherwise.
+ */
private static boolean isVideoCall(CallContext callContext) {
return callContext != null && VideoProfile.VideoState.isVideo(callContext.getVideoState());
}
/**
- * Returns true if call is in incoming/waiting state, false otherwise.
+ * Determines if call is in incoming/waiting state.
+ *
+ * @param call The call context.
+ * @return {@code true} if the call is in incoming or waiting state, {@code false} otherwise.
*/
- private static boolean isWaitingCall(CallContext call) {
- return call != null && (call.getState() == Call.State.CALL_WAITING
- || call.getState() == Call.State.INCOMING);
+ private static boolean isIncomingCall(CallContext call) {
+ return call != null && isIncomingCall(call.getCall());
}
- private static boolean isWaitingCall(Call call) {
+ /**
+ * Determines if a call is in incoming/waiting state.
+ *
+ * @param call The call.
+ * @return {@code true} if the call is in incoming or waiting state, {@code false} otherwise.
+ */
+ private static boolean isIncomingCall(Call call) {
return call != null && (call.getState() == Call.State.CALL_WAITING
|| call.getState() == Call.State.INCOMING);
}
/**
- * Returns true if the call is outgoing, false otherwise
+ * Determines if a call is dialing.
+ *
+ * @param call The call context.
+ * @return {@code true} if the call is dialing, {@code false} otherwise.
*/
- private static boolean isOutgoing(CallContext call) {
+ private static boolean isDialing(CallContext call) {
return call != null && Call.State.isDialing(call.getState());
}
/**
- * Returns true if the call is on hold, false otherwise
+ * Determines if a call is holding.
+ *
+ * @param call The call context.
+ * @return {@code true} if the call is holding, {@code false} otherwise.
*/
private static boolean isHolding(CallContext call) {
return call != null && call.getState() == Call.State.ONHOLD;
}
+ /**
+ * Logs a debug message.
+ *
+ * @param msg The message.
+ */
private void log(String msg) {
Log.d(this, TAG + msg);
}
+ /**
+ * Logs an error message.
+ *
+ * @param msg The message.
+ */
private void loge(String msg) {
Log.e(this, TAG + msg);
}