Chromium Code Reviews| 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 |