Commit 2bc300c5 authored by Ted Choc's avatar Ted Choc Committed by Commit Bot

Move the voice suggestion provider into suggestions/ package.

BUG=898522

Change-Id: Id9ef47429b19582982480ff0dcd5af78ab21b99e
Reviewed-on: https://chromium-review.googlesource.com/c/1311496
Commit-Queue: Ted Choc <tedchoc@chromium.org>
Reviewed-by: default avatarPedro Amaral <amaralp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604614}
parent cd932740
......@@ -9,6 +9,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
......@@ -17,7 +18,6 @@ import android.text.TextUtils;
import org.chromium.base.metrics.CachedMetrics;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.omnibox.VoiceSuggestionProvider.VoiceResult;
import org.chromium.chrome.browser.omnibox.suggestions.AutocompleteController;
import org.chromium.chrome.browser.omnibox.suggestions.AutocompleteCoordinator;
import org.chromium.chrome.browser.search_engines.TemplateUrlService;
......@@ -30,6 +30,9 @@ import org.chromium.content_public.browser.WebContentsObserver;
import org.chromium.ui.base.PermissionCallback;
import org.chromium.ui.base.WindowAndroid;
import java.util.ArrayList;
import java.util.List;
/**
* Class containing functionality related to voice search in the location bar.
*/
......@@ -124,6 +127,38 @@ public class LocationBarVoiceRecognitionHandler {
WindowAndroid getWindowAndroid();
}
/**
* A storage class that holds voice recognition string matches and confidence scores.
*/
public static class VoiceResult {
private final String mMatch;
private final float mConfidence;
/**
* Creates an instance of a VoiceResult.
* @param match The text match from the voice recognition.
* @param confidence The confidence value of the recognition that should go from 0.0 to 1.0.
*/
public VoiceResult(String match, float confidence) {
mMatch = match;
mConfidence = confidence;
}
/**
* @return The text match from the voice recognition.
*/
public String getMatch() {
return mMatch;
}
/**
* @return The confidence value of the recognition that should go from 0.0 to 1.0.
*/
public float getConfidence() {
return mConfidence;
}
}
public LocationBarVoiceRecognitionHandler(Delegate delegate) {
mDelegate = delegate;
}
......@@ -196,7 +231,10 @@ public class LocationBarVoiceRecognitionHandler {
recordVoiceSearchFinishEventSource(mSource);
VoiceResult topResult = autocompleteCoordinator.onVoiceResults(data.getExtras());
List<VoiceResult> voiceResults = convertBundleToVoiceResults(data.getExtras());
autocompleteCoordinator.onVoiceResults(voiceResults);
VoiceResult topResult =
(voiceResults != null && voiceResults.size() > 0) ? voiceResults.get(0) : null;
if (topResult == null) {
recordVoiceSearchResult(false);
return;
......@@ -238,6 +276,33 @@ public class LocationBarVoiceRecognitionHandler {
}
}
/** Convert the android voice intent bundle to a list of result objects. */
@VisibleForTesting
protected static List<VoiceResult> convertBundleToVoiceResults(Bundle extras) {
if (extras == null) return null;
ArrayList<String> strings = extras.getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
float[] confidences = extras.getFloatArray(RecognizerIntent.EXTRA_CONFIDENCE_SCORES);
if (strings == null || confidences == null) return null;
if (strings.size() != confidences.length) return null;
List<VoiceResult> results = new ArrayList<>();
for (int i = 0; i < strings.size(); ++i) {
// Remove any spaces in the voice search match when determining whether it
// appears to be a URL. This is to prevent cases like (
// "tech crunch.com" and "www. engadget .com" from not appearing like URLs)
// from not navigating to the URL.
// If the string appears to be a URL, then use it instead of the string returned from
// the voice engine.
String culledString = strings.get(i).replaceAll(" ", "");
String url = AutocompleteController.nativeQualifyPartialURLQuery(culledString);
results.add(
new VoiceResult(url == null ? strings.get(i) : culledString, confidences[i]));
}
return results;
}
/**
* Triggers a voice recognition intent to allow the user to specify a search query.
* @param source The source of the voice recognition initiation, such as NTP or omnibox.
......
......@@ -4,7 +4,7 @@
package org.chromium.chrome.browser.omnibox.suggestions;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import org.chromium.base.Log;
......@@ -12,9 +12,8 @@ import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.browser.WarmupManager;
import org.chromium.chrome.browser.ntp.NewTabPage;
import org.chromium.chrome.browser.omnibox.LocationBarVoiceRecognitionHandler.VoiceResult;
import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType;
import org.chromium.chrome.browser.omnibox.VoiceSuggestionProvider;
import org.chromium.chrome.browser.omnibox.VoiceSuggestionProvider.VoiceResult;
import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion.MatchClassification;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.content_public.browser.WebContents;
......@@ -271,15 +270,11 @@ public class AutocompleteController {
}
/**
* Pass the autocomplete controller a {@link Bundle} representing the results of a voice
* recognition.
* @param data A {@link Bundle} containing the results of a voice recognition.
* @return The top voice match if one exists, {@code null} otherwise.
* Pass the voice provider a list representing the results of a voice recognition.
* @param results A list containing the results of a voice recognition.
*/
public VoiceResult onVoiceResults(Bundle data) {
mVoiceSuggestionProvider.setVoiceResultsFromIntentBundle(data);
List<VoiceResult> results = mVoiceSuggestionProvider.getResults();
return (results != null && results.size() > 0) ? results.get(0) : null;
public void onVoiceResults(@Nullable List<VoiceResult> results) {
mVoiceSuggestionProvider.setVoiceResults(results);
}
@CalledByNative
......
......@@ -6,8 +6,8 @@ package org.chromium.chrome.browser.omnibox.suggestions;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
......@@ -23,11 +23,11 @@ import org.chromium.base.StrictModeContext;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.omnibox.LocationBarVoiceRecognitionHandler;
import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType;
import org.chromium.chrome.browser.omnibox.UrlBar.UrlTextChangeListener;
import org.chromium.chrome.browser.omnibox.UrlBarEditingTextStateProvider;
import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener;
import org.chromium.chrome.browser.omnibox.VoiceSuggestionProvider.VoiceResult;
import org.chromium.chrome.browser.omnibox.suggestions.AutocompleteController.OnSuggestionsReceivedListener;
import org.chromium.chrome.browser.omnibox.suggestions.OmniboxResultsAdapter.OmniboxResultItem;
import org.chromium.chrome.browser.omnibox.suggestions.OmniboxResultsAdapter.OmniboxSuggestionDelegate;
......@@ -292,11 +292,11 @@ public class AutocompleteCoordinator
}
/**
* @see AutocompleteController#onVoiceResults(Bundle)
* @see AutocompleteController#onVoiceResults(List)
*/
// TODO(tedchoc): Should this coordinator own the voice query logic too?
public VoiceResult onVoiceResults(Bundle data) {
return mAutocomplete.onVoiceResults(data);
public void onVoiceResults(
@Nullable List<LocationBarVoiceRecognitionHandler.VoiceResult> results) {
mAutocomplete.onVoiceResults(results);
}
/**
......
......@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.omnibox;
package org.chromium.chrome.browser.omnibox.suggestions;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.support.annotation.Nullable;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.omnibox.suggestions.AutocompleteController;
import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion;
import org.chromium.chrome.browser.omnibox.LocationBarVoiceRecognitionHandler.VoiceResult;
import org.chromium.chrome.browser.omnibox.MatchClassificationStyle;
import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType;
import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion.MatchClassification;
import org.chromium.chrome.browser.search_engines.TemplateUrlService;
......@@ -21,7 +21,7 @@ import java.util.List;
* A search provider that processes and stores voice recognition results and makes them available
* in the omnibox results. The voice results are added to the end of the omnibox results.
*/
public class VoiceSuggestionProvider {
class VoiceSuggestionProvider {
private static final float CONFIDENCE_THRESHOLD_SHOW = 0.3f;
private static final float CONFIDENCE_THRESHOLD_HIDE_ALTS = 0.8f;
......@@ -48,8 +48,8 @@ public class VoiceSuggestionProvider {
* between 0.0 and 1.0.
*/
@VisibleForTesting
protected VoiceSuggestionProvider(float confidenceThresholdShow,
float confidenceThresholdHideAlts) {
protected VoiceSuggestionProvider(
float confidenceThresholdShow, float confidenceThresholdHideAlts) {
mConfidenceThresholdShow = confidenceThresholdShow;
mConfidenceThresholdHideAlts = confidenceThresholdHideAlts;
}
......@@ -57,7 +57,7 @@ public class VoiceSuggestionProvider {
/**
* Clears the current voice search results.
*/
public void clearVoiceSearchResults() {
void clearVoiceSearchResults() {
mResults.clear();
}
......@@ -65,45 +65,19 @@ public class VoiceSuggestionProvider {
* @return The current voice search results. This could be {@code null} if no results are
* currently present.
*/
public List<VoiceResult> getResults() {
@VisibleForTesting
List<VoiceResult> getResults() {
return Collections.unmodifiableList(mResults);
}
/**
* Takes and processes the results from a recognition action. It parses the confidence and
* string values and stores the processed results here so they are made available to the
* {@link AutocompleteController} and show up in the omnibox results. This method does not
* reorder the voice results that come back from the recognizer.
* @param extras The {@link Bundle} that contains the recognition results from a
* {@link RecognizerIntent#ACTION_RECOGNIZE_SPEECH} action.
* Sets the voice result options to be displayed in the autocomplete suggestion list.
* @param results The list that contains the recognition results from a voice action.
*/
public void setVoiceResultsFromIntentBundle(Bundle extras) {
void setVoiceResults(@Nullable List<VoiceResult> results) {
clearVoiceSearchResults();
if (extras == null) return;
ArrayList<String> strings = extras.getStringArrayList(
RecognizerIntent.EXTRA_RESULTS);
float[] confidences = extras.getFloatArray(
RecognizerIntent.EXTRA_CONFIDENCE_SCORES);
if (strings == null || confidences == null) return;
assert (strings.size() == confidences.length);
if (strings.size() != confidences.length) return;
for (int i = 0; i < strings.size(); ++i) {
// Remove any spaces in the voice search match when determining whether it
// appears to be a URL. This is to prevent cases like (
// "tech crunch.com" and "www. engadget .com" from not appearing like URLs)
// from not navigating to the URL.
// If the string appears to be a URL, then use it instead of the string returned from
// the voice engine.
String culledString = strings.get(i).replaceAll(" ", "");
String url = AutocompleteController.nativeQualifyPartialURLQuery(culledString);
mResults.add(new VoiceResult(
url == null ? strings.get(i) : culledString, confidences[i]));
}
if (results == null || results.size() == 0) return;
mResults.addAll(results);
}
/**
......@@ -113,7 +87,7 @@ public class VoiceSuggestionProvider {
* @param maxVoiceResults The maximum number of voice results that should be added.
* @return A new list of {@link OmniboxSuggestion}s, which can include voice results.
*/
public List<OmniboxSuggestion> addVoiceSuggestions(
List<OmniboxSuggestion> addVoiceSuggestions(
List<OmniboxSuggestion> suggestions, int maxVoiceResults) {
if (mResults.size() == 0 || maxVoiceResults == 0) return suggestions;
......@@ -128,78 +102,35 @@ public class VoiceSuggestionProvider {
final int suggestionLength = suggestions != null ? suggestions.size() : 0;
if (firstResult.getConfidence() < mConfidenceThresholdHideAlts) {
for (int i = 1; i < mResults.size()
&& newSuggestions.size() < suggestionLength + maxVoiceResults; ++i) {
addVoiceResultToOmniboxSuggestions(newSuggestions, mResults.get(i),
mConfidenceThresholdShow);
&& newSuggestions.size() < suggestionLength + maxVoiceResults;
++i) {
addVoiceResultToOmniboxSuggestions(
newSuggestions, mResults.get(i), mConfidenceThresholdShow);
}
}
return newSuggestions;
}
private void addVoiceResultToOmniboxSuggestions(List<OmniboxSuggestion> suggestions,
VoiceResult result, float confidenceThreshold) {
private void addVoiceResultToOmniboxSuggestions(
List<OmniboxSuggestion> suggestions, VoiceResult result, float confidenceThreshold) {
if (doesVoiceResultHaveMatch(suggestions, result)) return;
if (result.getConfidence() < confidenceThreshold && result.getConfidence() > 0) return;
String voiceUrl = TemplateUrlService.getInstance().getUrlForVoiceSearchQuery(
result.getMatch());
String voiceUrl =
TemplateUrlService.getInstance().getUrlForVoiceSearchQuery(result.getMatch());
List<MatchClassification> classifications = new ArrayList<>();
classifications.add(new MatchClassification(0, MatchClassificationStyle.NONE));
suggestions.add(new OmniboxSuggestion(
OmniboxSuggestionType.VOICE_SUGGEST,
true,
0,
1,
result.getMatch(),
classifications,
null,
classifications,
null,
null,
null,
voiceUrl,
false,
false));
suggestions.add(new OmniboxSuggestion(OmniboxSuggestionType.VOICE_SUGGEST, true, 0, 1,
result.getMatch(), classifications, null, classifications, null, null, null,
voiceUrl, false, false));
}
private boolean doesVoiceResultHaveMatch(List<OmniboxSuggestion> suggestions,
VoiceResult result) {
private boolean doesVoiceResultHaveMatch(
List<OmniboxSuggestion> suggestions, VoiceResult result) {
for (OmniboxSuggestion suggestion : suggestions) {
if (suggestion.getDisplayText().equals(result.getMatch())) return true;
}
return false;
}
/**
* A storage class that holds voice recognition string matches and confidence scores.
*/
public static class VoiceResult {
private final String mMatch;
private final float mConfidence;
/**
* Creates an instance of a VoiceResult.
* @param match The text match from the voice recognition.
* @param confidence The confidence value of the recognition that should go from 0.0 to 1.0.
*/
public VoiceResult(String match, float confidence) {
mMatch = match;
mConfidence = confidence;
}
/**
* @return The text match from the voice recognition.
*/
public String getMatch() {
return mMatch;
}
/**
* @return The confidence value of the recognition that should go from 0.0 to 1.0.
*/
public float getConfidence() {
return mConfidence;
}
}
}
......@@ -1086,7 +1086,6 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/omnibox/UrlBarProperties.java",
"java/src/org/chromium/chrome/browser/omnibox/UrlBarViewBinder.java",
"java/src/org/chromium/chrome/browser/omnibox/UrlFocusChangeListener.java",
"java/src/org/chromium/chrome/browser/omnibox/VoiceSuggestionProvider.java",
"java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java",
"java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationTracker.java",
"java/src/org/chromium/chrome/browser/omnibox/geo/PlatformNetworksManager.java",
......@@ -1104,6 +1103,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionView.java",
"java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionViewProperties.java",
"java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionViewViewBinder.java",
"java/src/org/chromium/chrome/browser/omnibox/suggestions/VoiceSuggestionProvider.java",
"java/src/org/chromium/chrome/browser/page_info/CertificateChainHelper.java",
"java/src/org/chromium/chrome/browser/page_info/CertificateViewer.java",
"java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java",
......@@ -2003,9 +2003,9 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java",
"javatests/src/org/chromium/chrome/browser/omnibox/OmniboxUrlEmphasizerTest.java",
"javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java",
"javatests/src/org/chromium/chrome/browser/omnibox/VoiceSuggestionProviderTest.java",
"javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java",
"javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionAnswerTest.java",
"javatests/src/org/chromium/chrome/browser/omnibox/suggestions/VoiceSuggestionProviderTest.java",
"javatests/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopupTest.java",
"javatests/src/org/chromium/chrome/browser/page_info/PageInfoControllerTest.java",
"javatests/src/org/chromium/chrome/browser/partnercustomizations/BasePartnerBrowserCustomizationIntegrationTestRule.java",
......
......@@ -10,8 +10,8 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.support.test.filters.SmallTest;
import android.view.View;
import android.view.ViewGroup;
import org.junit.Assert;
......@@ -26,8 +26,7 @@ import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.ntp.NewTabPage;
import org.chromium.chrome.browser.omnibox.LocationBarVoiceRecognitionHandler.VoiceInteractionSource;
import org.chromium.chrome.browser.omnibox.VoiceSuggestionProvider.VoiceResult;
import org.chromium.chrome.browser.omnibox.suggestions.AutocompleteController;
import org.chromium.chrome.browser.omnibox.LocationBarVoiceRecognitionHandler.VoiceResult;
import org.chromium.chrome.browser.omnibox.suggestions.AutocompleteController.OnSuggestionsReceivedListener;
import org.chromium.chrome.browser.omnibox.suggestions.AutocompleteCoordinator;
import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion;
......@@ -43,9 +42,10 @@ import org.chromium.ui.base.AndroidPermissionDelegate;
import org.chromium.ui.base.PermissionCallback;
import org.chromium.ui.base.WindowAndroid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
/**
......@@ -61,10 +61,11 @@ public class LocationBarVoiceRecognitionHandlerTest {
private TestDataProvider mDataProvider;
private TestDelegate mDelegate;
private TestLocationBarVoiceRecognitionHandler mHandler;
private LocalTestAutocompleteController mAutocomplete;
private TestAutocompleteController mAutocomplete;
private TestAndroidPermissionDelegate mPermissionDelegate;
private TestWindowAndroid mWindowAndroid;
private Tab mTab;
private List<VoiceResult> mAutocompleteVoiceResults;
private static final OnSuggestionsReceivedListener sEmptySuggestionListener =
new OnSuggestionsReceivedListener() {
......@@ -267,8 +268,8 @@ public class LocationBarVoiceRecognitionHandlerTest {
Assert.assertNotNull(parent);
mCoordinator = new AutocompleteCoordinator(parent, null, null, null) {
@Override
public VoiceResult onVoiceResults(Bundle data) {
return mAutocomplete.onVoiceResults(data);
public void onVoiceResults(List<VoiceResult> results) {
mAutocompleteVoiceResults = results;
}
};
}
......@@ -310,6 +311,7 @@ public class LocationBarVoiceRecognitionHandlerTest {
private class TestWindowAndroid extends ActivityWindowAndroid {
private boolean mCancelableIntentSuccess = true;
private int mResultCode = Activity.RESULT_OK;
private Intent mResults = new Intent();
public TestWindowAndroid(Context context) {
super(context);
......@@ -323,37 +325,20 @@ public class LocationBarVoiceRecognitionHandlerTest {
mResultCode = resultCode;
}
public void setVoiceResults(Bundle results) {
mResults.putExtras(results);
}
@Override
public int showCancelableIntent(Intent intent, IntentCallback callback, Integer errorId) {
if (mCancelableIntentSuccess) {
callback.onIntentCompleted(mWindowAndroid, mResultCode, intent);
callback.onIntentCompleted(mWindowAndroid, mResultCode, mResults);
return 0;
}
return WindowAndroid.START_INTENT_FAILURE;
}
}
/**
* Test implementation of the {@link AutocompleteController}.
*/
private class LocalTestAutocompleteController extends TestAutocompleteController {
private VoiceResult mVoiceResult;
public LocalTestAutocompleteController(View view, OnSuggestionsReceivedListener listener,
Map<String, List<SuggestionsResult>> suggestions) {
super(view, listener, suggestions);
}
public void setVoiceResult(VoiceResult voiceResult) {
mVoiceResult = voiceResult;
}
@Override
public VoiceResult onVoiceResults(Bundle data) {
return mVoiceResult;
}
}
/**
* Test implementation of {@link AndroidPermissionDelegate}.
*/
......@@ -426,8 +411,8 @@ public class LocationBarVoiceRecognitionHandlerTest {
mDelegate = ThreadUtils.runOnUiThreadBlocking(() -> new TestDelegate());
mHandler = new TestLocationBarVoiceRecognitionHandler(mDelegate);
mPermissionDelegate = new TestAndroidPermissionDelegate();
mAutocomplete = new LocalTestAutocompleteController(null /* view */,
sEmptySuggestionListener, new HashMap<String, List<SuggestionsResult>>());
mAutocomplete = new TestAutocompleteController(null /* view */, sEmptySuggestionListener,
new HashMap<String, List<SuggestionsResult>>());
ThreadUtils.runOnUiThreadBlocking(() -> {
mWindowAndroid = new TestWindowAndroid(mActivityTestRule.getActivity());
......@@ -560,6 +545,7 @@ public class LocationBarVoiceRecognitionHandlerTest {
@Test
@SmallTest
public void testCallback_noVoiceSearchResultWithNullAutocompleteResult() {
mWindowAndroid.setVoiceResults(new Bundle());
startVoiceRecognition(VoiceInteractionSource.SEARCH_WIDGET);
Assert.assertEquals(
VoiceInteractionSource.SEARCH_WIDGET, mHandler.getVoiceSearchStartEventSource());
......@@ -569,29 +555,33 @@ public class LocationBarVoiceRecognitionHandlerTest {
@Test
@SmallTest
public void testCallback_noVoiceSearchResultWithNoMatch() {
mAutocomplete.setVoiceResult(new VoiceResult("", 1.0f));
startVoiceRecognition(VoiceInteractionSource.OMNIBOX);
Assert.assertEquals(
VoiceInteractionSource.OMNIBOX, mHandler.getVoiceSearchStartEventSource());
Assert.assertEquals(false, mHandler.getVoiceSearchResult());
ThreadUtils.runOnUiThreadBlocking(() -> {
mWindowAndroid.setVoiceResults(createDummyBundle("", 1f));
startVoiceRecognition(VoiceInteractionSource.OMNIBOX);
Assert.assertEquals(
VoiceInteractionSource.OMNIBOX, mHandler.getVoiceSearchStartEventSource());
Assert.assertEquals(false, mHandler.getVoiceSearchResult());
});
}
@Test
@SmallTest
public void testCallback_successWithLowConfidence() {
mAutocomplete.setVoiceResult(new VoiceResult("testing",
LocationBarVoiceRecognitionHandler.VOICE_SEARCH_CONFIDENCE_NAVIGATE_THRESHOLD
- 0.01f));
startVoiceRecognition(VoiceInteractionSource.OMNIBOX);
Assert.assertEquals(
VoiceInteractionSource.OMNIBOX, mHandler.getVoiceSearchStartEventSource());
Assert.assertEquals(
VoiceInteractionSource.OMNIBOX, mHandler.getVoiceSearchFinishEventSource());
Assert.assertEquals(true, mHandler.getVoiceSearchResult());
Assert.assertTrue(
LocationBarVoiceRecognitionHandler.VOICE_SEARCH_CONFIDENCE_NAVIGATE_THRESHOLD
- 0.01f
== mHandler.getVoiceConfidenceValue());
ThreadUtils.runOnUiThreadBlocking(() -> {
float confidence =
LocationBarVoiceRecognitionHandler.VOICE_SEARCH_CONFIDENCE_NAVIGATE_THRESHOLD
- 0.01f;
mWindowAndroid.setVoiceResults(createDummyBundle("testing", confidence));
startVoiceRecognition(VoiceInteractionSource.OMNIBOX);
Assert.assertEquals(
VoiceInteractionSource.OMNIBOX, mHandler.getVoiceSearchStartEventSource());
Assert.assertEquals(
VoiceInteractionSource.OMNIBOX, mHandler.getVoiceSearchFinishEventSource());
Assert.assertEquals(true, mHandler.getVoiceSearchResult());
Assert.assertTrue(confidence == mHandler.getVoiceConfidenceValue());
assertVoiceResultsAreEqual(
mAutocompleteVoiceResults, new String[] {"testing"}, new float[] {confidence});
});
}
@Test
......@@ -599,7 +589,7 @@ public class LocationBarVoiceRecognitionHandlerTest {
public void testCallback_successWithHighConfidence() {
// Needs to run on the UI thread because we use the TemplateUrlService on success.
ThreadUtils.runOnUiThreadBlocking(() -> {
mAutocomplete.setVoiceResult(new VoiceResult("testing",
mWindowAndroid.setVoiceResults(createDummyBundle("testing",
LocationBarVoiceRecognitionHandler.VOICE_SEARCH_CONFIDENCE_NAVIGATE_THRESHOLD));
startVoiceRecognition(VoiceInteractionSource.OMNIBOX);
Assert.assertEquals(
......@@ -610,6 +600,84 @@ public class LocationBarVoiceRecognitionHandlerTest {
Assert.assertTrue(
LocationBarVoiceRecognitionHandler.VOICE_SEARCH_CONFIDENCE_NAVIGATE_THRESHOLD
== mHandler.getVoiceConfidenceValue());
assertVoiceResultsAreEqual(mAutocompleteVoiceResults, new String[] {"testing"},
new float[] {LocationBarVoiceRecognitionHandler
.VOICE_SEARCH_CONFIDENCE_NAVIGATE_THRESHOLD});
});
}
@Test
@SmallTest
public void testParseResults_EmptyBundle() {
Assert.assertNull(
LocationBarVoiceRecognitionHandler.convertBundleToVoiceResults(new Bundle()));
}
@Test
@SmallTest
public void testParseResults_MismatchedTextAndConfidenceScores() {
Assert.assertNull(LocationBarVoiceRecognitionHandler.convertBundleToVoiceResults(
createDummyBundle(new String[] {"blah"}, new float[] {0f, 1f})));
Assert.assertNull(LocationBarVoiceRecognitionHandler.convertBundleToVoiceResults(
createDummyBundle(new String[] {"blah", "foo"}, new float[] {7f})));
}
@Test
@SmallTest
public void testParseResults_ValidBundle() {
ThreadUtils.runOnUiThreadBlocking(() -> {
String[] texts = new String[] {"a", "b", "c"};
float[] confidences = new float[] {0.8f, 1.0f, 1.0f};
List<VoiceResult> results =
LocationBarVoiceRecognitionHandler.convertBundleToVoiceResults(
createDummyBundle(texts, confidences));
assertVoiceResultsAreEqual(results, texts, confidences);
});
}
@Test
@SmallTest
public void testParseResults_VoiceResponseURLConversion() {
ThreadUtils.runOnUiThreadBlocking(() -> {
String[] texts =
new String[] {"a", "www. b .co .uk", "engadget .com", "www.google.com"};
float[] confidences = new float[] {1.0f, 1.0f, 1.0f, 1.0f};
List<VoiceResult> results =
LocationBarVoiceRecognitionHandler.convertBundleToVoiceResults(
createDummyBundle(texts, confidences));
assertVoiceResultsAreEqual(results,
new String[] {"a", "www.b.co.uk", "engadget.com", "www.google.com"},
new float[] {1.0f, 1.0f, 1.0f, 1.0f});
});
}
private static Bundle createDummyBundle(String text, float confidence) {
return createDummyBundle(new String[] {text}, new float[] {confidence});
}
private static Bundle createDummyBundle(String[] texts, float[] confidences) {
Bundle b = new Bundle();
b.putStringArrayList(
RecognizerIntent.EXTRA_RESULTS, new ArrayList<String>(Arrays.asList(texts)));
b.putFloatArray(RecognizerIntent.EXTRA_CONFIDENCE_SCORES, confidences);
return b;
}
private static void assertVoiceResultsAreEqual(
List<VoiceResult> results, String[] texts, float[] confidences) {
Assert.assertTrue("Invalid array sizes",
results.size() == texts.length && texts.length == confidences.length);
for (int i = 0; i < texts.length; ++i) {
VoiceResult result = results.get(i);
Assert.assertEquals("Match text is not equal", texts[i], result.getMatch());
Assert.assertEquals(
"Confidence is not equal", confidences[i], result.getConfidence(), 0);
}
}
}
......@@ -2,10 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.omnibox;
package org.chromium.chrome.browser.omnibox.suggestions;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.support.test.rule.UiThreadTestRule;
......@@ -19,18 +17,18 @@ import org.junit.runner.RunWith;
import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.omnibox.VoiceSuggestionProvider.VoiceResult;
import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion;
import org.chromium.chrome.browser.omnibox.LocationBarVoiceRecognitionHandler.VoiceResult;
import org.chromium.chrome.browser.omnibox.MatchClassificationStyle;
import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType;
import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion.MatchClassification;
import org.chromium.chrome.browser.test.ChromeBrowserTestRule;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Test the {@link VoiceSuggestionProvider} class through simulating omnibox results and voice
* recognition result bundles.
* recognition results.
*/
@RunWith(BaseJUnit4ClassRunner.class)
public class VoiceSuggestionProviderTest {
......@@ -41,20 +39,9 @@ public class VoiceSuggestionProviderTest {
private static OmniboxSuggestion createDummySuggestion(String text) {
List<MatchClassification> classifications = new ArrayList<>();
classifications.add(new MatchClassification(0, MatchClassificationStyle.NONE));
return new OmniboxSuggestion(OmniboxSuggestionType.SEARCH_SUGGEST,
true,
0,
1,
text,
classifications,
null,
classifications,
null,
null,
"",
"http://www.google.com",
false,
false);
return new OmniboxSuggestion(OmniboxSuggestionType.SEARCH_SUGGEST, true, 0, 1, text,
classifications, null, classifications, null, null, "", "http://www.google.com",
false, false);
}
private static List<OmniboxSuggestion> createDummySuggestions(String... texts) {
......@@ -66,27 +53,12 @@ public class VoiceSuggestionProviderTest {
return suggestions;
}
private static Bundle createDummyBundle(String[] texts, float[] confidences) {
Bundle b = new Bundle();
b.putStringArrayList(RecognizerIntent.EXTRA_RESULTS, new ArrayList<String>(
Arrays.asList(texts)));
b.putFloatArray(RecognizerIntent.EXTRA_CONFIDENCE_SCORES, confidences);
return b;
}
private static void assertVoiceResultsAreEqual(List<VoiceResult> results, String[] texts,
float[] confidences) {
Assert.assertTrue("Invalid array sizes",
results.size() == texts.length && texts.length == confidences.length);
for (int i = 0; i < texts.length; ++i) {
VoiceResult result = results.get(i);
Assert.assertEquals("Match text is not equal", texts[i], result.getMatch());
Assert.assertEquals(
"Confidence is not equal", confidences[i], result.getConfidence(), 0);
private static List<VoiceResult> createVoiceResults(String[] texts, float[] confidences) {
List<VoiceResult> results = new ArrayList<>();
for (int i = 0; i < texts.length; i++) {
results.add(new VoiceResult(texts[i], confidences[i]));
}
return results;
}
private static boolean assertSuggestionMatchesVoiceResult(OmniboxSuggestion a, VoiceResult b) {
......@@ -105,8 +77,8 @@ public class VoiceSuggestionProviderTest {
}
}
private void assertArrayEndsWith(List<OmniboxSuggestion> a, List<VoiceResult> b,
int expectedResultCount) {
private void assertArrayEndsWith(
List<OmniboxSuggestion> a, List<VoiceResult> b, int expectedResultCount) {
Assert.assertTrue((a != null && b != null) || (a == null && b == null));
if (a == null || b == null) return;
......@@ -119,8 +91,8 @@ public class VoiceSuggestionProviderTest {
}
}
private boolean isVoiceResultInSuggestions(List<OmniboxSuggestion> suggestions,
VoiceResult result) {
private boolean isVoiceResultInSuggestions(
List<OmniboxSuggestion> suggestions, VoiceResult result) {
for (OmniboxSuggestion suggestion : suggestions) {
if (assertSuggestionMatchesVoiceResult(suggestion, result)) return true;
}
......@@ -128,37 +100,6 @@ public class VoiceSuggestionProviderTest {
return false;
}
@Test
@SmallTest
@UiThreadTest
@Feature({"Omnibox"})
public void testParseEmptyBundle() {
VoiceSuggestionProvider provider = new VoiceSuggestionProvider(0.0f, 1.1f);
provider.setVoiceResultsFromIntentBundle(new Bundle());
Assert.assertNotNull("Results is null", provider.getResults());
Assert.assertEquals(
"SuggestionProvider added invalid results", 0, provider.getResults().size());
provider.addVoiceSuggestions(null, 3);
}
@Test
@SmallTest
@UiThreadTest
@Feature({"Omnibox"})
public void testParseBundle() {
VoiceSuggestionProvider provider = new VoiceSuggestionProvider(0.0f, 1.1f);
String[] texts = new String[] {"a", "b", "c"};
float[] confidences = new float[] {0.8f, 1.0f, 1.0f};
provider.setVoiceResultsFromIntentBundle(createDummyBundle(texts, confidences));
assertVoiceResultsAreEqual(provider.getResults(), texts, confidences);
}
@Test
@SmallTest
@UiThreadTest
......@@ -180,7 +121,7 @@ public class VoiceSuggestionProviderTest {
String[] texts = new String[] {"a", "b", "c"};
float[] confidences = new float[] {1.0f, 0.99f, 0.98f};
provider.setVoiceResultsFromIntentBundle(createDummyBundle(texts, confidences));
provider.setVoiceResults(createVoiceResults(texts, confidences));
Assert.assertNotNull(provider.getResults());
Assert.assertEquals(
......@@ -201,8 +142,7 @@ public class VoiceSuggestionProviderTest {
String[] texts = new String[] {"a", "b", "c"};
float[] confidences = new float[] {1.0f, 1.0f, 1.0f};
provider.setVoiceResultsFromIntentBundle(createDummyBundle(texts, confidences));
assertVoiceResultsAreEqual(provider.getResults(), texts, confidences);
provider.setVoiceResults(createVoiceResults(texts, confidences));
List<OmniboxSuggestion> suggestions = provider.addVoiceSuggestions(null, texts.length);
assertArrayEndsWith(suggestions, provider.getResults(), texts.length);
}
......@@ -217,8 +157,7 @@ public class VoiceSuggestionProviderTest {
String[] texts = new String[] {"a", "b", "c"};
float[] confidences = new float[] {1.0f, 1.0f, 1.0f};
provider.setVoiceResultsFromIntentBundle(createDummyBundle(texts, confidences));
assertVoiceResultsAreEqual(provider.getResults(), texts, confidences);
provider.setVoiceResults(createVoiceResults(texts, confidences));
List<OmniboxSuggestion> suggestions = provider.addVoiceSuggestions(null, 2);
assertArrayEndsWith(suggestions, provider.getResults(), 2);
......@@ -233,7 +172,7 @@ public class VoiceSuggestionProviderTest {
String[] texts = new String[] {"a", "b", "c"};
float[] confidences = new float[] {1.0f, 1.0f, 1.0f};
provider.setVoiceResultsFromIntentBundle(createDummyBundle(texts, confidences));
provider.setVoiceResults(createVoiceResults(texts, confidences));
List<OmniboxSuggestion> suggestions = createDummySuggestions("oa", "ob", "oc");
List<OmniboxSuggestion> updatedSuggestions =
......@@ -253,7 +192,7 @@ public class VoiceSuggestionProviderTest {
String[] texts = new String[] {"a", "b", "c"};
float[] confidences = new float[] {1.0f, 1.0f, 1.0f};
provider.setVoiceResultsFromIntentBundle(createDummyBundle(texts, confidences));
provider.setVoiceResults(createVoiceResults(texts, confidences));
List<OmniboxSuggestion> suggestions = createDummySuggestions("oa", "ob", "oc");
List<OmniboxSuggestion> updatedSuggestions = provider.addVoiceSuggestions(suggestions, 2);
......@@ -271,7 +210,7 @@ public class VoiceSuggestionProviderTest {
String[] texts = new String[] {"a", "b", "c"};
float[] confidences = new float[] {1.0f, 1.0f, 1.0f};
provider.setVoiceResultsFromIntentBundle(createDummyBundle(texts, confidences));
provider.setVoiceResults(createVoiceResults(texts, confidences));
List<OmniboxSuggestion> suggestions = createDummySuggestions("oa", "b", "oc");
List<OmniboxSuggestion> updatedSuggestions =
......@@ -297,7 +236,7 @@ public class VoiceSuggestionProviderTest {
String[] texts = new String[] {"a", "b", "c"};
float[] confidences = new float[] {1.0f, 0.6f, 0.3f};
provider.setVoiceResultsFromIntentBundle(createDummyBundle(texts, confidences));
provider.setVoiceResults(createVoiceResults(texts, confidences));
List<OmniboxSuggestion> suggestions = createDummySuggestions("oa", "ob", "oc");
List<OmniboxSuggestion> updatedSuggestions =
......@@ -323,7 +262,7 @@ public class VoiceSuggestionProviderTest {
String[] texts = new String[] {"a", "b", "c"};
float[] confidences = new float[] {0.8f, 1.0f, 1.0f};
provider.setVoiceResultsFromIntentBundle(createDummyBundle(texts, confidences));
provider.setVoiceResults(createVoiceResults(texts, confidences));
List<OmniboxSuggestion> suggestions = createDummySuggestions("oa", "ob", "oc");
List<OmniboxSuggestion> updatedSuggestions =
......@@ -339,20 +278,4 @@ public class VoiceSuggestionProviderTest {
Assert.assertFalse("Result 'c' was found.",
isVoiceResultInSuggestions(updatedSuggestions, provider.getResults().get(2)));
}
@Test
@SmallTest
@UiThreadTest
@Feature({"Omnibox"})
public void testVoiceResponseURLConversion() {
VoiceSuggestionProvider provider = new VoiceSuggestionProvider();
String[] texts = new String[] {"a", "www. b .co .uk", "engadget .com", "www.google.com"};
float[] confidences = new float[] {1.0f, 1.0f, 1.0f, 1.0f};
provider.setVoiceResultsFromIntentBundle(createDummyBundle(texts, confidences));
assertVoiceResultsAreEqual(provider.getResults(),
new String[] {"a", "www.b.co.uk", "engadget.com", "www.google.com"},
new float[] {1.0f, 1.0f, 1.0f, 1.0f});
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment