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

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: update Created 4 years, 1 month 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 RequestPicker;
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);
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(AddRequestResult result,
235 const SavePageRequest& request);
236
237 // Receives the result of mark attempt completed requests.
238 void MarkAttemptCompletedDoneCallback(
239 int64_t request_id,
240 const ClientId& client_id,
241 std::unique_ptr<UpdateRequestsResult> result);
242
243 void UpdateMultipleRequestsCallback(
244 std::unique_ptr<UpdateRequestsResult> result);
245
246 void CompletedRequestCallback(const MultipleItemStatuses& status);
247
248 void HandleRemovedRequestsAndCallback(
249 const RemoveRequestsCallback& callback,
250 RequestNotifier::BackgroundSavePageResult status,
251 std::unique_ptr<UpdateRequestsResult> result);
252
253 void HandleRemovedRequests(RequestNotifier::BackgroundSavePageResult status,
254 std::unique_ptr<UpdateRequestsResult> result);
255
256 bool StartProcessingInternal(const ProcessingWindowState processing_state,
257 const DeviceConditions& device_conditions,
258 const base::Callback<void(bool)>& callback);
259
260 // Start processing now if connected (but with conservative assumption
261 // as to other device conditions).
262 void StartImmediatelyIfConnected();
263
264 OfflinerImmediateStartStatus TryImmediateStart();
265
266 // Check the request queue, and schedule a task corresponding
267 // to the least restrictive type of request in the queue.
268 void ScheduleAsNeeded();
269
270 // Callback from the request picker when it has chosen our next request.
271 void RequestPicked(const SavePageRequest& request);
272
273 // Callback from the request picker when no more requests are in the queue.
274 // The parameter is a signal for what (if any) conditions to schedule future
275 // processing for.
276 void RequestNotPicked(bool non_user_requested_tasks_remaining);
277
278 void HandleWatchdogTimeout();
279
280 // Cancels an in progress pre-rendering, and updates state appropriately.
281 void StopPrerendering(Offliner::RequestStatus stop_status);
282
283 // Marks attempt on the request and sends it to offliner in continuation.
284 void SendRequestToOffliner(const SavePageRequest& request);
285
286 // Continuation of |SendRequestToOffliner| after the request is marked as
287 // started.
288 void StartOffliner(int64_t request_id,
289 const std::string& client_namespace,
290 std::unique_ptr<UpdateRequestsResult> update_result);
291
292 // Called by the offliner when an offlining request is completed. (and by
293 // tests).
294 void OfflinerDoneCallback(const SavePageRequest& request,
295 Offliner::RequestStatus status);
296
297 // Records a completed attempt for the request and update it in the queue
298 // (possibly removing it).
299 void UpdateRequestForCompletedAttempt(const SavePageRequest& request,
300 Offliner::RequestStatus status);
301
302 // Returns whether we should try another request based on the outcome
303 // of the previous one.
304 bool ShouldTryNextRequest(Offliner::RequestStatus previous_request_status);
305
306 void TryNextRequest();
307
308 // If there is an active request in the list, cancel that request.
309 bool CancelActiveRequestIfItMatches(const std::vector<int64_t>& request_ids);
310
311 // Records an aborted attempt for the request and update it in the queue
312 // (possibly removing it).
313 void UpdateRequestForAbortedAttempt(const SavePageRequest& request);
314
315 // Remove the attempted request from the queue with status to pass through to
316 // any observers and UMA histogram.
317 void RemoveAttemptedRequest(const SavePageRequest& request,
318 BackgroundSavePageResult status);
319
320 // Completes aborting the request, reports an error if it fails.
321 void MarkAttemptAbortedDone(int64_t request_id,
322 const ClientId& client_id,
323 std::unique_ptr<UpdateRequestsResult> result);
324
325 // Returns the appropriate offliner to use, getting a new one from the factory
326 // if needed.
327 void GetOffliner();
328
329 // Method to wrap calls to getting the connection type so it can be
330 // changed for tests.
331 net::NetworkChangeNotifier::ConnectionType GetConnectionType();
332
333 void SetNetworkConditionsForTest(
334 net::NetworkChangeNotifier::ConnectionType connection) {
335 use_test_connection_type_ = true;
336 test_connection_type_ = connection;
337 }
338
339 void SetDeviceConditionsForTest(const DeviceConditions& current_conditions) {
340 current_conditions_.reset(new DeviceConditions(current_conditions));
341 }
342
343 // KeyedService implementation:
344 void Shutdown() override;
345
346 friend class RequestCoordinatorTest;
347
348 // Cached value of whether low end device. Overwritable for testing.
349 bool is_low_end_device_;
350
351 // The offliner can only handle one request at a time - if the offliner is
352 // busy, prevent other requests. This flag marks whether the offliner is in
353 // use.
354 bool is_busy_;
355 // There is more than one path to start processing so this flag is used
356 // to avoid race conditions before is_busy_ is established.
357 bool is_starting_;
358 // Identifies the type of current processing window or if processing stopped.
359 ProcessingWindowState processing_state_;
360 // True if we should use the test connection type instead of the actual type.
361 bool use_test_connection_type_;
362 // For use by tests, a fake network connection type
363 net::NetworkChangeNotifier::ConnectionType test_connection_type_;
364 // Unowned pointer to the current offliner, if any.
365 Offliner* offliner_;
366 base::Time operation_start_time_;
367 // The observers.
368 base::ObserverList<Observer> observers_;
369 // Last known conditions for network, battery
370 std::unique_ptr<DeviceConditions> current_conditions_;
371 // RequestCoordinator takes over ownership of the policy
372 std::unique_ptr<OfflinerPolicy> policy_;
373 // OfflinerFactory. Used to create offline pages. Owned.
374 std::unique_ptr<OfflinerFactory> factory_;
375 // RequestQueue. Used to store incoming requests. Owned.
376 std::unique_ptr<RequestQueue> queue_;
377 // Scheduler. Used to request a callback when network is available. Owned.
378 std::unique_ptr<Scheduler> scheduler_;
379 // Controller of client policies. Owned.
380 std::unique_ptr<ClientPolicyController> policy_controller_;
381 // Unowned pointer to the Network Quality Estimator.
382 net::NetworkQualityEstimator::NetworkQualityProvider*
383 network_quality_estimator_;
384 // Holds copy of the active request, if any.
385 std::unique_ptr<SavePageRequest> active_request_;
386 // Status of the most recent offlining.
387 Offliner::RequestStatus last_offlining_status_;
388 // A set of request_ids that we are holding off until the download manager is
389 // done with them.
390 std::set<int64_t> disabled_requests_;
391 // Calling this returns to the scheduler across the JNI bridge.
392 base::Callback<void(bool)> scheduler_callback_;
393 // Logger to record events.
394 RequestCoordinatorEventLogger event_logger_;
395 // Timer to watch for pre-render attempts running too long.
396 base::OneShotTimer watchdog_timer_;
397 // Callback invoked when an immediate request is done (default empty).
398 base::Callback<void(bool)> immediate_schedule_callback_;
399 // Allows us to pass a weak pointer to callbacks.
400 base::WeakPtrFactory<RequestCoordinator> weak_ptr_factory_;
401
402 DISALLOW_COPY_AND_ASSIGN(RequestCoordinator);
403 };
404
405 } // namespace offline_pages
406
407 #endif // COMPONENTS_OFFLINE_PAGES_BACKGROUND_REQUEST_COORDINATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698