| Index: chrome/browser/extensions/api/alarms/alarm_manager.cc
|
| diff --git a/chrome/browser/extensions/api/alarms/alarm_manager.cc b/chrome/browser/extensions/api/alarms/alarm_manager.cc
|
| index 17a48898c3b2317fc039120069fcbe6af7426cbb..f6c508012f96ad3865888c74cfd67e9a17be1bfe 100644
|
| --- a/chrome/browser/extensions/api/alarms/alarm_manager.cc
|
| +++ b/chrome/browser/extensions/api/alarms/alarm_manager.cc
|
| @@ -9,8 +9,12 @@
|
| #include "base/message_loop.h"
|
| #include "base/values.h"
|
| #include "chrome/browser/extensions/extension_event_router.h"
|
| +#include "chrome/browser/extensions/extension_prefs.h"
|
| +#include "chrome/browser/extensions/extension_service.h"
|
| #include "chrome/browser/extensions/extension_system.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/common/chrome_notification_types.h"
|
| +#include "content/public/browser/notification_service.h"
|
|
|
| namespace extensions {
|
|
|
| @@ -42,6 +46,8 @@ class DefaultAlarmDelegate : public AlarmManager::Delegate {
|
| AlarmManager::AlarmManager(Profile* profile)
|
| : profile_(profile),
|
| delegate_(new DefaultAlarmDelegate(profile)) {
|
| + registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
|
| + content::Source<Profile>(profile_));
|
| }
|
|
|
| AlarmManager::~AlarmManager() {
|
| @@ -49,21 +55,9 @@ AlarmManager::~AlarmManager() {
|
|
|
| void AlarmManager::AddAlarm(const std::string& extension_id,
|
| const linked_ptr<Alarm>& alarm) {
|
| - // TODO(mpcomplete): Better handling of granularity.
|
| - // http://crbug.com/122683
|
| -
|
| - // Override any old alarm with the same name.
|
| - AlarmIterator old_alarm = GetAlarmIterator(extension_id, alarm->name);
|
| - if (old_alarm.first != alarms_.end())
|
| - RemoveAlarmIterator(old_alarm);
|
| -
|
| - alarms_[extension_id].push_back(alarm);
|
| - base::Timer* timer = new base::Timer(true, alarm->repeating);
|
| - timers_[alarm.get()] = make_linked_ptr(timer);
|
| - timer->Start(FROM_HERE,
|
| - base::TimeDelta::FromSeconds(alarm->delay_in_seconds),
|
| - base::Bind(&AlarmManager::OnAlarm, base::Unretained(this),
|
| - extension_id, alarm->name));
|
| + AddAlarmImpl(extension_id, alarm,
|
| + base::TimeDelta::FromSeconds(alarm->delay_in_seconds));
|
| + WriteToPrefs(extension_id);
|
| }
|
|
|
| const AlarmManager::Alarm* AlarmManager::GetAlarm(
|
| @@ -102,7 +96,9 @@ bool AlarmManager::RemoveAlarm(const std::string& extension_id,
|
| AlarmIterator it = GetAlarmIterator(extension_id, name);
|
| if (it.first == alarms_.end())
|
| return false;
|
| +
|
| RemoveAlarmIterator(it);
|
| + WriteToPrefs(extension_id);
|
| return true;
|
| }
|
|
|
| @@ -117,6 +113,7 @@ void AlarmManager::RemoveAllAlarms(const std::string& extension_id) {
|
| RemoveAlarmIterator(AlarmIterator(list, list->second.begin()));
|
|
|
| CHECK(alarms_.find(extension_id) == alarms_.end());
|
| + WriteToPrefs(extension_id);
|
| }
|
|
|
| void AlarmManager::RemoveAlarmIterator(const AlarmIterator& iter) {
|
| @@ -135,10 +132,106 @@ void AlarmManager::OnAlarm(const std::string& extension_id,
|
| const std::string& name) {
|
| AlarmIterator it = GetAlarmIterator(extension_id, name);
|
| CHECK(it.first != alarms_.end());
|
| - delegate_->OnAlarm(extension_id, *it.second->get());
|
| + const Alarm* alarm = it.second->get();
|
| + delegate_->OnAlarm(extension_id, *alarm);
|
|
|
| - if (!(*it.second)->repeating)
|
| + if (!alarm->repeating) {
|
| RemoveAlarmIterator(it);
|
| + } else {
|
| + // Restart the timer, since it may have been set with a shorter delay
|
| + // initially.
|
| + base::Timer* timer = timers_[alarm].get();
|
| + timer->Start(FROM_HERE,
|
| + base::TimeDelta::FromSeconds(alarm->delay_in_seconds),
|
| + base::Bind(&AlarmManager::OnAlarm, base::Unretained(this),
|
| + extension_id, alarm->name));
|
| + }
|
| +
|
| + WriteToPrefs(extension_id);
|
| +}
|
| +
|
| +void AlarmManager::AddAlarmImpl(const std::string& extension_id,
|
| + const linked_ptr<Alarm>& alarm,
|
| + base::TimeDelta timer_delay) {
|
| + // Override any old alarm with the same name.
|
| + AlarmIterator old_alarm = GetAlarmIterator(extension_id, alarm->name);
|
| + if (old_alarm.first != alarms_.end())
|
| + RemoveAlarmIterator(old_alarm);
|
| +
|
| + alarms_[extension_id].push_back(alarm);
|
| +
|
| + base::Timer* timer = new base::Timer(true, alarm->repeating);
|
| + timers_[alarm.get()] = make_linked_ptr(timer);
|
| + timer->Start(FROM_HERE,
|
| + timer_delay,
|
| + base::Bind(&AlarmManager::OnAlarm, base::Unretained(this),
|
| + extension_id, alarm->name));
|
| +}
|
| +
|
| +void AlarmManager::WriteToPrefs(const std::string& extension_id) {
|
| + ExtensionService* service =
|
| + ExtensionSystem::Get(profile_)->extension_service();
|
| + if (!service || !service->extension_prefs())
|
| + return;
|
| +
|
| + std::vector<AlarmPref> alarm_prefs;
|
| +
|
| + AlarmMap::iterator list = alarms_.find(extension_id);
|
| + if (list != alarms_.end()) {
|
| + for (AlarmList::iterator it = list->second.begin();
|
| + it != list->second.end(); ++it) {
|
| + base::Timer* timer = timers_[it->get()].get();
|
| + base::TimeDelta delay =
|
| + timer->desired_run_time() - base::TimeTicks::Now();
|
| + AlarmPref pref;
|
| + pref.alarm = *it;
|
| + pref.scheduled_run_time = base::Time::Now() + delay;
|
| + alarm_prefs.push_back(pref);
|
| + }
|
| + }
|
| +
|
| + service->extension_prefs()->SetRegisteredAlarms(extension_id, alarm_prefs);
|
| +}
|
| +
|
| +void AlarmManager::ReadFromPrefs(const std::string& extension_id) {
|
| + ExtensionService* service =
|
| + ExtensionSystem::Get(profile_)->extension_service();
|
| + if (!service || !service->extension_prefs())
|
| + return;
|
| +
|
| + std::vector<AlarmPref> alarm_prefs =
|
| + service->extension_prefs()->GetRegisteredAlarms(extension_id);
|
| + for (size_t i = 0; i < alarm_prefs.size(); ++i) {
|
| + base::TimeDelta delay =
|
| + alarm_prefs[i].scheduled_run_time - base::Time::Now();
|
| + if (delay < base::TimeDelta::FromSeconds(0))
|
| + delay = base::TimeDelta::FromSeconds(0);
|
| +
|
| + AddAlarmImpl(extension_id, alarm_prefs[i].alarm, delay);
|
| + }
|
| +}
|
| +
|
| +void AlarmManager::Observe(
|
| + int type,
|
| + const content::NotificationSource& source,
|
| + const content::NotificationDetails& details) {
|
| + switch (type) {
|
| + case chrome::NOTIFICATION_EXTENSION_LOADED: {
|
| + const Extension* extension =
|
| + content::Details<const Extension>(details).ptr();
|
| + ReadFromPrefs(extension->id());
|
| + break;
|
| + }
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +}
|
| +
|
| +AlarmPref::AlarmPref() {
|
| +}
|
| +
|
| +AlarmPref::~AlarmPref() {
|
| }
|
|
|
| } // namespace extensions
|
|
|