1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/alarms/alarms_api.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/clock.h"
#include "base/time/default_clock.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/alarms/alarm_manager.h"
#include "chrome/common/extensions/api/alarms.h"
#include "extensions/common/error_utils.h"
namespace alarms = extensions::api::alarms;
namespace extensions {
namespace {
const char kDefaultAlarmName[] = "";
const char kAlarmNotFound[] = "No alarm named '*' exists.";
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 = 1;
const int kDevDelayMinimum = 0;
bool ValidateAlarmCreateInfo(const std::string& alarm_name,
const alarms::AlarmCreateInfo& create_info,
const Extension* extension,
std::string* error,
std::vector<std::string>* warnings) {
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 (*create_info.delay_in_minutes < kReleaseDelayMinimum) {
COMPILE_ASSERT(kReleaseDelayMinimum == 1, update_warning_message_below);
if (Manifest::IsUnpackedLocation(extension->location()))
warnings->push_back(ErrorUtils::FormatErrorMessage(
"Alarm delay is less than minimum of 1 minutes."
" In released .crx, alarm \"*\" will fire in approximately"
" 1 minutes.",
alarm_name));
else
warnings->push_back(ErrorUtils::FormatErrorMessage(
"Alarm delay is less than minimum of 1 minutes."
" Alarm \"*\" will fire in approximately 1 minutes.",
alarm_name));
}
}
if (create_info.period_in_minutes.get()) {
if (*create_info.period_in_minutes < kReleaseDelayMinimum) {
COMPILE_ASSERT(kReleaseDelayMinimum == 1, update_warning_message_below);
if (Manifest::IsUnpackedLocation(extension->location()))
warnings->push_back(ErrorUtils::FormatErrorMessage(
"Alarm period is less than minimum of 1 minutes."
" In released .crx, alarm \"*\" will fire approximately"
" every 1 minutes.",
alarm_name));
else
warnings->push_back(ErrorUtils::FormatErrorMessage(
"Alarm period is less than minimum of 1 minutes."
" Alarm \"*\" will fire approximately every 1 minutes.",
alarm_name));
}
}
return true;
}
} // namespace
AlarmsCreateFunction::AlarmsCreateFunction()
: clock_(new base::DefaultClock()), owns_clock_(true) {}
AlarmsCreateFunction::AlarmsCreateFunction(base::Clock* clock)
: clock_(clock), owns_clock_(false) {}
AlarmsCreateFunction::~AlarmsCreateFunction() {
if (owns_clock_)
delete clock_;
}
bool AlarmsCreateFunction::RunImpl() {
scoped_ptr<alarms::Create::Params> params(
alarms::Create::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
const std::string& alarm_name =
params->name.get() ? *params->name : kDefaultAlarmName;
std::vector<std::string> warnings;
if (!ValidateAlarmCreateInfo(
alarm_name, params->alarm_info, GetExtension(), &error_, &warnings))
return false;
for (std::vector<std::string>::const_iterator it = warnings.begin();
it != warnings.end(); ++it)
WriteToConsole(content::CONSOLE_MESSAGE_LEVEL_WARNING, *it);
Alarm alarm(alarm_name,
params->alarm_info,
base::TimeDelta::FromMinutes(
Manifest::IsUnpackedLocation(GetExtension()->location()) ?
kDevDelayMinimum : kReleaseDelayMinimum),
clock_->Now());
AlarmManager::Get(profile())->AddAlarm(extension_id(), alarm);
return true;
}
bool AlarmsGetFunction::RunImpl() {
scoped_ptr<alarms::Get::Params> params(alarms::Get::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
std::string name = params->name.get() ? *params->name : kDefaultAlarmName;
const Alarm* alarm =
AlarmManager::Get(profile())->GetAlarm(extension_id(), name);
if (!alarm) {
error_ = ErrorUtils::FormatErrorMessage(kAlarmNotFound, name);
return false;
}
results_ = alarms::Get::Results::Create(*alarm->js_alarm);
return true;
}
bool AlarmsGetAllFunction::RunImpl() {
const AlarmManager::AlarmList* alarms =
AlarmManager::Get(profile())->GetAllAlarms(extension_id());
if (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);
}
results_ = alarms::GetAll::Results::Create(create_arg);
} else {
SetResult(new base::ListValue());
}
return true;
}
bool AlarmsClearFunction::RunImpl() {
scoped_ptr<alarms::Clear::Params> params(
alarms::Clear::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
std::string name = params->name.get() ? *params->name : kDefaultAlarmName;
bool success = AlarmManager::Get(profile())->RemoveAlarm(extension_id(),
name);
if (!success) {
error_ = ErrorUtils::FormatErrorMessage(kAlarmNotFound, name);
return false;
}
return true;
}
bool AlarmsClearAllFunction::RunImpl() {
AlarmManager::Get(profile())->RemoveAllAlarms(extension_id());
return true;
}
} // namespace extensions
|