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

Side by Side Diff: chrome/browser/chromeos/gdata/gdata_operation_registry.cc

Issue 10834027: Control the frequency of fileBrowserPrivate.onFileTransfersUpdated events. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 1000msec Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/chromeos/gdata/gdata_operation_registry.h" 5 #include "chrome/browser/chromeos/gdata/gdata_operation_registry.h"
6 6
7 #include "base/string_number_conversions.h" 7 #include "base/string_number_conversions.h"
8 #include "content/public/browser/browser_thread.h" 8 #include "content/public/browser/browser_thread.h"
9 9
10 using content::BrowserThread; 10 using content::BrowserThread;
11 11
12 namespace {
13
14 const int64 kNotificationFrequencyInMilliseconds = 1000;
15
16 } // namespace
17
12 namespace gdata { 18 namespace gdata {
13 19
14 // static 20 // static
15 std::string GDataOperationRegistry::OperationTypeToString(OperationType type) { 21 std::string GDataOperationRegistry::OperationTypeToString(OperationType type) {
16 switch (type) { 22 switch (type) {
17 case OPERATION_UPLOAD: return "upload"; 23 case OPERATION_UPLOAD: return "upload";
18 case OPERATION_DOWNLOAD: return "download"; 24 case OPERATION_DOWNLOAD: return "download";
19 case OPERATION_OTHER: return "other"; 25 case OPERATION_OTHER: return "other";
20 } 26 }
21 NOTREACHED(); 27 NOTREACHED();
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 progress_status_.transfer_state = OPERATION_IN_PROGRESS; 136 progress_status_.transfer_state = OPERATION_IN_PROGRESS;
131 registry_->OnOperationResume(this, &progress_status_); 137 registry_->OnOperationResume(this, &progress_status_);
132 } 138 }
133 } 139 }
134 140
135 void GDataOperationRegistry::Operation::NotifyAuthFailed() { 141 void GDataOperationRegistry::Operation::NotifyAuthFailed() {
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
137 registry_->OnOperationAuthFailed(); 143 registry_->OnOperationAuthFailed();
138 } 144 }
139 145
140 GDataOperationRegistry::GDataOperationRegistry() { 146 GDataOperationRegistry::GDataOperationRegistry()
147 : do_notification_frequency_control_(true) {
141 in_flight_operations_.set_check_on_null_data(true); 148 in_flight_operations_.set_check_on_null_data(true);
142 } 149 }
143 150
144 GDataOperationRegistry::~GDataOperationRegistry() { 151 GDataOperationRegistry::~GDataOperationRegistry() {
145 DCHECK(in_flight_operations_.IsEmpty()); 152 DCHECK(in_flight_operations_.IsEmpty());
146 } 153 }
147 154
148 void GDataOperationRegistry::AddObserver(Observer* observer) { 155 void GDataOperationRegistry::AddObserver(Observer* observer) {
149 observer_list_.AddObserver(observer); 156 observer_list_.AddObserver(observer);
150 } 157 }
151 158
152 void GDataOperationRegistry::RemoveObserver(Observer* observer) { 159 void GDataOperationRegistry::RemoveObserver(Observer* observer) {
153 observer_list_.RemoveObserver(observer); 160 observer_list_.RemoveObserver(observer);
154 } 161 }
155 162
163 void GDataOperationRegistry::DisableNotificationFrequencyControlForTest() {
164 do_notification_frequency_control_ = false;
165 }
166
156 void GDataOperationRegistry::CancelAll() { 167 void GDataOperationRegistry::CancelAll() {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
158 169
159 for (OperationIDMap::iterator iter(&in_flight_operations_); 170 for (OperationIDMap::iterator iter(&in_flight_operations_);
160 !iter.IsAtEnd(); 171 !iter.IsAtEnd();
161 iter.Advance()) { 172 iter.Advance()) {
162 Operation* operation = iter.GetCurrentValue(); 173 Operation* operation = iter.GetCurrentValue();
163 operation->Cancel(); 174 operation->Cancel();
164 // Cancel() may immediately trigger OnOperationFinish and remove the 175 // Cancel() may immediately trigger OnOperationFinish and remove the
165 // operation from the map, but IDMap is designed to be safe on such remove 176 // operation from the map, but IDMap is designed to be safe on such remove
(...skipping 16 matching lines...) Expand all
182 return false; 193 return false;
183 } 194 }
184 195
185 void GDataOperationRegistry::OnOperationStart( 196 void GDataOperationRegistry::OnOperationStart(
186 GDataOperationRegistry::Operation* operation, 197 GDataOperationRegistry::Operation* operation,
187 OperationID* id) { 198 OperationID* id) {
188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
189 200
190 *id = in_flight_operations_.Add(operation); 201 *id = in_flight_operations_.Add(operation);
191 DVLOG(1) << "GDataOperation[" << *id << "] started."; 202 DVLOG(1) << "GDataOperation[" << *id << "] started.";
192 if (IsFileTransferOperation(operation)) { 203 if (IsFileTransferOperation(operation))
193 FOR_EACH_OBSERVER(Observer, observer_list_, 204 NotifyStatusToObservers();
194 OnProgressUpdate(GetProgressStatusList()));
195 }
196 } 205 }
197 206
198 void GDataOperationRegistry::OnOperationProgress(OperationID id) { 207 void GDataOperationRegistry::OnOperationProgress(OperationID id) {
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
200 209
201 Operation* operation = in_flight_operations_.Lookup(id); 210 Operation* operation = in_flight_operations_.Lookup(id);
202 DCHECK(operation); 211 DCHECK(operation);
203 212
204 DVLOG(1) << "GDataOperation[" << id << "] " 213 DVLOG(1) << "GDataOperation[" << id << "] "
205 << operation->progress_status().DebugString(); 214 << operation->progress_status().DebugString();
206 if (IsFileTransferOperation(operation)) { 215 if (IsFileTransferOperation(operation))
207 FOR_EACH_OBSERVER(Observer, observer_list_, 216 NotifyStatusToObservers();
208 OnProgressUpdate(GetProgressStatusList()));
209 }
210 } 217 }
211 218
212 void GDataOperationRegistry::OnOperationFinish(OperationID id) { 219 void GDataOperationRegistry::OnOperationFinish(OperationID id) {
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
214 221
215 Operation* operation = in_flight_operations_.Lookup(id); 222 Operation* operation = in_flight_operations_.Lookup(id);
216 DCHECK(operation); 223 DCHECK(operation);
217 224
218 DVLOG(1) << "GDataOperation[" << id << "] finished."; 225 DVLOG(1) << "GDataOperation[" << id << "] finished.";
219 if (IsFileTransferOperation(operation)) { 226 if (IsFileTransferOperation(operation))
220 FOR_EACH_OBSERVER(Observer, observer_list_, 227 NotifyStatusToObservers();
221 OnProgressUpdate(GetProgressStatusList()));
222 }
223 in_flight_operations_.Remove(id); 228 in_flight_operations_.Remove(id);
224 } 229 }
225 230
226 void GDataOperationRegistry::OnOperationResume( 231 void GDataOperationRegistry::OnOperationResume(
227 GDataOperationRegistry::Operation* operation, 232 GDataOperationRegistry::Operation* operation,
228 GDataOperationRegistry::ProgressStatus* new_status) { 233 GDataOperationRegistry::ProgressStatus* new_status) {
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
230 235
231 // Find the corresponding suspended task. 236 // Find the corresponding suspended task.
232 Operation* suspended = NULL; 237 Operation* suspended = NULL;
(...skipping 16 matching lines...) Expand all
249 254
250 new_status->progress_current = old_status.progress_current; 255 new_status->progress_current = old_status.progress_current;
251 new_status->progress_total = old_status.progress_total; 256 new_status->progress_total = old_status.progress_total;
252 new_status->start_time = old_status.start_time; 257 new_status->start_time = old_status.start_time;
253 258
254 // Remove the old one and initiate the new operation. 259 // Remove the old one and initiate the new operation.
255 in_flight_operations_.Remove(old_id); 260 in_flight_operations_.Remove(old_id);
256 new_status->operation_id = in_flight_operations_.Add(operation); 261 new_status->operation_id = in_flight_operations_.Add(operation);
257 DVLOG(1) << "GDataOperation[" << old_id << " -> " << 262 DVLOG(1) << "GDataOperation[" << old_id << " -> " <<
258 new_status->operation_id << "] resumed."; 263 new_status->operation_id << "] resumed.";
259 if (IsFileTransferOperation(operation)) { 264 if (IsFileTransferOperation(operation))
260 FOR_EACH_OBSERVER(Observer, observer_list_, 265 NotifyStatusToObservers();
261 OnProgressUpdate(GetProgressStatusList()));
262 }
263 } 266 }
264 267
265 void GDataOperationRegistry::OnOperationSuspend(OperationID id) { 268 void GDataOperationRegistry::OnOperationSuspend(OperationID id) {
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
267 270
268 Operation* operation = in_flight_operations_.Lookup(id); 271 Operation* operation = in_flight_operations_.Lookup(id);
269 DCHECK(operation); 272 DCHECK(operation);
270 273
271 DVLOG(1) << "GDataOperation[" << id << "] suspended."; 274 DVLOG(1) << "GDataOperation[" << id << "] suspended.";
272 if (IsFileTransferOperation(operation)) { 275 if (IsFileTransferOperation(operation))
273 FOR_EACH_OBSERVER(Observer, observer_list_, 276 NotifyStatusToObservers();
274 OnProgressUpdate(GetProgressStatusList()));
275 }
276 } 277 }
277 278
278 void GDataOperationRegistry::OnOperationAuthFailed() { 279 void GDataOperationRegistry::OnOperationAuthFailed() {
279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
280 281
281 DVLOG(1) << "GDataOperation authentication failed."; 282 DVLOG(1) << "GDataOperation authentication failed.";
282 FOR_EACH_OBSERVER(Observer, observer_list_, OnAuthenticationFailed()); 283 FOR_EACH_OBSERVER(Observer, observer_list_, OnAuthenticationFailed());
283 } 284 }
284 285
285 bool GDataOperationRegistry::IsFileTransferOperation( 286 bool GDataOperationRegistry::IsFileTransferOperation(
(...skipping 10 matching lines...) Expand all
296 for (OperationIDMap::const_iterator iter(&in_flight_operations_); 297 for (OperationIDMap::const_iterator iter(&in_flight_operations_);
297 !iter.IsAtEnd(); 298 !iter.IsAtEnd();
298 iter.Advance()) { 299 iter.Advance()) {
299 const Operation* operation = iter.GetCurrentValue(); 300 const Operation* operation = iter.GetCurrentValue();
300 if (IsFileTransferOperation(operation)) 301 if (IsFileTransferOperation(operation))
301 status_list.push_back(operation->progress_status()); 302 status_list.push_back(operation->progress_status());
302 } 303 }
303 return status_list; 304 return status_list;
304 } 305 }
305 306
307 bool GDataOperationRegistry::ShouldNotifyStatusNow(
308 const ProgressStatusList& list) {
309 if (!do_notification_frequency_control_)
310 return true;
311
312 base::Time now = base::Time::Now();
313
314 // If it is a first event, or some time abnormality is detected, we should
315 // not skip this notification.
316 if (last_notification_.is_null() || now < last_notification_) {
317 last_notification_ = now;
318 return true;
319 }
320
321 // If sufficiently long time has elapsed since the previous event, we should
322 // not skip this notification.
323 if ((now - last_notification_).InMilliseconds() >=
324 kNotificationFrequencyInMilliseconds) {
325 last_notification_ = now;
326 return true;
327 }
328
329 // If important events (OPERATION_STARTED, COMPLETED, or FAILED) are there,
330 // we should not skip this notification.
331 for (size_t i = 0; i < list.size(); ++i) {
332 if (list[i].transfer_state != OPERATION_IN_PROGRESS) {
333 last_notification_ = now;
334 return true;
335 }
336 }
337
338 // Otherwise we can skip it.
339 return false;
340 }
341
342 void GDataOperationRegistry::NotifyStatusToObservers() {
343 ProgressStatusList list(GetProgressStatusList());
344 if (ShouldNotifyStatusNow(list))
345 FOR_EACH_OBSERVER(Observer, observer_list_, OnProgressUpdate(list));
346 }
347
306 } // namespace gdata 348 } // namespace gdata
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698