blob: 8bddb9f800a61188e89b82358716c288252c4cec [file] [log] [blame]
sdefresne70948d62015-08-11 10:46:351// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "components/omnibox/browser/clipboard_url_provider.h"
6
mpearsonea5016a2017-06-01 22:20:327#include <algorithm>
8
gcomanici8cabc77f2017-04-27 20:04:549#include "base/feature_list.h"
sdefresne70948d62015-08-11 10:46:3510#include "base/logging.h"
Ilya Sherman1edb6f182017-12-12 04:00:4211#include "base/metrics/histogram_functions.h"
mpearsonab3761492017-03-31 17:29:5112#include "base/metrics/histogram_macros.h"
sdefresne70948d62015-08-11 10:46:3513#include "base/strings/utf_string_conversions.h"
14#include "components/omnibox/browser/autocomplete_input.h"
15#include "components/omnibox/browser/autocomplete_provider_client.h"
gcomanici8cabc77f2017-04-27 20:04:5416#include "components/omnibox/browser/omnibox_field_trial.h"
sdefresne70948d62015-08-11 10:46:3517#include "components/omnibox/browser/verbatim_match.h"
18#include "components/open_from_clipboard/clipboard_recent_content.h"
thakisfe8fa0a2017-02-23 19:46:3619#include "components/strings/grit/components_strings.h"
sdefresne70948d62015-08-11 10:46:3520#include "components/url_formatter/url_formatter.h"
sdefresne70948d62015-08-11 10:46:3521#include "ui/base/l10n/l10n_util.h"
22
23ClipboardURLProvider::ClipboardURLProvider(
24 AutocompleteProviderClient* client,
mpearson931028c2016-07-01 18:55:1125 HistoryURLProvider* history_url_provider,
sdefresne70948d62015-08-11 10:46:3526 ClipboardRecentContent* clipboard_content)
27 : AutocompleteProvider(AutocompleteProvider::TYPE_CLIPBOARD_URL),
28 client_(client),
mpearson931028c2016-07-01 18:55:1129 clipboard_content_(clipboard_content),
mpearsonea5016a2017-06-01 22:20:3230 history_url_provider_(history_url_provider),
31 current_url_suggested_times_(0) {
sdefresne70948d62015-08-11 10:46:3532 DCHECK(clipboard_content_);
33}
34
35ClipboardURLProvider::~ClipboardURLProvider() {}
36
37void ClipboardURLProvider::Start(const AutocompleteInput& input,
38 bool minimal_changes) {
39 matches_.clear();
jif3986ea502016-07-13 13:43:4240
41 // If the user started typing, do not offer clipboard based match.
sdefresne70948d62015-08-11 10:46:3542 if (!input.from_omnibox_focus())
43 return;
44
45 GURL url;
mpearsonea5016a2017-06-01 22:20:3246 // The clipboard does not contain a URL worth suggesting.
47 if (!clipboard_content_->GetRecentURLFromClipboard(&url)) {
48 current_url_suggested_ = GURL();
49 current_url_suggested_times_ = 0;
50 return;
51 }
52 // The URL on the page is the same as the URL in the clipboard. Don't
53 // bother suggesting it.
54 if (url == input.current_url())
sdefresne70948d62015-08-11 10:46:3555 return;
56
57 DCHECK(url.is_valid());
jif3986ea502016-07-13 13:43:4258 // If the omnibox is not empty, add a default match.
59 // This match will be opened when the user presses "Enter".
60 if (!input.text().empty()) {
gcomanici8cabc77f2017-04-27 20:04:5461 const base::string16 description =
62 (base::FeatureList::IsEnabled(omnibox::kDisplayTitleForCurrentUrl))
63 ? input.current_title()
64 : base::string16();
65 AutocompleteMatch verbatim_match =
66 VerbatimMatchForURL(client_, input, input.current_url(), description,
67 history_url_provider_, -1);
sdefresne70948d62015-08-11 10:46:3568 matches_.push_back(verbatim_match);
jif3986ea502016-07-13 13:43:4269 }
mpearsonab3761492017-03-31 17:29:5170 UMA_HISTOGRAM_BOOLEAN("Omnibox.ClipboardSuggestionShownWithCurrentURL",
71 !matches_.empty());
mpearsond3dcdb02017-04-08 01:11:0372 UMA_HISTOGRAM_LONG_TIMES_100("Omnibox.ClipboardSuggestionShownAge",
73 clipboard_content_->GetClipboardContentAge());
mpearsonea5016a2017-06-01 22:20:3274 // Record the number of times the currently-offered URL has been suggested.
75 // This only works over this run of Chrome; if the URL was in the clipboard
76 // on a previous run, those offerings will not be counted.
77 if (url == current_url_suggested_) {
78 current_url_suggested_times_++;
79 } else {
80 current_url_suggested_ = url;
81 current_url_suggested_times_ = 1;
82 }
Ilya Sherman1edb6f182017-12-12 04:00:4283 base::UmaHistogramSparse(
mpearsonea5016a2017-06-01 22:20:3284 "Omnibox.ClipboardSuggestionShownNumTimes",
85 std::min(current_url_suggested_times_, static_cast<size_t>(20)));
sdefresne70948d62015-08-11 10:46:3586
jif3986ea502016-07-13 13:43:4287 // Add the clipboard match. The relevance is 800 to beat ZeroSuggest results.
88 AutocompleteMatch match(this, 800, false, AutocompleteMatchType::CLIPBOARD);
sdefresne70948d62015-08-11 10:46:3589 match.destination_url = url;
Tommy C. Lic68f2e42017-12-19 20:43:4590 // Because the user did not type a related input to get this clipboard
91 // suggestion, preserve the path and subdomain so the user has extra context.
92 auto format_types = AutocompleteMatch::GetFormatTypes(false, true, true);
tommycli72014f62017-06-29 21:42:1693 match.contents.assign(url_formatter::FormatUrl(
94 url, format_types, net::UnescapeRule::SPACES, nullptr, nullptr, nullptr));
sdefresne70948d62015-08-11 10:46:3595 AutocompleteMatch::ClassifyLocationInString(
96 base::string16::npos, 0, match.contents.length(),
97 ACMatchClassification::URL, &match.contents_class);
98
99 match.description.assign(l10n_util::GetStringUTF16(IDS_LINK_FROM_CLIPBOARD));
100 AutocompleteMatch::ClassifyLocationInString(
101 base::string16::npos, 0, match.description.length(),
102 ACMatchClassification::NONE, &match.description_class);
103
sdefresne70948d62015-08-11 10:46:35104 matches_.push_back(match);
105}
mpearsonea5016a2017-06-01 22:20:32106
107void ClipboardURLProvider::AddProviderInfo(ProvidersInfo* provider_info) const {
108 // If a URL wasn't suggested on this most recent focus event, don't bother
109 // setting |times_returned_results_in_session|, as in effect this URL has
110 // never been suggested during the current session. (For the purpose of
111 // this provider, we define a session as intervals between when a URL
112 // clipboard suggestion changes.)
113 if (current_url_suggested_times_ == 0)
114 return;
115 provider_info->push_back(metrics::OmniboxEventProto_ProviderInfo());
116 metrics::OmniboxEventProto_ProviderInfo& new_entry = provider_info->back();
117 new_entry.set_provider(AsOmniboxEventProviderType());
118 new_entry.set_times_returned_results_in_session(current_url_suggested_times_);
119}