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

Side by Side Diff: chrome/browser/installable/installable_checker.h

Issue 2160513002: Extract AppBannerDataFetcher into an InstallableManager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressing reviewer comments Created 4 years, 5 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/installable/OWNERS ('k') | chrome/browser/installable/installable_checker.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 CHROME_BROWSER_INSTALLABLE_INSTALLABLE_CHECKER_H_
6 #define CHROME_BROWSER_INSTALLABLE_INSTALLABLE_CHECKER_H_
7
8 #include <utility>
9
10 #include "base/callback_forward.h"
11 #include "base/gtest_prod_util.h"
12 #include "base/macros.h"
13 #include "base/memory/weak_ptr.h"
14 #include "chrome/browser/installable/installable_logging.h"
15 #include "content/public/browser/web_contents_observer.h"
16 #include "content/public/browser/web_contents_user_data.h"
17 #include "content/public/common/manifest.h"
18 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "url/gurl.h"
20
21 namespace installable {
benwells 2016/07/21 06:52:47 Do we need the namespace? All the classes in this
dominickn 2016/07/21 09:13:38 Removed.
22
23 // This struct specifies the work to be done by the InstallableChecker on the
24 // site loaded in the main frame of the WebContents to which it is attached.
25 // Results are cached and evaluated the order specified in this struct; if any
26 // previous step is requested and fails, no further steps will be performed.
27 // For example, if |check_valid_icon| and |check_service_worker| are both true,
28 // then the site's icon will only be fetched if a service worker was found.
29 // The checker will *always* look for a web app manifest first as this is
30 // required for all other resources.
benwells 2016/07/21 06:52:47 This confused me. Maybe instead of putting this co
dominickn 2016/07/21 09:13:38 Thinned.
31 struct InstallableParams {
32 // The ideal icon size that should be fetched. Used only if |check_valid_icon|
33 // is true.
34 int ideal_icon_size_in_dp;
35
36 // The minimum icon size that should be fetched. Used only if
37 // |check_valid_icon| is true.
38 int minimum_icon_size_in_dp;
39
40 // Check whether the site's manifest is valid for a web app. That is, the
41 // manifest:
42 // - is non-empty
43 // - has a valid start URL
44 // - has a non-null name OR a non-null short_name
45 // - has a display field set to "standalone" or "fullscreen"
46 // - contains a PNG icon of at least 144x144px
47 bool check_valid_webapp_manifest;
48
49 // Check whether the site has an active service worker controlling it and the
50 // manifest start URL.
51 bool check_service_worker;
52
53 // Check whether there is an icon in the manifest conforming to the icon size
54 // parameters, and that the icon can be fetched and isn't an empty bitmap.
benwells 2016/07/21 06:52:47 The icon size checking seems a bit confusing. Why
dominickn 2016/07/21 09:13:38 The 144px is a minimum, but platforms may want a h
55 bool check_valid_icon;
56
57 // The default constructor sets all bool parameters are set to false.
benwells 2016/07/21 06:52:47 Wanna just use defaults on the parameters instead
dominickn 2016/07/21 09:13:38 Done.
58 InstallableParams();
59 };
60
61 // This struct is passed to an InstallableCallback when the InstallableChecker
benwells 2016/07/21 06:52:47 So the InstallableChecker is also an InstallableIn
62 // has finished working. Each pointer/reference member is a reference to the
63 // data in InstallableChecker; the checker owns these resources, and callers
64 // should copy any which they wish to use later.
65 // Fields which were not requested by callers will be set to null, empty, or
66 // false objects when the callback is invoked.
67 struct InstallableResult {
68 // NO_ERROR if there were no issues.
69 const ErrorCode error_code;
70
71 // The manifest URL. If non-empty, the site specified a <link rel="manifest">
72 // tag.
73 const GURL& manifest_url;
74
75 // The manifest object. Empty if a manifest was not specified, or could not be
76 // parsed.
77 const content::Manifest& manifest;
78
79 // The URL of the most appropriate icon from the manifest. Empty if no icon
80 // was requested.
81 const GURL& icon_url;
82
83 // The most appropriate icon from the manifest. nullptr if no icon was
84 // requested.
85 const SkBitmap* icon;
86
87 // True if the site has a manifest which is valid for a webapp. False if the
88 // manifest isn't valid for a webapp, or this check wasn't requested.
89 const bool has_valid_webapp_manifest;
90
91 // True if the site has a service worker controlling the manifest start URL.
92 // False if there is no such service worker, or this check wasn't requested.
93 const bool has_service_worker;
94 };
95
96 // The callback type passed to InstallableChecker::Start. Invoked on the UI
97 // thread once the checker has performed all of the operations specified in the
98 // InstallableParams passed to Start.
99 using InstallableCallback = base::Callback<void(const InstallableResult&)>;
benwells 2016/07/21 06:52:47 Can we split this out into two callbacks / functio
dominickn 2016/07/21 09:13:38 I think this comment is redundant based on the red
100
101 // This class is responsible for fetching the resources required to check and
102 // install a site. Minimally, this is a web app manifest for the document in the
103 // main frame; this manifest is all that is required for a site offering native
104 // app banners. Progressive web apps must have specific fields in the manifest
105 // set, a service worker controlling the manifest's start URL, and a valid,
106 // fetchable icon in the manifest. Sites which do not have a service worker may
107 // still specify a valid, fetchable icon in the manifest, and this will be used
108 // when the site is added to homescreen.
109 class InstallableChecker
110 : public content::WebContentsObserver,
111 public content::WebContentsUserData<InstallableChecker> {
112 public:
113 explicit InstallableChecker(content::WebContents* web_contents);
114 ~InstallableChecker() override;
115
116 // Returns true if the InstallableChecker is currently running.
117 bool IsActive() const { return HasFlag(STARTED); }
118
119 // Returns true if |manifest| meets the requirements for being installable.
120 // Sets |valid_webapp_manifest_error_| if any errors are encountered.
121 bool IsManifestValidForWebApp(const content::Manifest& manifest);
122
123 // Returns the minimum icon size in pixels for a site to be installable.
124 // TODO(dominickn): consolidate this concept with minimum_icon_size_in_dp
125 // across all platforms.
126 static int GetMinimumIconSizeInPx();
127
128 // Start the installable check, fetching the resources specified in |params|.
129 // |callback| is invoked on the UI thread when the checks are complete,
130 // passing an InstallableResult struct containing the requested resources.
131 //
132 // Separate calls to Start are processed serially; each call is guaranteed to
133 // invoke |callback| before the next one is processed. Resources are cached on
134 // this object: a previous call for the same page and with the same icon sizes
135 // will not perform duplicate work and will run the callback immediately with
136 // the cached resources. When |callback| runs, it should copy any resources on
137 // the result that are necessary for future work. It should also avoid running
138 // expensive tasks directly and defer them to later as the callback is
139 // directly invoked by the InstallableChecker to guarantee the consistency of
140 // the check results (i.e. the icon).
141 // This method is marked virtual so clients may mock this object in tests.
142 virtual void Start(const InstallableParams& params,
143 const InstallableCallback& callback);
144
145 private:
146 friend class InstallableCheckerUnitTest;
147 FRIEND_TEST_ALL_PREFIXES(InstallableCheckerBrowserTest,
148 CheckerBeginsInEmptyState);
149 FRIEND_TEST_ALL_PREFIXES(InstallableCheckerBrowserTest,
150 CheckWebapp);
151
152 // This pair holds the parameters for a request to Start, along with the
153 // callback to be invoked when the request parameters are fulfilled. This is
154 // cheaply copyable and will be held in a std::vector.
155 using Task = std::pair<InstallableParams, InstallableCallback>;
156
157 // Bit flags used to maintain internal state regarding what has and hasn't yet
158 // been fetched/computed.
159 enum StatusFlag : uint32_t {
160 DORMANT = 0,
161 STARTED = 1 << 0,
162 RUNNING_CALLBACKS = 1 << 1,
163 MANIFEST_FETCHED = 1 << 2,
164 MANIFEST_VALIDATED = 1 << 3,
165 ICON_FETCHED = 1 << 4,
166 SERVICE_WORKER_CHECKED = 1 << 5,
167 };
168
169 // Stops the checking pipeline for the current task. Does not cancel any other
170 // tasks which may be queued.
171 void Cancel();
172
173 // Returns true if the icon size in |params| match those currently being
174 // requested.
175 bool DoesIconSizeMatch(const InstallableParams& params) const;
176
177 // Returns the error code associated with the resources requested in |params|,
178 // or NO_ERROR if there is no error.
179 ErrorCode GetErrorCode(const InstallableParams& params);
180
181 // Returns the WebContents to which this object is attached, or nullptr if the
182 // WebContents doesn't exist or is currently being destroyed.
183 content::WebContents* GetWebContents();
184
185 // Returns true if |params| requires no more work to be done (i.e. all the
186 // resources originally requested by |params| have been retrieved).
187 bool IsComplete(const InstallableParams& params) const;
188
189 // Returns true if |web_contents| is non-null and this checker remains active.
190 // If false is returned, |processing_error_| will be set.
191 bool IsRunning(content::WebContents* web_contents);
192
193 // Resets this object and removes all queued tasks. Called when navigating to
194 // a new page.
195 void Reset();
196
197 // Runs the callback associated with any task that is now complete.
198 void RunCallbacks();
199
200 // Runs the callbacks for any completed tasks, and starts work on the next.
201 void StartTask();
202
203 // Sets |flag| bit in |status_| to 0 and 1 respectively.
204 void ClearFlag(StatusFlag flag) { status_ &= ~flag; }
205 void SetFlag(StatusFlag flag) { status_ |= flag; }
206
207 // Returns true if the current status has the |flag| bit set to 1.
208 bool HasFlag(StatusFlag flag) const { return (status_ & flag) != 0; }
209
210 // Fetches the next required resource.
211 void FetchResource();
212
213 // Data retrieval methods.
214 void FetchManifest();
215 void OnDidGetManifest(const GURL& manifest_url,
216 const content::Manifest& manifest);
217
218 void CheckValidWebappManifest();
219
220 void CheckServiceWorker();
221 void OnDidCheckHasServiceWorker(bool has_service_worker);
222
223 void ExtractAndFetchBestIcon();
224 void OnAppIconFetched(const GURL icon_url, const SkBitmap& bitmap);
225
226 // content::WebContentsObserver overrides
227 void DidFinishNavigation(content::NavigationHandle* handle) override;
228 void WebContentsDestroyed() override;
229
230 // Internal status field to keep track of what resources have been retrieved.
231 uint32_t status_;
232
233 // Error codes for each resource retrieval operation.
234 ErrorCode processing_error_;
235 ErrorCode manifest_error_;
236 ErrorCode valid_webapp_manifest_error_;
237 ErrorCode service_worker_error_;
238 ErrorCode icon_error_;
239
240 // The list of params + callback pairs that have come from a call to Start.
241 std::vector<Task> tasks_;
242
243 // Tasks received while we are currently working. These are held separately to
244 // avoid contaminating the tasks_ vector (e.g. if a new Task is received
245 // during RunCallbacks, e.g. an InstallableCallback is invoked which calls
246 // Start), we cannot add it to tasks_ as the vector may be modified).
247 std::vector<Task> pending_tasks_;
248
249 // The icon size parameters used if a valid icon was requested.
250 int ideal_icon_size_in_dp_;
251 int minimum_icon_size_in_dp_;
252
253 // Installable properties cached on this object.
254 GURL manifest_url_;
255 content::Manifest manifest_;
256 GURL icon_url_;
257 std::unique_ptr<SkBitmap> icon_;
258 bool has_valid_webapp_manifest_;
259 bool has_service_worker_;
260
261 // This object has a lifetime scoped to a WebContents, so WeakPtrs can be used
262 // for binding callbacks.
263 base::WeakPtrFactory<InstallableChecker> weak_factory_;
264
265 DISALLOW_COPY_AND_ASSIGN(InstallableChecker);
266 };
267
268 } // namespace installable
269
270 #endif // CHROME_BROWSER_INSTALLABLE_INSTALLABLE_CHECKER_H_
OLDNEW
« no previous file with comments | « chrome/browser/installable/OWNERS ('k') | chrome/browser/installable/installable_checker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698