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

Side by Side Diff: components/offline_pages/background/request_coordinator.h

Issue 2489443002: Move all components/offline_pages/ files into component/offline_pages/core (Closed)
Patch Set: more rebase Created 4 years 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
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 COMPONENTS_OFFLINE_PAGES_BACKGROUND_REQUEST_COORDINATOR_H_
6 #define COMPONENTS_OFFLINE_PAGES_BACKGROUND_REQUEST_COORDINATOR_H_
7
8 #include <memory>
9 #include <set>
10 #include <string>
11 #include <vector>
12
13 #include "base/callback.h"
14 #include "base/macros.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/observer_list.h"
17 #include "base/supports_user_data.h"
18 #include "base/time/time.h"
19 #include "base/timer/timer.h"
20 #include "components/keyed_service/core/keyed_service.h"
21 #include "components/offline_pages/background/device_conditions.h"
22 #include "components/offline_pages/background/offliner.h"
23 #include "components/offline_pages/background/request_coordinator_event_logger.h "
24 #include "components/offline_pages/background/request_notifier.h"
25 #include "components/offline_pages/background/request_queue.h"
26 #include "components/offline_pages/background/scheduler.h"
27 #include "net/nqe/network_quality_estimator.h"
28 #include "url/gurl.h"
29
30 namespace offline_pages {
31
32 struct ClientId;
33 class OfflinerPolicy;
34 class OfflinerFactory;
35 class Offliner;
36 class RequestQueue;
37 class SavePageRequest;
38 class Scheduler;
39 class ClientPolicyController;
40
41 // Coordinates queueing and processing save page later requests.
42 class RequestCoordinator : public KeyedService,
43 public RequestNotifier,
44 public base::SupportsUserData {
45 public:
46 // Nested observer class. To make sure that no events are missed, the client
47 // code should first register for notifications, then |GetAllRequests|, and
48 // ignore all events before the return from |GetAllRequests|, and consume
49 // events after the return callback from |GetAllRequests|.
50 class Observer {
51 public:
52 virtual ~Observer() = default;
53
54 virtual void OnAdded(const SavePageRequest& request) = 0;
55 virtual void OnCompleted(
56 const SavePageRequest& request,
57 RequestNotifier::BackgroundSavePageResult status) = 0;
58 virtual void OnChanged(const SavePageRequest& request) = 0;
59 };
60
61 enum class RequestAvailability {
62 ENABLED_FOR_OFFLINER,
63 DISABLED_FOR_OFFLINER,
64 };
65
66 // Callback specifying which request IDs were actually removed.
67 typedef base::Callback<void(const MultipleItemStatuses&)>
68 RemoveRequestsCallback;
69
70 // Callback that receives the response for GetAllRequests.
71 typedef base::Callback<void(std::vector<std::unique_ptr<SavePageRequest>>)>
72 GetRequestsCallback;
73
74 RequestCoordinator(std::unique_ptr<OfflinerPolicy> policy,
75 std::unique_ptr<OfflinerFactory> factory,
76 std::unique_ptr<RequestQueue> queue,
77 std::unique_ptr<Scheduler> scheduler,
78 net::NetworkQualityEstimator::NetworkQualityProvider*
79 network_quality_estimator);
80
81 ~RequestCoordinator() override;
82
83 // Queues |request| to later load and save when system conditions allow.
84 // Returns an id if the page could be queued successfully, 0L otherwise.
85 int64_t SavePageLater(const GURL& url,
86 const ClientId& client_id,
87 bool user_requested,
88 RequestAvailability availability);
89
90 // Remove a list of requests by |request_id|. This removes requests from the
91 // request queue, and cancels an in-progress prerender.
92 void RemoveRequests(const std::vector<int64_t>& request_ids,
93 const RemoveRequestsCallback& callback);
94
95 // Pause a list of requests by |request_id|. This will change the state
96 // in the request queue so the request cannot be started.
97 void PauseRequests(const std::vector<int64_t>& request_ids);
98
99 // Resume a list of previously paused requests, making them available.
100 void ResumeRequests(const std::vector<int64_t>& request_ids);
101
102 // Get all save page request items in the callback.
103 void GetAllRequests(const GetRequestsCallback& callback);
104
105 // Starts processing of one or more queued save page later requests.
106 // Returns whether processing was started and that caller should expect
107 // a callback. If processing was already active, returns false.
108 bool StartProcessing(const DeviceConditions& device_conditions,
109 const base::Callback<void(bool)>& callback);
110
111 // Stops the current request processing if active. This is a way for
112 // caller to abort processing; otherwise, processing will complete on
113 // its own. In either case, the callback will be called when processing
114 // is stopped or complete.
115 void StopProcessing(Offliner::RequestStatus stop_status);
116
117 // Used to denote that the foreground thread is ready for the offliner
118 // to start work on a previously entered, but unavailable request.
119 void EnableForOffliner(int64_t request_id, const ClientId& client_id);
120
121 // If a request that is unavailable to the offliner is finished elsewhere,
122 // (by the tab helper synchronous download), send a notificaiton that it
123 // succeeded through our notificaiton system.
124 void MarkRequestCompleted(int64_t request_id);
125
126 const Scheduler::TriggerConditions GetTriggerConditions(
127 const bool user_requested);
128
129 // A way for tests to set the callback in use when an operation is over.
130 void SetProcessingCallbackForTest(const base::Callback<void(bool)> callback) {
131 scheduler_callback_ = callback;
132 }
133
134 // A way to set the callback which would be called if the request will be
135 // scheduled immediately. Used by testing harness to determine if a request
136 // has been processed.
137 void SetImmediateScheduleCallbackForTest(
138 const base::Callback<void(bool)> callback) {
139 immediate_schedule_callback_ = callback;
140 }
141
142 void StartImmediatelyForTest() { StartImmediatelyIfConnected(); }
143
144 // Observers implementing the RequestCoordinator::Observer interface can
145 // register here to get notifications of changes to request state. This
146 // pointer is not owned, and it is the callers responsibility to remove the
147 // observer before the observer is deleted.
148 void AddObserver(RequestCoordinator::Observer* observer);
149
150 void RemoveObserver(RequestCoordinator::Observer* observer);
151
152 // Implement RequestNotifier
153 void NotifyAdded(const SavePageRequest& request) override;
154 void NotifyCompleted(
155 const SavePageRequest& request,
156 RequestNotifier::BackgroundSavePageResult status) override;
157 void NotifyChanged(const SavePageRequest& request) override;
158
159 // Returns the request queue used for requests. Coordinator keeps ownership.
160 RequestQueue* queue() { return queue_.get(); }
161
162 // Return an unowned pointer to the Scheduler.
163 Scheduler* scheduler() { return scheduler_.get(); }
164
165 OfflinerPolicy* policy() { return policy_.get(); }
166
167 ClientPolicyController* GetPolicyController();
168
169 // Returns the status of the most recent offlining.
170 Offliner::RequestStatus last_offlining_status() {
171 return last_offlining_status_;
172 }
173
174 bool is_busy() {
175 return is_busy_;
176 }
177
178 // Returns whether processing is starting (before it is decided to actually
179 // process a request (is_busy()) at this time or not.
180 bool is_starting() { return is_starting_; }
181
182 // Tracks whether the last offlining attempt got canceled. This is reset by
183 // the next StartProcessing() call.
184 bool is_canceled() {
185 return processing_state_ == ProcessingWindowState::STOPPED;
186 }
187
188 RequestCoordinatorEventLogger* GetLogger() { return &event_logger_; }
189
190 private:
191 // Immediate start attempt status code for UMA.
192 // These values are written to logs. New enum values can be added, but
193 // existing enums must never be renumbered or deleted and reused.
194 // For any additions, also update corresponding histogram in histograms.xml.
195 enum OfflinerImmediateStartStatus {
196 // Did start processing request.
197 STARTED = 0,
198 // Already busy processing a request.
199 BUSY = 1,
200 // The Offliner did not accept processing the request.
201 NOT_ACCEPTED = 2,
202 // No current network connection.
203 NO_CONNECTION = 3,
204 // Weak network connection (worse than 2G speed)
205 // according to network quality estimator.
206 WEAK_CONNECTION = 4,
207 // Did not start because this is svelte device.
208 NOT_STARTED_ON_SVELTE = 5,
209 // NOTE: insert new values above this line and update histogram enum too.
210 STATUS_COUNT = 6,
211 };
212
213 enum class ProcessingWindowState {
214 STOPPED,
215 SCHEDULED_WINDOW,
216 IMMEDIATE_WINDOW,
217 };
218
219 // Receives the results of a get from the request queue, and turns that into
220 // SavePageRequest objects for the caller of GetQueuedRequests.
221 void GetQueuedRequestsCallback(
222 const GetRequestsCallback& callback,
223 GetRequestsResult result,
224 std::vector<std::unique_ptr<SavePageRequest>> requests);
225
226 // Receives the results of a get from the request queue, and turns that into
227 // SavePageRequest objects for the caller of GetQueuedRequests.
228 void GetRequestsForSchedulingCallback(
229 GetRequestsResult result,
230 std::vector<std::unique_ptr<SavePageRequest>> requests);
231
232 // Receives the result of add requests to the request queue.
233 void AddRequestResultCallback(RequestAvailability availability,
234 AddRequestResult result,
235 const SavePageRequest& request);
236
237 void UpdateMultipleRequestsCallback(
238 std::unique_ptr<UpdateRequestsResult> result);
239
240 void HandleRemovedRequestsAndCallback(
241 const RemoveRequestsCallback& callback,
242 RequestNotifier::BackgroundSavePageResult status,
243 std::unique_ptr<UpdateRequestsResult> result);
244
245 void HandleRemovedRequests(RequestNotifier::BackgroundSavePageResult status,
246 std::unique_ptr<UpdateRequestsResult> result);
247
248 bool StartProcessingInternal(const ProcessingWindowState processing_state,
249 const DeviceConditions& device_conditions,
250 const base::Callback<void(bool)>& callback);
251
252 // Start processing now if connected (but with conservative assumption
253 // as to other device conditions).
254 void StartImmediatelyIfConnected();
255
256 OfflinerImmediateStartStatus TryImmediateStart();
257
258 // Check the request queue, and schedule a task corresponding
259 // to the least restrictive type of request in the queue.
260 void ScheduleAsNeeded();
261
262 // Callback from the request picker when it has chosen our next request.
263 void RequestPicked(const SavePageRequest& request);
264
265 // Callback from the request picker when no more requests are in the queue.
266 // The parameter is a signal for what (if any) conditions to schedule future
267 // processing for.
268 void RequestNotPicked(bool non_user_requested_tasks_remaining);
269
270 // Callback from request picker that receives the current available queued
271 // request count as well as the total queued request count (which may be
272 // different if unavailable requests are queued such as paused requests).
273 // It also receives a flag as to whether this request picking is due to the
274 // start of a request processing window.
275 void RequestCounts(bool is_start_of_processing,
276 size_t total_requests,
277 size_t available_requests);
278
279 void HandleWatchdogTimeout();
280
281 // Cancels an in progress pre-rendering, and updates state appropriately.
282 void StopPrerendering(Offliner::RequestStatus stop_status);
283
284 // Marks attempt on the request and sends it to offliner in continuation.
285 void SendRequestToOffliner(const SavePageRequest& request);
286
287 // Continuation of |SendRequestToOffliner| after the request is marked as
288 // started.
289 void StartOffliner(int64_t request_id,
290 const std::string& client_namespace,
291 std::unique_ptr<UpdateRequestsResult> update_result);
292
293 // Called by the offliner when an offlining request is completed. (and by
294 // tests).
295 void OfflinerDoneCallback(const SavePageRequest& request,
296 Offliner::RequestStatus status);
297
298 // Records a completed attempt for the request and update it in the queue
299 // (possibly removing it).
300 void UpdateRequestForCompletedAttempt(const SavePageRequest& request,
301 Offliner::RequestStatus status);
302
303 // Returns whether we should try another request based on the outcome
304 // of the previous one.
305 bool ShouldTryNextRequest(Offliner::RequestStatus previous_request_status);
306
307 // Try to find and start offlining an available request.
308 // |is_start_of_processing| identifies if this is the beginning of a
309 // processing window (vs. continuing within a current processing window).
310 void TryNextRequest(bool is_start_of_processing);
311
312 // If there is an active request in the list, cancel that request.
313 bool CancelActiveRequestIfItMatches(const std::vector<int64_t>& request_ids);
314
315 // Records an aborted attempt for the request and update it in the queue
316 // (possibly removing it).
317 void UpdateRequestForAbortedAttempt(const SavePageRequest& request);
318
319 // Remove the attempted request from the queue with status to pass through to
320 // any observers and UMA histogram.
321 void RemoveAttemptedRequest(const SavePageRequest& request,
322 BackgroundSavePageResult status);
323
324 // Marks the attempt as aborted. This makes the request available again
325 // for offlining.
326 void MarkAttemptAborted(int64_t request_id, const std::string& name_space);
327
328 // Reports change from marking request, reports an error if it fails.
329 void MarkAttemptDone(int64_t request_id,
330 const std::string& name_space,
331 std::unique_ptr<UpdateRequestsResult> result);
332
333 // Returns the appropriate offliner to use, getting a new one from the factory
334 // if needed.
335 void GetOffliner();
336
337 // Method to wrap calls to getting the connection type so it can be
338 // changed for tests.
339 net::NetworkChangeNotifier::ConnectionType GetConnectionType();
340
341 void SetNetworkConditionsForTest(
342 net::NetworkChangeNotifier::ConnectionType connection) {
343 use_test_connection_type_ = true;
344 test_connection_type_ = connection;
345 }
346
347 void SetDeviceConditionsForTest(const DeviceConditions& current_conditions) {
348 current_conditions_.reset(new DeviceConditions(current_conditions));
349 }
350
351 // KeyedService implementation:
352 void Shutdown() override;
353
354 friend class RequestCoordinatorTest;
355
356 // Cached value of whether low end device. Overwritable for testing.
357 bool is_low_end_device_;
358
359 // The offliner can only handle one request at a time - if the offliner is
360 // busy, prevent other requests. This flag marks whether the offliner is in
361 // use.
362 bool is_busy_;
363 // There is more than one path to start processing so this flag is used
364 // to avoid race conditions before is_busy_ is established.
365 bool is_starting_;
366 // Identifies the type of current processing window or if processing stopped.
367 ProcessingWindowState processing_state_;
368 // True if we should use the test connection type instead of the actual type.
369 bool use_test_connection_type_;
370 // For use by tests, a fake network connection type
371 net::NetworkChangeNotifier::ConnectionType test_connection_type_;
372 // Unowned pointer to the current offliner, if any.
373 Offliner* offliner_;
374 base::Time operation_start_time_;
375 // The observers.
376 base::ObserverList<Observer> observers_;
377 // Last known conditions for network, battery
378 std::unique_ptr<DeviceConditions> current_conditions_;
379 // RequestCoordinator takes over ownership of the policy
380 std::unique_ptr<OfflinerPolicy> policy_;
381 // OfflinerFactory. Used to create offline pages. Owned.
382 std::unique_ptr<OfflinerFactory> factory_;
383 // RequestQueue. Used to store incoming requests. Owned.
384 std::unique_ptr<RequestQueue> queue_;
385 // Scheduler. Used to request a callback when network is available. Owned.
386 std::unique_ptr<Scheduler> scheduler_;
387 // Controller of client policies. Owned.
388 std::unique_ptr<ClientPolicyController> policy_controller_;
389 // Unowned pointer to the Network Quality Estimator.
390 net::NetworkQualityEstimator::NetworkQualityProvider*
391 network_quality_estimator_;
392 // Holds copy of the active request, if any.
393 std::unique_ptr<SavePageRequest> active_request_;
394 // Status of the most recent offlining.
395 Offliner::RequestStatus last_offlining_status_;
396 // A set of request_ids that we are holding off until the download manager is
397 // done with them.
398 std::set<int64_t> disabled_requests_;
399 // Calling this returns to the scheduler across the JNI bridge.
400 base::Callback<void(bool)> scheduler_callback_;
401 // Logger to record events.
402 RequestCoordinatorEventLogger event_logger_;
403 // Timer to watch for pre-render attempts running too long.
404 base::OneShotTimer watchdog_timer_;
405 // Callback invoked when an immediate request is done (default empty).
406 base::Callback<void(bool)> immediate_schedule_callback_;
407 // Allows us to pass a weak pointer to callbacks.
408 base::WeakPtrFactory<RequestCoordinator> weak_ptr_factory_;
409
410 DISALLOW_COPY_AND_ASSIGN(RequestCoordinator);
411 };
412
413 } // namespace offline_pages
414
415 #endif // COMPONENTS_OFFLINE_PAGES_BACKGROUND_REQUEST_COORDINATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698