1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/alarms/alarms_api.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/time/clock.h"
9 #include "base/time/default_clock.h"
10 #include "base/values.h"
11 #include "chrome/browser/extensions/api/alarms/alarm_manager.h"
12 #include "chrome/common/extensions/api/alarms.h"
13 #include "extensions/common/error_utils.h"
15 namespace alarms
= extensions::api::alarms
;
17 namespace extensions
{
21 const char kDefaultAlarmName
[] = "";
22 const char kBothRelativeAndAbsoluteTime
[] =
23 "Cannot set both when and delayInMinutes.";
24 const char kNoScheduledTime
[] =
25 "Must set at least one of when, delayInMinutes, or periodInMinutes.";
26 const int kReleaseDelayMinimum
= 1;
27 const int kDevDelayMinimum
= 0;
29 bool ValidateAlarmCreateInfo(const std::string
& alarm_name
,
30 const alarms::AlarmCreateInfo
& create_info
,
31 const Extension
* extension
,
33 std::vector
<std::string
>* warnings
) {
34 if (create_info
.delay_in_minutes
.get() &&
35 create_info
.when
.get()) {
36 *error
= kBothRelativeAndAbsoluteTime
;
39 if (create_info
.delay_in_minutes
== NULL
&&
40 create_info
.when
== NULL
&&
41 create_info
.period_in_minutes
== NULL
) {
42 *error
= kNoScheduledTime
;
46 // Users can always use an absolute timeout to request an arbitrarily-short or
47 // negative delay. We won't honor the short timeout, but we can't check it
48 // and warn the user because it would introduce race conditions (say they
49 // compute a long-enough timeout, but then the call into the alarms interface
50 // gets delayed past the boundary). However, it's still worth warning about
51 // relative delays that are shorter than we'll honor.
52 if (create_info
.delay_in_minutes
.get()) {
53 if (*create_info
.delay_in_minutes
< kReleaseDelayMinimum
) {
54 COMPILE_ASSERT(kReleaseDelayMinimum
== 1, update_warning_message_below
);
55 if (Manifest::IsUnpackedLocation(extension
->location()))
56 warnings
->push_back(ErrorUtils::FormatErrorMessage(
57 "Alarm delay is less than minimum of 1 minutes."
58 " In released .crx, alarm \"*\" will fire in approximately"
62 warnings
->push_back(ErrorUtils::FormatErrorMessage(
63 "Alarm delay is less than minimum of 1 minutes."
64 " Alarm \"*\" will fire in approximately 1 minutes.",
68 if (create_info
.period_in_minutes
.get()) {
69 if (*create_info
.period_in_minutes
< kReleaseDelayMinimum
) {
70 COMPILE_ASSERT(kReleaseDelayMinimum
== 1, update_warning_message_below
);
71 if (Manifest::IsUnpackedLocation(extension
->location()))
72 warnings
->push_back(ErrorUtils::FormatErrorMessage(
73 "Alarm period is less than minimum of 1 minutes."
74 " In released .crx, alarm \"*\" will fire approximately"
78 warnings
->push_back(ErrorUtils::FormatErrorMessage(
79 "Alarm period is less than minimum of 1 minutes."
80 " Alarm \"*\" will fire approximately every 1 minutes.",
90 AlarmsCreateFunction::AlarmsCreateFunction()
91 : clock_(new base::DefaultClock()), owns_clock_(true) {}
93 AlarmsCreateFunction::AlarmsCreateFunction(base::Clock
* clock
)
94 : clock_(clock
), owns_clock_(false) {}
96 AlarmsCreateFunction::~AlarmsCreateFunction() {
101 bool AlarmsCreateFunction::RunAsync() {
102 scoped_ptr
<alarms::Create::Params
> params(
103 alarms::Create::Params::Create(*args_
));
104 EXTENSION_FUNCTION_VALIDATE(params
.get());
105 const std::string
& alarm_name
=
106 params
->name
.get() ? *params
->name
: kDefaultAlarmName
;
107 std::vector
<std::string
> warnings
;
108 if (!ValidateAlarmCreateInfo(
109 alarm_name
, params
->alarm_info
, GetExtension(), &error_
, &warnings
)) {
112 for (std::vector
<std::string
>::const_iterator it
= warnings
.begin();
113 it
!= warnings
.end(); ++it
)
114 WriteToConsole(content::CONSOLE_MESSAGE_LEVEL_WARNING
, *it
);
116 Alarm
alarm(alarm_name
,
118 base::TimeDelta::FromMinutes(
119 Manifest::IsUnpackedLocation(GetExtension()->location()) ?
120 kDevDelayMinimum
: kReleaseDelayMinimum
),
122 AlarmManager::Get(GetProfile())->AddAlarm(
123 extension_id(), alarm
, base::Bind(&AlarmsCreateFunction::Callback
, this));
128 void AlarmsCreateFunction::Callback() {
132 bool AlarmsGetFunction::RunAsync() {
133 scoped_ptr
<alarms::Get::Params
> params(alarms::Get::Params::Create(*args_
));
134 EXTENSION_FUNCTION_VALIDATE(params
.get());
136 std::string name
= params
->name
.get() ? *params
->name
: kDefaultAlarmName
;
137 AlarmManager::Get(GetProfile())
138 ->GetAlarm(extension_id(),
140 base::Bind(&AlarmsGetFunction::Callback
, this, name
));
145 void AlarmsGetFunction::Callback(
146 const std::string
& name
, extensions::Alarm
* alarm
) {
148 results_
= alarms::Get::Results::Create(*alarm
->js_alarm
);
153 bool AlarmsGetAllFunction::RunAsync() {
154 AlarmManager::Get(GetProfile())->GetAllAlarms(
155 extension_id(), base::Bind(&AlarmsGetAllFunction::Callback
, this));
159 void AlarmsGetAllFunction::Callback(const AlarmList
* alarms
) {
161 std::vector
<linked_ptr
<extensions::api::alarms::Alarm
> > create_arg
;
162 create_arg
.reserve(alarms
->size());
163 for (size_t i
= 0, size
= alarms
->size(); i
< size
; ++i
) {
164 create_arg
.push_back((*alarms
)[i
].js_alarm
);
166 results_
= alarms::GetAll::Results::Create(create_arg
);
168 SetResult(new base::ListValue());
173 bool AlarmsClearFunction::RunAsync() {
174 scoped_ptr
<alarms::Clear::Params
> params(
175 alarms::Clear::Params::Create(*args_
));
176 EXTENSION_FUNCTION_VALIDATE(params
.get());
178 std::string name
= params
->name
.get() ? *params
->name
: kDefaultAlarmName
;
179 AlarmManager::Get(GetProfile())
180 ->RemoveAlarm(extension_id(),
182 base::Bind(&AlarmsClearFunction::Callback
, this, name
));
187 void AlarmsClearFunction::Callback(const std::string
& name
, bool success
) {
188 SetResult(new base::FundamentalValue(success
));
192 bool AlarmsClearAllFunction::RunAsync() {
193 AlarmManager::Get(GetProfile())->RemoveAllAlarms(
194 extension_id(), base::Bind(&AlarmsClearAllFunction::Callback
, this));
198 void AlarmsClearAllFunction::Callback() {
199 SetResult(new base::FundamentalValue(true));
203 } // namespace extensions