| OLD | NEW |
| 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 "chrome/browser/android/offline_pages/prerendering_offliner.h" | 5 #include "chrome/browser/android/offline_pages/prerendering_offliner.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| 11 #include "base/sys_info.h" | 11 #include "base/sys_info.h" |
| 12 #include "base/test/scoped_feature_list.h" |
| 12 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
| 13 #include "chrome/browser/android/offline_pages/prerendering_loader.h" | 14 #include "chrome/browser/android/offline_pages/prerendering_loader.h" |
| 14 #include "chrome/browser/net/prediction_options.h" | 15 #include "chrome/browser/net/prediction_options.h" |
| 15 #include "chrome/common/pref_names.h" | 16 #include "chrome/common/pref_names.h" |
| 16 #include "chrome/test/base/testing_profile.h" | 17 #include "chrome/test/base/testing_profile.h" |
| 17 #include "components/content_settings/core/common/pref_names.h" | 18 #include "components/content_settings/core/common/pref_names.h" |
| 18 #include "components/offline_pages/core/background/offliner.h" | 19 #include "components/offline_pages/core/background/offliner.h" |
| 19 #include "components/offline_pages/core/background/offliner_policy.h" | 20 #include "components/offline_pages/core/background/offliner_policy.h" |
| 20 #include "components/offline_pages/core/background/save_page_request.h" | 21 #include "components/offline_pages/core/background/save_page_request.h" |
| 22 #include "components/offline_pages/core/offline_page_feature.h" |
| 21 #include "components/offline_pages/core/stub_offline_page_model.h" | 23 #include "components/offline_pages/core/stub_offline_page_model.h" |
| 22 #include "components/prefs/pref_service.h" | 24 #include "components/prefs/pref_service.h" |
| 25 #include "content/public/browser/mhtml_extra_parts.h" |
| 23 #include "content/public/test/test_browser_thread_bundle.h" | 26 #include "content/public/test/test_browser_thread_bundle.h" |
| 24 #include "content/public/test/web_contents_tester.h" | 27 #include "content/public/test/web_contents_tester.h" |
| 25 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 26 | 29 |
| 27 namespace offline_pages { | 30 namespace offline_pages { |
| 28 | 31 |
| 29 namespace { | 32 namespace { |
| 30 const int64_t kRequestId = 7; | 33 const int64_t kRequestId = 7; |
| 31 const GURL kHttpUrl("http://tunafish.com"); | 34 const GURL kHttpUrl("http://tunafish.com"); |
| 32 const GURL kFileUrl("file://sailfish.png"); | 35 const GURL kFileUrl("file://sailfish.png"); |
| 33 const ClientId kClientId("AsyncLoading", "88"); | 36 const ClientId kClientId("AsyncLoading", "88"); |
| 34 const bool kUserRequested = true; | 37 const bool kUserRequested = true; |
| 35 | 38 |
| 36 // Mock Loader for testing the Offliner calls. | 39 // Mock Loader for testing the Offliner calls. |
| 37 class MockPrerenderingLoader : public PrerenderingLoader { | 40 class MockPrerenderingLoader : public PrerenderingLoader { |
| 38 public: | 41 public: |
| 39 explicit MockPrerenderingLoader(content::BrowserContext* browser_context) | 42 explicit MockPrerenderingLoader(content::BrowserContext* browser_context) |
| 40 : PrerenderingLoader(browser_context), | 43 : PrerenderingLoader(browser_context), |
| 41 can_prerender_(true), | 44 can_prerender_(true), |
| 42 mock_loading_(false), | 45 mock_loading_(false), |
| 43 mock_loaded_(false), | 46 mock_loaded_(false), |
| 44 mock_is_lowbar_met_(false), | 47 mock_is_lowbar_met_(false), |
| 45 start_snapshot_called_(false) {} | 48 start_snapshot_called_(false) {} |
| 46 ~MockPrerenderingLoader() override {} | 49 ~MockPrerenderingLoader() override { delete web_contents_; } |
| 47 | 50 |
| 48 bool LoadPage(const GURL& url, | 51 bool LoadPage(const GURL& url, |
| 49 const LoadPageCallback& load_done_callback, | 52 const LoadPageCallback& load_done_callback, |
| 50 const ProgressCallback& progress_callback) override { | 53 const ProgressCallback& progress_callback) override { |
| 51 mock_loading_ = can_prerender_; | 54 mock_loading_ = can_prerender_; |
| 52 load_page_callback_ = load_done_callback; | 55 load_page_callback_ = load_done_callback; |
| 53 progress_callback_ = progress_callback; | 56 progress_callback_ = progress_callback; |
| 54 return mock_loading_; | 57 return mock_loading_; |
| 55 } | 58 } |
| 56 | 59 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 72 base::ThreadTaskRunnerHandle::Get()->PostTask( | 75 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 73 FROM_HERE, | 76 FROM_HERE, |
| 74 base::Bind(load_page_callback_, Offliner::RequestStatus::LOADING_FAILED, | 77 base::Bind(load_page_callback_, Offliner::RequestStatus::LOADING_FAILED, |
| 75 nullptr /* web_contents */)); | 78 nullptr /* web_contents */)); |
| 76 } | 79 } |
| 77 | 80 |
| 78 void CompleteLoadingAsLoaded() { | 81 void CompleteLoadingAsLoaded() { |
| 79 DCHECK(mock_loading_); | 82 DCHECK(mock_loading_); |
| 80 mock_loading_ = false; | 83 mock_loading_ = false; |
| 81 mock_loaded_ = true; | 84 mock_loaded_ = true; |
| 85 web_contents_ = content::WebContentsTester::CreateTestWebContents( |
| 86 new TestingProfile(), NULL); |
| 82 base::ThreadTaskRunnerHandle::Get()->PostTask( | 87 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 83 FROM_HERE, | 88 FROM_HERE, base::Bind(load_page_callback_, |
| 84 base::Bind(load_page_callback_, Offliner::RequestStatus::LOADED, | 89 Offliner::RequestStatus::LOADED, web_contents_)); |
| 85 content::WebContentsTester::CreateTestWebContents( | |
| 86 new TestingProfile(), NULL))); | |
| 87 } | 90 } |
| 88 | 91 |
| 89 void CompleteLoadingAsCanceled() { | 92 void CompleteLoadingAsCanceled() { |
| 90 DCHECK(!IsIdle()); | 93 DCHECK(!IsIdle()); |
| 91 mock_loading_ = false; | 94 mock_loading_ = false; |
| 92 mock_loaded_ = false; | 95 mock_loaded_ = false; |
| 93 base::ThreadTaskRunnerHandle::Get()->PostTask( | 96 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 94 FROM_HERE, base::Bind(load_page_callback_, | 97 FROM_HERE, base::Bind(load_page_callback_, |
| 95 Offliner::RequestStatus::LOADING_CANCELED, | 98 Offliner::RequestStatus::LOADING_CANCELED, |
| 96 nullptr /* web_contents */)); | 99 nullptr /* web_contents */)); |
| 97 } | 100 } |
| 98 | 101 |
| 99 void DisablePrerendering() { can_prerender_ = false; } | 102 void DisablePrerendering() { can_prerender_ = false; } |
| 100 const LoadPageCallback& load_page_callback() { return load_page_callback_; } | 103 const LoadPageCallback& load_page_callback() { return load_page_callback_; } |
| 101 void set_is_lowbar_met(bool is_lowbar_met) { | 104 void set_is_lowbar_met(bool is_lowbar_met) { |
| 102 mock_is_lowbar_met_ = is_lowbar_met; | 105 mock_is_lowbar_met_ = is_lowbar_met; |
| 103 } | 106 } |
| 104 bool start_snapshot_called() { return start_snapshot_called_; } | 107 bool start_snapshot_called() { return start_snapshot_called_; } |
| 105 | 108 |
| 109 content::WebContents* web_contents() { return web_contents_; } |
| 110 |
| 106 private: | 111 private: |
| 107 bool can_prerender_; | 112 bool can_prerender_; |
| 108 bool mock_loading_; | 113 bool mock_loading_; |
| 109 bool mock_loaded_; | 114 bool mock_loaded_; |
| 110 bool mock_is_lowbar_met_; | 115 bool mock_is_lowbar_met_; |
| 111 bool start_snapshot_called_; | 116 bool start_snapshot_called_; |
| 112 LoadPageCallback load_page_callback_; | 117 LoadPageCallback load_page_callback_; |
| 113 ProgressCallback progress_callback_; | 118 ProgressCallback progress_callback_; |
| 119 content::WebContents* web_contents_; |
| 114 | 120 |
| 115 DISALLOW_COPY_AND_ASSIGN(MockPrerenderingLoader); | 121 DISALLOW_COPY_AND_ASSIGN(MockPrerenderingLoader); |
| 116 }; | 122 }; |
| 117 | 123 |
| 118 // Mock OfflinePageModel for testing the SavePage calls. | 124 // Mock OfflinePageModel for testing the SavePage calls. |
| 119 class MockOfflinePageModel : public StubOfflinePageModel { | 125 class MockOfflinePageModel : public StubOfflinePageModel { |
| 120 public: | 126 public: |
| 121 MockOfflinePageModel() : mock_saving_(false) {} | 127 MockOfflinePageModel() : mock_saving_(false) {} |
| 122 ~MockOfflinePageModel() override {} | 128 ~MockOfflinePageModel() override {} |
| 123 | 129 |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 base::Time creation_time = base::Time::Now(); | 524 base::Time creation_time = base::Time::Now(); |
| 519 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time, | 525 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time, |
| 520 kUserRequested); | 526 kUserRequested); |
| 521 EXPECT_TRUE(offliner()->LoadAndSave(request, completion_callback(), | 527 EXPECT_TRUE(offliner()->LoadAndSave(request, completion_callback(), |
| 522 progress_callback())); | 528 progress_callback())); |
| 523 loader()->set_is_lowbar_met(true); | 529 loader()->set_is_lowbar_met(true); |
| 524 EXPECT_FALSE(offliner()->HandleTimeout(request)); | 530 EXPECT_FALSE(offliner()->HandleTimeout(request)); |
| 525 EXPECT_FALSE(loader()->start_snapshot_called()); | 531 EXPECT_FALSE(loader()->start_snapshot_called()); |
| 526 } | 532 } |
| 527 | 533 |
| 534 TEST_F(PrerenderingOfflinerTest, SignalCollectionDisabled) { |
| 535 // Ensure feature flag for Signal collection is off, |
| 536 EXPECT_FALSE(offline_pages::IsOfflinePagesLoadSignalCollectingEnabled()); |
| 537 |
| 538 base::Time creation_time = base::Time::Now(); |
| 539 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time, |
| 540 kUserRequested); |
| 541 EXPECT_TRUE(offliner()->LoadAndSave(request, completion_callback(), |
| 542 progress_callback())); |
| 543 EXPECT_FALSE(loader()->IsIdle()); |
| 544 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status()); |
| 545 |
| 546 loader()->CompleteLoadingAsLoaded(); |
| 547 PumpLoop(); |
| 548 |
| 549 model()->CompleteSavingAsSuccess(); |
| 550 PumpLoop(); |
| 551 EXPECT_EQ(Offliner::RequestStatus::SAVED, request_status()); |
| 552 |
| 553 // No extra parts should be added if the flag is off. |
| 554 content::MHTMLExtraParts* extra_parts = |
| 555 content::MHTMLExtraParts::FromWebContents(loader()->web_contents()); |
| 556 EXPECT_EQ(extra_parts->size(), 0); |
| 557 } |
| 558 |
| 559 TEST_F(PrerenderingOfflinerTest, SignalCollectionEnabled) { |
| 560 // Ensure feature flag for signal collection is on. |
| 561 base::test::ScopedFeatureList scoped_feature_list; |
| 562 scoped_feature_list.InitAndEnableFeature( |
| 563 kOfflinePagesLoadSignalCollectingFeature); |
| 564 EXPECT_TRUE(IsOfflinePagesLoadSignalCollectingEnabled()); |
| 565 |
| 566 base::Time creation_time = base::Time::Now(); |
| 567 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time, |
| 568 kUserRequested); |
| 569 EXPECT_TRUE(offliner()->LoadAndSave(request, completion_callback(), |
| 570 progress_callback())); |
| 571 EXPECT_FALSE(loader()->IsIdle()); |
| 572 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status()); |
| 573 |
| 574 loader()->CompleteLoadingAsLoaded(); |
| 575 PumpLoop(); |
| 576 |
| 577 model()->CompleteSavingAsSuccess(); |
| 578 PumpLoop(); |
| 579 EXPECT_EQ(Offliner::RequestStatus::SAVED, request_status()); |
| 580 |
| 581 // One extra part should be added if the flag is on. |
| 582 content::MHTMLExtraParts* extra_parts = |
| 583 content::MHTMLExtraParts::FromWebContents(loader()->web_contents()); |
| 584 EXPECT_EQ(extra_parts->size(), 1); |
| 585 } |
| 586 |
| 528 } // namespace offline_pages | 587 } // namespace offline_pages |
| OLD | NEW |