Some improvements to the answer fragment layouts.

Test: unit
PiperOrigin-RevId: 198080186
Change-Id: I0ecc1f918b2c62e42b287e4fc9ea38fafaf1e6c9
diff --git a/java/com/android/incallui/answer/impl/AnswerFragment.java b/java/com/android/incallui/answer/impl/AnswerFragment.java
index d44a5da..18e0e98 100644
--- a/java/com/android/incallui/answer/impl/AnswerFragment.java
+++ b/java/com/android/incallui/answer/impl/AnswerFragment.java
@@ -49,6 +49,8 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.FragmentUtils;
 import com.android.dialer.common.LogUtil;
@@ -82,6 +84,8 @@
 import com.android.incallui.maps.MapsComponent;
 import com.android.incallui.sessiondata.AvatarPresenter;
 import com.android.incallui.sessiondata.MultimediaFragment;
+import com.android.incallui.speakeasy.Annotations.SpeakEasyIcon;
+import com.android.incallui.speakeasy.Annotations.SpeakEasyText;
 import com.android.incallui.speakeasy.SpeakEasyComponent;
 import com.android.incallui.util.AccessibilityUtil;
 import com.android.incallui.video.protocol.VideoCallScreen;
@@ -144,6 +148,9 @@
   private View importanceBadge;
   private SwipeButtonView secondaryButton;
   private SwipeButtonView answerAndReleaseButton;
+  private LinearLayout chipLayout;
+  private ImageView chipIcon;
+  private TextView chipText;
   private AffordanceHolderLayout affordanceHolderLayout;
   // Use these flags to prevent user from clicking accept/reject buttons multiple times.
   // We use separate flags because in some rare cases accepting a call may fail to join the room,
@@ -195,17 +202,6 @@
       public void performAction(AnswerFragment fragment) {
         fragment.performAnswerAndRelease();
       }
-    },
-
-    SPEAKEASY(
-        R.drawable.quantum_ic_rtt_vd_theme_24,
-        R.string.speakeasy_secondary_button_hint,
-        R.string.speakeasy_secondary_button_hint,
-        R.string.speakeasy_secondary_button_hint) {
-      @Override
-      public void performAction(AnswerFragment fragment) {
-        fragment.performSpeakEasy();
-      }
     };
 
     @DrawableRes public int icon;
@@ -232,8 +228,7 @@
     }
   }
 
-  private void performSpeakEasy() {
-    restoreAnswerAndReleaseButtonAnimation();
+  private void performSpeakEasy(View unused) {
     answerScreenDelegate.onSpeakEasyCall();
     buttonAcceptClicked = true;
   }
@@ -457,16 +452,6 @@
     if (allowAnswerAndRelease()) {
       answerAndReleaseButton.setVisibility(View.VISIBLE);
       answerScreenDelegate.onAnswerAndReleaseButtonEnabled();
-    } else if (allowSpeakEasy()) {
-      Optional<Integer> alternativeIcon = SpeakEasyComponent.get(getContext()).speakEasyIcon();
-      if (alternativeIcon.isPresent()) {
-        // TODO(erfanian): Replace enum hack when we have a dedicated button.
-        SecondaryBehavior.SPEAKEASY.icon = alternativeIcon.get();
-      }
-      answerAndReleaseBehavior = SecondaryBehavior.SPEAKEASY;
-      answerAndReleaseBehavior.applyToView(answerAndReleaseButton);
-      answerAndReleaseButton.setVisibility(View.VISIBLE);
-      answerScreenDelegate.onAnswerAndReleaseButtonEnabled();
     } else {
       answerAndReleaseButton.setVisibility(View.INVISIBLE);
       answerScreenDelegate.onAnswerAndReleaseButtonDisabled();
@@ -480,6 +465,27 @@
         });
   }
 
+  /** Initialize chip buttons */
+  private void initChips() {
+    if (!allowSpeakEasy()) {
+      chipLayout.setVisibility(View.GONE);
+      return;
+    }
+    chipLayout.setVisibility(View.VISIBLE);
+    chipLayout.setOnClickListener(this::performSpeakEasy);
+
+    @SpeakEasyIcon
+    Optional<Integer> alternativeIcon = SpeakEasyComponent.get(getContext()).speakEasyIcon();
+    @SpeakEasyText
+    Optional<Integer> alternativeText = SpeakEasyComponent.get(getContext()).speakEasyText();
+    if (alternativeIcon.isPresent() && alternativeText.isPresent()) {
+      chipIcon.setImageDrawable(getContext().getDrawable(alternativeIcon.get()));
+      chipText.setText(alternativeText.get());
+      // The button needs to override normal swipe up/down behavior.
+      chipLayout.bringToFront();
+    }
+  }
+
   @Override
   public boolean allowAnswerAndRelease() {
     return getArguments().getBoolean(ARG_ALLOW_ANSWER_AND_RELEASE);
@@ -715,6 +721,9 @@
     View view = inflater.inflate(R.layout.fragment_incoming_call, container, false);
     secondaryButton = (SwipeButtonView) view.findViewById(R.id.incoming_secondary_button);
     answerAndReleaseButton = (SwipeButtonView) view.findViewById(R.id.incoming_secondary_button2);
+    chipLayout = view.findViewById(R.id.incall_data_container_chip_container);
+    chipIcon = view.findViewById(R.id.incall_data_container_chip_icon);
+    chipText = view.findViewById(R.id.incall_data_container_chip_text);
 
     affordanceHolderLayout = (AffordanceHolderLayout) view.findViewById(R.id.incoming_container);
     affordanceHolderLayout.setAffordanceCallback(affordanceCallback);
@@ -755,6 +764,7 @@
             .newAnswerScreenDelegate(this);
 
     initSecondaryButton();
+    initChips();
 
     int flags = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
     if (!isInMultiWindowMode
diff --git a/java/com/android/incallui/answer/impl/res/drawable/shape_chip_drawable.xml b/java/com/android/incallui/answer/impl/res/drawable/shape_chip_drawable.xml
new file mode 100644
index 0000000..3740f3d
--- /dev/null
+++ b/java/com/android/incallui/answer/impl/res/drawable/shape_chip_drawable.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2018 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
+  -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="#DADCE0">
+  <item android:id="@android:id/mask">
+    <shape xmlns:android="http://schemas.android.com/apk/res/android">
+      <solid android:color="@color/dialer_background_light"/>
+      <padding
+          android:bottom="9dp"
+          android:left="8dp"
+          android:right="8dp"
+          android:top="9dp"/>
+      <corners android:radius="40dp"/>
+    </shape>
+  </item>
+  <item>
+    <shape xmlns:android="http://schemas.android.com/apk/res/android">
+      <solid android:color="@color/dialer_background_floating_light"/>
+      <stroke
+          android:width="1dp"
+          android:color="#DADCE0"/>
+      <padding
+          android:bottom="9dp"
+          android:left="8dp"
+          android:right="8dp"
+          android:top="9dp"/>
+      <corners android:radius="40dp"/>
+    </shape>
+  </item>
+</ripple>
\ No newline at end of file
diff --git a/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml b/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml
index a2319b9..944d290 100644
--- a/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml
+++ b/java/com/android/incallui/answer/impl/res/layout/fragment_incoming_call.xml
@@ -53,6 +53,13 @@
       android:layout_height="match_parent"
       android:fitsSystemWindows="true">
 
+    <FrameLayout
+        android:id="@+id/answer_method_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:clipChildren="false"
+        android:clipToPadding="false"/>
+
     <TextView
         android:id="@+id/videocall_video_off"
         android:layout_width="wrap_content"
@@ -74,8 +81,8 @@
         android:layout_marginTop="24dp"
         android:clipChildren="false"
         android:clipToPadding="false"
-        android:gravity="top|center_horizontal"
         android:focusable="true"
+        android:gravity="top|center_horizontal"
         android:orientation="vertical">
 
       <include
@@ -114,19 +121,19 @@
       <!-- TODO(a bug): textColorPrimary or textColorPrimaryInverse? -->
       <TextView
           android:id="@+id/incall_important_call_badge"
+          android:textStyle="bold"
           android:layout_width="wrap_content"
           android:layout_height="48dp"
           android:layout_marginTop="4dp"
           android:layout_marginBottom="@dimen/answer_importance_margin_bottom"
-          android:gravity="center"
+          android:background="@drawable/urgent_call_background"
           android:elevation="@dimen/answer_data_elevation"
+          android:gravity="center"
           android:maxLines="1"
           android:text="@string/call_incoming_important"
           android:textAllCaps="true"
-          android:textSize="14sp"
-          android:textStyle="bold"
           android:textColor="?android:attr/colorBackground"
-          android:background="@drawable/urgent_call_background"/>
+          android:textSize="14sp"/>
 
       <FrameLayout
           android:id="@+id/incall_location_holder"
@@ -144,7 +151,34 @@
           android:layout_height="0dp"
           android:layout_weight="1"
           android:clipChildren="false"
-          android:clipToPadding="false"/>
+          android:clipToPadding="false">
+        <LinearLayout
+            android:id="@+id/incall_data_container_chip_container"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal|bottom"
+            android:background="@drawable/shape_chip_drawable"
+            android:clickable="true"
+            android:orientation="horizontal"
+            android:visibility="gone">
+          <ImageView
+              android:id="@+id/incall_data_container_chip_icon"
+              android:layout_width="20dp"
+              android:layout_height="20dp"
+              android:src="@drawable/quantum_ic_rtt_vd_theme_24"
+              android:tint="#1A73E8"/>
+          <TextView
+              android:id="@+id/incall_data_container_chip_text"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:layout_marginStart="8dp"
+              android:layout_marginEnd="8dp"
+              android:fontFamily="sans-serif-medium"
+              android:text="@string/speakeasy_secondary_button_hint"
+              android:textColor="@color/dialer_primary_text_color"
+              android:textSize="14sp"/>
+        </LinearLayout>
+      </FrameLayout>
 
       <!-- Space holder for answer method. This is used to get better scaling to make room for
       incall_data_container on different screen size. -->
@@ -153,14 +187,6 @@
           android:layout_height="220dp"/>
 
     </LinearLayout>
-
-    <FrameLayout
-        android:id="@+id/answer_method_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:clipChildren="false"
-        android:clipToPadding="false"/>
-
   </FrameLayout>
 
   <com.android.incallui.answer.impl.affordance.SwipeButtonView
diff --git a/java/com/android/incallui/speakeasy/Annotations.java b/java/com/android/incallui/speakeasy/Annotations.java
new file mode 100644
index 0000000..f369ce4
--- /dev/null
+++ b/java/com/android/incallui/speakeasy/Annotations.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 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.speakeasy;
+
+import javax.inject.Qualifier;
+
+/** Annotations for Speakeasy providers. */
+public final class Annotations {
+
+  /** A Speakeasy icon */
+  @Qualifier
+  public @interface SpeakEasyIcon {}
+
+  /** Speakeasy text */
+  @Qualifier
+  public @interface SpeakEasyText {}
+
+  /** A Speakeasy settings fragment */
+  @Qualifier
+  public @interface SpeakEasySettingsFragment {}
+}
diff --git a/java/com/android/incallui/speakeasy/SpeakEasyComponent.java b/java/com/android/incallui/speakeasy/SpeakEasyComponent.java
index 6dae441..6257cc0 100644
--- a/java/com/android/incallui/speakeasy/SpeakEasyComponent.java
+++ b/java/com/android/incallui/speakeasy/SpeakEasyComponent.java
@@ -19,6 +19,9 @@
 import android.content.Context;
 import android.support.v4.app.Fragment;
 import com.android.dialer.inject.HasRootComponent;
+import com.android.incallui.speakeasy.Annotations.SpeakEasyIcon;
+import com.android.incallui.speakeasy.Annotations.SpeakEasySettingsFragment;
+import com.android.incallui.speakeasy.Annotations.SpeakEasyText;
 import com.google.common.base.Optional;
 import dagger.Subcomponent;
 
@@ -28,9 +31,11 @@
 
   public abstract SpeakEasyCallManager speakEasyCallManager();
 
-  public abstract Optional<Fragment> speakEasySettingsFragment();
+  public abstract @SpeakEasySettingsFragment Optional<Fragment> speakEasySettingsFragment();
 
-  public abstract Optional<Integer> speakEasyIcon();
+  public abstract @SpeakEasyIcon Optional<Integer> speakEasyIcon();
+
+  public abstract @SpeakEasyText Optional<Integer> speakEasyText();
 
   public static SpeakEasyComponent get(Context context) {
     return ((SpeakEasyComponent.HasComponent)
diff --git a/java/com/android/incallui/speakeasy/StubSpeakEasyModule.java b/java/com/android/incallui/speakeasy/StubSpeakEasyModule.java
index 67b564c..9f23ddd 100644
--- a/java/com/android/incallui/speakeasy/StubSpeakEasyModule.java
+++ b/java/com/android/incallui/speakeasy/StubSpeakEasyModule.java
@@ -19,6 +19,9 @@
 import android.support.v4.app.Fragment;
 import com.android.dialer.inject.DialerVariant;
 import com.android.dialer.inject.InstallIn;
+import com.android.incallui.speakeasy.Annotations.SpeakEasyIcon;
+import com.android.incallui.speakeasy.Annotations.SpeakEasySettingsFragment;
+import com.android.incallui.speakeasy.Annotations.SpeakEasyText;
 import com.google.common.base.Optional;
 import dagger.Binds;
 import dagger.Module;
@@ -33,12 +36,17 @@
   abstract SpeakEasyCallManager bindsSpeakEasy(SpeakEasyCallManagerStub stub);
 
   @Provides
-  static Optional<Fragment> provideSpeakEasySettingsFragment() {
+  static @SpeakEasySettingsFragment Optional<Fragment> provideSpeakEasySettingsFragment() {
     return Optional.absent();
   }
 
   @Provides
-  static Optional<Integer> provideSpeakEasyIcon() {
+  static @SpeakEasyIcon Optional<Integer> provideSpeakEasyIcon() {
+    return Optional.absent();
+  }
+
+  @Provides
+  static @SpeakEasyText Optional<Integer> provideSpeakEasyText() {
     return Optional.absent();
   }
 }