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

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

Powered by Google App Engine
This is Rietveld 408576698