summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Gunn <tgunn@google.com>2015-05-14 13:20:24 -0700
committerTyler Gunn <tgunn@google.com>2015-12-06 22:04:27 -0800
commita860052619d1c3d13a33629e97a8e05509fa0e1b (patch)
tree8541c2ab65ceefbcd334093a8be6775cea8c8429
parentcb7cae60b850cad577e03e4688f05e9819c3202e (diff)
Fix issue where secondary call info overlaps video preview.
Other issues: - Secondary caller info should not be shown when in fullscreen mode. Solution: - Added onSecondaryCallerInfoVisibilityChanged to InCallEventListener ( which is documented as a place for events between fragments). - In CallCard fragment, call notify listeners of this callback of the state change. - In VideoCallPresenter/Fragment, handle changes to the visibility of the secondary caller info box to shift the preview surface up or down. - Added hide/show animation for the secondary caller info when entering and exiting fullscreen mode. Bug: 20914754 Change-Id: I44ae0e94e214892776487bff4cc09be8c5640db1
-rw-r--r--InCallUI/src/com/android/incallui/CallCardFragment.java108
-rw-r--r--InCallUI/src/com/android/incallui/CallCardPresenter.java22
-rw-r--r--InCallUI/src/com/android/incallui/InCallPresenter.java16
-rw-r--r--InCallUI/src/com/android/incallui/VideoCallFragment.java29
-rw-r--r--InCallUI/src/com/android/incallui/VideoCallPresenter.java18
5 files changed, 178 insertions, 15 deletions
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index 3efdb7570..e7d4f4836 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -183,6 +183,11 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
private boolean mCallStateLabelResetPending = false;
private Handler mHandler;
+ /**
+ * Determines if secondary call info is populated in the secondary call info UI.
+ */
+ private boolean mHasSecondaryCallInfo = false;
+
@Override
public CallCardPresenter.CallCardUi getUi() {
return this;
@@ -585,15 +590,16 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
@Override
public void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
- String providerLabel, boolean isConference, boolean isVideoCall) {
-
- if (show != mSecondaryCallInfo.isShown()) {
- updateFabPositionForSecondaryCallInfo();
- }
+ String providerLabel, boolean isConference, boolean isVideoCall, boolean isFullscreen) {
if (show) {
+ mHasSecondaryCallInfo = true;
boolean hasProvider = !TextUtils.isEmpty(providerLabel);
- showAndInitializeSecondaryCallInfo(hasProvider);
+ initializeSecondaryCallInfo(hasProvider);
+
+ // Do not show the secondary caller info in fullscreen mode, but ensure it is populated
+ // in case fullscreen mode is exited in the future.
+ setSecondaryInfoVisible(!isFullscreen);
mSecondaryCallConferenceCallIcon.setVisibility(isConference ? View.VISIBLE : View.GONE);
mSecondaryCallVideoCallIcon.setVisibility(isVideoCall ? View.VISIBLE : View.GONE);
@@ -611,10 +617,94 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
}
mSecondaryCallName.setTextDirection(nameDirection);
} else {
- mSecondaryCallInfo.setVisibility(View.GONE);
+ mHasSecondaryCallInfo = false;
+ setSecondaryInfoVisible(false);
}
}
+ /**
+ * Sets the visibility of the secondary caller info box. Note, if the {@code visible} parameter
+ * is passed in {@code true}, and there is no secondary caller info populated (as determined by
+ * {@code mHasSecondaryCallInfo}, the secondary caller info box will not be shown.
+ *
+ * @param visible {@code true} if the secondary caller info should be shown, {@code false}
+ * otherwise.
+ */
+ @Override
+ public void setSecondaryInfoVisible(final boolean visible) {
+ boolean wasVisible = mSecondaryCallInfo.isShown();
+ final boolean isVisible = visible && mHasSecondaryCallInfo;
+ Log.v(this, "setSecondaryInfoVisible: wasVisible = " + wasVisible + " isVisible = "
+ + isVisible);
+
+ // If visibility didn't change, nothing to do.
+ if (wasVisible == isVisible) {
+ return;
+ }
+
+ // If we are showing the secondary info, we need to show it before animating so that its
+ // height will be determined on layout.
+ if (isVisible) {
+ mSecondaryCallInfo.setVisibility(View.VISIBLE);
+ }
+
+ // We need to translate the secondary caller info, but we need to know its position after
+ // the layout has occurred so use a {@code ViewTreeObserver}.
+ final ViewTreeObserver observer = getView().getViewTreeObserver();
+ observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ // We don't want to continue getting called.
+ if (observer.isAlive()) {
+ observer.removeOnPreDrawListener(this);
+ }
+
+ updateFabPositionForSecondaryCallInfo();
+
+ // Get the height of the secondary call info now, and then re-hide the view prior
+ // to doing the actual animation.
+ int secondaryHeight = mSecondaryCallInfo.getHeight();
+ if (isVisible) {
+ mSecondaryCallInfo.setVisibility(View.GONE);
+ }
+ Log.v(this, "setSecondaryInfoVisible: secondaryHeight = " + secondaryHeight);
+
+ // Set the position of the secondary call info card to its starting location.
+ mSecondaryCallInfo.setTranslationY(visible ? secondaryHeight : 0);
+
+ // Animate the secondary card info slide up/down as it appears and disappears.
+ ViewPropertyAnimator secondaryInfoAnimator = mSecondaryCallInfo.animate()
+ .setInterpolator(AnimUtils.EASE_OUT_EASE_IN)
+ .setDuration(mVideoAnimationDuration)
+ .translationY(isVisible ? 0 : secondaryHeight)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!isVisible) {
+ mSecondaryCallInfo.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (isVisible) {
+ mSecondaryCallInfo.setVisibility(View.VISIBLE);
+ }
+ }
+ });
+ secondaryInfoAnimator.start();
+
+ // Notify listeners of a change in the visibility of the secondary info. This is
+ // important when in a video call so that the video call presenter can shift the
+ // video preview up or down to accommodate the secondary caller info.
+ InCallPresenter.getInstance().notifySecondaryCallerInfoVisibilityChanged(visible,
+ secondaryHeight);
+
+ return true;
+ }
+ });
+ }
+
@Override
public void setCallState(
int state,
@@ -1006,9 +1096,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
return new CallStateLabel(callStateLabel, isAutoDismissing);
}
- private void showAndInitializeSecondaryCallInfo(boolean hasProvider) {
- mSecondaryCallInfo.setVisibility(View.VISIBLE);
-
+ private void initializeSecondaryCallInfo(boolean hasProvider) {
// mSecondaryCallName is initialized here (vs. onViewCreated) because it is inaccessible
// until mSecondaryCallInfo is inflated in the call above.
if (mSecondaryCallName == null) {
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index ba5823d5a..170e78501 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -83,6 +83,7 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
private boolean mSpinnerShowing = false;
private boolean mHasShownToast = false;
private InCallContactInteractions mInCallContactInteractions;
+ private boolean mIsFullscreen = false;
public static class ContactLookupCallback implements ContactInfoCacheCallback {
private final WeakReference<CallCardPresenter> mCallCardPresenter;
@@ -775,7 +776,7 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
if (mSecondary == null) {
// Clear the secondary display info.
ui.setSecondary(false, null, false, null, null, false /* isConference */,
- false /* isVideoCall */);
+ false /* isVideoCall */, mIsFullscreen);
return;
}
@@ -787,7 +788,8 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
null /* label */,
getCallProviderLabel(mSecondary),
true /* isConference */,
- mSecondary.isVideoCall(mContext));
+ mSecondary.isVideoCall(mContext),
+ mIsFullscreen);
} else if (mSecondaryContactInfo != null) {
Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo);
String name = getNameForCall(mSecondaryContactInfo);
@@ -799,11 +801,12 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
mSecondaryContactInfo.label,
getCallProviderLabel(mSecondary),
false /* isConference */,
- mSecondary.isVideoCall(mContext));
+ mSecondary.isVideoCall(mContext),
+ mIsFullscreen);
} else {
// Clear the secondary display info.
ui.setSecondary(false, null, false, null, null, false /* isConference */,
- false /* isVideoCall */);
+ false /* isVideoCall */, mIsFullscreen);
}
}
@@ -955,11 +958,18 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
*/
@Override
public void onFullscreenModeChanged(boolean isFullscreenMode) {
+ mIsFullscreen = isFullscreenMode;
final CallCardUi ui = getUi();
if (ui == null) {
return;
}
ui.setCallCardVisible(!isFullscreenMode);
+ ui.setSecondaryInfoVisible(!isFullscreenMode);
+ }
+
+ @Override
+ public void onSecondaryCallerInfoVisibilityChanged(boolean isVisible, int height) {
+ // No-op - the Call Card is the origin of this event.
}
private boolean isPrimaryCallActive() {
@@ -1061,7 +1071,9 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
void setPrimary(String number, String name, boolean nameIsNumber, String label,
Drawable photo, boolean isSipCall, boolean isContactPhotoShown);
void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
- String providerLabel, boolean isConference, boolean isVideoCall);
+ String providerLabel, boolean isConference, boolean isVideoCall,
+ boolean isFullscreen);
+ void setSecondaryInfoVisible(boolean visible);
void setCallState(int state, int videoState, int sessionModificationState,
DisconnectCause disconnectCause, String connectionLabel,
Drawable connectionIcon, String gatewayNumber, boolean isWifi,
diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java
index 33e4e5ace..d4d95bc54 100644
--- a/InCallUI/src/com/android/incallui/InCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/InCallPresenter.java
@@ -1175,6 +1175,21 @@ public class InCallPresenter implements CallList.Listener,
}
/**
+ * Called by the {@link CallCardPresenter} to inform of a change in visibility of the secondary
+ * caller info bar.
+ *
+ * @param isVisible {@code true} if the secondary caller info is visible, {@code false}
+ * otherwise.
+ * @param height the height of the secondary caller info bar.
+ */
+ public void notifySecondaryCallerInfoVisibilityChanged(boolean isVisible, int height) {
+ for (InCallEventListener listener : mInCallEventListeners) {
+ listener.onSecondaryCallerInfoVisibilityChanged(isVisible, height);
+ }
+ }
+
+
+ /**
* For some disconnected causes, we show a dialog. This calls into the activity to show
* the dialog if appropriate for the call.
*/
@@ -1796,6 +1811,7 @@ public class InCallPresenter implements CallList.Listener,
*/
public interface InCallEventListener {
public void onFullscreenModeChanged(boolean isFullscreenMode);
+ public void onSecondaryCallerInfoVisibilityChanged(boolean isVisible, int height);
}
public interface InCallUiListener {
diff --git a/InCallUI/src/com/android/incallui/VideoCallFragment.java b/InCallUI/src/com/android/incallui/VideoCallFragment.java
index ce14e48f9..eca9ab883 100644
--- a/InCallUI/src/com/android/incallui/VideoCallFragment.java
+++ b/InCallUI/src/com/android/incallui/VideoCallFragment.java
@@ -31,6 +31,7 @@ import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import com.android.phone.common.animation.AnimUtils;
import com.google.common.base.Objects;
/**
@@ -105,6 +106,8 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
*/
private boolean mIsLandscape;
+ private int mAnimationDuration;
+
/**
* Inner-class representing a {@link TextureView} and its associated {@link SurfaceTexture} and
* {@link Surface}. Used to manage the lifecycle of these objects across device orientation
@@ -419,6 +422,8 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
+ mAnimationDuration = getResources().getInteger(R.integer.video_animation_duration);
}
/**
@@ -581,6 +586,30 @@ public class VideoCallFragment extends BaseFragment<VideoCallPresenter,
return mPreviewPhoto;
}
+ /**
+ * Adjusts the location of the video preview view by the specified offset.
+ *
+ * @param shiftUp {@code true} if the preview should shift up, {@code false} if it should shift
+ * down.
+ * @param offset The offset.
+ */
+ @Override
+ public void adjustPreviewLocation(boolean shiftUp, int offset) {
+ if (sPreviewSurface == null || mPreviewVideoContainer == null) {
+ return;
+ }
+
+ // Set the position of the secondary call info card to its starting location.
+ mPreviewVideoContainer.setTranslationY(shiftUp ? 0 : -offset);
+
+ // Animate the secondary card info slide up/down as it appears and disappears.
+ mPreviewVideoContainer.animate()
+ .setInterpolator(AnimUtils.EASE_OUT_EASE_IN)
+ .setDuration(mAnimationDuration)
+ .translationY(shiftUp ? -offset : 0)
+ .start();
+ }
+
private void onPresenterChanged(VideoCallPresenter presenter) {
Log.d(this, "onPresenterChanged: Presenter=" + presenter);
if (sDisplaySurface != null) {
diff --git a/InCallUI/src/com/android/incallui/VideoCallPresenter.java b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
index 84d9c9781..a8812a672 100644
--- a/InCallUI/src/com/android/incallui/VideoCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
@@ -239,6 +239,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
InCallPresenter.getInstance().addOrientationListener(this);
// To get updates of video call details changes
InCallPresenter.getInstance().addDetailsListener(this);
+ InCallPresenter.getInstance().addInCallEventListener(this);
// Register for surface and video events from {@link InCallVideoCallListener}s.
InCallVideoCallCallbackNotifier.getInstance().addSurfaceChangeListener(this);
@@ -266,6 +267,7 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
InCallPresenter.getInstance().removeDetailsListener(this);
InCallPresenter.getInstance().removeIncomingCallListener(this);
InCallPresenter.getInstance().removeOrientationListener(this);
+ InCallPresenter.getInstance().removeInCallEventListener(this);
InCallVideoCallCallbackNotifier.getInstance().removeSurfaceChangeListener(this);
InCallVideoCallCallbackNotifier.getInstance().removeVideoEventListener(this);
@@ -469,6 +471,21 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
cancelAutoFullScreen();
}
+ /**
+ * Handles changes to the visibility of the secondary caller info bar.
+ *
+ * @param isVisible {@code true} if the secondary caller info is showing, {@code false}
+ * otherwise.
+ * @param height the height of the secondary caller info bar.
+ */
+ @Override
+ public void onSecondaryCallerInfoVisibilityChanged(boolean isVisible, int height) {
+ Log.d(this,
+ "onSecondaryCallerInfoVisibilityChanged : isVisible = " + isVisible + " height = "
+ + height);
+ getUi().adjustPreviewLocation(isVisible /* shiftUp */, height);
+ }
+
private void checkForVideoStateChange(Call call) {
final boolean isVideoCall = CallUtils.isVideoCall(call);
final boolean hasVideoStateChanged = mCurrentVideoState != call.getVideoState();
@@ -1354,5 +1371,6 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
Point getPreviewSize();
void cleanupSurfaces();
ImageView getPreviewPhotoView();
+ void adjustPreviewLocation(boolean shiftUp, int offset);
}
}