Index: chrome/browser/chromeos/gdata/gdata_operation_registry.cc |
diff --git a/chrome/browser/chromeos/gdata/gdata_operation_registry.cc b/chrome/browser/chromeos/gdata/gdata_operation_registry.cc |
index f1c07ddd5ef8dbc7c8fc48218e8e2092e5a949ce..539b29815bdd7c9eea6379f0a49cffe9fb08fb10 100644 |
--- a/chrome/browser/chromeos/gdata/gdata_operation_registry.cc |
+++ b/chrome/browser/chromeos/gdata/gdata_operation_registry.cc |
@@ -9,6 +9,12 @@ |
using content::BrowserThread; |
+namespace { |
+ |
+const int64 kNotificationFrequencyInMilliseconds = 150; |
zel
2012/07/31 15:24:50
even this looks too frequent to me. let's bring it
kinaba
2012/08/01 02:28:56
OK, now it's 1000ms.
|
+ |
+} // namespace |
+ |
namespace gdata { |
// static |
@@ -137,7 +143,8 @@ void GDataOperationRegistry::Operation::NotifyAuthFailed() { |
registry_->OnOperationAuthFailed(); |
} |
-GDataOperationRegistry::GDataOperationRegistry() { |
+GDataOperationRegistry::GDataOperationRegistry() |
+ : do_notification_frequency_control_(true) { |
in_flight_operations_.set_check_on_null_data(true); |
} |
@@ -153,6 +160,10 @@ void GDataOperationRegistry::RemoveObserver(Observer* observer) { |
observer_list_.RemoveObserver(observer); |
} |
+void GDataOperationRegistry::DisableNotificationFrequencyControlForTest() { |
+ do_notification_frequency_control_ = false; |
+} |
+ |
void GDataOperationRegistry::CancelAll() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
@@ -189,10 +200,8 @@ void GDataOperationRegistry::OnOperationStart( |
*id = in_flight_operations_.Add(operation); |
DVLOG(1) << "GDataOperation[" << *id << "] started."; |
- if (IsFileTransferOperation(operation)) { |
- FOR_EACH_OBSERVER(Observer, observer_list_, |
- OnProgressUpdate(GetProgressStatusList())); |
- } |
+ if (IsFileTransferOperation(operation)) |
+ NotifyStatusToObservers(); |
} |
void GDataOperationRegistry::OnOperationProgress(OperationID id) { |
@@ -203,10 +212,8 @@ void GDataOperationRegistry::OnOperationProgress(OperationID id) { |
DVLOG(1) << "GDataOperation[" << id << "] " |
<< operation->progress_status().DebugString(); |
- if (IsFileTransferOperation(operation)) { |
- FOR_EACH_OBSERVER(Observer, observer_list_, |
- OnProgressUpdate(GetProgressStatusList())); |
- } |
+ if (IsFileTransferOperation(operation)) |
+ NotifyStatusToObservers(); |
} |
void GDataOperationRegistry::OnOperationFinish(OperationID id) { |
@@ -216,10 +223,8 @@ void GDataOperationRegistry::OnOperationFinish(OperationID id) { |
DCHECK(operation); |
DVLOG(1) << "GDataOperation[" << id << "] finished."; |
- if (IsFileTransferOperation(operation)) { |
- FOR_EACH_OBSERVER(Observer, observer_list_, |
- OnProgressUpdate(GetProgressStatusList())); |
- } |
+ if (IsFileTransferOperation(operation)) |
+ NotifyStatusToObservers(); |
in_flight_operations_.Remove(id); |
} |
@@ -256,10 +261,8 @@ void GDataOperationRegistry::OnOperationResume( |
new_status->operation_id = in_flight_operations_.Add(operation); |
DVLOG(1) << "GDataOperation[" << old_id << " -> " << |
new_status->operation_id << "] resumed."; |
- if (IsFileTransferOperation(operation)) { |
- FOR_EACH_OBSERVER(Observer, observer_list_, |
- OnProgressUpdate(GetProgressStatusList())); |
- } |
+ if (IsFileTransferOperation(operation)) |
+ NotifyStatusToObservers(); |
} |
void GDataOperationRegistry::OnOperationSuspend(OperationID id) { |
@@ -269,10 +272,8 @@ void GDataOperationRegistry::OnOperationSuspend(OperationID id) { |
DCHECK(operation); |
DVLOG(1) << "GDataOperation[" << id << "] suspended."; |
- if (IsFileTransferOperation(operation)) { |
- FOR_EACH_OBSERVER(Observer, observer_list_, |
- OnProgressUpdate(GetProgressStatusList())); |
- } |
+ if (IsFileTransferOperation(operation)) |
+ NotifyStatusToObservers(); |
} |
void GDataOperationRegistry::OnOperationAuthFailed() { |
@@ -303,4 +304,45 @@ GDataOperationRegistry::GetProgressStatusList() { |
return status_list; |
} |
+bool GDataOperationRegistry::ShouldNotifyStatusNow( |
+ const ProgressStatusList& list) { |
+ if (!do_notification_frequency_control_) |
+ return true; |
+ |
+ base::Time now = base::Time::Now(); |
+ |
+ // If it is a first event, or some time abnormality is detected, we should |
+ // not skip this notification. |
+ if (last_notification_.is_null() || now < last_notification_) { |
+ last_notification_ = now; |
+ return true; |
+ } |
+ |
+ // If sufficiently long time has elapsed since the previous event, we should |
+ // not skip this notification. |
+ if ((now - last_notification_).InMilliseconds() >= |
+ kNotificationFrequencyInMilliseconds) { |
+ last_notification_ = now; |
+ return true; |
+ } |
+ |
+ // If important events (OPERATION_STARTED, COMPLETED, or FAILED) are there, |
+ // we should not skip this notification. |
+ for (size_t i = 0; i < list.size(); ++i) { |
+ if (list[i].transfer_state != OPERATION_IN_PROGRESS) { |
+ last_notification_ = now; |
+ return true; |
+ } |
+ } |
+ |
+ // Otherwise we can skip it. |
+ return false; |
+} |
+ |
+void GDataOperationRegistry::NotifyStatusToObservers() { |
+ ProgressStatusList list(GetProgressStatusList()); |
+ if (ShouldNotifyStatusNow(list)) |
+ FOR_EACH_OBSERVER(Observer, observer_list_, OnProgressUpdate(list)); |
+} |
+ |
} // namespace gdata |