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..72101b61ac02698dd4ba091b24061da34e87a8bb 100644 |
--- a/chrome/browser/extensions/api/alarms/alarms_api.cc |
+++ b/chrome/browser/extensions/api/alarms/alarms_api.cc |
@@ -19,21 +19,27 @@ namespace { |
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 kDelayLessThanMinimum[] = "* is less than minimum of * minutes."; |
+const char kDelayIsNonInteger[] = "* is not an integer value."; |
+const char kBothRelativeAndAbsoluteTime[] = |
+ "Cannot set both when and delayInMinutes."; |
+const char kNoScheduledTime[] = |
+ "Must set at least one of when, delayInMinutes, or periodInMinutes."; |
const int kReleaseDelayMinimum = 5; |
const int kDevDelayMinimum = 0; |
-bool ValidateDelayTime(double delay_in_minutes, |
- const Extension* extension, |
- std::string* error) { |
+bool ValidateDelay(double delay_in_minutes, |
+ const Extension* extension, |
+ const std::string& delay_or_period, |
+ 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; |
+ *error = ExtensionErrorUtils::FormatErrorMessage( |
+ kDelayIsNonInteger, |
+ delay_or_period); |
return false; |
} |
delay_minimum = kReleaseDelayMinimum; |
@@ -41,29 +47,71 @@ bool ValidateDelayTime(double delay_in_minutes, |
// Validate against our found delay minimum. |
if (delay_in_minutes < delay_minimum) { |
- *error = ExtensionErrorUtils::FormatErrorMessage(kDelayLessThanMinimum, |
+ *error = ExtensionErrorUtils::FormatErrorMessage( |
+ kDelayLessThanMinimum, |
+ delay_or_period, |
base::DoubleToString(delay_minimum)); |
return false; |
} |
+ |
+ return true; |
+} |
+ |
+bool ValidateAlarmCreateInfo(const alarms::AlarmCreateInfo& create_info, |
+ const Extension* extension, |
+ std::string* error) { |
+ if (create_info.delay_in_minutes.get() && |
+ create_info.when.get()) { |
+ *error = kBothRelativeAndAbsoluteTime; |
+ return false; |
+ } |
+ if (create_info.delay_in_minutes == NULL && |
+ create_info.when == NULL && |
+ create_info.period_in_minutes == NULL) { |
+ *error = kNoScheduledTime; |
+ 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()) { |
+ if (!ValidateDelay(*create_info.delay_in_minutes, |
+ extension, "Delay", error)) |
+ return false; |
+ } |
+ if (create_info.period_in_minutes.get()) { |
+ if (!ValidateDelay(*create_info.period_in_minutes, |
+ extension, "Period", error)) |
+ 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 +124,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 +133,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 +142,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()); |
} |