Index: chrome/browser/extensions/api/alarms/alarms_api.cc |
diff --git a/chrome/browser/extensions/api/alarms/alarms_api.cc b/chrome/browser/extensions/api/alarms/alarms_api.cc |
index 8591f01d0447de18b625771ec8c358e181c9925e..0214905330171f40c89e4fe5d34fcda58f35114f 100644 |
--- a/chrome/browser/extensions/api/alarms/alarms_api.cc |
+++ b/chrome/browser/extensions/api/alarms/alarms_api.cc |
@@ -21,49 +21,85 @@ const char kDefaultAlarmName[] = ""; |
const char kAlarmNotFound[] = "No alarm named '*' exists."; |
const char kDelayLessThanMinimum[] = "Delay is less than minimum of * minutes."; |
const char kDelayIsNonInteger[] = "Delay is not an integer value."; |
- |
+const char kBothRelativeAndAbsoluteTime[] = |
+ "Cannot set both approxTimeToFire and delayInMinutes."; |
+const char kNeitherRelativeNorAbsoluteTime[] = |
+ "Must set one of approxTimeToFire and delayInMinutes."; |
+const char kRepeatingAlarmMustBeRelative[] = |
+ "A repeating alarm must set delayInMinutes."; |
const int kReleaseDelayMinimum = 5; |
const int kDevDelayMinimum = 0; |
-bool ValidateDelayTime(double delay_in_minutes, |
- const Extension* extension, |
- std::string* error) { |
- double delay_minimum = kDevDelayMinimum; |
- if (extension->location() != Extension::LOAD) { |
- // In release mode we check for integer delay values and a stricter delay |
- // minimum. |
- if (delay_in_minutes != static_cast<int>(delay_in_minutes)) { |
- *error = kDelayIsNonInteger; |
+bool ValidateAlarmCreateInfo(const alarms::AlarmCreateInfo& create_info, |
+ const Extension* extension, |
+ std::string* error) { |
+ if (create_info.delay_in_minutes.get() && |
+ create_info.approx_time_to_fire.get()) { |
+ *error = kBothRelativeAndAbsoluteTime; |
+ return false; |
+ } |
+ if (create_info.delay_in_minutes == NULL && |
+ create_info.approx_time_to_fire == NULL) { |
+ *error = kNeitherRelativeNorAbsoluteTime; |
+ return false; |
+ } |
+ const bool repeating = create_info.repeating.get() ? |
+ *create_info.repeating : false; |
+ if (repeating && create_info.approx_time_to_fire.get()) { |
+ *error = kRepeatingAlarmMustBeRelative; |
+ return false; |
+ } |
+ |
+ // Users can always use an absolute timeout to request an arbitrarily-short or |
+ // negative delay. We won't honor the short timeout, but we can't check it |
+ // and warn the user because it would introduce race conditions (say they |
+ // compute a long-enough timeout, but then the call into the alarms interface |
+ // gets delayed past the boundary). However, it's still worth warning about |
+ // relative delays that are shorter than we'll honor. |
+ if (create_info.delay_in_minutes.get()) { |
+ const double delay_in_minutes = *create_info.delay_in_minutes; |
+ double delay_minimum = kDevDelayMinimum; |
+ if (extension->location() != Extension::LOAD) { |
+ // In release mode we check for integer delay values and a stricter delay |
+ // minimum. |
+ if (delay_in_minutes != static_cast<int>(delay_in_minutes)) { |
+ *error = kDelayIsNonInteger; |
+ return false; |
+ } |
+ delay_minimum = kReleaseDelayMinimum; |
+ } |
+ |
+ // Validate against our found delay minimum. |
+ if (delay_in_minutes < delay_minimum) { |
+ *error = ExtensionErrorUtils::FormatErrorMessage( |
+ kDelayLessThanMinimum, |
+ base::DoubleToString(delay_minimum)); |
return false; |
} |
- delay_minimum = kReleaseDelayMinimum; |
} |
- // Validate against our found delay minimum. |
- if (delay_in_minutes < delay_minimum) { |
- *error = ExtensionErrorUtils::FormatErrorMessage(kDelayLessThanMinimum, |
- base::DoubleToString(delay_minimum)); |
- return false; |
- } |
return true; |
} |
} // namespace |
+AlarmsCreateFunction::AlarmsCreateFunction() |
+ : now_(&base::Time::Now) { |
+} |
+ |
bool AlarmsCreateFunction::RunImpl() { |
scoped_ptr<alarms::Create::Params> params( |
alarms::Create::Params::Create(*args_)); |
EXTENSION_FUNCTION_VALIDATE(params.get()); |
- |
- double delay_in_minutes = params->alarm_info.delay_in_minutes; |
- if (!ValidateDelayTime(delay_in_minutes, GetExtension(), &error_)) |
+ if (!ValidateAlarmCreateInfo(params->alarm_info, GetExtension(), &error_)) |
return false; |
- linked_ptr<AlarmManager::Alarm> alarm(new AlarmManager::Alarm()); |
- alarm->name = params->name.get() ? *params->name : kDefaultAlarmName; |
- alarm->delay_in_minutes = params->alarm_info.delay_in_minutes; |
- alarm->repeating = params->alarm_info.repeating.get() ? |
- *params->alarm_info.repeating : false; |
+ Alarm alarm(params->name.get() ? *params->name : kDefaultAlarmName, |
+ params->alarm_info, |
+ base::TimeDelta::FromMinutes( |
+ GetExtension()->location() == Extension::LOAD |
+ ? kDevDelayMinimum : kReleaseDelayMinimum), |
+ now_); |
ExtensionSystem::Get(profile())->alarm_manager()->AddAlarm( |
extension_id(), alarm); |
@@ -76,7 +112,7 @@ bool AlarmsGetFunction::RunImpl() { |
EXTENSION_FUNCTION_VALIDATE(params.get()); |
std::string name = params->name.get() ? *params->name : kDefaultAlarmName; |
- const AlarmManager::Alarm* alarm = |
+ const Alarm* alarm = |
ExtensionSystem::Get(profile())->alarm_manager()->GetAlarm( |
extension_id(), name); |
@@ -85,7 +121,7 @@ bool AlarmsGetFunction::RunImpl() { |
return false; |
} |
- result_.reset(alarms::Get::Result::Create(*alarm)); |
+ result_.reset(alarms::Get::Result::Create(*alarm->js_alarm)); |
return true; |
} |
@@ -94,7 +130,12 @@ bool AlarmsGetAllFunction::RunImpl() { |
ExtensionSystem::Get(profile())->alarm_manager()->GetAllAlarms( |
extension_id()); |
if (alarms) { |
- result_.reset(alarms::GetAll::Result::Create(*alarms)); |
+ std::vector<linked_ptr<extensions::api::alarms::Alarm> > create_arg; |
+ create_arg.reserve(alarms->size()); |
+ for (size_t i = 0, size = alarms->size(); i < size; ++i) { |
+ create_arg.push_back((*alarms)[i].js_alarm); |
+ } |
+ result_.reset(alarms::GetAll::Result::Create(create_arg)); |
} else { |
result_.reset(new base::ListValue()); |
} |