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

Side by Side Diff: components/offline_pages/background/request_coordinator_unittest.cc

Issue 2420503002: [Offline Pages] Define separate watchdog timeout for concurrent bg loads (Closed)
Patch Set: Cleaned up 16 lint errors from "git cl lint" Created 4 years, 2 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
« no previous file with comments | « components/offline_pages/background/request_coordinator.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "components/offline_pages/background/request_coordinator.h" 5 #include "components/offline_pages/background/request_coordinator.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <string>
8 #include <utility> 9 #include <utility>
9 #include <vector> 10 #include <vector>
10 11
11 #include "base/bind.h" 12 #include "base/bind.h"
12 #include "base/location.h" 13 #include "base/location.h"
13 #include "base/logging.h" 14 #include "base/logging.h"
14 #include "base/synchronization/waitable_event.h" 15 #include "base/synchronization/waitable_event.h"
15 #include "base/sys_info.h" 16 #include "base/sys_info.h"
16 #include "base/test/test_mock_time_task_runner.h" 17 #include "base/test/test_mock_time_task_runner.h"
17 #include "base/threading/thread_task_runner_handle.h" 18 #include "base/threading/thread_task_runner_handle.h"
(...skipping 14 matching lines...) Expand all
32 // put test constants here 33 // put test constants here
33 const GURL kUrl1("http://universe.com/everything"); 34 const GURL kUrl1("http://universe.com/everything");
34 const GURL kUrl2("http://universe.com/toinfinityandbeyond"); 35 const GURL kUrl2("http://universe.com/toinfinityandbeyond");
35 const std::string kClientNamespace("bookmark"); 36 const std::string kClientNamespace("bookmark");
36 const std::string kId1("42"); 37 const std::string kId1("42");
37 const std::string kId2("life*universe+everything"); 38 const std::string kId2("life*universe+everything");
38 const ClientId kClientId1(kClientNamespace, kId1); 39 const ClientId kClientId1(kClientNamespace, kId1);
39 const ClientId kClientId2(kClientNamespace, kId2); 40 const ClientId kClientId2(kClientNamespace, kId2);
40 const int kRequestId1(1); 41 const int kRequestId1(1);
41 const int kRequestId2(2); 42 const int kRequestId2(2);
42 const long kTestTimeoutSeconds = 1;
43 const long kTestTimeBudgetSeconds = 200; 43 const long kTestTimeBudgetSeconds = 200;
44 const int kBatteryPercentageHigh = 75; 44 const int kBatteryPercentageHigh = 75;
45 const bool kPowerRequired = true; 45 const bool kPowerRequired = true;
46 const bool kUserRequested = true; 46 const bool kUserRequested = true;
47 const int kAttemptCount = 1; 47 const int kAttemptCount = 1;
48 } // namespace 48 } // namespace
49 49
50 class SchedulerStub : public Scheduler { 50 class SchedulerStub : public Scheduler {
51 public: 51 public:
52 SchedulerStub() 52 SchedulerStub()
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 void CallRequestNotPicked(bool non_user_requested_tasks_remaining, 299 void CallRequestNotPicked(bool non_user_requested_tasks_remaining,
300 bool disabled_tasks_remaining) { 300 bool disabled_tasks_remaining) {
301 if (disabled_tasks_remaining) 301 if (disabled_tasks_remaining)
302 coordinator_->disabled_requests_.insert(kRequestId1); 302 coordinator_->disabled_requests_.insert(kRequestId1);
303 else 303 else
304 coordinator_->disabled_requests_.clear(); 304 coordinator_->disabled_requests_.clear();
305 305
306 coordinator_->RequestNotPicked(non_user_requested_tasks_remaining); 306 coordinator_->RequestNotPicked(non_user_requested_tasks_remaining);
307 } 307 }
308 308
309 void SetOfflinerTimeoutForTest(const base::TimeDelta& timeout) {
310 coordinator_->SetOfflinerTimeoutForTest(timeout);
311 }
312
313 void SetDeviceConditionsForTest(DeviceConditions device_conditions) { 309 void SetDeviceConditionsForTest(DeviceConditions device_conditions) {
314 coordinator_->SetDeviceConditionsForTest(device_conditions); 310 coordinator_->SetDeviceConditionsForTest(device_conditions);
315 } 311 }
316 312
317 void WaitForCallback() { 313 void WaitForCallback() {
318 waiter_.Wait(); 314 waiter_.Wait();
319 } 315 }
320 316
321 void AdvanceClockBy(base::TimeDelta delta) { 317 void AdvanceClockBy(base::TimeDelta delta) {
322 task_runner_->FastForwardBy(delta); 318 task_runner_->FastForwardBy(delta);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 net::NetworkChangeNotifier::CONNECTION_3G); 408 net::NetworkChangeNotifier::CONNECTION_3G);
413 base::Callback<void(bool)> callback = 409 base::Callback<void(bool)> callback =
414 base::Bind( 410 base::Bind(
415 &RequestCoordinatorTest::EmptyCallbackFunction, 411 &RequestCoordinatorTest::EmptyCallbackFunction,
416 base::Unretained(this)); 412 base::Unretained(this));
417 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback)); 413 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback));
418 } 414 }
419 415
420 TEST_F(RequestCoordinatorTest, StartProcessingWithRequestInProgress) { 416 TEST_F(RequestCoordinatorTest, StartProcessingWithRequestInProgress) {
421 // Put the request on the queue. 417 // Put the request on the queue.
422 EXPECT_TRUE( 418 EXPECT_NE(
423 coordinator()->SavePageLater( 419 coordinator()->SavePageLater(
424 kUrl1, kClientId1, kUserRequested, 420 kUrl1, kClientId1, kUserRequested,
425 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER) != 0); 421 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER), 0);
426 422
427 // Set up for the call to StartProcessing by building arguments. 423 // Set up for the call to StartProcessing by building arguments.
428 DeviceConditions device_conditions( 424 DeviceConditions device_conditions(
429 false, 75, net::NetworkChangeNotifier::CONNECTION_3G); 425 false, 75, net::NetworkChangeNotifier::CONNECTION_3G);
430 base::Callback<void(bool)> callback = 426 base::Callback<void(bool)> callback =
431 base::Bind(&RequestCoordinatorTest::EmptyCallbackFunction, 427 base::Bind(&RequestCoordinatorTest::EmptyCallbackFunction,
432 base::Unretained(this)); 428 base::Unretained(this));
433 429
434 // Ensure that the forthcoming request does not finish - we simulate it being 430 // Ensure that the forthcoming request does not finish - we simulate it being
435 // in progress by asking it to skip making the completion callback. 431 // in progress by asking it to skip making the completion callback.
436 EnableOfflinerCallback(false); 432 EnableOfflinerCallback(false);
437 433
438 // Sending the request to the offliner should make it busy. 434 // Sending the request to the offliner should make it busy.
439 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback)); 435 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback));
440 PumpLoop(); 436 PumpLoop();
441 EXPECT_TRUE(is_busy()); 437 EXPECT_TRUE(is_busy());
442 438
443 // Now trying to start processing on another request should return false. 439 // Now trying to start processing on another request should return false.
444 EXPECT_FALSE(coordinator()->StartProcessing(device_conditions, callback)); 440 EXPECT_FALSE(coordinator()->StartProcessing(device_conditions, callback));
445 } 441 }
446 442
447 TEST_F(RequestCoordinatorTest, SavePageLater) { 443 TEST_F(RequestCoordinatorTest, SavePageLater) {
448 EXPECT_TRUE( 444 EXPECT_NE(
449 coordinator()->SavePageLater( 445 coordinator()->SavePageLater(
450 kUrl1, kClientId1, kUserRequested, 446 kUrl1, kClientId1, kUserRequested,
451 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER) != 0); 447 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER), 0);
452 448
453 // Expect that a request got placed on the queue. 449 // Expect that a request got placed on the queue.
454 coordinator()->queue()->GetRequests( 450 coordinator()->queue()->GetRequests(
455 base::Bind(&RequestCoordinatorTest::GetRequestsDone, 451 base::Bind(&RequestCoordinatorTest::GetRequestsDone,
456 base::Unretained(this))); 452 base::Unretained(this)));
457 453
458 // Wait for callbacks to finish, both request queue and offliner. 454 // Wait for callbacks to finish, both request queue and offliner.
459 PumpLoop(); 455 PumpLoop();
460 456
461 // Check the request queue is as expected. 457 // Check the request queue is as expected.
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 // Call the method under test, making sure we send SUCCESS to the observer. 962 // Call the method under test, making sure we send SUCCESS to the observer.
967 coordinator()->MarkRequestCompleted(request_id); 963 coordinator()->MarkRequestCompleted(request_id);
968 PumpLoop(); 964 PumpLoop();
969 965
970 // Our observer should have seen SUCCESS instead of REMOVED. 966 // Our observer should have seen SUCCESS instead of REMOVED.
971 EXPECT_EQ(RequestCoordinator::BackgroundSavePageResult::SUCCESS, 967 EXPECT_EQ(RequestCoordinator::BackgroundSavePageResult::SUCCESS,
972 observer().last_status()); 968 observer().last_status());
973 EXPECT_TRUE(observer().completed_called()); 969 EXPECT_TRUE(observer().completed_called());
974 } 970 }
975 971
976 TEST_F(RequestCoordinatorTest, WatchdogTimeout) { 972 TEST_F(RequestCoordinatorTest, WatchdogTimeoutForScheduledProcessing) {
977 // Build a request to use with the pre-renderer, and put it on the queue. 973 // Build a request to use with the pre-renderer, and put it on the queue.
978 offline_pages::SavePageRequest request( 974 offline_pages::SavePageRequest request(
979 kRequestId1, kUrl1, kClientId1, base::Time::Now(), kUserRequested); 975 kRequestId1, kUrl1, kClientId1, base::Time::Now(), kUserRequested);
980 coordinator()->queue()->AddRequest( 976 coordinator()->queue()->AddRequest(
981 request, 977 request,
982 base::Bind(&RequestCoordinatorTest::AddRequestDone, 978 base::Bind(&RequestCoordinatorTest::AddRequestDone,
983 base::Unretained(this))); 979 base::Unretained(this)));
984 PumpLoop(); 980 PumpLoop();
985 981
986 // Set up for the call to StartProcessing. 982 // Set up for the call to StartProcessing.
987 DeviceConditions device_conditions( 983 DeviceConditions device_conditions(
988 !kPowerRequired, kBatteryPercentageHigh, 984 !kPowerRequired, kBatteryPercentageHigh,
989 net::NetworkChangeNotifier::CONNECTION_3G); 985 net::NetworkChangeNotifier::CONNECTION_3G);
990 base::Callback<void(bool)> callback = 986 base::Callback<void(bool)> callback =
991 base::Bind(&RequestCoordinatorTest::WaitingCallbackFunction, 987 base::Bind(&RequestCoordinatorTest::WaitingCallbackFunction,
992 base::Unretained(this)); 988 base::Unretained(this));
993 989
994 // Ensure that the new request does not finish - we simulate it being 990 // Ensure that the new request does not finish - we simulate it being
995 // in progress by asking it to skip making the completion callback. 991 // in progress by asking it to skip making the completion callback.
996 EnableOfflinerCallback(false); 992 EnableOfflinerCallback(false);
997 993
998 // Ask RequestCoordinator to stop waiting for the offliner after this many
999 // seconds.
1000 SetOfflinerTimeoutForTest(base::TimeDelta::FromSeconds(kTestTimeoutSeconds));
1001
1002 // Sending the request to the offliner. 994 // Sending the request to the offliner.
1003 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback)); 995 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback));
1004 PumpLoop(); 996 PumpLoop();
1005 997
1006 // Advance the mock clock far enough to cause a watchdog timeout 998 // Advance the mock clock far enough to cause a watchdog timeout
1007 AdvanceClockBy(base::TimeDelta::FromSeconds(kTestTimeoutSeconds + 1)); 999 AdvanceClockBy(base::TimeDelta::FromSeconds(
1000 coordinator()
1001 ->policy()
1002 ->GetSinglePageTimeLimitWhenBackgroundScheduledInSeconds() + 1));
1008 PumpLoop(); 1003 PumpLoop();
1009 1004
1010 // Wait for timeout to expire. Use a TaskRunner with a DelayedTaskRunner 1005 // Wait for timeout to expire. Use a TaskRunner with a DelayedTaskRunner
1011 // which won't time out immediately, so the watchdog thread doesn't kill valid 1006 // which won't time out immediately, so the watchdog thread doesn't kill valid
1012 // tasks too soon. 1007 // tasks too soon.
1013 WaitForCallback(); 1008 WaitForCallback();
1014 PumpLoop(); 1009 PumpLoop();
1015 1010
1016 EXPECT_FALSE(is_starting()); 1011 EXPECT_FALSE(is_starting());
1017 EXPECT_TRUE(OfflinerWasCanceled()); 1012 EXPECT_TRUE(OfflinerWasCanceled());
1018 EXPECT_EQ(Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT, 1013 EXPECT_EQ(Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT,
1019 last_offlining_status()); 1014 last_offlining_status());
1020 } 1015 }
1021 1016
1017 TEST_F(RequestCoordinatorTest, WatchdogTimeoutForImmediateProcessing) {
1018 // Test only applies on non-svelte device.
1019 if (base::SysInfo::IsLowEndDevice())
1020 return;
1021
1022 // Set good network connection so that adding request will trigger
1023 // immediate processing.
1024 SetEffectiveConnectionTypeForTest(
1025 net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G);
1026
1027 // Ensure that the new request does not finish - we simulate it being
1028 // in progress by asking it to skip making the completion callback.
1029 EnableOfflinerCallback(false);
1030
1031 EXPECT_NE(
1032 coordinator()->SavePageLater(
1033 kUrl1, kClientId1, kUserRequested,
1034 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER), 0);
1035 PumpLoop();
1036
1037 // Verify that immediate start from adding the request did happen.
1038 EXPECT_TRUE(coordinator()->is_busy());
1039
1040 // Advance the mock clock 1 second before the watchdog timeout.
1041 AdvanceClockBy(base::TimeDelta::FromSeconds(
1042 coordinator()
1043 ->policy()
1044 ->GetSinglePageTimeLimitForImmediateLoadInSeconds() - 1));
1045 PumpLoop();
1046
1047 // Verify still busy.
1048 EXPECT_TRUE(coordinator()->is_busy());
1049 EXPECT_FALSE(OfflinerWasCanceled());
1050
1051 // Advance the mock clock past the watchdog timeout now.
1052 AdvanceClockBy(base::TimeDelta::FromSeconds(2));
1053 PumpLoop();
1054
1055 // Verify the request timed out.
1056 EXPECT_FALSE(coordinator()->is_busy());
1057 EXPECT_TRUE(OfflinerWasCanceled());
1058 EXPECT_EQ(Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT,
1059 last_offlining_status());
1060 }
1061
1022 TEST_F(RequestCoordinatorTest, TimeBudgetExceeded) { 1062 TEST_F(RequestCoordinatorTest, TimeBudgetExceeded) {
1023 // Build two requests to use with the pre-renderer, and put it on the queue. 1063 // Build two requests to use with the pre-renderer, and put it on the queue.
1024 offline_pages::SavePageRequest request1( 1064 offline_pages::SavePageRequest request1(
1025 kRequestId1, kUrl1, kClientId1, base::Time::Now(), kUserRequested); 1065 kRequestId1, kUrl1, kClientId1, base::Time::Now(), kUserRequested);
1026 offline_pages::SavePageRequest request2( 1066 offline_pages::SavePageRequest request2(
1027 kRequestId1 + 1, kUrl1, kClientId1, base::Time::Now(), kUserRequested); 1067 kRequestId1 + 1, kUrl1, kClientId1, base::Time::Now(), kUserRequested);
1028 request2.set_completed_attempt_count(kAttemptCount); 1068 request2.set_completed_attempt_count(kAttemptCount);
1029 coordinator()->queue()->AddRequest( 1069 coordinator()->queue()->AddRequest(
1030 request1, 1070 request1,
1031 base::Bind(&RequestCoordinatorTest::AddRequestDone, 1071 base::Bind(&RequestCoordinatorTest::AddRequestDone,
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 EXPECT_EQ(RequestCoordinator::BackgroundSavePageResult::REMOVED, 1187 EXPECT_EQ(RequestCoordinator::BackgroundSavePageResult::REMOVED,
1148 observer().last_status()); 1188 observer().last_status());
1149 EXPECT_EQ(1UL, last_remove_results().size()); 1189 EXPECT_EQ(1UL, last_remove_results().size());
1150 EXPECT_EQ(kRequestId1, std::get<0>(last_remove_results().at(0))); 1190 EXPECT_EQ(kRequestId1, std::get<0>(last_remove_results().at(0)));
1151 } 1191 }
1152 1192
1153 TEST_F(RequestCoordinatorTest, 1193 TEST_F(RequestCoordinatorTest,
1154 SavePageStartsProcessingWhenConnectedAndNotLowEndDevice) { 1194 SavePageStartsProcessingWhenConnectedAndNotLowEndDevice) {
1155 SetEffectiveConnectionTypeForTest( 1195 SetEffectiveConnectionTypeForTest(
1156 net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G); 1196 net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G);
1157 EXPECT_TRUE( 1197 EXPECT_NE(
1158 coordinator()->SavePageLater( 1198 coordinator()->SavePageLater(
1159 kUrl1, kClientId1, kUserRequested, 1199 kUrl1, kClientId1, kUserRequested,
1160 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER) != 0); 1200 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER), 0);
1161 PumpLoop(); 1201 PumpLoop();
1162 1202
1163 // Now whether processing triggered immediately depends on whether test 1203 // Now whether processing triggered immediately depends on whether test
1164 // is run on svelte device or not. 1204 // is run on svelte device or not.
1165 if (base::SysInfo::IsLowEndDevice()) { 1205 if (base::SysInfo::IsLowEndDevice()) {
1166 EXPECT_FALSE(is_busy()); 1206 EXPECT_FALSE(is_busy());
1167 } else { 1207 } else {
1168 EXPECT_TRUE(is_busy()); 1208 EXPECT_TRUE(is_busy());
1169 } 1209 }
1170 } 1210 }
1171 1211
1172 TEST_F(RequestCoordinatorTest, SavePageDoesntStartProcessingWhenDisconnected) { 1212 TEST_F(RequestCoordinatorTest, SavePageDoesntStartProcessingWhenDisconnected) {
1173 EXPECT_TRUE( 1213 EXPECT_NE(
1174 coordinator()->SavePageLater( 1214 coordinator()->SavePageLater(
1175 kUrl1, kClientId1, kUserRequested, 1215 kUrl1, kClientId1, kUserRequested,
1176 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER) != 0); 1216 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER), 0);
1177 PumpLoop(); 1217 PumpLoop();
1178 EXPECT_FALSE(is_busy()); 1218 EXPECT_FALSE(is_busy());
1179 } 1219 }
1180 1220
1181 TEST_F(RequestCoordinatorTest, 1221 TEST_F(RequestCoordinatorTest,
1182 SavePageDoesntStartProcessingWhenPoorlyConnected) { 1222 SavePageDoesntStartProcessingWhenPoorlyConnected) {
1183 SetEffectiveConnectionTypeForTest( 1223 SetEffectiveConnectionTypeForTest(
1184 net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_SLOW_2G); 1224 net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
1185 EXPECT_TRUE( 1225 EXPECT_NE(
1186 coordinator()->SavePageLater( 1226 coordinator()->SavePageLater(
1187 kUrl1, kClientId1, kUserRequested, 1227 kUrl1, kClientId1, kUserRequested,
1188 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER) != 0); 1228 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER), 0);
1189 PumpLoop(); 1229 PumpLoop();
1190 EXPECT_FALSE(is_busy()); 1230 EXPECT_FALSE(is_busy());
1191 } 1231 }
1192 1232
1193 TEST_F(RequestCoordinatorTest, 1233 TEST_F(RequestCoordinatorTest,
1194 ResumeStartsProcessingWhenConnectedAndNotLowEndDevice) { 1234 ResumeStartsProcessingWhenConnectedAndNotLowEndDevice) {
1195
1196 // Add a request to the queue. 1235 // Add a request to the queue.
1197 offline_pages::SavePageRequest request1(kRequestId1, kUrl1, kClientId1, 1236 offline_pages::SavePageRequest request1(kRequestId1, kUrl1, kClientId1,
1198 base::Time::Now(), kUserRequested); 1237 base::Time::Now(), kUserRequested);
1199 coordinator()->queue()->AddRequest( 1238 coordinator()->queue()->AddRequest(
1200 request1, base::Bind(&RequestCoordinatorTest::AddRequestDone, 1239 request1, base::Bind(&RequestCoordinatorTest::AddRequestDone,
1201 base::Unretained(this))); 1240 base::Unretained(this)));
1202 PumpLoop(); 1241 PumpLoop();
1203 EXPECT_FALSE(is_busy()); 1242 EXPECT_FALSE(is_busy());
1204 1243
1205 // Pause the request. 1244 // Pause the request.
(...skipping 23 matching lines...) Expand all
1229 // Now whether processing triggered immediately depends on whether test 1268 // Now whether processing triggered immediately depends on whether test
1230 // is run on svelte device or not. 1269 // is run on svelte device or not.
1231 if (base::SysInfo::IsLowEndDevice()) { 1270 if (base::SysInfo::IsLowEndDevice()) {
1232 EXPECT_FALSE(is_busy()); 1271 EXPECT_FALSE(is_busy());
1233 } else { 1272 } else {
1234 EXPECT_TRUE(is_busy()); 1273 EXPECT_TRUE(is_busy());
1235 } 1274 }
1236 } 1275 }
1237 1276
1238 } // namespace offline_pages 1277 } // namespace offline_pages
OLDNEW
« no previous file with comments | « components/offline_pages/background/request_coordinator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698