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

Unified Diff: chrome/browser/extensions/api/alarms/alarms_api_unittest.cc

Issue 22900005: Fixing race conditions in chrome.alarms (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/alarms/alarms_api_unittest.cc
diff --git a/chrome/browser/extensions/api/alarms/alarms_api_unittest.cc b/chrome/browser/extensions/api/alarms/alarms_api_unittest.cc
index 6cf0f7434ed803c353412c39fe2af09debf570d9..6c13b86d6d791007371c5ed84661adce8f8084b1 100644
--- a/chrome/browser/extensions/api/alarms/alarms_api_unittest.cc
+++ b/chrome/browser/extensions/api/alarms/alarms_api_unittest.cc
@@ -44,6 +44,10 @@ class AlarmDelegate : public AlarmManager::Delegate {
} // namespace
+void RunScheduleNextPoll(AlarmManager* alarm_manager) {
+ alarm_manager->ScheduleNextPoll();
+}
+
class ExtensionAlarmsTest : public BrowserWithTestWindowTest {
public:
virtual void SetUp() {
@@ -135,21 +139,23 @@ class ExtensionAlarmsTest : public BrowserWithTestWindowTest {
}
}
- protected:
base::SimpleTestClock* test_clock_;
AlarmManager* alarm_manager_;
AlarmDelegate* alarm_delegate_;
scoped_refptr<extensions::Extension> extension_;
+
+ protected:
content::WebContents* contents_;
};
-TEST_F(ExtensionAlarmsTest, Create) {
- test_clock_->SetNow(base::Time::FromDoubleT(10));
- // Create 1 non-repeating alarm.
- CreateAlarm("[null, {\"delayInMinutes\": 0}]");
+void ExtensionAlarmsTestGetAllAlarmsCallback(
+ const AlarmManager::AlarmList* alarms) {
+ // Ensure the alarm is gone.
+ ASSERT_FALSE(alarms);
+}
- const Alarm* alarm =
- alarm_manager_->GetAlarm(extension_->id(), std::string());
+void ExtensionAlarmsTestGetAlarmCallback(
+ ExtensionAlarmsTest* test, Alarm* alarm) {
ASSERT_TRUE(alarm);
EXPECT_EQ("", alarm->js_alarm->name);
EXPECT_DOUBLE_EQ(10000, alarm->js_alarm->scheduled_time);
@@ -159,93 +165,142 @@ TEST_F(ExtensionAlarmsTest, Create) {
// MessageLoop when that happens.
base::MessageLoop::current()->Run();
- ASSERT_EQ(1u, alarm_delegate_->alarms_seen.size());
- EXPECT_EQ("", alarm_delegate_->alarms_seen[0]);
+ ASSERT_EQ(1u, test->alarm_delegate_->alarms_seen.size());
+ EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
// Ensure the alarm is gone.
- {
- const AlarmManager::AlarmList* alarms =
- alarm_manager_->GetAllAlarms(extension_->id());
- ASSERT_FALSE(alarms);
- }
+ test->alarm_manager_->GetAllAlarms(test->extension_->id(), base::Bind(
+ ExtensionAlarmsTestGetAllAlarmsCallback));
}
-TEST_F(ExtensionAlarmsTest, CreateRepeating) {
+TEST_F(ExtensionAlarmsTest, Create) {
test_clock_->SetNow(base::Time::FromDoubleT(10));
+ // Create 1 non-repeating alarm.
+ CreateAlarm("[null, {\"delayInMinutes\": 0}]");
- // Create 1 repeating alarm.
- CreateAlarm("[null, {\"periodInMinutes\": 0.001}]");
+ alarm_manager_->GetAlarm(extension_->id(), std::string(), base::Bind(
+ ExtensionAlarmsTestGetAlarmCallback, this));
+}
- const Alarm* alarm =
- alarm_manager_->GetAlarm(extension_->id(), std::string());
+void ExtensionAlarmsTestCreateRepeatingGetAlarmCallback(
+ ExtensionAlarmsTest* test, Alarm* alarm) {
ASSERT_TRUE(alarm);
EXPECT_EQ("", alarm->js_alarm->name);
EXPECT_DOUBLE_EQ(10060, alarm->js_alarm->scheduled_time);
EXPECT_THAT(alarm->js_alarm->period_in_minutes,
testing::Pointee(testing::DoubleEq(0.001)));
- test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ test->test_clock_->Advance(base::TimeDelta::FromSeconds(1));
// Now wait for the alarm to fire. Our test delegate will quit the
// MessageLoop when that happens.
base::MessageLoop::current()->Run();
- test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ test->test_clock_->Advance(base::TimeDelta::FromSeconds(1));
// Wait again, and ensure the alarm fires again.
- alarm_manager_->ScheduleNextPoll();
+ RunScheduleNextPoll(test->alarm_manager_);
base::MessageLoop::current()->Run();
- ASSERT_EQ(2u, alarm_delegate_->alarms_seen.size());
- EXPECT_EQ("", alarm_delegate_->alarms_seen[0]);
+ ASSERT_EQ(2u, test->alarm_delegate_->alarms_seen.size());
+ EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
}
-TEST_F(ExtensionAlarmsTest, CreateAbsolute) {
- test_clock_->SetNow(base::Time::FromDoubleT(9.99));
- CreateAlarm("[null, {\"when\": 10001}]");
+TEST_F(ExtensionAlarmsTest, CreateRepeating) {
+ test_clock_->SetNow(base::Time::FromDoubleT(10));
+
+ // Create 1 repeating alarm.
+ CreateAlarm("[null, {\"periodInMinutes\": 0.001}]");
+
+ alarm_manager_->GetAlarm(extension_->id(), std::string(), base::Bind(
+ ExtensionAlarmsTestCreateRepeatingGetAlarmCallback, this));
+}
+
+void ExtensionAlarmsTestCreateAbsoluteGetAlarm2Callback(
+ ExtensionAlarmsTest* test, Alarm* alarm) {
+ ASSERT_FALSE(alarm);
- const Alarm* alarm =
- alarm_manager_->GetAlarm(extension_->id(), std::string());
+ ASSERT_EQ(1u, test->alarm_delegate_->alarms_seen.size());
+ EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
+}
+
+void ExtensionAlarmsTestCreateAbsoluteGetAlarm1Callback(
+ ExtensionAlarmsTest* test, Alarm* alarm) {
ASSERT_TRUE(alarm);
EXPECT_EQ("", alarm->js_alarm->name);
EXPECT_DOUBLE_EQ(10001, alarm->js_alarm->scheduled_time);
EXPECT_THAT(alarm->js_alarm->period_in_minutes,
testing::IsNull());
- test_clock_->SetNow(base::Time::FromDoubleT(10.1));
+ test->test_clock_->SetNow(base::Time::FromDoubleT(10.1));
// Now wait for the alarm to fire. Our test delegate will quit the
// MessageLoop when that happens.
base::MessageLoop::current()->Run();
- ASSERT_FALSE(alarm_manager_->GetAlarm(extension_->id(), std::string()));
-
- ASSERT_EQ(1u, alarm_delegate_->alarms_seen.size());
- EXPECT_EQ("", alarm_delegate_->alarms_seen[0]);
+ test->alarm_manager_->GetAlarm(
+ test->extension_->id(), std::string(), base::Bind(
+ ExtensionAlarmsTestCreateAbsoluteGetAlarm2Callback, test));
}
-TEST_F(ExtensionAlarmsTest, CreateRepeatingWithQuickFirstCall) {
+TEST_F(ExtensionAlarmsTest, CreateAbsolute) {
test_clock_->SetNow(base::Time::FromDoubleT(9.99));
- CreateAlarm("[null, {\"when\": 10001, \"periodInMinutes\": 0.001}]");
+ CreateAlarm("[null, {\"when\": 10001}]");
+
+ alarm_manager_->GetAlarm(extension_->id(), std::string(), base::Bind(
+ ExtensionAlarmsTestCreateAbsoluteGetAlarm1Callback, this));
+}
+
+void ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm3Callback(
+ ExtensionAlarmsTest* test, Alarm* alarm) {
+ ASSERT_TRUE(alarm);
+ EXPECT_THAT(test->alarm_delegate_->alarms_seen, testing::ElementsAre("", ""));
+}
+
+void ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm2Callback(
+ ExtensionAlarmsTest* test, Alarm* alarm) {
+ ASSERT_TRUE(alarm);
+ EXPECT_THAT(test->alarm_delegate_->alarms_seen, testing::ElementsAre(""));
+
+ test->test_clock_->SetNow(base::Time::FromDoubleT(10.7));
+ base::MessageLoop::current()->Run();
+
+ test->alarm_manager_->GetAlarm(
+ test->extension_->id(), std::string(), base::Bind(
+ ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm3Callback,
+ test));
+}
- const Alarm* alarm =
- alarm_manager_->GetAlarm(extension_->id(), std::string());
+void ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm1Callback(
+ ExtensionAlarmsTest* test, Alarm* alarm) {
ASSERT_TRUE(alarm);
EXPECT_EQ("", alarm->js_alarm->name);
EXPECT_DOUBLE_EQ(10001, alarm->js_alarm->scheduled_time);
EXPECT_THAT(alarm->js_alarm->period_in_minutes,
testing::Pointee(testing::DoubleEq(0.001)));
- test_clock_->SetNow(base::Time::FromDoubleT(10.1));
+ test->test_clock_->SetNow(base::Time::FromDoubleT(10.1));
// Now wait for the alarm to fire. Our test delegate will quit the
// MessageLoop when that happens.
base::MessageLoop::current()->Run();
- ASSERT_TRUE(alarm_manager_->GetAlarm(extension_->id(), std::string()));
- EXPECT_THAT(alarm_delegate_->alarms_seen, testing::ElementsAre(""));
+ test->alarm_manager_->GetAlarm(
+ test->extension_->id(), std::string(), base::Bind(
+ ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm2Callback,
+ test));
+}
- test_clock_->SetNow(base::Time::FromDoubleT(10.7));
- base::MessageLoop::current()->Run();
+TEST_F(ExtensionAlarmsTest, CreateRepeatingWithQuickFirstCall) {
+ test_clock_->SetNow(base::Time::FromDoubleT(9.99));
+ CreateAlarm("[null, {\"when\": 10001, \"periodInMinutes\": 0.001}]");
+
+ alarm_manager_->GetAlarm(extension_->id(), std::string(), base::Bind(
+ ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm1Callback,
+ this));
+}
- ASSERT_TRUE(alarm_manager_->GetAlarm(extension_->id(), std::string()));
- EXPECT_THAT(alarm_delegate_->alarms_seen, testing::ElementsAre("", ""));
+void ExtensionAlarmsTestCreateDupeGetAllAlarmsCallback(
+ const AlarmManager::AlarmList* alarms) {
+ ASSERT_TRUE(alarms);
+ EXPECT_EQ(1u, alarms->size());
+ EXPECT_DOUBLE_EQ(430000, (*alarms)[0].js_alarm->scheduled_time);
}
TEST_F(ExtensionAlarmsTest, CreateDupe) {
@@ -255,13 +310,8 @@ TEST_F(ExtensionAlarmsTest, CreateDupe) {
CreateAlarm("[\"dup\", {\"delayInMinutes\": 1}]");
CreateAlarm("[\"dup\", {\"delayInMinutes\": 7}]");
- {
- const AlarmManager::AlarmList* alarms =
- alarm_manager_->GetAllAlarms(extension_->id());
- ASSERT_TRUE(alarms);
- EXPECT_EQ(1u, alarms->size());
- EXPECT_DOUBLE_EQ(430000, (*alarms)[0].js_alarm->scheduled_time);
- }
+ alarm_manager_->GetAllAlarms(extension_->id(), base::Bind(
+ ExtensionAlarmsTestCreateDupeGetAllAlarmsCallback));
}
TEST_F(ExtensionAlarmsTest, CreateDelayBelowMinimum) {
@@ -345,6 +395,36 @@ TEST_F(ExtensionAlarmsTest, GetAll) {
}
}
+void ExtensionAlarmsTestClearGetAllAlarms2Callback(
+ const AlarmManager::AlarmList* alarms) {
+ // Ensure the 0.001-minute alarm is still there, since it's repeating.
+ ASSERT_TRUE(alarms);
+ EXPECT_EQ(1u, alarms->size());
+ EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes,
+ testing::Pointee(0.001));
+}
+
+void ExtensionAlarmsTestClearGetAllAlarms1Callback(
+ ExtensionAlarmsTest* test, const AlarmManager::AlarmList* alarms) {
+ ASSERT_TRUE(alarms);
+ EXPECT_EQ(1u, alarms->size());
+ EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes,
+ testing::Pointee(0.001));
+
+ // Now wait for the alarms to fire, and ensure the cancelled alarms don't
+ // fire.
+ test->test_clock_->Advance(base::TimeDelta::FromMilliseconds(60));
+ RunScheduleNextPoll(test->alarm_manager_);
+ base::MessageLoop::current()->Run();
+
+ ASSERT_EQ(1u, test->alarm_delegate_->alarms_seen.size());
+ EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
+
+ // Ensure the 0.001-minute alarm is still there, since it's repeating.
+ test->alarm_manager_->GetAllAlarms(test->extension_->id(), base::Bind(
+ ExtensionAlarmsTestClearGetAllAlarms2Callback));
+}
+
TEST_F(ExtensionAlarmsTest, Clear) {
// Clear a non-existent one.
{
@@ -357,35 +437,28 @@ TEST_F(ExtensionAlarmsTest, Clear) {
CreateAlarms(3);
// Clear all but the 0.001-minute alarm.
- {
- RunFunction(new AlarmsClearFunction(), "[\"7\"]");
- RunFunction(new AlarmsClearFunction(), "[\"0\"]");
-
- const AlarmManager::AlarmList* alarms =
- alarm_manager_->GetAllAlarms(extension_->id());
- ASSERT_TRUE(alarms);
- EXPECT_EQ(1u, alarms->size());
- EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes,
- testing::Pointee(0.001));
- }
+ RunFunction(new AlarmsClearFunction(), "[\"7\"]");
+ RunFunction(new AlarmsClearFunction(), "[\"0\"]");
- // Now wait for the alarms to fire, and ensure the cancelled alarms don't
- // fire.
- alarm_manager_->ScheduleNextPoll();
- base::MessageLoop::current()->Run();
+ alarm_manager_->GetAllAlarms(extension_->id(), base::Bind(
+ ExtensionAlarmsTestClearGetAllAlarms1Callback, this));
+}
- ASSERT_EQ(1u, alarm_delegate_->alarms_seen.size());
- EXPECT_EQ("", alarm_delegate_->alarms_seen[0]);
+void ExtensionAlarmsTestClearAllGetAllAlarms2Callback(
+ const AlarmManager::AlarmList* alarms) {
+ ASSERT_FALSE(alarms);
+}
- // Ensure the 0.001-minute alarm is still there, since it's repeating.
- {
- const AlarmManager::AlarmList* alarms =
- alarm_manager_->GetAllAlarms(extension_->id());
- ASSERT_TRUE(alarms);
- EXPECT_EQ(1u, alarms->size());
- EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes,
- testing::Pointee(0.001));
- }
+void ExtensionAlarmsTestClearAllGetAllAlarms1Callback(
+ ExtensionAlarmsTest* test, const AlarmManager::AlarmList* alarms) {
+ ASSERT_TRUE(alarms);
+ EXPECT_EQ(3u, alarms->size());
+
+ // Clear them.
+ test->RunFunction(new AlarmsClearAllFunction(), "[]");
+ test->alarm_manager_->GetAllAlarms(
+ test->extension_->id(), base::Bind(
+ ExtensionAlarmsTestClearAllGetAllAlarms2Callback));
}
TEST_F(ExtensionAlarmsTest, ClearAll) {
@@ -397,31 +470,39 @@ TEST_F(ExtensionAlarmsTest, ClearAll) {
}
// Create 3 alarms.
- {
- CreateAlarms(3);
- const AlarmManager::AlarmList* alarms =
- alarm_manager_->GetAllAlarms(extension_->id());
- ASSERT_TRUE(alarms);
- EXPECT_EQ(3u, alarms->size());
- }
-
- // Clear them.
- {
- RunFunction(new AlarmsClearAllFunction(), "[]");
- const AlarmManager::AlarmList* alarms =
- alarm_manager_->GetAllAlarms(extension_->id());
- ASSERT_FALSE(alarms);
- }
+ CreateAlarms(3);
+ alarm_manager_->GetAllAlarms(extension_->id(), base::Bind(
+ ExtensionAlarmsTestClearAllGetAllAlarms1Callback, this));
}
class ExtensionAlarmsSchedulingTest : public ExtensionAlarmsTest {
+ void GetAlarmCallback(Alarm* alarm) {
+ CHECK(alarm);
+ const base::Time scheduled_time =
+ base::Time::FromJsTime(alarm->js_alarm->scheduled_time);
+ EXPECT_EQ(scheduled_time, alarm_manager_->test_next_poll_time_);
+ }
+
+ static void RemoveAlarmCallback (bool success) { EXPECT_TRUE(success); }
+ static void RemoveAllAlarmsCallback () {}
public:
// Get the time that the alarm named is scheduled to run.
- base::Time GetScheduledTime(const std::string& alarm_name) {
- const extensions::Alarm* alarm =
- alarm_manager_->GetAlarm(extension_->id(), alarm_name);
- CHECK(alarm);
- return base::Time::FromJsTime(alarm->js_alarm->scheduled_time);
+ void VerifyScheduledTime(const std::string& alarm_name) {
+ alarm_manager_->GetAlarm(extension_->id(), alarm_name, base::Bind(
+ &ExtensionAlarmsSchedulingTest::GetAlarmCallback,
+ base::Unretained(this)));
+ }
+
+ void RemoveAlarm(const std::string& name) {
+ alarm_manager_->RemoveAlarm(
+ extension_->id(),
+ name,
+ base::Bind(&ExtensionAlarmsSchedulingTest::RemoveAlarmCallback));
+ }
+
+ void RemoveAllAlarms () {
+ alarm_manager_->RemoveAllAlarms(extension_->id(), base::Bind(
+ &ExtensionAlarmsSchedulingTest::RemoveAllAlarmsCallback));
}
};
@@ -429,14 +510,14 @@ TEST_F(ExtensionAlarmsSchedulingTest, PollScheduling) {
{
CreateAlarm("[\"a\", {\"periodInMinutes\": 6}]");
CreateAlarm("[\"bb\", {\"periodInMinutes\": 8}]");
- EXPECT_EQ(GetScheduledTime("a"), alarm_manager_->next_poll_time_);
- alarm_manager_->RemoveAllAlarms(extension_->id());
+ VerifyScheduledTime("a");
+ RemoveAllAlarms();
}
{
CreateAlarm("[\"a\", {\"delayInMinutes\": 10}]");
CreateAlarm("[\"bb\", {\"delayInMinutes\": 21}]");
- EXPECT_EQ(GetScheduledTime("a"), alarm_manager_->next_poll_time_);
- alarm_manager_->RemoveAllAlarms(extension_->id());
+ VerifyScheduledTime("a");
+ RemoveAllAlarms();
}
{
test_clock_->SetNow(base::Time::FromDoubleT(10));
@@ -446,9 +527,8 @@ TEST_F(ExtensionAlarmsSchedulingTest, PollScheduling) {
alarm.js_alarm->scheduled_time = 30 * 60000;
alarm.js_alarm->period_in_minutes.reset(new double(30));
alarm_manager_->AddAlarmImpl(extension_->id(), alarm);
- EXPECT_DOUBLE_EQ(GetScheduledTime("a").ToDoubleT(),
- alarm_manager_->next_poll_time_.ToDoubleT());
- alarm_manager_->RemoveAllAlarms(extension_->id());
+ VerifyScheduledTime("a");
+ RemoveAllAlarms();
}
{
test_clock_->SetNow(base::Time::FromDoubleT(3 * 60 + 1));
@@ -459,13 +539,13 @@ TEST_F(ExtensionAlarmsSchedulingTest, PollScheduling) {
alarm_manager_->AddAlarmImpl(extension_->id(), alarm);
base::MessageLoop::current()->Run();
EXPECT_EQ(alarm_manager_->last_poll_time_ + base::TimeDelta::FromMinutes(3),
- alarm_manager_->next_poll_time_);
- alarm_manager_->RemoveAllAlarms(extension_->id());
+ alarm_manager_->test_next_poll_time_);
+ RemoveAllAlarms();
}
{
test_clock_->SetNow(base::Time::FromDoubleT(4 * 60 + 1));
CreateAlarm("[\"a\", {\"periodInMinutes\": 2}]");
- alarm_manager_->RemoveAlarm(extension_->id(), "a");
+ RemoveAlarm("a");
Alarm alarm2;
alarm2.js_alarm->name = "bb";
alarm2.js_alarm->scheduled_time = 4 * 60000;
@@ -478,8 +558,8 @@ TEST_F(ExtensionAlarmsSchedulingTest, PollScheduling) {
alarm_manager_->AddAlarmImpl(extension_->id(), alarm3);
base::MessageLoop::current()->Run();
EXPECT_EQ(alarm_manager_->last_poll_time_ + base::TimeDelta::FromMinutes(4),
- alarm_manager_->next_poll_time_);
- alarm_manager_->RemoveAllAlarms(extension_->id());
+ alarm_manager_->test_next_poll_time_);
+ RemoveAllAlarms();
}
}
@@ -492,7 +572,7 @@ TEST_F(ExtensionAlarmsSchedulingTest, ReleasedExtensionPollsInfrequently) {
// On startup (when there's no "last poll"), we let alarms fire as
// soon as they're scheduled.
- EXPECT_DOUBLE_EQ(300010, alarm_manager_->next_poll_time_.ToJsTime());
+ EXPECT_DOUBLE_EQ(300010, alarm_manager_->test_next_poll_time_.ToJsTime());
alarm_manager_->last_poll_time_ = base::Time::FromJsTime(290000);
// In released extensions, we set the granularity to at least 5
@@ -501,18 +581,19 @@ TEST_F(ExtensionAlarmsSchedulingTest, ReleasedExtensionPollsInfrequently) {
alarm_manager_->ScheduleNextPoll();
EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
base::TimeDelta::FromMinutes(1)).ToJsTime(),
- alarm_manager_->next_poll_time_.ToJsTime());
+ alarm_manager_->test_next_poll_time_.ToJsTime());
}
TEST_F(ExtensionAlarmsSchedulingTest, TimerRunning) {
EXPECT_FALSE(alarm_manager_->timer_.IsRunning());
CreateAlarm("[\"a\", {\"delayInMinutes\": 0.001}]");
EXPECT_TRUE(alarm_manager_->timer_.IsRunning());
+ test_clock_->Advance(base::TimeDelta::FromMilliseconds(60));
base::MessageLoop::current()->Run();
EXPECT_FALSE(alarm_manager_->timer_.IsRunning());
CreateAlarm("[\"bb\", {\"delayInMinutes\": 10}]");
EXPECT_TRUE(alarm_manager_->timer_.IsRunning());
- alarm_manager_->RemoveAllAlarms(extension_->id());
+ RemoveAllAlarms();
EXPECT_FALSE(alarm_manager_->timer_.IsRunning());
}
« no previous file with comments | « chrome/browser/extensions/api/alarms/alarms_api.cc ('k') | chrome/renderer/resources/extensions/last_error.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698