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

Side by Side Diff: components/safe_browsing/password_protection/password_protection_service_unittest.cc

Issue 2869253002: Add UMA metrics to phishguard pings (Closed)
Patch Set: resolve comments on histograms.xml Created 3 years, 7 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 #include "components/safe_browsing/password_protection/password_protection_servi ce.h" 4 #include "components/safe_browsing/password_protection/password_protection_servi ce.h"
5 5
6 #include "base/memory/ptr_util.h" 6 #include "base/memory/ptr_util.h"
7 #include "base/run_loop.h" 7 #include "base/run_loop.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "base/test/histogram_tester.h" 9 #include "base/test/histogram_tester.h"
10 #include "base/test/null_task_runner.h" 10 #include "base/test/null_task_runner.h"
11 #include "components/content_settings/core/browser/host_content_settings_map.h" 11 #include "components/content_settings/core/browser/host_content_settings_map.h"
12 #include "components/safe_browsing/password_protection/password_protection_reque st.h" 12 #include "components/safe_browsing/password_protection/password_protection_reque st.h"
13 #include "components/safe_browsing_db/test_database_manager.h" 13 #include "components/safe_browsing_db/test_database_manager.h"
14 #include "components/sync_preferences/testing_pref_service_syncable.h" 14 #include "components/sync_preferences/testing_pref_service_syncable.h"
15 #include "content/public/test/test_browser_thread_bundle.h" 15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "net/url_request/test_url_fetcher_factory.h" 16 #include "net/url_request/test_url_fetcher_factory.h"
17 #include "testing/gmock/include/gmock/gmock.h" 17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
19 19
20 namespace { 20 namespace {
21 21
22 const char kPasswordReuseMatchWhitelistHistogramName[] = 22 const char kPasswordReuseMatchWhitelistHistogramName[] =
23 "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist"; 23 "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist";
24 const char kWhitelistedUrl[] = "http://inwhitelist.com"; 24 const char kWhitelistedUrl[] = "http://inwhitelist.com";
25 const char kNoneWhitelistedUrl[] = "http://notinwhitelist.com"; 25 const char kNoneWhitelistedUrl[] = "http://notinwhitelist.com";
26 const char kRequestOutcomeHistogramName[] = "PasswordProtection.RequestOutcome";
27 const char kTargetUrl[] = "http://foo.com"; 26 const char kTargetUrl[] = "http://foo.com";
27 const char kVerdictHistogramName[] =
28 "PasswordProtection.Verdict.PasswordFieldOnFocus";
28 29
29 } // namespace 30 } // namespace
30 31
31 namespace safe_browsing { 32 namespace safe_browsing {
32 33
33 class MockSafeBrowsingDatabaseManager : public TestSafeBrowsingDatabaseManager { 34 class MockSafeBrowsingDatabaseManager : public TestSafeBrowsingDatabaseManager {
34 public: 35 public:
35 MockSafeBrowsingDatabaseManager() {} 36 MockSafeBrowsingDatabaseManager() {}
36 37
37 MOCK_METHOD1(MatchCsdWhitelistUrl, bool(const GURL&)); 38 MOCK_METHOD1(MatchCsdWhitelistUrl, bool(const GURL&));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 bool IsExtendedReporting() override { return is_extended_reporting_; } 91 bool IsExtendedReporting() override { return is_extended_reporting_; }
91 92
92 bool IsIncognito() override { return is_incognito_; } 93 bool IsIncognito() override { return is_incognito_; }
93 94
94 void set_extended_reporting(bool enabled) { 95 void set_extended_reporting(bool enabled) {
95 is_extended_reporting_ = enabled; 96 is_extended_reporting_ = enabled;
96 } 97 }
97 98
98 void set_incognito(bool enabled) { is_incognito_ = enabled; } 99 void set_incognito(bool enabled) { is_incognito_ = enabled; }
99 100
100 bool IsPingingEnabled(const base::Feature& feature) override { return true; } 101 bool IsPingingEnabled(const base::Feature& feature,
102 RequestOutcome* reason) override {
103 return true;
104 }
101 105
102 bool IsHistorySyncEnabled() override { return false; } 106 bool IsHistorySyncEnabled() override { return false; }
103 107
104 LoginReputationClientResponse* latest_response() { 108 LoginReputationClientResponse* latest_response() {
105 return latest_response_.get(); 109 return latest_response_.get();
106 } 110 }
107 111
108 ~TestPasswordProtectionService() override {} 112 ~TestPasswordProtectionService() override {}
109 113
110 size_t GetPendingRequestsCount() { return requests_.size(); } 114 size_t GetPendingRequestsCount() { return requests_.size(); }
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 // If delete all history. All password protection content settings should be 404 // If delete all history. All password protection content settings should be
401 // gone. 405 // gone.
402 password_protection_service_->RemoveContentSettingsOnURLsDeleted( 406 password_protection_service_->RemoveContentSettingsOnURLsDeleted(
403 true /* all_history */, history::URLRows()); 407 true /* all_history */, history::URLRows());
404 EXPECT_EQ(0U, GetStoredVerdictCount()); 408 EXPECT_EQ(0U, GetStoredVerdictCount());
405 } 409 }
406 410
407 TEST_F(PasswordProtectionServiceTest, 411 TEST_F(PasswordProtectionServiceTest,
408 TestNoRequestCreatedIfMainFrameURLIsNotValid) { 412 TestNoRequestCreatedIfMainFrameURLIsNotValid) {
409 ASSERT_EQ(0u, password_protection_service_->GetPendingRequestsCount()); 413 ASSERT_EQ(0u, password_protection_service_->GetPendingRequestsCount());
410 password_protection_service_->MaybeStartLowReputationRequest( 414 password_protection_service_->MaybeStartPasswordFieldOnFocusRequest(
411 GURL(), GURL("http://foo.com/submit"), GURL("http://foo.com/frame")); 415 GURL(), GURL("http://foo.com/submit"), GURL("http://foo.com/frame"));
412 EXPECT_EQ(0u, password_protection_service_->GetPendingRequestsCount()); 416 EXPECT_EQ(0u, password_protection_service_->GetPendingRequestsCount());
413 } 417 }
414 418
415 TEST_F(PasswordProtectionServiceTest, 419 TEST_F(PasswordProtectionServiceTest,
416 TestNoRequestCreatedIfMainFrameURLIsNotHttpOrHttps) { 420 TestNoRequestCreatedIfMainFrameURLIsNotHttpOrHttps) {
417 ASSERT_EQ(0u, password_protection_service_->GetPendingRequestsCount()); 421 ASSERT_EQ(0u, password_protection_service_->GetPendingRequestsCount());
418 // If main frame url is data url, don't create request. 422 // If main frame url is data url, don't create request.
419 password_protection_service_->MaybeStartLowReputationRequest( 423 password_protection_service_->MaybeStartPasswordFieldOnFocusRequest(
420 GURL("data:text/html, <p>hellow"), GURL("http://foo.com/submit"), 424 GURL("data:text/html, <p>hellow"), GURL("http://foo.com/submit"),
421 GURL("http://foo.com/frame")); 425 GURL("http://foo.com/frame"));
422 EXPECT_EQ(0u, password_protection_service_->GetPendingRequestsCount()); 426 EXPECT_EQ(0u, password_protection_service_->GetPendingRequestsCount());
423 427
424 // If main frame url is ftp, don't create request. 428 // If main frame url is ftp, don't create request.
425 password_protection_service_->MaybeStartLowReputationRequest( 429 password_protection_service_->MaybeStartPasswordFieldOnFocusRequest(
426 GURL("ftp://foo.com:21"), GURL("http://foo.com/submit"), 430 GURL("ftp://foo.com:21"), GURL("http://foo.com/submit"),
427 GURL("http://foo.com/frame")); 431 GURL("http://foo.com/frame"));
428 EXPECT_EQ(0u, password_protection_service_->GetPendingRequestsCount()); 432 EXPECT_EQ(0u, password_protection_service_->GetPendingRequestsCount());
429 } 433 }
430 434
431 TEST_F(PasswordProtectionServiceTest, TestNoRequestSentForWhitelistedURL) { 435 TEST_F(PasswordProtectionServiceTest, TestNoRequestSentForWhitelistedURL) {
432 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); 436 histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
433 InitializeAndStartRequest(true /* match whitelist */, 437 InitializeAndStartRequest(true /* match whitelist */,
434 10000 /* timeout in ms*/); 438 10000 /* timeout in ms*/);
435 base::RunLoop().RunUntilIdle(); 439 base::RunLoop().RunUntilIdle();
436 EXPECT_EQ(nullptr, password_protection_service_->latest_response()); 440 EXPECT_EQ(nullptr, password_protection_service_->latest_response());
437 EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName), 441 EXPECT_THAT(
438 testing::ElementsAre(base::Bucket(4 /* MATCHED_WHITELIST */, 1))); 442 histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
443 testing::ElementsAre(base::Bucket(4 /* MATCHED_WHITELIST */, 1)));
439 } 444 }
440 445
441 TEST_F(PasswordProtectionServiceTest, TestNoRequestSentIfVerdictAlreadyCached) { 446 TEST_F(PasswordProtectionServiceTest, TestNoRequestSentIfVerdictAlreadyCached) {
442 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); 447 histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
443 CacheVerdict(GURL(kTargetUrl), LoginReputationClientResponse::LOW_REPUTATION, 448 CacheVerdict(GURL(kTargetUrl), LoginReputationClientResponse::LOW_REPUTATION,
444 600, GURL(kTargetUrl).host(), base::Time::Now()); 449 600, GURL(kTargetUrl).host(), base::Time::Now());
445 InitializeAndStartRequest(false /* match whitelist */, 450 InitializeAndStartRequest(false /* match whitelist */,
446 10000 /* timeout in ms*/); 451 10000 /* timeout in ms*/);
447 base::RunLoop().RunUntilIdle(); 452 base::RunLoop().RunUntilIdle();
448 EXPECT_THAT( 453 EXPECT_THAT(
449 histograms_.GetAllSamples(kRequestOutcomeHistogramName), 454 histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
450 testing::ElementsAre(base::Bucket(5 /* RESPONSE_ALREADY_CACHED */, 1))); 455 testing::ElementsAre(base::Bucket(5 /* RESPONSE_ALREADY_CACHED */, 1)));
451 EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION, 456 EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION,
452 password_protection_service_->latest_response()->verdict_type()); 457 password_protection_service_->latest_response()->verdict_type());
453 } 458 }
454 459
455 TEST_F(PasswordProtectionServiceTest, TestResponseFetchFailed) { 460 TEST_F(PasswordProtectionServiceTest, TestResponseFetchFailed) {
456 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); 461 histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
457 net::TestURLFetcher failed_fetcher(0, GURL("http://bar.com"), nullptr); 462 net::TestURLFetcher failed_fetcher(0, GURL("http://bar.com"), nullptr);
458 // Set up failed response. 463 // Set up failed response.
459 failed_fetcher.set_status( 464 failed_fetcher.set_status(
460 net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); 465 net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED));
461 466
462 InitializeAndStartRequest(false /* match whitelist */, 467 InitializeAndStartRequest(false /* match whitelist */,
463 10000 /* timeout in ms*/); 468 10000 /* timeout in ms*/);
464 request_->OnURLFetchComplete(&failed_fetcher); 469 request_->OnURLFetchComplete(&failed_fetcher);
465 base::RunLoop().RunUntilIdle(); 470 base::RunLoop().RunUntilIdle();
466 EXPECT_EQ(nullptr, password_protection_service_->latest_response()); 471 EXPECT_EQ(nullptr, password_protection_service_->latest_response());
467 EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName), 472 EXPECT_THAT(
468 testing::ElementsAre(base::Bucket(9 /* FETCH_FAILED */, 1))); 473 histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
474 testing::ElementsAre(base::Bucket(9 /* FETCH_FAILED */, 1)));
469 } 475 }
470 476
471 TEST_F(PasswordProtectionServiceTest, TestMalformedResponse) { 477 TEST_F(PasswordProtectionServiceTest, TestMalformedResponse) {
472 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); 478 histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
473 // Set up malformed response. 479 // Set up malformed response.
474 net::TestURLFetcher fetcher(0, GURL("http://bar.com"), nullptr); 480 net::TestURLFetcher fetcher(0, GURL("http://bar.com"), nullptr);
475 fetcher.set_status( 481 fetcher.set_status(
476 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK)); 482 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK));
477 fetcher.set_response_code(200); 483 fetcher.set_response_code(200);
478 fetcher.SetResponseString("invalid response"); 484 fetcher.SetResponseString("invalid response");
479 485
480 InitializeAndStartRequest(false /* match whitelist */, 486 InitializeAndStartRequest(false /* match whitelist */,
481 10000 /* timeout in ms*/); 487 10000 /* timeout in ms*/);
482 request_->OnURLFetchComplete(&fetcher); 488 request_->OnURLFetchComplete(&fetcher);
483 base::RunLoop().RunUntilIdle(); 489 base::RunLoop().RunUntilIdle();
484 EXPECT_EQ(nullptr, password_protection_service_->latest_response()); 490 EXPECT_EQ(nullptr, password_protection_service_->latest_response());
485 EXPECT_THAT( 491 EXPECT_THAT(
486 histograms_.GetAllSamples(kRequestOutcomeHistogramName), 492 histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
487 testing::ElementsAre(base::Bucket(10 /* RESPONSE_MALFORMED */, 1))); 493 testing::ElementsAre(base::Bucket(10 /* RESPONSE_MALFORMED */, 1)));
488 } 494 }
489 495
490 TEST_F(PasswordProtectionServiceTest, TestRequestTimedout) { 496 TEST_F(PasswordProtectionServiceTest, TestRequestTimedout) {
491 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); 497 histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
492 InitializeAndStartRequest(false /* match whitelist */, 498 InitializeAndStartRequest(false /* match whitelist */,
493 0 /* timeout immediately */); 499 0 /* timeout immediately */);
494 base::RunLoop().RunUntilIdle(); 500 base::RunLoop().RunUntilIdle();
495 EXPECT_EQ(nullptr, password_protection_service_->latest_response()); 501 EXPECT_EQ(nullptr, password_protection_service_->latest_response());
496 EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName), 502 EXPECT_THAT(
497 testing::ElementsAre(base::Bucket(3 /* TIMEDOUT */, 1))); 503 histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
504 testing::ElementsAre(base::Bucket(3 /* TIMEDOUT */, 1)));
498 } 505 }
499 506
500 TEST_F(PasswordProtectionServiceTest, TestRequestAndResponseSuccessfull) { 507 TEST_F(PasswordProtectionServiceTest, TestRequestAndResponseSuccessfull) {
501 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); 508 histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
502 // Set up valid response. 509 // Set up valid response.
503 net::TestURLFetcher fetcher(0, GURL("http://bar.com"), nullptr); 510 net::TestURLFetcher fetcher(0, GURL("http://bar.com"), nullptr);
504 fetcher.set_status( 511 fetcher.set_status(
505 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK)); 512 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK));
506 fetcher.set_response_code(200); 513 fetcher.set_response_code(200);
507 LoginReputationClientResponse expected_response = CreateVerdictProto( 514 LoginReputationClientResponse expected_response = CreateVerdictProto(
508 LoginReputationClientResponse::PHISHING, 600, GURL(kTargetUrl).host()); 515 LoginReputationClientResponse::PHISHING, 600, GURL(kTargetUrl).host());
509 fetcher.SetResponseString(expected_response.SerializeAsString()); 516 fetcher.SetResponseString(expected_response.SerializeAsString());
510 517
511 InitializeAndStartRequest(false /* match whitelist */, 518 InitializeAndStartRequest(false /* match whitelist */,
512 10000 /* timeout in ms*/); 519 10000 /* timeout in ms*/);
513 request_->OnURLFetchComplete(&fetcher); 520 request_->OnURLFetchComplete(&fetcher);
514 base::RunLoop().RunUntilIdle(); 521 base::RunLoop().RunUntilIdle();
515 EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName), 522 EXPECT_THAT(
516 testing::ElementsAre(base::Bucket(1 /* SUCCEEDED */, 1))); 523 histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
524 testing::ElementsAre(base::Bucket(1 /* SUCCEEDED */, 1)));
525 EXPECT_THAT(histograms_.GetAllSamples(kVerdictHistogramName),
526 testing::ElementsAre(base::Bucket(3 /* PHISHING */, 1)));
517 LoginReputationClientResponse* actual_response = 527 LoginReputationClientResponse* actual_response =
518 password_protection_service_->latest_response(); 528 password_protection_service_->latest_response();
519 EXPECT_EQ(expected_response.verdict_type(), actual_response->verdict_type()); 529 EXPECT_EQ(expected_response.verdict_type(), actual_response->verdict_type());
520 EXPECT_EQ(expected_response.cache_expression(), 530 EXPECT_EQ(expected_response.cache_expression(),
521 actual_response->cache_expression()); 531 actual_response->cache_expression());
522 EXPECT_EQ(expected_response.cache_duration_sec(), 532 EXPECT_EQ(expected_response.cache_duration_sec(),
523 actual_response->cache_duration_sec()); 533 actual_response->cache_duration_sec());
524 } 534 }
525 535
526 TEST_F(PasswordProtectionServiceTest, TestTearDownWithPendingRequests) { 536 TEST_F(PasswordProtectionServiceTest, TestTearDownWithPendingRequests) {
527 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); 537 histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
528 GURL target_url(kTargetUrl); 538 GURL target_url(kTargetUrl);
529 EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(target_url)) 539 EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(target_url))
530 .WillRepeatedly(testing::Return(false)); 540 .WillRepeatedly(testing::Return(false));
531 password_protection_service_->StartRequest( 541 password_protection_service_->StartRequest(
532 target_url, GURL("http://foo.com/submit"), GURL("http://foo.com/frame"), 542 target_url, GURL("http://foo.com/submit"), GURL("http://foo.com/frame"),
533 LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE); 543 LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE);
534 544
535 // Destroy password_protection_service_ while there is one request pending. 545 // Destroy password_protection_service_ while there is one request pending.
536 password_protection_service_.reset(); 546 password_protection_service_.reset();
537 base::RunLoop().RunUntilIdle(); 547 base::RunLoop().RunUntilIdle();
538 548
539 EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName), 549 EXPECT_THAT(
540 testing::ElementsAre(base::Bucket(2 /* CANCELED */, 1))); 550 histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
551 testing::ElementsAre(base::Bucket(2 /* CANCELED */, 1)));
541 } 552 }
542 553
543 TEST_F(PasswordProtectionServiceTest, TestCleanUpExpiredVerdict) { 554 TEST_F(PasswordProtectionServiceTest, TestCleanUpExpiredVerdict) {
544 ASSERT_EQ(0U, GetStoredVerdictCount()); 555 ASSERT_EQ(0U, GetStoredVerdictCount());
545 // Prepare 4 verdicts: 556 // Prepare 4 verdicts:
546 // (1) "foo.com/abc" valid 557 // (1) "foo.com/abc" valid
547 // (2) "foo.com/def" expired 558 // (2) "foo.com/def" expired
548 // (3) "bar.com/abc" expired 559 // (3) "bar.com/abc" expired
549 // (4) "bar.com/def" expired 560 // (4) "bar.com/def" expired
550 base::Time now = base::Time::Now(); 561 base::Time now = base::Time::Now();
(...skipping 21 matching lines...) Expand all
572 EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, 583 EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED,
573 password_protection_service_->GetCachedVerdict( 584 password_protection_service_->GetCachedVerdict(
574 GURL("https://foo.com/def/index.jsp"), &actual_verdict)); 585 GURL("https://foo.com/def/index.jsp"), &actual_verdict));
575 // Nothing in content setting for bar.com. 586 // Nothing in content setting for bar.com.
576 EXPECT_EQ(nullptr, content_setting_map_->GetWebsiteSetting( 587 EXPECT_EQ(nullptr, content_setting_map_->GetWebsiteSetting(
577 GURL("https://bar.com"), GURL(), 588 GURL("https://bar.com"), GURL(),
578 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, 589 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION,
579 std::string(), nullptr)); 590 std::string(), nullptr));
580 } 591 }
581 } // namespace safe_browsing 592 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « components/safe_browsing/password_protection/password_protection_service.cc ('k') | tools/metrics/histograms/enums.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698