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",
......
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