Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: chrome/browser/extensions/api/alarms/alarms_api.cc

Issue 11818010: Make chrome.alarms API accept non-integers and too-short delays. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: After discussion, switch to 1-minute minimum alarm time Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/alarms/alarms_api.h" 5 #include "chrome/browser/extensions/api/alarms/alarms_api.h"
6 6
7 #include "base/string_number_conversions.h" 7 #include "base/string_number_conversions.h"
8 #include "base/values.h" 8 #include "base/values.h"
9 #include "chrome/browser/extensions/api/alarms/alarm_manager.h" 9 #include "chrome/browser/extensions/api/alarms/alarm_manager.h"
10 #include "chrome/browser/extensions/extension_system.h" 10 #include "chrome/browser/extensions/extension_system.h"
11 #include "chrome/common/extensions/api/alarms.h" 11 #include "chrome/common/extensions/api/alarms.h"
12 #include "extensions/common/error_utils.h" 12 #include "extensions/common/error_utils.h"
13 13
14 namespace alarms = extensions::api::alarms; 14 namespace alarms = extensions::api::alarms;
15 15
16 namespace extensions { 16 namespace extensions {
17 17
18 namespace { 18 namespace {
19 19
20 const char kDefaultAlarmName[] = ""; 20 const char kDefaultAlarmName[] = "";
21 const char kAlarmNotFound[] = "No alarm named '*' exists."; 21 const char kAlarmNotFound[] = "No alarm named '*' exists.";
22 const char kDelayLessThanMinimum[] = "* is less than minimum of * minutes.";
23 const char kDelayIsNonInteger[] = "* is not an integer value.";
24 const char kBothRelativeAndAbsoluteTime[] = 22 const char kBothRelativeAndAbsoluteTime[] =
25 "Cannot set both when and delayInMinutes."; 23 "Cannot set both when and delayInMinutes.";
26 const char kNoScheduledTime[] = 24 const char kNoScheduledTime[] =
27 "Must set at least one of when, delayInMinutes, or periodInMinutes."; 25 "Must set at least one of when, delayInMinutes, or periodInMinutes.";
28 const int kReleaseDelayMinimum = 5; 26 const int kReleaseDelayMinimum = 1;
29 const int kDevDelayMinimum = 0; 27 const int kDevDelayMinimum = 0;
30 28
31 bool ValidateDelay(double delay_in_minutes, 29 bool ValidateAlarmCreateInfo(const std::string& alarm_name,
32 const Extension* extension, 30 const alarms::AlarmCreateInfo& create_info,
33 const std::string& delay_or_period,
34 std::string* error) {
35 double delay_minimum = kDevDelayMinimum;
36 if (extension->location() != Extension::LOAD) {
37 // In release mode we check for integer delay values and a stricter delay
38 // minimum.
39 if (delay_in_minutes != static_cast<int>(delay_in_minutes)) {
40 *error = ErrorUtils::FormatErrorMessage(
41 kDelayIsNonInteger,
42 delay_or_period);
43 return false;
44 }
45 delay_minimum = kReleaseDelayMinimum;
46 }
47
48 // Validate against our found delay minimum.
49 if (delay_in_minutes < delay_minimum) {
50 *error = ErrorUtils::FormatErrorMessage(
51 kDelayLessThanMinimum,
52 delay_or_period,
53 base::DoubleToString(delay_minimum));
54 return false;
55 }
56
57 return true;
58 }
59
60 bool ValidateAlarmCreateInfo(const alarms::AlarmCreateInfo& create_info,
61 const Extension* extension, 31 const Extension* extension,
62 std::string* error) { 32 std::string* error,
33 std::vector<std::string>* warnings) {
63 if (create_info.delay_in_minutes.get() && 34 if (create_info.delay_in_minutes.get() &&
64 create_info.when.get()) { 35 create_info.when.get()) {
65 *error = kBothRelativeAndAbsoluteTime; 36 *error = kBothRelativeAndAbsoluteTime;
66 return false; 37 return false;
67 } 38 }
68 if (create_info.delay_in_minutes == NULL && 39 if (create_info.delay_in_minutes == NULL &&
69 create_info.when == NULL && 40 create_info.when == NULL &&
70 create_info.period_in_minutes == NULL) { 41 create_info.period_in_minutes == NULL) {
71 *error = kNoScheduledTime; 42 *error = kNoScheduledTime;
72 return false; 43 return false;
73 } 44 }
74 45
75 // Users can always use an absolute timeout to request an arbitrarily-short or 46 // Users can always use an absolute timeout to request an arbitrarily-short or
76 // negative delay. We won't honor the short timeout, but we can't check it 47 // negative delay. We won't honor the short timeout, but we can't check it
77 // and warn the user because it would introduce race conditions (say they 48 // and warn the user because it would introduce race conditions (say they
78 // compute a long-enough timeout, but then the call into the alarms interface 49 // compute a long-enough timeout, but then the call into the alarms interface
79 // gets delayed past the boundary). However, it's still worth warning about 50 // gets delayed past the boundary). However, it's still worth warning about
80 // relative delays that are shorter than we'll honor. 51 // relative delays that are shorter than we'll honor.
81 if (create_info.delay_in_minutes.get()) { 52 if (create_info.delay_in_minutes.get()) {
82 if (!ValidateDelay(*create_info.delay_in_minutes, 53 if (*create_info.delay_in_minutes < kReleaseDelayMinimum) {
83 extension, "Delay", error)) 54 COMPILE_ASSERT(kReleaseDelayMinimum == 1, update_warning_message_below);
84 return false; 55 if (extension->location() == Extension::LOAD)
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"
59 " 1 minutes.",
60 alarm_name));
61 else
62 warnings->push_back(ErrorUtils::FormatErrorMessage(
63 "Alarm delay is less than minimum of 1 minutes."
64 " Alarm \"*\" will fire in approximately 1 minutes.",
65 alarm_name));
66 }
85 } 67 }
86 if (create_info.period_in_minutes.get()) { 68 if (create_info.period_in_minutes.get()) {
87 if (!ValidateDelay(*create_info.period_in_minutes, 69 if (*create_info.period_in_minutes < kReleaseDelayMinimum) {
88 extension, "Period", error)) 70 COMPILE_ASSERT(kReleaseDelayMinimum == 1, update_warning_message_below);
89 return false; 71 if (extension->location() == Extension::LOAD)
72 warnings->push_back(ErrorUtils::FormatErrorMessage(
73 "Alarm period is less than minimum of 1 minutes."
74 " In released .crx, alarm \"*\" will fire approximately"
75 " every 1 minutes.",
76 alarm_name));
77 else
78 warnings->push_back(ErrorUtils::FormatErrorMessage(
79 "Alarm period is less than minimum of 1 minutes."
80 " Alarm \"*\" will fire approximately every 1 minutes.",
81 alarm_name));
82 }
90 } 83 }
91 84
92 return true; 85 return true;
93 } 86 }
94 87
95 } // namespace 88 } // namespace
96 89
97 AlarmsCreateFunction::AlarmsCreateFunction() 90 AlarmsCreateFunction::AlarmsCreateFunction()
98 : now_(&base::Time::Now) { 91 : now_(&base::Time::Now) {
99 } 92 }
100 93
101 bool AlarmsCreateFunction::RunImpl() { 94 bool AlarmsCreateFunction::RunImpl() {
102 scoped_ptr<alarms::Create::Params> params( 95 scoped_ptr<alarms::Create::Params> params(
103 alarms::Create::Params::Create(*args_)); 96 alarms::Create::Params::Create(*args_));
104 EXTENSION_FUNCTION_VALIDATE(params.get()); 97 EXTENSION_FUNCTION_VALIDATE(params.get());
98 const std::string& alarm_name =
99 params->name.get() ? *params->name : kDefaultAlarmName;
100 std::vector<std::string> warnings;
105 if (!ValidateAlarmCreateInfo( 101 if (!ValidateAlarmCreateInfo(
106 params->alarm_info, GetExtension(), &error_)) 102 alarm_name, params->alarm_info, GetExtension(), &error_, &warnings))
107 return false; 103 return false;
104 for (std::vector<std::string>::const_iterator it = warnings.begin();
105 it != warnings.end(); ++it)
106 WriteToConsole(content::CONSOLE_MESSAGE_LEVEL_WARNING, *it);
108 107
109 Alarm alarm(params->name.get() ? *params->name : kDefaultAlarmName, 108 Alarm alarm(alarm_name,
110 params->alarm_info, 109 params->alarm_info,
111 base::TimeDelta::FromMinutes( 110 base::TimeDelta::FromMinutes(
112 GetExtension()->location() == Extension::LOAD ? 111 GetExtension()->location() == Extension::LOAD ?
113 kDevDelayMinimum : kReleaseDelayMinimum), 112 kDevDelayMinimum : kReleaseDelayMinimum),
114 now_); 113 now_);
115 ExtensionSystem::Get(profile())->alarm_manager()->AddAlarm( 114 ExtensionSystem::Get(profile())->alarm_manager()->AddAlarm(
116 extension_id(), alarm); 115 extension_id(), alarm);
117 116
118 return true; 117 return true;
119 } 118 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 return true; 169 return true;
171 } 170 }
172 171
173 bool AlarmsClearAllFunction::RunImpl() { 172 bool AlarmsClearAllFunction::RunImpl() {
174 ExtensionSystem::Get(profile())->alarm_manager()->RemoveAllAlarms( 173 ExtensionSystem::Get(profile())->alarm_manager()->RemoveAllAlarms(
175 extension_id()); 174 extension_id());
176 return true; 175 return true;
177 } 176 }
178 177
179 } // namespace extensions 178 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698