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 "extensions/browser/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 "extensions/browser/api/alarms/alarm_manager.h"
12 #include "extensions/common/api/alarms.h"
13 #include "extensions/common/error_utils.h"
15 namespace extensions
{
17 namespace alarms
= api::alarms
;
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() && create_info
.when
.get()) {
35 *error
= kBothRelativeAndAbsoluteTime
;
38 if (create_info
.delay_in_minutes
== NULL
&& create_info
.when
== NULL
&&
39 create_info
.period_in_minutes
== NULL
) {
40 *error
= kNoScheduledTime
;
44 // Users can always use an absolute timeout to request an arbitrarily-short or
45 // negative delay. We won't honor the short timeout, but we can't check it
46 // and warn the user because it would introduce race conditions (say they
47 // compute a long-enough timeout, but then the call into the alarms interface
48 // gets delayed past the boundary). However, it's still worth warning about
49 // relative delays that are shorter than we'll honor.
50 if (create_info
.delay_in_minutes
.get()) {
51 if (*create_info
.delay_in_minutes
< kReleaseDelayMinimum
) {
52 static_assert(kReleaseDelayMinimum
== 1,
53 "warning message must be updated");
54 if (Manifest::IsUnpackedLocation(extension
->location()))
55 warnings
->push_back(ErrorUtils::FormatErrorMessage(
56 "Alarm delay is less than minimum of 1 minutes."
57 " In released .crx, alarm \"*\" will fire in approximately"
61 warnings
->push_back(ErrorUtils::FormatErrorMessage(
62 "Alarm delay is less than minimum of 1 minutes."
63 " Alarm \"*\" will fire in approximately 1 minutes.",
67 if (create_info
.period_in_minutes
.get()) {
68 if (*create_info
.period_in_minutes
< kReleaseDelayMinimum
) {
69 static_assert(kReleaseDelayMinimum
== 1,
70 "warning message must be updated");
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) {
94 AlarmsCreateFunction::AlarmsCreateFunction(base::Clock
* clock
)
95 : clock_(clock
), owns_clock_(false) {
98 AlarmsCreateFunction::~AlarmsCreateFunction() {
103 bool AlarmsCreateFunction::RunAsync() {
104 scoped_ptr
<alarms::Create::Params
> params(
105 alarms::Create::Params::Create(*args_
));
106 EXTENSION_FUNCTION_VALIDATE(params
.get());
107 const std::string
& alarm_name
=
108 params
->name
.get() ? *params
->name
: kDefaultAlarmName
;
109 std::vector
<std::string
> warnings
;
110 if (!ValidateAlarmCreateInfo(alarm_name
, params
->alarm_info
, extension(),
111 &error_
, &warnings
)) {
114 for (std::vector
<std::string
>::const_iterator it
= warnings
.begin();
115 it
!= warnings
.end(); ++it
)
116 WriteToConsole(content::CONSOLE_MESSAGE_LEVEL_WARNING
, *it
);
118 Alarm
alarm(alarm_name
, params
->alarm_info
,
119 base::TimeDelta::FromMinutes(
120 Manifest::IsUnpackedLocation(extension()->location())
122 : kReleaseDelayMinimum
),
124 AlarmManager::Get(browser_context())
125 ->AddAlarm(extension_id(), alarm
,
126 base::Bind(&AlarmsCreateFunction::Callback
, this));
131 void AlarmsCreateFunction::Callback() {
135 bool AlarmsGetFunction::RunAsync() {
136 scoped_ptr
<alarms::Get::Params
> params(alarms::Get::Params::Create(*args_
));
137 EXTENSION_FUNCTION_VALIDATE(params
.get());
139 std::string name
= params
->name
.get() ? *params
->name
: kDefaultAlarmName
;
140 AlarmManager::Get(browser_context())
141 ->GetAlarm(extension_id(), name
,
142 base::Bind(&AlarmsGetFunction::Callback
, this, name
));
147 void AlarmsGetFunction::Callback(const std::string
& name
,
148 extensions::Alarm
* alarm
) {
150 results_
= alarms::Get::Results::Create(*alarm
->js_alarm
);
155 bool AlarmsGetAllFunction::RunAsync() {
156 AlarmManager::Get(browser_context())
157 ->GetAllAlarms(extension_id(),
158 base::Bind(&AlarmsGetAllFunction::Callback
, this));
162 void AlarmsGetAllFunction::Callback(const AlarmList
* alarms
) {
164 std::vector
<linked_ptr
<alarms::Alarm
>> create_arg
;
165 create_arg
.reserve(alarms
->size());
166 for (size_t i
= 0, size
= alarms
->size(); i
< size
; ++i
) {
167 create_arg
.push_back((*alarms
)[i
].js_alarm
);
169 results_
= alarms::GetAll::Results::Create(create_arg
);
171 SetResult(new base::ListValue());
176 bool AlarmsClearFunction::RunAsync() {
177 scoped_ptr
<alarms::Clear::Params
> params(
178 alarms::Clear::Params::Create(*args_
));
179 EXTENSION_FUNCTION_VALIDATE(params
.get());
181 std::string name
= params
->name
.get() ? *params
->name
: kDefaultAlarmName
;
182 AlarmManager::Get(browser_context())
183 ->RemoveAlarm(extension_id(), name
,
184 base::Bind(&AlarmsClearFunction::Callback
, this, name
));
189 void AlarmsClearFunction::Callback(const std::string
& name
, bool success
) {
190 SetResult(new base::FundamentalValue(success
));
194 bool AlarmsClearAllFunction::RunAsync() {
195 AlarmManager::Get(browser_context())
196 ->RemoveAllAlarms(extension_id(),
197 base::Bind(&AlarmsClearAllFunction::Callback
, this));
201 void AlarmsClearAllFunction::Callback() {
202 SetResult(new base::FundamentalValue(true));
206 } // namespace extensions