1 // 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 #ifndef COMPONENTS_OMNIBOX_BROWSER_CLIPBOARD_PROVIDER_H_
6 #define COMPONENTS_OMNIBOX_BROWSER_CLIPBOARD_PROVIDER_H_
7 
8 #include "base/gtest_prod_util.h"
9 #include "components/omnibox/browser/autocomplete_provider.h"
10 #include "components/omnibox/browser/history_url_provider.h"
11 
12 class AutocompleteProviderClient;
13 class ClipboardRecentContent;
14 class HistoryURLProvider;
15 enum class ClipboardContentType;
16 
17 // Autocomplete provider offering content based on the clipboard's content.
18 class ClipboardProvider : public AutocompleteProvider {
19  public:
20   ClipboardProvider(AutocompleteProviderClient* client,
21                     AutocompleteProviderListener* listener,
22                     HistoryURLProvider* history_url_provider,
23                     ClipboardRecentContent* clipboard_content);
24 
25   ClipboardProvider(const ClipboardProvider&) = delete;
26   ClipboardProvider& operator=(const ClipboardProvider&) = delete;
27 
28   // Returns a new AutocompleteMatch clipboard match that will navigate to the
29   // given copied url. Used to construct a match later when the URL is not
30   // available at match creation time (e.g. iOS 14).
31   AutocompleteMatch NewClipboardURLMatch(GURL url);
32   // Returns a new AutocompleteMatch clipboard match that will search for the
33   // given copied text. Used to construct a match later when the text is not
34   // available at match creation time (e.g. iOS 14).
35   base::Optional<AutocompleteMatch> NewClipboardTextMatch(base::string16 text);
36 
37   using ClipboardImageMatchCallback =
38       base::OnceCallback<void(base::Optional<AutocompleteMatch>)>;
39   // Returns a new AutocompleteMatch clipboard match that will search for the
40   // given copied image. Used to construct a match later when the image is not
41   // available at match creation time (e.g. iOS 14).
42   void NewClipboardImageMatch(gfx::Image image,
43                               ClipboardImageMatchCallback callback);
44 
45   // AutocompleteProvider implementation.
46   void Start(const AutocompleteInput& input, bool minimal_changes) override;
47   void Stop(bool clear_cached_results, bool due_to_user_inactivity) override;
48   void DeleteMatch(const AutocompleteMatch& match) override;
49   void AddProviderInfo(ProvidersInfo* provider_info) const override;
50   void ResetSession() override;
51 
52  private:
53   FRIEND_TEST_ALL_PREFIXES(ClipboardProviderTest, MatchesImage);
54 
55   ~ClipboardProvider() override;
56 
57   // Handle the match created from one of the match creation methods and do
58   // extra tracking and match adding.
59   void AddCreatedMatchWithTracking(
60       const AutocompleteInput& input,
61       const AutocompleteMatch& match,
62       const base::TimeDelta clipboard_contents_age);
63 
64   // Uses asynchronous clipboard APIs to check which content types have
65   // clipboard data without actually accessing the data. If any do, then one
66   // clipboard match is created. Calls back to |OnReceiveClipboardContent| with
67   // the result.
68   void CheckClipboardContent(const AutocompleteInput& input);
69   // Called when the clipboard data is returned from the asynchronous call.
70   void OnReceiveClipboardContent(const AutocompleteInput& input,
71                                  base::TimeDelta clipboard_contents_age,
72                                  std::set<ClipboardContentType> matched_types);
73 
74   // Checks whether the current template url supports text searches.
75   bool TemplateURLSupportsTextSearch();
76   // Checks whether the current template url supports image searches.
77   bool TemplateURLSupportsImageSearch();
78 
79   // Returns a URL match with no URL. This can be used if the clipboard content
80   // is inaccessible at match creation time (e.g. iOS 14).
81   AutocompleteMatch NewBlankURLMatch();
82 
83   // Returns a text match with no text. This can be used if the clipboard
84   // content is inaccessible at match creation time (e.g. iOS 14).
85   AutocompleteMatch NewBlankTextMatch();
86 
87   // Returns a image match with no attached image. This can be used if the
88   // clipboard content is inaccessible at match creation time (e.g. iOS 14).
89   AutocompleteMatch NewBlankImageMatch();
90 
91   // If there is a url copied to the clipboard and accessing it will not show a
92   // clipboard access notification (e.g. iOS 14), use it to create a match.
93   // |read_clipboard_content| will be filled with false if the clipboard didn't
94   // have any content (either because there was none or because accessing it
95   // would have shown a clipboard access notification, and true if there was
96   // content.
97   base::Optional<AutocompleteMatch> CreateURLMatch(
98       const AutocompleteInput& input,
99       bool* read_clipboard_content);
100   // If there is text copied to the clipboard and accessing it will not show a
101   // clipboard access notification (e.g. iOS 14), use it to create a match.
102   // |read_clipboard_content| will be filled with false if the clipboard didn't
103   // have any content (either because there was none or because accessing it
104   // would have shown a clipboard access notification, and true if there was
105   // content.
106   base::Optional<AutocompleteMatch> CreateTextMatch(
107       const AutocompleteInput& input,
108       bool* read_clipboard_content);
109   // If there is an image copied to the clipboard and accessing it will not show
110   // a clipboard access notification (e.g. iOS 14), use it to create a match.
111   // The image match is asynchronous (because constructing the image post data
112   // takes time), so instead of returning an optional match like the other
113   // Create functions, it returns a boolean indicating whether there will be a
114   // match.
115   bool CreateImageMatch(const AutocompleteInput& input);
116 
117   // Handles the callback response from |CreateImageMatch| and turns the image
118   // into an AutocompleteMatch.
119   void CreateImageMatchCallback(const AutocompleteInput& input,
120                                 const base::TimeDelta clipboard_contents_age,
121                                 base::Optional<gfx::Image>);
122   // Handles the callback response from |CreateImageMatchCallback| and adds the
123   // created AutocompleteMatch to the matches list.
124   void AddImageMatchCallback(const AutocompleteInput& input,
125                              const base::TimeDelta clipboard_contents_age,
126                              base::Optional<AutocompleteMatch> match);
127 
128   // Called when image data is received from clipboard.
129   void OnReceiveImage(ClipboardImageMatchCallback callback,
130                       base::Optional<gfx::Image> optional_image);
131 
132   // Resize and encode the image data into bytes. This can take some time if the
133   // image is large, so this should happen on a background thread.
134   static scoped_refptr<base::RefCountedMemory> EncodeClipboardImage(
135       gfx::ImageSkia image);
136   // Construct the actual image match once the image has been encoded into
137   // bytes. This should be called back on the main thread.
138   void ConstructImageMatchCallback(
139       ClipboardImageMatchCallback callback,
140       scoped_refptr<base::RefCountedMemory> image_bytes);
141 
142   AutocompleteProviderClient* client_;
143   AutocompleteProviderListener* listener_;
144   ClipboardRecentContent* clipboard_content_;
145 
146   // Used for efficiency when creating the verbatim match.  Can be NULL.
147   HistoryURLProvider* history_url_provider_;
148 
149   // The current URL suggested and the number of times it has been offered.
150   // Used for recording metrics.
151   GURL current_url_suggested_;
152   size_t current_url_suggested_times_;
153 
154   // Whether a field trial has triggered for this query and this session,
155   // respectively. Works similarly to BaseSearchProvider, though this class does
156   // not inherit from it.
157   bool field_trial_triggered_;
158   bool field_trial_triggered_in_session_;
159 
160   // Used to cancel image construction callbacks if autocomplete Stop() is
161   // called.
162   base::WeakPtrFactory<ClipboardProvider> callback_weak_ptr_factory_{this};
163 };
164 
165 #endif  // COMPONENTS_OMNIBOX_BROWSER_CLIPBOARD_PROVIDER_H_
166