OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/offline_pages/background/request_picker.h" | 5 #include "components/offline_pages/background/request_picker.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "components/offline_pages/background/save_page_request.h" | 9 #include "components/offline_pages/background/save_page_request.h" |
10 | 10 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 current_conditions_.reset(new DeviceConditions(*device_conditions)); | 43 current_conditions_.reset(new DeviceConditions(*device_conditions)); |
44 // Get all requests from queue (there is no filtering mechanism). | 44 // Get all requests from queue (there is no filtering mechanism). |
45 queue_->GetRequests(base::Bind(&RequestPicker::GetRequestResultCallback, | 45 queue_->GetRequests(base::Bind(&RequestPicker::GetRequestResultCallback, |
46 weak_ptr_factory_.GetWeakPtr())); | 46 weak_ptr_factory_.GetWeakPtr())); |
47 } | 47 } |
48 | 48 |
49 // When we get contents from the queue, use them to pick the next | 49 // When we get contents from the queue, use them to pick the next |
50 // request to operate on (if any). | 50 // request to operate on (if any). |
51 void RequestPicker::GetRequestResultCallback( | 51 void RequestPicker::GetRequestResultCallback( |
52 RequestQueue::GetRequestsResult, | 52 RequestQueue::GetRequestsResult, |
53 const std::vector<SavePageRequest>& requests) { | 53 std::vector<std::unique_ptr<SavePageRequest>> requests) { |
54 // If there is nothing to do, return right away. | 54 // If there is nothing to do, return right away. |
55 if (requests.size() == 0) { | 55 if (requests.size() == 0) { |
56 not_picked_callback_.Run(false); | 56 not_picked_callback_.Run(false); |
57 return; | 57 return; |
58 } | 58 } |
59 | 59 |
60 // Get the expired requests to be removed from the queue, and the valid ones | 60 // Get the expired requests to be removed from the queue, and the valid ones |
61 // from which to pick the next request. | 61 // from which to pick the next request. |
62 std::vector<SavePageRequest> valid_requests; | 62 std::vector<std::unique_ptr<SavePageRequest>> valid_requests; |
63 std::vector<SavePageRequest> expired_requests; | 63 std::vector<std::unique_ptr<SavePageRequest>> expired_requests; |
64 SplitRequests(requests, valid_requests, expired_requests); | 64 SplitRequests(std::move(requests), &valid_requests, &expired_requests); |
65 std::vector<int64_t> expired_request_ids; | 65 std::vector<int64_t> expired_request_ids; |
66 for (auto request : expired_requests) | 66 for (const auto& request : expired_requests) |
67 expired_request_ids.push_back(request.request_id()); | 67 expired_request_ids.push_back(request->request_id()); |
68 | 68 |
69 queue_->RemoveRequests(expired_request_ids, | 69 queue_->RemoveRequests(expired_request_ids, |
70 base::Bind(&RequestPicker::OnRequestExpired, | 70 base::Bind(&RequestPicker::OnRequestExpired, |
71 weak_ptr_factory_.GetWeakPtr())); | 71 weak_ptr_factory_.GetWeakPtr())); |
72 | 72 |
73 // Pick the most deserving request for our conditions. | 73 // Pick the most deserving request for our conditions. |
74 const SavePageRequest* picked_request = nullptr; | 74 const SavePageRequest* picked_request = nullptr; |
75 | 75 |
76 RequestCompareFunction comparator = nullptr; | 76 RequestCompareFunction comparator = nullptr; |
77 | 77 |
78 // Choose which comparison function to use based on policy. | 78 // Choose which comparison function to use based on policy. |
79 if (policy_->RetryCountIsMoreImportantThanRecency()) | 79 if (policy_->RetryCountIsMoreImportantThanRecency()) |
80 comparator = &RequestPicker::RetryCountFirstCompareFunction; | 80 comparator = &RequestPicker::RetryCountFirstCompareFunction; |
81 else | 81 else |
82 comparator = &RequestPicker::RecencyFirstCompareFunction; | 82 comparator = &RequestPicker::RecencyFirstCompareFunction; |
83 | 83 |
84 // Iterate once through the requests, keeping track of best candidate. | 84 // Iterate once through the requests, keeping track of best candidate. |
85 bool non_user_requested_tasks_remaining = false; | 85 bool non_user_requested_tasks_remaining = false; |
86 for (unsigned i = 0; i < valid_requests.size(); ++i) { | 86 for (unsigned i = 0; i < valid_requests.size(); ++i) { |
87 if (!valid_requests[i].user_requested()) | 87 if (!valid_requests[i]->user_requested()) |
88 non_user_requested_tasks_remaining = true; | 88 non_user_requested_tasks_remaining = true; |
89 if (!RequestConditionsSatisfied(valid_requests[i])) | 89 if (!RequestConditionsSatisfied(valid_requests[i].get())) |
90 continue; | 90 continue; |
91 if (IsNewRequestBetter(picked_request, &(valid_requests[i]), comparator)) | 91 if (IsNewRequestBetter(picked_request, valid_requests[i].get(), comparator)) |
92 picked_request = &(valid_requests[i]); | 92 picked_request = valid_requests[i].get(); |
93 } | 93 } |
94 | 94 |
95 // If we have a best request to try next, get the request coodinator to | 95 // If we have a best request to try next, get the request coodinator to |
96 // start it. Otherwise return that we have no candidates. | 96 // start it. Otherwise return that we have no candidates. |
97 if (picked_request != nullptr) { | 97 if (picked_request != nullptr) { |
98 picked_callback_.Run(*picked_request); | 98 picked_callback_.Run(*picked_request); |
99 } else { | 99 } else { |
100 not_picked_callback_.Run(non_user_requested_tasks_remaining); | 100 not_picked_callback_.Run(non_user_requested_tasks_remaining); |
101 } | 101 } |
102 } | 102 } |
103 | 103 |
104 // Filter out requests that don't meet the current conditions. For instance, if | 104 // Filter out requests that don't meet the current conditions. For instance, if |
105 // this is a predictive request, and we are not on WiFi, it should be ignored | 105 // this is a predictive request, and we are not on WiFi, it should be ignored |
106 // this round. | 106 // this round. |
107 bool RequestPicker::RequestConditionsSatisfied(const SavePageRequest& request) { | 107 bool RequestPicker::RequestConditionsSatisfied(const SavePageRequest* request) { |
108 // If the user did not request the page directly, make sure we are connected | 108 // If the user did not request the page directly, make sure we are connected |
109 // to power and have WiFi and sufficient battery remaining before we take this | 109 // to power and have WiFi and sufficient battery remaining before we take this |
110 // request. | 110 // request. |
111 | 111 |
112 if (!current_conditions_->IsPowerConnected() && | 112 if (!current_conditions_->IsPowerConnected() && |
113 policy_->PowerRequired(request.user_requested())) { | 113 policy_->PowerRequired(request->user_requested())) { |
114 return false; | 114 return false; |
115 } | 115 } |
116 | 116 |
117 if (current_conditions_->GetNetConnectionType() != | 117 if (current_conditions_->GetNetConnectionType() != |
118 net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI && | 118 net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI && |
119 policy_->UnmeteredNetworkRequired(request.user_requested())) { | 119 policy_->UnmeteredNetworkRequired(request->user_requested())) { |
120 return false; | 120 return false; |
121 } | 121 } |
122 | 122 |
123 if (current_conditions_->GetBatteryPercentage() < | 123 if (current_conditions_->GetBatteryPercentage() < |
124 policy_->BatteryPercentageRequired(request.user_requested())) { | 124 policy_->BatteryPercentageRequired(request->user_requested())) { |
125 return false; | 125 return false; |
126 } | 126 } |
127 | 127 |
128 // If we have already started this page the max number of times, it is not | 128 // If we have already started this page the max number of times, it is not |
129 // eligible to try again. | 129 // eligible to try again. |
130 if (request.started_attempt_count() >= policy_->GetMaxStartedTries()) | 130 if (request->started_attempt_count() >= policy_->GetMaxStartedTries()) |
131 return false; | 131 return false; |
132 | 132 |
133 // If we have already completed trying this page the max number of times, it | 133 // If we have already completed trying this page the max number of times, it |
134 // is not eligible to try again. | 134 // is not eligible to try again. |
135 if (request.completed_attempt_count() >= policy_->GetMaxCompletedTries()) | 135 if (request->completed_attempt_count() >= policy_->GetMaxCompletedTries()) |
136 return false; | 136 return false; |
137 | 137 |
138 // If the request is paused, do not consider it. | 138 // If the request is paused, do not consider it. |
139 if (request.request_state() == SavePageRequest::RequestState::PAUSED) | 139 if (request->request_state() == SavePageRequest::RequestState::PAUSED) |
140 return false; | 140 return false; |
141 | 141 |
142 // If the request is expired, do not consider it. | 142 // If the request is expired, do not consider it. |
143 base::TimeDelta requestAge = base::Time::Now() - request.creation_time(); | 143 base::TimeDelta requestAge = base::Time::Now() - request->creation_time(); |
144 if (requestAge > | 144 if (requestAge > |
145 base::TimeDelta::FromSeconds( | 145 base::TimeDelta::FromSeconds( |
146 policy_->GetRequestExpirationTimeInSeconds())) | 146 policy_->GetRequestExpirationTimeInSeconds())) |
147 return false; | 147 return false; |
148 | 148 |
149 // If this request is not active yet, return false. | 149 // If this request is not active yet, return false. |
150 // TODO(petewil): If the only reason we return nothing to do is that we have | 150 // TODO(petewil): If the only reason we return nothing to do is that we have |
151 // inactive requests, we still want to try again later after their activation | 151 // inactive requests, we still want to try again later after their activation |
152 // time elapses, we shouldn't take ourselves completely off the scheduler. | 152 // time elapses, we shouldn't take ourselves completely off the scheduler. |
153 if (request.activation_time() > base::Time::Now()) | 153 if (request->activation_time() > base::Time::Now()) |
154 return false; | 154 return false; |
155 | 155 |
156 return true; | 156 return true; |
157 } | 157 } |
158 | 158 |
159 // Look at policies to decide which requests to prefer. | 159 // Look at policies to decide which requests to prefer. |
160 bool RequestPicker::IsNewRequestBetter(const SavePageRequest* oldRequest, | 160 bool RequestPicker::IsNewRequestBetter(const SavePageRequest* oldRequest, |
161 const SavePageRequest* newRequest, | 161 const SavePageRequest* newRequest, |
162 RequestCompareFunction comparator) { | 162 RequestCompareFunction comparator) { |
163 | 163 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 base::TimeDelta difference = left->creation_time() - right->creation_time(); | 229 base::TimeDelta difference = left->creation_time() - right->creation_time(); |
230 int result = signum(difference.InMilliseconds()); | 230 int result = signum(difference.InMilliseconds()); |
231 | 231 |
232 // Flip the direction of comparison if policy prefers fewer retries. | 232 // Flip the direction of comparison if policy prefers fewer retries. |
233 if (earlier_requests_better_) | 233 if (earlier_requests_better_) |
234 result *= -1; | 234 result *= -1; |
235 | 235 |
236 return result; | 236 return result; |
237 } | 237 } |
238 | 238 |
239 // Split all requests into expired ones and still valid ones. | |
240 void RequestPicker::SplitRequests( | 239 void RequestPicker::SplitRequests( |
241 const std::vector<SavePageRequest>& requests, | 240 std::vector<std::unique_ptr<SavePageRequest>> requests, |
242 std::vector<SavePageRequest>& valid_requests, | 241 std::vector<std::unique_ptr<SavePageRequest>>* valid_requests, |
243 std::vector<SavePageRequest>& expired_requests) { | 242 std::vector<std::unique_ptr<SavePageRequest>>* expired_requests) { |
244 for (SavePageRequest request : requests) { | 243 std::vector<std::unique_ptr<SavePageRequest>>::iterator request; |
brucedawson
2016/09/12 17:20:04
This local variable is not used and should be dele
Pete Williamson
2016/09/12 20:25:57
Removed in https://codereview.chromium.org/2332923
| |
245 if (base::Time::Now() - request.creation_time() >= | 244 for (auto& request : requests) { |
245 if (base::Time::Now() - request->creation_time() >= | |
246 base::TimeDelta::FromSeconds(kRequestExpirationTimeInSeconds)) { | 246 base::TimeDelta::FromSeconds(kRequestExpirationTimeInSeconds)) { |
247 expired_requests.push_back(request); | 247 expired_requests->push_back(std::move(request)); |
248 } else { | 248 } else { |
249 valid_requests.push_back(request); | 249 valid_requests->push_back(std::move(request)); |
250 } | 250 } |
251 } | 251 } |
252 } | 252 } |
253 | 253 |
254 // Callback used after expired requests are deleted from the queue and notifies | 254 // Callback used after expired requests are deleted from the queue and notifies |
255 // the coordinator. | 255 // the coordinator. |
256 void RequestPicker::OnRequestExpired( | 256 void RequestPicker::OnRequestExpired( |
257 const RequestQueue::UpdateMultipleRequestResults& results, | 257 const RequestQueue::UpdateMultipleRequestResults& results, |
258 const std::vector<SavePageRequest>& requests) { | 258 const std::vector<std::unique_ptr<SavePageRequest>> requests) { |
259 for (auto request : requests) | 259 std::vector<std::unique_ptr<SavePageRequest>>::const_iterator request; |
260 for (request = requests.begin(); request != requests.end(); ++request) | |
brucedawson
2016/09/12 17:20:06
I'm confused as to why this was changed to an expl
Pete Williamson
2016/09/12 20:25:57
Due to CR feedback, I changed some places to use t
brucedawson
2016/09/12 20:48:40
Although, this one *started out* using for-each st
| |
260 notifier_->NotifyCompleted( | 261 notifier_->NotifyCompleted( |
261 request, RequestCoordinator::BackgroundSavePageResult::EXPIRED); | 262 *(request->get()), |
263 RequestCoordinator::BackgroundSavePageResult::EXPIRED); | |
262 } | 264 } |
263 | 265 |
264 } // namespace offline_pages | 266 } // namespace offline_pages |
OLD | NEW |