Add voice search to NUI.

Bug: 72525718
Test: MainActivityIntegrationTest
PiperOrigin-RevId: 183418364
Change-Id: I30a4b7fe3e8a82c1b5cddcd747bd01ebd127b624
diff --git a/java/com/android/dialer/main/impl/MainActivity.java b/java/com/android/dialer/main/impl/MainActivity.java
index 168589f..242bf2d 100644
--- a/java/com/android/dialer/main/impl/MainActivity.java
+++ b/java/com/android/dialer/main/impl/MainActivity.java
@@ -28,6 +28,7 @@
 import com.android.dialer.calllog.ui.NewCallLogFragment;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.compat.CompatUtils;
+import com.android.dialer.constants.ActivityRequestCodes;
 import com.android.dialer.contactsfragment.ContactsFragment;
 import com.android.dialer.contactsfragment.ContactsFragment.Header;
 import com.android.dialer.contactsfragment.ContactsFragment.OnContactSelectedListener;
@@ -117,6 +118,16 @@
   }
 
   @Override
+  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+    super.onActivityResult(requestCode, resultCode, data);
+    if (requestCode == ActivityRequestCodes.DIALTACTS_VOICE_SEARCH) {
+      searchController.onVoiceResults(resultCode, data);
+    } else {
+      LogUtil.e("MainActivity.onActivityResult", "Unknown request code: " + requestCode);
+    }
+  }
+
+  @Override
   public void onContactSelected(ImageView photo, Uri contactUri, long contactId) {
     // TODO(calderwoodra): Add impression logging
     QuickContact.showQuickContact(
diff --git a/java/com/android/dialer/main/impl/MainSearchController.java b/java/com/android/dialer/main/impl/MainSearchController.java
index 041e32e..b01f80d 100644
--- a/java/com/android/dialer/main/impl/MainSearchController.java
+++ b/java/com/android/dialer/main/impl/MainSearchController.java
@@ -17,16 +17,22 @@
 package com.android.dialer.main.impl;
 
 import android.app.FragmentTransaction;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
 import android.os.Bundle;
+import android.speech.RecognizerIntent;
 import android.support.annotation.Nullable;
 import android.support.design.widget.FloatingActionButton;
+import android.support.v7.app.AppCompatActivity;
 import android.text.TextUtils;
 import android.view.View;
 import android.view.animation.Animation;
 import android.view.animation.Animation.AnimationListener;
+import android.widget.Toast;
 import com.android.dialer.callintent.CallInitiationType;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
+import com.android.dialer.constants.ActivityRequestCodes;
 import com.android.dialer.dialpadview.DialpadFragment;
 import com.android.dialer.dialpadview.DialpadFragment.DialpadListener;
 import com.android.dialer.dialpadview.DialpadFragment.OnDialpadQueryChangedListener;
@@ -36,6 +42,7 @@
 import com.android.dialer.searchfragment.list.NewSearchFragment.SearchFragmentListener;
 import com.android.dialer.util.ViewUtil;
 import com.google.common.base.Optional;
+import java.util.ArrayList;
 
 /**
  * Search controller for handling all the logic related to entering and exiting the search UI.
@@ -255,8 +262,12 @@
    */
   @Override
   public void onSearchBarClicked() {
+    openSearch(Optional.absent());
+  }
+
+  private void openSearch(Optional<String> query) {
     fab.hide();
-    toolbar.expand(/* animate=*/ true, Optional.absent());
+    toolbar.expand(/* animate=*/ true, query);
     toolbar.showKeyboard();
     hideBottomNav();
 
@@ -294,7 +305,28 @@
   }
 
   @Override
-  public void onVoiceButtonClicked(VoiceSearchResultCallback voiceSearchResultCallback) {}
+  public void onVoiceButtonClicked(VoiceSearchResultCallback voiceSearchResultCallback) {
+    try {
+      Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
+      mainActivity.startActivityForResult(voiceIntent, ActivityRequestCodes.DIALTACTS_VOICE_SEARCH);
+    } catch (ActivityNotFoundException e) {
+      Toast.makeText(mainActivity, R.string.voice_search_not_available, Toast.LENGTH_SHORT).show();
+    }
+  }
+
+  public void onVoiceResults(int resultCode, Intent data) {
+    if (resultCode == AppCompatActivity.RESULT_OK) {
+      ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
+      if (matches.size() > 0) {
+        LogUtil.i("MainSearchController.onVoiceResults", "voice search - match found");
+        openSearch(Optional.of(matches.get(0)));
+      } else {
+        LogUtil.i("MainSearchController.onVoiceResults", "voice search - nothing heard");
+      }
+    } else {
+      LogUtil.e("MainSearchController.onVoiceResults", "voice search failed");
+    }
+  }
 
   @Override
   public void openSettings() {}
diff --git a/java/com/android/dialer/main/impl/res/values/strings.xml b/java/com/android/dialer/main/impl/res/values/strings.xml
index f530fa2..0fc1246 100644
--- a/java/com/android/dialer/main/impl/res/values/strings.xml
+++ b/java/com/android/dialer/main/impl/res/values/strings.xml
@@ -46,4 +46,7 @@
   <string name="tab_title_voicemail">Voicemail</string>
   <!-- Tab text to show users their contacts  [CHAR LIMIT=10] -->
   <string name="tab_title_contacts">Contacts</string>
+
+  <!-- Message displayed when there is no application available to handle voice search. [CHAR LIMIT=NONE] -->
+  <string name="voice_search_not_available">Voice search not available</string>
 </resources>