summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Gunn <tgunn@google.com>2015-04-09 02:06:22 +0000
committerAndroid Partner Code Review <android-gerrit-partner@google.com>2015-04-09 02:06:26 +0000
commitc846fef0f0183115dff49ee753ee1990c532c03e (patch)
tree3e67c1f0fbed8d70ebdb0eb669f357f3e07814b2
parent63310252e8ab53ac9dd705ac86a91d2dde8d7fbf (diff)
parent3570e970a2812b95ed82bf8e232d1e22f71f118e (diff)
Merge "Cleanup of Video Call pause functionality." into m-wireless-dev
-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);
}