Merge changes Ib013b10f,I07563fd2

* changes:
  Use simulator to add in-call UI integration tests
  Adjusted layout dimensions in new search UI.
diff --git a/java/com/android/contacts/common/res/layout/search_bar_expanded.xml b/java/com/android/contacts/common/res/layout/search_bar_expanded.xml
index 7192eb0..f0179ad 100644
--- a/java/com/android/contacts/common/res/layout/search_bar_expanded.xml
+++ b/java/com/android/contacts/common/res/layout/search_bar_expanded.xml
@@ -13,20 +13,19 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout
+<RelativeLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/search_box_expanded"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
-  android:gravity="center_vertical"
-  android:orientation="horizontal"
   android:visibility="gone">
 
   <ImageButton
     android:id="@+id/search_back_button"
     android:layout_width="@dimen/search_box_icon_size"
     android:layout_height="@dimen/search_box_icon_size"
-    android:layout_margin="@dimen/search_box_navigation_icon_margin"
+    android:layout_marginStart="16dp"
+    android:layout_centerVertical="true"
     android:background="?attr/selectableItemBackgroundBorderless"
     android:contentDescription="@string/action_menu_back_from_search"
     android:src="@drawable/quantum_ic_arrow_back_vd_theme_24"
@@ -34,15 +33,17 @@
 
   <EditText
     android:id="@+id/search_view"
-    android:layout_width="0dp"
-    android:layout_height="@dimen/search_box_icon_size"
-    android:layout_weight="1"
-    android:layout_marginLeft="@dimen/search_box_text_left_margin"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_toEndOf="@+id/search_back_button"
+    android:layout_toStartOf="@+id/search_close_button"
+    android:layout_centerVertical="true"
+    android:layout_marginStart="8dp"
     android:background="@null"
     android:fontFamily="@string/search_font_family"
     android:imeOptions="flagNoExtractUi"
     android:inputType="textFilter"
-    android:singleLine="true"
+    android:maxLines="1"
     android:textColor="@color/searchbox_text_color"
     android:textColorHint="@color/searchbox_hint_text_color"
     android:textCursorDrawable="@drawable/searchedittext_custom_cursor"
@@ -52,11 +53,12 @@
     android:id="@+id/search_close_button"
     android:layout_width="@dimen/search_box_close_icon_size"
     android:layout_height="@dimen/search_box_close_icon_size"
+    android:layout_alignParentEnd="true"
+    android:layout_centerVertical="true"
     android:padding="@dimen/search_box_close_icon_padding"
     android:background="?attr/selectableItemBackgroundBorderless"
     android:clickable="true"
     android:contentDescription="@string/description_clear_search"
     android:src="@drawable/quantum_ic_close_vd_theme_24"
     android:tint="@color/searchbox_icon_tint"/>
-
-</LinearLayout>
+</RelativeLayout>
diff --git a/java/com/android/contacts/common/res/values/colors.xml b/java/com/android/contacts/common/res/values/colors.xml
index 1f46233..3044339 100644
--- a/java/com/android/contacts/common/res/values/colors.xml
+++ b/java/com/android/contacts/common/res/values/colors.xml
@@ -68,7 +68,7 @@
   <color name="actionbar_unselected_text_color">#a6ffffff</color>
 
   <!-- Text color of the search box text as entered by user  -->
-  <color name="searchbox_text_color">#000000</color>
+  <color name="searchbox_text_color">@color/dialer_primary_text_color</color>
   <!-- Background color of the search box -->
   <color name="searchbox_background_color">#ffffff</color>
 
diff --git a/java/com/android/contacts/common/res/values/dimens.xml b/java/com/android/contacts/common/res/values/dimens.xml
index 19b27b8..1ad9b30 100644
--- a/java/com/android/contacts/common/res/values/dimens.xml
+++ b/java/com/android/contacts/common/res/values/dimens.xml
@@ -80,7 +80,7 @@
   <!-- Left margin of the text field in the search box. -->
   <dimen name="search_box_text_left_margin">15dp</dimen>
   <!-- Search box text size -->
-  <dimen name="search_text_size">20sp</dimen>
+  <dimen name="search_text_size">16sp</dimen>
 
   <dimen name="contact_list_card_elevation">2dp</dimen>
 
diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java
index a4c075c..74bc8cc 100644
--- a/java/com/android/dialer/app/DialtactsActivity.java
+++ b/java/com/android/dialer/app/DialtactsActivity.java
@@ -419,6 +419,7 @@
 
     mSearchView = searchEditTextLayout.findViewById(R.id.search_view);
     mSearchView.addTextChangedListener(mPhoneSearchQueryTextListener);
+    mSearchView.setHint(getSearchBoxHint());
     mVoiceSearchButton = searchEditTextLayout.findViewById(R.id.voice_search_button);
     searchEditTextLayout
         .findViewById(R.id.search_box_collapsed)
diff --git a/java/com/android/dialer/app/res/layout/search_edittext.xml b/java/com/android/dialer/app/res/layout/search_edittext.xml
index bb6a5f7..63786df 100644
--- a/java/com/android/dialer/app/res/layout/search_edittext.xml
+++ b/java/com/android/dialer/app/res/layout/search_edittext.xml
@@ -1,4 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
 <view xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/search_view_container"
   class="com.android.dialer.app.widget.SearchEditTextLayout"
@@ -13,20 +27,18 @@
   android:theme="@style/DialtactsSearchBarThemeOverlay"
   android:orientation="horizontal">
 
-  <LinearLayout
+  <RelativeLayout
     android:id="@+id/search_box_collapsed"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="?android:selectableItemBackground"
-    android:paddingStart="@dimen/search_box_left_padding"
-    android:gravity="center_vertical"
-    android:orientation="horizontal">
+    android:gravity="center_vertical">
 
     <ImageView
       android:id="@+id/search_magnifying_glass"
       android:layout_width="@dimen/search_box_icon_size"
       android:layout_height="@dimen/search_box_icon_size"
-      android:padding="@dimen/search_box_search_icon_padding"
+      android:layout_marginStart="8dp"
       android:importantForAccessibility="no"
       android:scaleType="center"
       android:src="@drawable/quantum_ic_search_vd_theme_24"
@@ -34,10 +46,11 @@
 
     <TextView
       android:id="@+id/search_box_start_search"
-      android:layout_width="0dp"
+      android:layout_width="wrap_content"
       android:layout_height="match_parent"
-      android:layout_weight="1"
-      android:layout_marginLeft="@dimen/search_box_collapsed_text_margin_left"
+      android:layout_toEndOf="@+id/search_magnifying_glass"
+      android:layout_toStartOf="@+id/voice_search_button"
+      android:layout_marginStart="8dp"
       android:fontFamily="@string/search_font_family"
       android:gravity="center_vertical"
       android:hint="@string/dialer_hint_find_contact"
@@ -48,6 +61,7 @@
       android:id="@+id/voice_search_button"
       android:layout_width="@dimen/search_box_icon_size"
       android:layout_height="match_parent"
+      android:layout_toStartOf="@+id/dialtacts_options_menu_button"
       android:background="?android:attr/selectableItemBackgroundBorderless"
       android:clickable="true"
       android:contentDescription="@string/description_start_voice_search"
@@ -59,15 +73,13 @@
       android:id="@+id/dialtacts_options_menu_button"
       android:layout_width="@dimen/search_box_icon_size"
       android:layout_height="match_parent"
-      android:paddingEnd="@dimen/search_box_right_padding"
+      android:layout_alignParentEnd="true"
       android:background="?android:attr/selectableItemBackgroundBorderless"
       android:contentDescription="@string/action_menu_overflow_description"
       android:scaleType="center"
       android:src="@drawable/quantum_ic_more_vert_white_24"
       android:tint="@color/searchbox_icon_tint"/>
-
-  </LinearLayout>
+  </RelativeLayout>
 
   <include layout="@layout/search_bar_expanded"/>
-
 </view>
diff --git a/java/com/android/dialer/app/res/values/dimens.xml b/java/com/android/dialer/app/res/values/dimens.xml
index 5f252ee..fdbcac9 100644
--- a/java/com/android/dialer/app/res/values/dimens.xml
+++ b/java/com/android/dialer/app/res/values/dimens.xml
@@ -61,11 +61,9 @@
   <dimen name="search_top_margin">8dp</dimen>
   <!-- Margin below the search box. -->
   <dimen name="search_bottom_margin">8dp</dimen>
-  <dimen name="search_collapsed_text_size">14sp</dimen>
+  <dimen name="search_collapsed_text_size">16sp</dimen>
   <!-- Search box interior padding - left -->
-  <dimen name="search_box_left_padding">8dp</dimen>
-  <!-- Search box interior padding - right -->
-  <dimen name="search_box_right_padding">8dp</dimen>
+  <dimen name="search_box_left_padding">4dp</dimen>
   <dimen name="search_box_search_icon_padding">2dp</dimen>
   <dimen name="search_box_collapsed_text_margin_left">22dp</dimen>
   <dimen name="search_list_padding_top">16dp</dimen>
diff --git a/java/com/android/dialer/searchfragment/common/res/layout/search_contact_row.xml b/java/com/android/dialer/searchfragment/common/res/layout/search_contact_row.xml
index dd871af..407207a 100644
--- a/java/com/android/dialer/searchfragment/common/res/layout/search_contact_row.xml
+++ b/java/com/android/dialer/searchfragment/common/res/layout/search_contact_row.xml
@@ -36,13 +36,13 @@
       android:layout_height="wrap_content"
       android:layout_toEndOf="@+id/photo"
       android:layout_toStartOf="@+id/call_to_action"
-      android:layout_centerVertical="true">
+      android:layout_centerVertical="true"
+      android:layout_marginStart="8dp">
 
     <TextView
         android:id="@+id/primary"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:paddingStart="@dimen/search_text_padding_start"
         android:gravity="center_vertical|start"
         android:fontFamily="sans-serif"
         style="@style/PrimaryText"/>
@@ -51,7 +51,6 @@
         android:id="@+id/secondary"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:paddingStart="@dimen/search_text_padding_start"
         android:gravity="center_vertical|start"
         android:fontFamily="sans-serif"
         style="@style/SecondaryText"/>
diff --git a/java/com/android/dialer/searchfragment/common/res/values/dimens.xml b/java/com/android/dialer/searchfragment/common/res/values/dimens.xml
index f666416..fabb030 100644
--- a/java/com/android/dialer/searchfragment/common/res/values/dimens.xml
+++ b/java/com/android/dialer/searchfragment/common/res/values/dimens.xml
@@ -18,5 +18,5 @@
   <dimen name="search_row_height">56dp</dimen>
   <dimen name="search_photo_padding">8dp</dimen>
   <dimen name="call_to_action_padding">8dp</dimen>
-  <dimen name="search_text_padding_start">16dp</dimen>
+  <dimen name="search_text_padding_start">8dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/java/com/android/dialer/searchfragment/list/res/layout/header_layout.xml b/java/com/android/dialer/searchfragment/list/res/layout/header_layout.xml
index eef0dee..6eb1d2e 100644
--- a/java/com/android/dialer/searchfragment/list/res/layout/header_layout.xml
+++ b/java/com/android/dialer/searchfragment/list/res/layout/header_layout.xml
@@ -14,10 +14,18 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/header"
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_marginTop="8dp"
-    android:paddingStart="16dp"
-    style="@style/SecondaryText"/>
+    android:layout_height="48dp"
+    android:layout_marginStart="16dp"
+    android:layout_marginEnd="16dp"
+    android:layout_marginBottom="2dp">
+
+  <TextView
+      android:id="@+id/header"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:layout_gravity="center_vertical"
+      style="@style/SecondaryText"/>
+</FrameLayout>
diff --git a/java/com/android/dialer/simulator/Simulator.java b/java/com/android/dialer/simulator/Simulator.java
index 78058a4..f416415 100644
--- a/java/com/android/dialer/simulator/Simulator.java
+++ b/java/com/android/dialer/simulator/Simulator.java
@@ -17,11 +17,59 @@
 package com.android.dialer.simulator;
 
 import android.content.Context;
+import android.support.annotation.IntDef;
+import android.support.annotation.Nullable;
 import android.view.ActionProvider;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /** Used to add menu items to the Dialer menu to test the app using simulated calls and data. */
 public interface Simulator {
   boolean shouldShow();
 
   ActionProvider getActionProvider(Context context);
+
+  /** Information about a connection event. */
+  public static class Event {
+    /** The type of connection event. */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+      NONE,
+      ANSWER,
+      REJECT,
+      HOLD,
+      UNHOLD,
+      DISCONNECT,
+      STATE_CHANGE,
+      DTMF,
+    })
+    public @interface Type {}
+
+    public static final int NONE = -1;
+    public static final int ANSWER = 1;
+    public static final int REJECT = 2;
+    public static final int HOLD = 3;
+    public static final int UNHOLD = 4;
+    public static final int DISCONNECT = 5;
+    public static final int STATE_CHANGE = 6;
+    public static final int DTMF = 7;
+
+    @Type public final int type;
+    /** Holds event specific information. For example, for DTMF this could be the keycode. */
+    @Nullable public final String data1;
+    /**
+     * Holds event specific information. For example, for STATE_CHANGE this could be the new state.
+     */
+    @Nullable public final String data2;
+
+    public Event(@Type int type) {
+      this(type, null, null);
+    }
+
+    public Event(@Type int type, String data1, String data2) {
+      this.type = type;
+      this.data1 = data1;
+      this.data2 = data2;
+    }
+  }
 }
diff --git a/java/com/android/dialer/simulator/impl/SimulatorConnection.java b/java/com/android/dialer/simulator/impl/SimulatorConnection.java
index 12d0958..b462b54 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorConnection.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorConnection.java
@@ -16,41 +16,85 @@
 
 package com.android.dialer.simulator.impl;
 
+import android.support.annotation.NonNull;
 import android.telecom.Connection;
-import android.telecom.DisconnectCause;
+import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
+import com.android.dialer.simulator.Simulator.Event;
+import java.util.ArrayList;
+import java.util.List;
 
 /** Represents a single phone call on the device. */
-final class SimulatorConnection extends Connection {
+public final class SimulatorConnection extends Connection {
+  private final List<Listener> listeners = new ArrayList<>();
+  private final List<Event> events = new ArrayList<>();
+  private int currentState = STATE_NEW;
+
+  public void addListener(@NonNull Listener listener) {
+    listeners.add(Assert.isNotNull(listener));
+  }
+
+  public void removeListener(@NonNull Listener listener) {
+    listeners.remove(Assert.isNotNull(listener));
+  }
+
+  @NonNull
+  public List<Event> getEvents() {
+    return events;
+  }
 
   @Override
   public void onAnswer() {
     LogUtil.enterBlock("SimulatorConnection.onAnswer");
-    setActive();
+    onEvent(new Event(Event.ANSWER));
   }
 
   @Override
   public void onReject() {
     LogUtil.enterBlock("SimulatorConnection.onReject");
-    setDisconnected(new DisconnectCause(DisconnectCause.REJECTED));
+    onEvent(new Event(Event.REJECT));
   }
 
   @Override
   public void onHold() {
     LogUtil.enterBlock("SimulatorConnection.onHold");
-    setOnHold();
+    onEvent(new Event(Event.HOLD));
   }
 
   @Override
   public void onUnhold() {
     LogUtil.enterBlock("SimulatorConnection.onUnhold");
-    setActive();
+    onEvent(new Event(Event.UNHOLD));
   }
 
   @Override
   public void onDisconnect() {
     LogUtil.enterBlock("SimulatorConnection.onDisconnect");
-    setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
-    destroy();
+    onEvent(new Event(Event.DISCONNECT));
+  }
+
+  @Override
+  public void onStateChanged(int newState) {
+    LogUtil.enterBlock("SimulatorConnection.onStateChanged");
+    onEvent(new Event(Event.STATE_CHANGE, stateToString(currentState), stateToString(newState)));
+    currentState = newState;
+  }
+
+  @Override
+  public void onPlayDtmfTone(char c) {
+    LogUtil.enterBlock("SimulatorConnection.onPlayDtmfTone");
+    onEvent(new Event(Event.DTMF, Character.toString(c), null));
+  }
+
+  private void onEvent(@NonNull Event event) {
+    events.add(Assert.isNotNull(event));
+    for (Listener listener : listeners) {
+      listener.onEvent(this, event);
+    }
+  }
+
+  /** Callback for when a new event arrives. */
+  public interface Listener {
+    void onEvent(@NonNull SimulatorConnection connection, @NonNull Event event);
   }
 }
diff --git a/java/com/android/dialer/simulator/impl/SimulatorConnectionService.java b/java/com/android/dialer/simulator/impl/SimulatorConnectionService.java
index 9e107ed..06c2591 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorConnectionService.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorConnectionService.java
@@ -40,6 +40,7 @@
   private static final String PHONE_ACCOUNT_ID = "SIMULATOR_ACCOUNT_ID";
   private static final String EXTRA_IS_SIMULATOR_CONNECTION = "is_simulator_connection";
   private static final List<Listener> listeners = new ArrayList<>();
+  private static SimulatorConnectionService instance;
 
   private static void register(@NonNull Context context) {
     LogUtil.enterBlock("SimulatorConnectionService.register");
@@ -55,6 +56,30 @@
         .unregisterPhoneAccount(buildPhoneAccount(context).getAccountHandle());
   }
 
+  public static SimulatorConnectionService getInstance() {
+    return instance;
+  }
+
+  public static void addNewOutgoingCall(
+      @NonNull Context context, @NonNull Bundle extras, @NonNull String phoneNumber) {
+    LogUtil.enterBlock("SimulatorConnectionService.addNewOutgoingCall");
+    Assert.isNotNull(context);
+    Assert.isNotNull(extras);
+    Assert.isNotNull(phoneNumber);
+
+    register(context);
+
+    Bundle bundle = new Bundle(extras);
+    bundle.putBoolean(EXTRA_IS_SIMULATOR_CONNECTION, true);
+    Bundle outgoingCallExtras = new Bundle();
+    outgoingCallExtras.putBundle(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, bundle);
+
+    // Use the system's phone account so that these look like regular SIM call.
+    TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
+    telecomManager.placeCall(
+        Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null), outgoingCallExtras);
+  }
+
   public static void addNewIncomingCall(
       @NonNull Context context, @NonNull Bundle extras, @NonNull String callerId) {
     LogUtil.enterBlock("SimulatorConnectionService.addNewIncomingCall");
@@ -76,13 +101,11 @@
   }
 
   public static void addListener(@NonNull Listener listener) {
-    Assert.isNotNull(listener);
-    listeners.add(listener);
+    listeners.add(Assert.isNotNull(listener));
   }
 
   public static void removeListener(@NonNull Listener listener) {
-    Assert.isNotNull(listener);
-    listeners.remove(listener);
+    listeners.remove(Assert.isNotNull(listener));
   }
 
   @NonNull
@@ -112,6 +135,19 @@
   }
 
   @Override
+  public void onCreate() {
+    super.onCreate();
+    instance = this;
+  }
+
+  @Override
+  public void onDestroy() {
+    LogUtil.enterBlock("SimulatorConnectionService.onDestroy");
+    instance = null;
+    super.onDestroy();
+  }
+
+  @Override
   public Connection onCreateOutgoingConnection(
       PhoneAccountHandle phoneAccount, ConnectionRequest request) {
     LogUtil.enterBlock("SimulatorConnectionService.onCreateOutgoingConnection");
@@ -127,10 +163,12 @@
     }
 
     SimulatorConnection connection = new SimulatorConnection();
-    connection.setActive();
+    connection.setDialing();
     connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
     connection.setConnectionCapabilities(
-        Connection.CAPABILITY_MUTE | Connection.CAPABILITY_SUPPORT_HOLD);
+        Connection.CAPABILITY_MUTE
+            | Connection.CAPABILITY_SUPPORT_HOLD
+            | Connection.CAPABILITY_HOLD);
     connection.putExtras(request.getExtras());
 
     for (Listener listener : listeners) {
diff --git a/java/com/android/dialer/simulator/impl/SimulatorSpamCallCreator.java b/java/com/android/dialer/simulator/impl/SimulatorSpamCallCreator.java
index 4b1d7a5..ae97bc1 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorSpamCallCreator.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorSpamCallCreator.java
@@ -88,7 +88,7 @@
     extras.putInt(EXTRA_CALL_COUNT, callCount - 1);
     extras.putBoolean(EXTRA_IS_SPAM_CALL_CONNECTION, true);
 
-    // We need to clear the call log because spam notifiations are only shown for new calls.
+    // We need to clear the call log because spam notifications are only shown for new calls.
     clearCallLog(context);
 
     SimulatorConnectionService.addNewIncomingCall(context, extras, callerId);
diff --git a/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java b/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
index 5930dff..2512828 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
@@ -23,7 +23,7 @@
 
 /** Utilities to simulate phone calls. */
 final class SimulatorVoiceCall {
-  public static void addNewIncomingCall(@NonNull Context context) {
+  static void addNewIncomingCall(@NonNull Context context) {
     LogUtil.enterBlock("SimulatorVoiceCall.addNewIncomingCall");
     // Set the caller ID to the Google London office.
     String callerId = "+44 (0) 20 7031 3000";
diff --git a/java/com/android/incallui/answer/impl/answermethod/AnswerMethodFactory.java b/java/com/android/incallui/answer/impl/answermethod/AnswerMethodFactory.java
index 35f36f7..ccb132b 100644
--- a/java/com/android/incallui/answer/impl/answermethod/AnswerMethodFactory.java
+++ b/java/com/android/incallui/answer/impl/answermethod/AnswerMethodFactory.java
@@ -19,12 +19,15 @@
 import android.app.Activity;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
 import android.support.v4.app.Fragment;
+import com.android.dialer.common.LogUtil;
 import com.android.dialer.compat.ActivityCompat;
 import com.android.incallui.util.AccessibilityUtil;
 
 /** Creates the appropriate {@link AnswerMethod} for the circumstances. */
 public class AnswerMethodFactory {
+  private static boolean shouldUseTwoButtonMethodForTesting;
 
   @NonNull
   public static AnswerMethod createAnswerMethod(@NonNull Activity activity) {
@@ -45,7 +48,17 @@
     return !(answerMethod instanceof TwoButtonMethod) && needTwoButton(answerMethod.getActivity());
   }
 
+  @VisibleForTesting
+  public static void setShouldUseTwoButtonMethodForTesting(boolean shouldUse) {
+    shouldUseTwoButtonMethodForTesting = shouldUse;
+  }
+
   private static boolean needTwoButton(@NonNull Activity activity) {
+    if (shouldUseTwoButtonMethodForTesting) {
+      LogUtil.i("AnswerMethodFactory.needTwoButton", "enabled for testing");
+      return true;
+    }
+
     return AccessibilityUtil.isTouchExplorationEnabled(activity)
         || ActivityCompat.isInMultiWindowMode(activity);
   }
diff --git a/java/com/android/incallui/call/CallList.java b/java/com/android/incallui/call/CallList.java
index d0931dd..954fdc9 100644
--- a/java/com/android/incallui/call/CallList.java
+++ b/java/com/android/incallui/call/CallList.java
@@ -44,6 +44,7 @@
 import com.android.incallui.latencyreport.LatencyReport;
 import com.android.incallui.util.TelecomCallUtil;
 import com.android.incallui.videotech.utils.SessionModificationState;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Map;
@@ -509,6 +510,10 @@
     return mCallById.get(callId);
   }
 
+  public Collection<DialerCall> getAllCalls() {
+    return mCallById.values();
+  }
+
   /** Returns first call found in the call map with the specified state. */
   public DialerCall getFirstCallWithState(int state) {
     return getCallWithState(state, 0);