Merge "Revert "Merge commit '8bd143b' into merge""
diff --git a/InCallUI/res/layout/incall_screen.xml b/InCallUI/res/layout/incall_screen.xml
index d46778c..3922ea0 100644
--- a/InCallUI/res/layout/incall_screen.xml
+++ b/InCallUI/res/layout/incall_screen.xml
@@ -18,5 +18,6 @@
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:background="@android:color/black"
     android:id="@+id/main" >
 </FrameLayout>
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index 3211c47..80c8815 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -443,10 +443,16 @@
         }
     }
 
+    /**
+     * Sets the primary image for the contact photo.
+     *
+     * @param image The drawable to set.
+     * @param isVisible Whether the contact photo should be visible after being set.
+     */
     @Override
-    public void setPrimaryImage(Drawable image) {
+    public void setPrimaryImage(Drawable image, boolean isVisible) {
         if (image != null) {
-            setDrawableToImageView(mPhoto, image);
+            setDrawableToImageView(mPhoto, image, isVisible);
         }
     }
 
@@ -474,9 +480,21 @@
 
     }
 
+    /**
+     * Sets the primary caller information.
+     *
+     * @param number The caller phone number.
+     * @param name The caller name.
+     * @param nameIsNumber {@code true} if the name should be shown in place of the phone number.
+     * @param label The label.
+     * @param photo The contact photo drawable.
+     * @param isSipCall {@code true} if this is a SIP call.
+     * @param isContactPhotoShown {@code true} if the contact photo should be shown (it will be
+     *      updated even if it is not shown).
+     */
     @Override
     public void setPrimary(String number, String name, boolean nameIsNumber, String label,
-            Drawable photo, boolean isSipCall) {
+            Drawable photo, boolean isSipCall, boolean isContactPhotoShown) {
         Log.d(this, "Setting primary call");
         // set the name field.
         setPrimaryName(name, nameIsNumber);
@@ -496,7 +514,7 @@
 
         showInternetCallLabel(isSipCall);
 
-        setDrawableToImageView(mPhoto, photo);
+        setDrawableToImageView(mPhoto, photo, isContactPhotoShown);
     }
 
     @Override
@@ -552,6 +570,12 @@
         Log.v(this, "DisconnectCause " + disconnectCause.toString());
         Log.v(this, "gateway " + connectionLabel + gatewayNumber);
 
+        // Check for video state change and update the visibility of the contact photo.  The contact
+        // photo is hidden when the incoming video surface is shown.
+        // The contact photo visibility can also change in setPrimary().
+        boolean showContactPhoto = !VideoCallPresenter.showIncomingVideo(videoState, state);
+        mPhoto.setVisibility(showContactPhoto ? View.VISIBLE : View.GONE);
+
         if (TextUtils.equals(callStateLabel.getCallStateLabel(), mCallStateLabel.getText())) {
             // Nothing to do if the labels are the same
             if (state == Call.State.ACTIVE || state == Call.State.CONFERENCED) {
@@ -719,7 +743,7 @@
         }
     }
 
-    private void setDrawableToImageView(ImageView view, Drawable photo) {
+    private void setDrawableToImageView(ImageView view, Drawable photo, boolean isVisible) {
         if (photo == null) {
             photo = ContactInfoCache.getInstance(
                     view.getContext()).getDefaultContactPhotoDrawable();
@@ -733,13 +757,15 @@
         final Drawable current = view.getDrawable();
         if (current == null) {
             view.setImageDrawable(photo);
-            AnimUtils.fadeIn(mElapsedTime, AnimUtils.DEFAULT_DURATION);
+            if (isVisible) {
+                AnimUtils.fadeIn(mElapsedTime, AnimUtils.DEFAULT_DURATION);
+            }
         } else {
             // Cross fading is buggy and not noticable due to the multiple calls to this method
             // that switch drawables in the middle of the cross-fade animations. Just set the
             // photo directly instead.
             view.setImageDrawable(photo);
-            view.setVisibility(View.VISIBLE);
+            view.setVisibility(isVisible ? View.VISIBLE : View.GONE);
         }
     }
 
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index 5cbffa6..3dc22a5 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -487,7 +487,9 @@
 
         if (entry.photo != null) {
             if (mPrimary != null && callId.equals(mPrimary.getId())) {
-                getUi().setPrimaryImage(entry.photo);
+                boolean showContactPhoto = !VideoCallPresenter.showIncomingVideo(
+                        mPrimary.getVideoState(), mPrimary.getState());
+                getUi().setPrimaryImage(entry.photo, showContactPhoto);
             }
         }
     }
@@ -511,7 +513,6 @@
      * @param ignore A call to ignore if found.
      */
     private Call getCallToDisplay(CallList callList, Call ignore, boolean skipDisconnected) {
-
         // Active calls come second.  An active call always gets precedent.
         Call retval = callList.getActiveCall();
         if (retval != null && retval != ignore) {
@@ -555,10 +556,15 @@
 
         if (mPrimary == null) {
             // Clear the primary display info.
-            ui.setPrimary(null, null, false, null, null, false);
+            ui.setPrimary(null, null, false, null, null, false, false);
             return;
         }
 
+        // Hide the contact photo if we are in a video call and the incoming video surface is
+        // showing.
+        boolean showContactPhoto = !VideoCallPresenter
+                .showIncomingVideo(mPrimary.getVideoState(), mPrimary.getState());
+
         if (mPrimary.isConferenceCall()) {
             Log.d(TAG, "Update primary display info for conference call.");
 
@@ -568,7 +574,8 @@
                     false /* nameIsNumber */,
                     null /* label */,
                     getConferencePhoto(mPrimary),
-                    false /* isSipCall */);
+                    false /* isSipCall */,
+                    showContactPhoto);
         } else if (mPrimaryContactInfo != null) {
             Log.d(TAG, "Update primary display info for " + mPrimaryContactInfo);
 
@@ -581,10 +588,11 @@
                     nameIsNumber,
                     mPrimaryContactInfo.label,
                     mPrimaryContactInfo.photo,
-                    mPrimaryContactInfo.isSipCall);
+                    mPrimaryContactInfo.isSipCall,
+                    showContactPhoto);
         } else {
             // Clear the primary display info.
-            ui.setPrimary(null, null, false, null, null, false);
+            ui.setPrimary(null, null, false, null, null, false, false);
         }
 
         if (mEmergencyCallListener != null) {
@@ -826,7 +834,7 @@
         void setVisible(boolean on);
         void setCallCardVisible(boolean visible);
         void setPrimary(String number, String name, boolean nameIsNumber, String label,
-                Drawable photo, boolean isSipCall);
+                Drawable photo, boolean isSipCall, boolean isContactPhotoShown);
         void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
                 String providerLabel, boolean isConference, boolean isVideoCall);
         void setCallState(int state, int videoState, int sessionModificationState,
@@ -835,7 +843,7 @@
                 boolean isConference);
         void setPrimaryCallElapsedTime(boolean show, long duration);
         void setPrimaryName(String name, boolean nameIsNumber);
-        void setPrimaryImage(Drawable image);
+        void setPrimaryImage(Drawable image, boolean isVisible);
         void setPrimaryPhoneNumber(String phoneNumber);
         void setPrimaryLabel(String label);
         void setEndCallButtonEnabled(boolean enabled, boolean animate);
diff --git a/InCallUI/src/com/android/incallui/VideoCallPresenter.java b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
index 20f3912..644c8f9 100644
--- a/InCallUI/src/com/android/incallui/VideoCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
@@ -767,15 +767,16 @@
             Log.e(this, "showVideoUi, VideoCallUi is null returning");
             return;
         }
-        boolean isPaused = VideoProfile.VideoState.isPaused(videoState);
-        boolean isCallActive = callState == Call.State.ACTIVE;
-        if (VideoProfile.VideoState.isBidirectional(videoState)) {
-            ui.showVideoViews(true, !isPaused && isCallActive);
-        } else if (VideoProfile.VideoState.isTransmissionEnabled(videoState)) {
-            ui.showVideoViews(true, false);
-        } else if (VideoProfile.VideoState.isReceptionEnabled(videoState)) {
-            ui.showVideoViews(false, !isPaused && isCallActive);
-            loadProfilePhotoAsync();
+        boolean showIncomingVideo = showIncomingVideo(videoState, callState);
+        boolean showOutgoingVideo = showOutgoingVideo(videoState);
+        Log.v(this, "showVideoUi : showIncoming = " + showIncomingVideo + " showOutgoing = "
+                + showOutgoingVideo);
+        if (showIncomingVideo || showOutgoingVideo) {
+            ui.showVideoViews(showOutgoingVideo, showIncomingVideo);
+
+            if (VideoProfile.VideoState.isReceptionEnabled(videoState)) {
+                loadProfilePhotoAsync();
+            }
         } else {
             ui.hideVideoUi();
         }
@@ -785,6 +786,34 @@
     }
 
     /**
+     * Determines if the incoming video surface should be shown based on the current videoState and
+     * callState.  The video surface is shown when incoming video is not paused, the call is active,
+     * and video reception is enabled.
+     *
+     * @param videoState The current video state.
+     * @param callState The current call state.
+     * @return {@code true} if the incoming video surface should be shown, {@code false} otherwise.
+     */
+    public static boolean showIncomingVideo(int videoState, int callState) {
+        boolean isPaused = VideoProfile.VideoState.isPaused(videoState);
+        boolean isCallActive = callState == Call.State.ACTIVE;
+
+        return !isPaused && isCallActive && VideoProfile.VideoState.isReceptionEnabled(videoState);
+    }
+
+    /**
+     * Determines if the outgoing video surface should be shown based on the current videoState.
+     * The video surface is shown if video transmission is enabled.
+     *
+     * @param videoState The current video state.
+     * @return {@code true} if the the outgoing video surface should be shown, {@code false}
+     *      otherwise.
+     */
+    public static boolean showOutgoingVideo(int videoState) {
+        return VideoProfile.VideoState.isTransmissionEnabled(videoState);
+    }
+
+    /**
      * Handles peer video pause state changes.
      *
      * @param call The call which paused or un-pausedvideo transmission.