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

Side by Side Diff: chrome/browser/push_messaging/push_messaging_browsertest.cc

Issue 2697793004: Push API: Validate storage before returning cached subscriptions (Closed)
Patch Set: Fix include Created 3 years, 8 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <map> 8 #include <map>
9 #include <string> 9 #include <string>
10 10
(...skipping 10 matching lines...) Expand all
21 #include "chrome/browser/browsing_data/browsing_data_helper.h" 21 #include "chrome/browser/browsing_data/browsing_data_helper.h"
22 #include "chrome/browser/browsing_data/browsing_data_remover.h" 22 #include "chrome/browser/browsing_data/browsing_data_remover.h"
23 #include "chrome/browser/browsing_data/browsing_data_remover_factory.h" 23 #include "chrome/browser/browsing_data/browsing_data_remover_factory.h"
24 #include "chrome/browser/browsing_data/browsing_data_remover_test_util.h" 24 #include "chrome/browser/browsing_data/browsing_data_remover_test_util.h"
25 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h" 25 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
26 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 26 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
27 #include "chrome/browser/engagement/site_engagement_score.h" 27 #include "chrome/browser/engagement/site_engagement_score.h"
28 #include "chrome/browser/engagement/site_engagement_service.h" 28 #include "chrome/browser/engagement/site_engagement_service.h"
29 #include "chrome/browser/gcm/fake_gcm_profile_service.h" 29 #include "chrome/browser/gcm/fake_gcm_profile_service.h"
30 #include "chrome/browser/gcm/gcm_profile_service_factory.h" 30 #include "chrome/browser/gcm/gcm_profile_service_factory.h"
31 #include "chrome/browser/gcm/instance_id/instance_id_profile_service.h"
32 #include "chrome/browser/gcm/instance_id/instance_id_profile_service_factory.h"
31 #include "chrome/browser/lifetime/keep_alive_registry.h" 33 #include "chrome/browser/lifetime/keep_alive_registry.h"
32 #include "chrome/browser/lifetime/keep_alive_types.h" 34 #include "chrome/browser/lifetime/keep_alive_types.h"
33 #include "chrome/browser/notifications/message_center_display_service.h" 35 #include "chrome/browser/notifications/message_center_display_service.h"
34 #include "chrome/browser/notifications/notification_test_util.h" 36 #include "chrome/browser/notifications/notification_test_util.h"
35 #include "chrome/browser/notifications/platform_notification_service_impl.h" 37 #include "chrome/browser/notifications/platform_notification_service_impl.h"
36 #include "chrome/browser/permissions/permission_request_manager.h" 38 #include "chrome/browser/permissions/permission_request_manager.h"
37 #include "chrome/browser/profiles/profile.h" 39 #include "chrome/browser/profiles/profile.h"
38 #include "chrome/browser/push_messaging/push_messaging_app_identifier.h" 40 #include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
39 #include "chrome/browser/push_messaging/push_messaging_constants.h" 41 #include "chrome/browser/push_messaging/push_messaging_constants.h"
40 #include "chrome/browser/push_messaging/push_messaging_service_factory.h" 42 #include "chrome/browser/push_messaging/push_messaging_service_factory.h"
41 #include "chrome/browser/push_messaging/push_messaging_service_impl.h" 43 #include "chrome/browser/push_messaging/push_messaging_service_impl.h"
42 #include "chrome/browser/ui/browser.h" 44 #include "chrome/browser/ui/browser.h"
43 #include "chrome/browser/ui/tabs/tab_strip_model.h" 45 #include "chrome/browser/ui/tabs/tab_strip_model.h"
44 #include "chrome/common/chrome_switches.h" 46 #include "chrome/common/chrome_switches.h"
45 #include "chrome/common/features.h" 47 #include "chrome/common/features.h"
46 #include "chrome/test/base/in_process_browser_test.h" 48 #include "chrome/test/base/in_process_browser_test.h"
47 #include "chrome/test/base/ui_test_utils.h" 49 #include "chrome/test/base/ui_test_utils.h"
48 #include "components/content_settings/core/browser/host_content_settings_map.h" 50 #include "components/content_settings/core/browser/host_content_settings_map.h"
49 #include "components/content_settings/core/common/content_settings.h" 51 #include "components/content_settings/core/common/content_settings.h"
50 #include "components/content_settings/core/common/content_settings_types.h" 52 #include "components/content_settings/core/common/content_settings_types.h"
51 #include "components/gcm_driver/common/gcm_messages.h" 53 #include "components/gcm_driver/common/gcm_messages.h"
52 #include "components/gcm_driver/gcm_client.h" 54 #include "components/gcm_driver/gcm_client.h"
53 #include "components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h" 55 #include "components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h"
56 #include "components/gcm_driver/instance_id/instance_id_driver.h"
54 #include "content/public/browser/web_contents.h" 57 #include "content/public/browser/web_contents.h"
55 #include "content/public/common/content_switches.h" 58 #include "content/public/common/content_switches.h"
56 #include "content/public/common/push_subscription_options.h" 59 #include "content/public/common/push_subscription_options.h"
57 #include "content/public/test/browser_test_utils.h" 60 #include "content/public/test/browser_test_utils.h"
58 #include "content/public/test/test_utils.h" 61 #include "content/public/test/test_utils.h"
59 #include "net/test/embedded_test_server/embedded_test_server.h" 62 #include "net/test/embedded_test_server/embedded_test_server.h"
60 #include "testing/gmock/include/gmock/gmock.h" 63 #include "testing/gmock/include/gmock/gmock.h"
61 #include "ui/base/window_open_disposition.h" 64 #include "ui/base/window_open_disposition.h"
62 65
63 #if BUILDFLAG(ENABLE_BACKGROUND) 66 #if BUILDFLAG(ENABLE_BACKGROUND)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 void DidRegister(base::Closure done_callback, 106 void DidRegister(base::Closure done_callback,
104 const std::string& registration_id, 107 const std::string& registration_id,
105 const std::vector<uint8_t>& p256dh, 108 const std::vector<uint8_t>& p256dh,
106 const std::vector<uint8_t>& auth, 109 const std::vector<uint8_t>& auth,
107 content::PushRegistrationStatus status) { 110 content::PushRegistrationStatus status) {
108 EXPECT_EQ(content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE, 111 EXPECT_EQ(content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE,
109 status); 112 status);
110 done_callback.Run(); 113 done_callback.Run();
111 } 114 }
112 115
116 void InstanceIDResultCallback(base::Closure done_callback,
117 instance_id::InstanceID::Result* out_result,
118 instance_id::InstanceID::Result result) {
119 DCHECK(out_result);
120 *out_result = result;
121 done_callback.Run();
122 }
123
113 } // namespace 124 } // namespace
114 125
115 class PushMessagingBrowserTest : public InProcessBrowserTest { 126 class PushMessagingBrowserTest : public InProcessBrowserTest {
116 public: 127 public:
117 PushMessagingBrowserTest() : gcm_service_(nullptr), gcm_driver_(nullptr) {} 128 PushMessagingBrowserTest() : gcm_service_(nullptr), gcm_driver_(nullptr) {}
118 ~PushMessagingBrowserTest() override {} 129 ~PushMessagingBrowserTest() override {}
119 130
120 // InProcessBrowserTest: 131 // InProcessBrowserTest:
121 void SetUp() override { 132 void SetUp() override {
122 https_server_.reset( 133 https_server_.reset(
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 // for testing that we maintain support for existing stored registrations. 248 // for testing that we maintain support for existing stored registrations.
238 // Calls should be wrapped in the ASSERT_NO_FATAL_FAILURE() macro. 249 // Calls should be wrapped in the ASSERT_NO_FATAL_FAILURE() macro.
239 void LegacySubscribeSuccessfully(std::string* out_subscription_id = nullptr); 250 void LegacySubscribeSuccessfully(std::string* out_subscription_id = nullptr);
240 251
241 // Strips server URL from a registration endpoint to get subscription token. 252 // Strips server URL from a registration endpoint to get subscription token.
242 // Calls should be wrapped in the ASSERT_NO_FATAL_FAILURE() macro. 253 // Calls should be wrapped in the ASSERT_NO_FATAL_FAILURE() macro.
243 void EndpointToToken(const std::string& endpoint, 254 void EndpointToToken(const std::string& endpoint,
244 bool standard_protocol = true, 255 bool standard_protocol = true,
245 std::string* out_token = nullptr); 256 std::string* out_token = nullptr);
246 257
258 // Deletes an Instance ID from the GCM Store but keeps the push subscription
259 // stored in the PushMessagingAppIdentifier map and Service Worker DB.
260 // Calls should be wrapped in the ASSERT_NO_FATAL_FAILURE() macro.
261 void DeleteInstanceIDAsIfGCMStoreReset(const std::string& app_id);
262
247 PushMessagingAppIdentifier GetAppIdentifierForServiceWorkerRegistration( 263 PushMessagingAppIdentifier GetAppIdentifierForServiceWorkerRegistration(
248 int64_t service_worker_registration_id); 264 int64_t service_worker_registration_id);
249 265
250 void SendMessageAndWaitUntilHandled( 266 void SendMessageAndWaitUntilHandled(
251 const PushMessagingAppIdentifier& app_identifier, 267 const PushMessagingAppIdentifier& app_identifier,
252 const gcm::IncomingMessage& message); 268 const gcm::IncomingMessage& message);
253 269
254 net::EmbeddedTestServer* https_server() const { return https_server_.get(); } 270 net::EmbeddedTestServer* https_server() const { return https_server_.get(); }
255 271
256 // To be called when delivery of a push message has finished. The |run_loop| 272 // To be called when delivery of a push message has finished. The |run_loop|
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 395
380 std::string script_result; 396 std::string script_result;
381 ASSERT_TRUE(RunScript("registerServiceWorker()", &script_result)); 397 ASSERT_TRUE(RunScript("registerServiceWorker()", &script_result));
382 ASSERT_EQ("ok - service worker registered", script_result); 398 ASSERT_EQ("ok - service worker registered", script_result);
383 399
384 ASSERT_NO_FATAL_FAILURE(RequestAndAcceptPermission()); 400 ASSERT_NO_FATAL_FAILURE(RequestAndAcceptPermission());
385 401
386 GURL requesting_origin = https_server()->GetURL("/").GetOrigin(); 402 GURL requesting_origin = https_server()->GetURL("/").GetOrigin();
387 int64_t service_worker_registration_id = 0LL; 403 int64_t service_worker_registration_id = 0LL;
388 PushMessagingAppIdentifier app_identifier = 404 PushMessagingAppIdentifier app_identifier =
389 PushMessagingAppIdentifier::Generate(requesting_origin, 405 PushMessagingAppIdentifier::LegacyGenerateForTesting(
390 service_worker_registration_id); 406 requesting_origin, service_worker_registration_id);
391 push_service_->IncreasePushSubscriptionCount(1, true /* is_pending */); 407 push_service_->IncreasePushSubscriptionCount(1, true /* is_pending */);
392 408
393 std::string subscription_id; 409 std::string subscription_id;
394 { 410 {
395 base::RunLoop run_loop; 411 base::RunLoop run_loop;
396 gcm::GCMClient::Result register_result = gcm::GCMClient::UNKNOWN_ERROR; 412 gcm::GCMClient::Result register_result = gcm::GCMClient::UNKNOWN_ERROR;
397 gcm_driver_->Register( 413 gcm_driver_->Register(
398 app_identifier.app_id(), {kManifestSenderId}, 414 app_identifier.app_id(), {kManifestSenderId},
399 base::Bind(&LegacyRegisterCallback, run_loop.QuitClosure(), 415 base::Bind(&LegacyRegisterCallback, run_loop.QuitClosure(),
400 &subscription_id, &register_result)); 416 &subscription_id, &register_result));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 PushMessagingBrowserTest::GetAppIdentifierForServiceWorkerRegistration( 453 PushMessagingBrowserTest::GetAppIdentifierForServiceWorkerRegistration(
438 int64_t service_worker_registration_id) { 454 int64_t service_worker_registration_id) {
439 GURL origin = https_server()->GetURL("/").GetOrigin(); 455 GURL origin = https_server()->GetURL("/").GetOrigin();
440 PushMessagingAppIdentifier app_identifier = 456 PushMessagingAppIdentifier app_identifier =
441 PushMessagingAppIdentifier::FindByServiceWorker( 457 PushMessagingAppIdentifier::FindByServiceWorker(
442 GetBrowser()->profile(), origin, service_worker_registration_id); 458 GetBrowser()->profile(), origin, service_worker_registration_id);
443 EXPECT_FALSE(app_identifier.is_null()); 459 EXPECT_FALSE(app_identifier.is_null());
444 return app_identifier; 460 return app_identifier;
445 } 461 }
446 462
463 void PushMessagingBrowserTest::DeleteInstanceIDAsIfGCMStoreReset(
464 const std::string& app_id) {
465 // Delete the Instance ID directly, keeping the push subscription stored in
466 // the PushMessagingAppIdentifier map and the Service Worker database. This
467 // simulates the GCM Store getting reset but failing to clear push
468 // subscriptions, either because the store got reset before
469 // 93ec793ac69a542b2213297737178a55d069fd0d (Chrome 56), or because a race
470 // condition (e.g. shutdown) prevents PushMessagingServiceImpl::OnStoreReset
471 // from clearing all subscriptions.
472 instance_id::InstanceIDProfileService* instance_id_profile_service =
473 instance_id::InstanceIDProfileServiceFactory::GetForProfile(
474 GetBrowser()->profile());
475 DCHECK(instance_id_profile_service);
476 instance_id::InstanceIDDriver* instance_id_driver =
477 instance_id_profile_service->driver();
478 DCHECK(instance_id_driver);
479 instance_id::InstanceID::Result delete_result =
480 instance_id::InstanceID::UNKNOWN_ERROR;
481 base::RunLoop run_loop;
482 instance_id_driver->GetInstanceID(app_id)->DeleteID(base::Bind(
483 &InstanceIDResultCallback, run_loop.QuitClosure(), &delete_result));
484 run_loop.Run();
485 ASSERT_EQ(instance_id::InstanceID::SUCCESS, delete_result);
486 }
487
447 void PushMessagingBrowserTest::SendMessageAndWaitUntilHandled( 488 void PushMessagingBrowserTest::SendMessageAndWaitUntilHandled(
448 const PushMessagingAppIdentifier& app_identifier, 489 const PushMessagingAppIdentifier& app_identifier,
449 const gcm::IncomingMessage& message) { 490 const gcm::IncomingMessage& message) {
450 base::RunLoop run_loop; 491 base::RunLoop run_loop;
451 push_service()->SetMessageCallbackForTesting(run_loop.QuitClosure()); 492 push_service()->SetMessageCallbackForTesting(run_loop.QuitClosure());
452 push_service()->OnMessage(app_identifier.app_id(), message); 493 push_service()->OnMessage(app_identifier.app_id(), message);
453 run_loop.Run(); 494 run_loop.Run();
454 } 495 }
455 496
456 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, 497 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
(...skipping 1303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 // We should not be able to look up the app id. 1801 // We should not be able to look up the app id.
1761 GURL origin = https_server()->GetURL("/").GetOrigin(); 1802 GURL origin = https_server()->GetURL("/").GetOrigin();
1762 PushMessagingAppIdentifier app_identifier = 1803 PushMessagingAppIdentifier app_identifier =
1763 PushMessagingAppIdentifier::FindByServiceWorker( 1804 PushMessagingAppIdentifier::FindByServiceWorker(
1764 GetBrowser()->profile(), origin, 1805 GetBrowser()->profile(), origin,
1765 0LL /* service_worker_registration_id */); 1806 0LL /* service_worker_registration_id */);
1766 EXPECT_TRUE(app_identifier.is_null()); 1807 EXPECT_TRUE(app_identifier.is_null());
1767 } 1808 }
1768 1809
1769 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, 1810 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
1811 InvalidGetSubscriptionUnsubscribes) {
1812 std::string script_result;
1813
1814 ASSERT_NO_FATAL_FAILURE(SubscribeSuccessfully());
1815
1816 GURL origin = https_server()->GetURL("/").GetOrigin();
1817 PushMessagingAppIdentifier app_identifier1 =
1818 PushMessagingAppIdentifier::FindByServiceWorker(
1819 GetBrowser()->profile(), origin,
1820 0LL /* service_worker_registration_id */);
1821 ASSERT_FALSE(app_identifier1.is_null());
1822
1823 ASSERT_NO_FATAL_FAILURE(
1824 DeleteInstanceIDAsIfGCMStoreReset(app_identifier1.app_id()));
1825
1826 // Push messaging should not yet be aware of the InstanceID being deleted.
1827 histogram_tester_.ExpectTotalCount("PushMessaging.UnregistrationReason", 0);
1828 // We should still be able to look up the app id.
1829 PushMessagingAppIdentifier app_identifier2 =
1830 PushMessagingAppIdentifier::FindByServiceWorker(
1831 GetBrowser()->profile(), origin,
1832 0LL /* service_worker_registration_id */);
1833 EXPECT_FALSE(app_identifier2.is_null());
1834 EXPECT_EQ(app_identifier1.app_id(), app_identifier2.app_id());
1835
1836 // Now call PushManager.getSubscription(). It should return null.
1837 ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
1838 EXPECT_EQ("false - not subscribed", script_result);
1839
1840 // This should have unsubscribed the push subscription.
1841 histogram_tester_.ExpectUniqueSample(
1842 "PushMessaging.UnregistrationReason",
1843 content::PUSH_UNREGISTRATION_REASON_GET_SUBSCRIPTION_STORAGE_CORRUPT, 1);
1844 // We should no longer be able to look up the app id.
1845 PushMessagingAppIdentifier app_identifier3 =
1846 PushMessagingAppIdentifier::FindByServiceWorker(
1847 GetBrowser()->profile(), origin,
1848 0LL /* service_worker_registration_id */);
1849 EXPECT_TRUE(app_identifier3.is_null());
1850 }
1851
1852 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, InvalidSubscribeUnsubscribes) {
1853 std::string script_result;
1854
1855 std::string token1;
1856 ASSERT_NO_FATAL_FAILURE(SubscribeSuccessfully(true /* use_key */, &token1));
1857
1858 GURL origin = https_server()->GetURL("/").GetOrigin();
1859 PushMessagingAppIdentifier app_identifier1 =
1860 PushMessagingAppIdentifier::FindByServiceWorker(
1861 GetBrowser()->profile(), origin,
1862 0LL /* service_worker_registration_id */);
1863 ASSERT_FALSE(app_identifier1.is_null());
1864
1865 ASSERT_NO_FATAL_FAILURE(
1866 DeleteInstanceIDAsIfGCMStoreReset(app_identifier1.app_id()));
1867
1868 // Push messaging should not yet be aware of the InstanceID being deleted.
1869 histogram_tester_.ExpectTotalCount("PushMessaging.UnregistrationReason", 0);
1870 // We should still be able to look up the app id.
1871 PushMessagingAppIdentifier app_identifier2 =
1872 PushMessagingAppIdentifier::FindByServiceWorker(
1873 GetBrowser()->profile(), origin,
1874 0LL /* service_worker_registration_id */);
1875 EXPECT_FALSE(app_identifier2.is_null());
1876 EXPECT_EQ(app_identifier1.app_id(), app_identifier2.app_id());
1877
1878 // Now call PushManager.subscribe() again. It should succeed, but with a
1879 // *different* token, indicating that it unsubscribed and re-subscribed.
1880 std::string token2;
1881 ASSERT_NO_FATAL_FAILURE(SubscribeSuccessfully(true /* use_key */, &token2));
1882 EXPECT_NE(token1, token2);
1883
1884 // This should have unsubscribed the original push subscription.
1885 histogram_tester_.ExpectUniqueSample(
1886 "PushMessaging.UnregistrationReason",
1887 content::PUSH_UNREGISTRATION_REASON_SUBSCRIBE_STORAGE_CORRUPT, 1);
1888 // Looking up the app id should return a different id.
1889 PushMessagingAppIdentifier app_identifier3 =
1890 PushMessagingAppIdentifier::FindByServiceWorker(
1891 GetBrowser()->profile(), origin,
1892 0LL /* service_worker_registration_id */);
1893 EXPECT_FALSE(app_identifier3.is_null());
1894 EXPECT_NE(app_identifier2.app_id(), app_identifier3.app_id());
1895 }
1896
1897 IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest,
1770 GlobalResetPushPermissionUnsubscribes) { 1898 GlobalResetPushPermissionUnsubscribes) {
1771 std::string script_result; 1899 std::string script_result;
1772 1900
1773 ASSERT_NO_FATAL_FAILURE(SubscribeSuccessfully()); 1901 ASSERT_NO_FATAL_FAILURE(SubscribeSuccessfully());
1774 1902
1775 ASSERT_TRUE(RunScript("hasSubscription()", &script_result)); 1903 ASSERT_TRUE(RunScript("hasSubscription()", &script_result));
1776 EXPECT_EQ("true - subscribed", script_result); 1904 EXPECT_EQ("true - subscribed", script_result);
1777 1905
1778 ASSERT_TRUE(RunScript("permissionState()", &script_result)); 1906 ASSERT_TRUE(RunScript("permissionState()", &script_result));
1779 EXPECT_EQ("permission status - granted", script_result); 1907 EXPECT_EQ("permission status - granted", script_result);
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
2248 push_service()->SetUnsubscribeCallbackForTesting(run_loop.QuitClosure()); 2376 push_service()->SetUnsubscribeCallbackForTesting(run_loop.QuitClosure());
2249 ASSERT_TRUE(RunScript("unsubscribePush()", &script_result)); 2377 ASSERT_TRUE(RunScript("unsubscribePush()", &script_result));
2250 EXPECT_EQ("unsubscribe result: true", script_result); 2378 EXPECT_EQ("unsubscribe result: true", script_result);
2251 // Background mode is only guaranteed to have updated once the unsubscribe 2379 // Background mode is only guaranteed to have updated once the unsubscribe
2252 // callback for testing has been run (PushSubscription.unsubscribe() usually 2380 // callback for testing has been run (PushSubscription.unsubscribe() usually
2253 // resolves before that, in order to avoid blocking on network retries etc). 2381 // resolves before that, in order to avoid blocking on network retries etc).
2254 run_loop.Run(); 2382 run_loop.Run();
2255 ASSERT_FALSE(background_mode_manager->IsBackgroundModeActive()); 2383 ASSERT_FALSE(background_mode_manager->IsBackgroundModeActive());
2256 } 2384 }
2257 #endif // BUILDFLAG(ENABLE_BACKGROUND) && !defined(OS_CHROMEOS) 2385 #endif // BUILDFLAG(ENABLE_BACKGROUND) && !defined(OS_CHROMEOS)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698