Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(405)

Unified Diff: components/omnibox/browser/physical_web_provider.cc

Issue 2203993002: Add a Physical Web omnibox autocomplete provider (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: almost done Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/omnibox/browser/physical_web_provider.cc
diff --git a/components/omnibox/browser/physical_web_provider.cc b/components/omnibox/browser/physical_web_provider.cc
new file mode 100644
index 0000000000000000000000000000000000000000..cb73722e61cfc784eb30df1fdb8b2e9e1945919d
--- /dev/null
+++ b/components/omnibox/browser/physical_web_provider.cc
@@ -0,0 +1,155 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/ptr_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "components/omnibox/browser/autocomplete_provider_client.h"
+#include "components/omnibox/browser/autocomplete_provider_listener.h"
+#include "components/omnibox/browser/physical_web_provider.h"
+#include "components/physical_web/data_source/physical_web_data_source.h"
+#include "components/url_formatter/url_formatter.h"
+#include "grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
+
+namespace {
+
+// The maximum number of match results to provide. If the number of nearby URLs
+// exceeds this limit, an overflow item is created. Tapping the overflow item
+// navigates to a page with the full list of nearby URLs. The overflow item is
+// counted as a match result for the purposes of the match limit.
+//
+// ex: With kPhysicalWebMaxMatches == 1, there should be at most one suggestion
+// created by this provider. If there is a single nearby URL, then the
+// suggestion will be for that URL. If there are multiple nearby URLs, the
+// suggestion will be the overflow item which navigates to the WebUI when
+// tapped.
+static const size_t kPhysicalWebMaxMatches = 1;
+
+// Relevance score of the first Physical Web URL autocomplete match. This score
+// is intended to be between ClipboardURLProvider and ZeroSuggestProvider.
+// Subsequent matches should decrease in relevance to preserve the ordering
+// in the metadata list.
+static const int kPhysicalWebUrlBaseRelevance = 700;
+
+}
+
+// static
+PhysicalWebProvider* PhysicalWebProvider::Create(
+ AutocompleteProviderClient* client) {
+ return new PhysicalWebProvider(client);
+}
+
+void PhysicalWebProvider::Start(const AutocompleteInput& input,
+ bool minimal_changes) {
+ DCHECK(kPhysicalWebMaxMatches < kMaxMatches);
+
+ Stop(false, false);
+
+ done_ = false;
+ matches_.clear();
+
+ // Stop providing suggestions when the user enters text into the omnibox.
+ if (!input.from_omnibox_focus()) {
+ done_ = true;
+ return;
+ }
+
+ PhysicalWebDataSource* data_source = client_->GetPhysicalWebDataSource();
+ if (!data_source) {
+ done_ = true;
+ return;
+ }
+
+ ConstructMatches(data_source->GetMetadata().get());
+
+ done_ = true;
+}
+
+void PhysicalWebProvider::Stop(bool clear_cached_results,
+ bool due_to_user_inactivity) {
+ done_ = true;
+}
+
+PhysicalWebProvider::PhysicalWebProvider(AutocompleteProviderClient* client)
+ : AutocompleteProvider(AutocompleteProvider::TYPE_PHYSICAL_WEB),
+ client_(client) {
+}
+
+PhysicalWebProvider::~PhysicalWebProvider() {
+}
+
+void PhysicalWebProvider::ConstructMatches(base::ListValue* metadata_list) {
+ const size_t metadata_count = metadata_list->GetSize();
+
+ for (size_t i = 0; i < metadata_count; ++i) {
+ base::DictionaryValue* metadata_item = NULL;
+ if (!metadata_list->GetDictionary(i, &metadata_item)) {
+ continue;
+ }
+
+ std::string url_string;
+ std::string title_string;
+ if (!metadata_item->GetString("resolvedUrl", &url_string) ||
+ !metadata_item->GetString("title", &title_string)) {
+ continue;
+ }
+
+ // Add match items with decreasing relevance to preserve the ordering in
+ // the metadata list.
+ int relevance = kPhysicalWebUrlBaseRelevance - matches_.size();
+
+ // Append an overflow item if creating a match for each metadata item would
+ // exceed the match limit.
+ const size_t remaining_slots = kPhysicalWebMaxMatches - matches_.size();
+ const size_t remaining_metadata = metadata_count - i;
+ if ((remaining_slots == 1) && (remaining_metadata > remaining_slots)) {
+ AppendOverflowItem(remaining_metadata, relevance);
+ return;
+ }
+
+ GURL url(url_string);
+ base::string16 title = base::UTF8ToUTF16(title_string);
+
+ AutocompleteMatch match(this, relevance, false,
+ AutocompleteMatchType::PHYSICAL_WEB);
+ match.destination_url = url;
+
+ // Physical Web results should omit http:// (but not https://) and never
+ // appear bold.
+ match.contents = url_formatter::FormatUrl(url,
+ url_formatter::kFormatUrlOmitHTTP, net::UnescapeRule::SPACES,
+ nullptr, nullptr, nullptr);
+ match.contents_class.push_back(
+ ACMatchClassification(0, ACMatchClassification::URL));
+
+ match.fill_into_edit =
+ AutocompleteInput::FormattedStringWithEquivalentMeaning(
+ url, match.contents, client_->GetSchemeClassifier());
+
+ match.description = AutocompleteMatch::SanitizeString(title);
+ match.description_class.push_back(
+ ACMatchClassification(0, ACMatchClassification::NONE));
+
+ match.allowed_to_be_default_match = matches_.empty();
+
+ matches_.push_back(match);
+ }
+}
+
+void PhysicalWebProvider::AppendOverflowItem(int additional_url_count,
+ int relevance) {
+ AutocompleteMatch match(this, relevance, false,
+ AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW);
+ match.destination_url = GURL("chrome://physical-web");
+ match.description = l10n_util::GetPluralStringFUTF16(
+ IDS_PHYSICAL_WEB_OVERFLOW, additional_url_count);
+ match.description_class.push_back(
+ ACMatchClassification(0, ACMatchClassification::NONE));
+
+ match.allowed_to_be_default_match = matches_.empty();
+
+ matches_.push_back(match);
+}

Powered by Google App Engine
This is Rietveld 408576698