Chromium Code Reviews| 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 "ios/chrome/browser/reading_list/reading_list_download_service.h" | 5 #include "ios/chrome/browser/reading_list/reading_list_download_service.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "ios/chrome/browser/reading_list/reading_list_entry.h" | 12 #include "ios/chrome/browser/reading_list/reading_list_entry.h" |
| 13 #include "ios/chrome/browser/reading_list/reading_list_model.h" | 13 #include "ios/chrome/browser/reading_list/reading_list_model.h" |
| 14 #include "ios/web/public/web_thread.h" | |
| 15 | |
| 16 namespace { | |
| 17 // Number of time the download must fail before the download occurs only in | |
| 18 // wifi. | |
| 19 const int kNumberOfFailsBeforeWifiOnly = 5; | |
| 20 // Number of time the download must fail before we give up trying to download | |
| 21 // it. | |
| 22 const int kNumberOfFailsBeforeStop = 7; | |
| 23 } // namespace | |
| 14 | 24 |
| 15 ReadingListDownloadService::ReadingListDownloadService( | 25 ReadingListDownloadService::ReadingListDownloadService( |
| 16 ReadingListModel* reading_list_model, | 26 ReadingListModel* reading_list_model, |
| 17 dom_distiller::DomDistillerService* distiller_service, | 27 dom_distiller::DomDistillerService* distiller_service, |
| 18 PrefService* prefs, | 28 PrefService* prefs, |
| 19 base::FilePath chrome_profile_path) | 29 base::FilePath chrome_profile_path) |
| 20 : reading_list_model_(reading_list_model) { | 30 : reading_list_model_(reading_list_model), |
| 31 had_connection_(!net::NetworkChangeNotifier::IsOffline()), | |
| 32 weak_ptr_factory_(this) { | |
| 21 DCHECK(reading_list_model); | 33 DCHECK(reading_list_model); |
| 22 url_downloader_ = base::MakeUnique<URLDownloader>( | 34 url_downloader_ = base::MakeUnique<URLDownloader>( |
| 23 distiller_service, prefs, chrome_profile_path, | 35 distiller_service, prefs, chrome_profile_path, |
| 24 base::Bind(&ReadingListDownloadService::OnDownloadEnd, | 36 base::Bind(&ReadingListDownloadService::OnDownloadEnd, |
| 25 base::Unretained(this)), | 37 base::Unretained(this)), |
| 26 base::Bind(&ReadingListDownloadService::OnDeleteEnd, | 38 base::Bind(&ReadingListDownloadService::OnDeleteEnd, |
| 27 base::Unretained(this))); | 39 base::Unretained(this))); |
| 40 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); | |
| 28 } | 41 } |
| 29 | 42 |
| 30 ReadingListDownloadService::~ReadingListDownloadService() {} | 43 ReadingListDownloadService::~ReadingListDownloadService() { |
| 44 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | |
| 45 } | |
| 31 | 46 |
| 32 void ReadingListDownloadService::Initialize() { | 47 void ReadingListDownloadService::Initialize() { |
| 33 reading_list_model_->AddObserver(this); | 48 reading_list_model_->AddObserver(this); |
| 34 } | 49 } |
| 35 | 50 |
| 36 void ReadingListDownloadService::Shutdown() { | 51 void ReadingListDownloadService::Shutdown() { |
| 37 reading_list_model_->RemoveObserver(this); | 52 reading_list_model_->RemoveObserver(this); |
| 38 } | 53 } |
| 39 | 54 |
| 40 void ReadingListDownloadService::ReadingListModelLoaded( | 55 void ReadingListDownloadService::ReadingListModelLoaded( |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 54 const ReadingListModel* model, | 69 const ReadingListModel* model, |
| 55 size_t index) { | 70 size_t index) { |
| 56 DCHECK_EQ(reading_list_model_, model); | 71 DCHECK_EQ(reading_list_model_, model); |
| 57 RemoveDownloadedEntry(model->GetUnreadEntryAtIndex(index)); | 72 RemoveDownloadedEntry(model->GetUnreadEntryAtIndex(index)); |
| 58 } | 73 } |
| 59 | 74 |
| 60 void ReadingListDownloadService::ReadingListWillAddUnreadEntry( | 75 void ReadingListDownloadService::ReadingListWillAddUnreadEntry( |
| 61 const ReadingListModel* model, | 76 const ReadingListModel* model, |
| 62 const ReadingListEntry& entry) { | 77 const ReadingListEntry& entry) { |
| 63 DCHECK_EQ(reading_list_model_, model); | 78 DCHECK_EQ(reading_list_model_, model); |
| 64 DownloadEntry(entry); | 79 ScheduleDownloadEntry(entry); |
| 65 } | 80 } |
| 66 | 81 |
| 67 void ReadingListDownloadService::ReadingListWillAddReadEntry( | 82 void ReadingListDownloadService::ReadingListWillAddReadEntry( |
| 68 const ReadingListModel* model, | 83 const ReadingListModel* model, |
| 69 const ReadingListEntry& entry) { | 84 const ReadingListEntry& entry) { |
| 70 DCHECK_EQ(reading_list_model_, model); | 85 DCHECK_EQ(reading_list_model_, model); |
| 71 DownloadEntry(entry); | 86 ScheduleDownloadEntry(entry); |
| 72 } | 87 } |
| 73 | 88 |
| 74 void ReadingListDownloadService::DownloadAllEntries() { | 89 void ReadingListDownloadService::DownloadAllEntries() { |
| 75 DCHECK(reading_list_model_->loaded()); | 90 DCHECK(reading_list_model_->loaded()); |
| 76 size_t size = reading_list_model_->unread_size(); | 91 size_t size = reading_list_model_->unread_size(); |
| 77 for (size_t i = 0; i < size; i++) { | 92 for (size_t i = 0; i < size; i++) { |
| 78 const ReadingListEntry& entry = | 93 const ReadingListEntry& entry = |
| 79 reading_list_model_->GetUnreadEntryAtIndex(i); | 94 reading_list_model_->GetUnreadEntryAtIndex(i); |
| 80 this->DownloadEntry(entry); | 95 this->ScheduleDownloadEntry(entry); |
| 81 } | 96 } |
| 82 size = reading_list_model_->read_size(); | 97 size = reading_list_model_->read_size(); |
| 83 for (size_t i = 0; i < size; i++) { | 98 for (size_t i = 0; i < size; i++) { |
| 84 const ReadingListEntry& entry = reading_list_model_->GetReadEntryAtIndex(i); | 99 const ReadingListEntry& entry = reading_list_model_->GetReadEntryAtIndex(i); |
| 85 this->DownloadEntry(entry); | 100 this->ScheduleDownloadEntry(entry); |
| 86 } | 101 } |
| 87 } | 102 } |
| 88 | 103 |
| 104 void ReadingListDownloadService::ScheduleDownloadEntry( | |
| 105 const ReadingListEntry& entry) { | |
| 106 DCHECK(reading_list_model_->loaded()); | |
| 107 if (entry.DistilledState() == ReadingListEntry::ERROR || | |
| 108 entry.DistilledState() == ReadingListEntry::PROCESSED) | |
| 109 return; | |
| 110 | |
| 111 web::WebThread::PostDelayedTask( | |
| 112 web::WebThread::UI, FROM_HERE, | |
| 113 base::Bind(&ReadingListDownloadService::DownloadEntryFromURL, | |
|
gambard
2016/09/22 16:46:55
This is a loop
| |
| 114 weak_ptr_factory_.GetWeakPtr(), entry.URL()), | |
| 115 entry.TimeUntilNextTry()); | |
| 116 } | |
| 117 | |
| 118 void ReadingListDownloadService::DownloadEntryFromURL(const GURL& url) { | |
| 119 auto download_callback = | |
| 120 base::Bind(&ReadingListDownloadService::ScheduleDownloadEntry, | |
| 121 base::Unretained(this)); | |
| 122 reading_list_model_->CallbackEntryURL(url, download_callback); | |
| 123 } | |
| 124 | |
| 89 void ReadingListDownloadService::DownloadEntry(const ReadingListEntry& entry) { | 125 void ReadingListDownloadService::DownloadEntry(const ReadingListEntry& entry) { |
| 90 DCHECK(reading_list_model_->loaded()); | 126 DCHECK(reading_list_model_->loaded()); |
| 91 if (entry.DistilledState() != ReadingListEntry::ERROR) { | 127 if (entry.DistilledState() == ReadingListEntry::ERROR || |
| 128 entry.DistilledState() == ReadingListEntry::PROCESSED) | |
| 129 return; | |
| 130 | |
| 131 if (net::NetworkChangeNotifier::IsOffline()) { | |
| 132 // There is no connection, save it for download only if we did not exceed | |
| 133 // the maximaxum number of tries. | |
| 134 if (entry.FailedDownloadCounter() < kNumberOfFailsBeforeWifiOnly) | |
| 135 url_to_download_cellular_.push_back(entry.URL()); | |
| 136 if (entry.FailedDownloadCounter() < kNumberOfFailsBeforeStop) | |
| 137 url_to_download_wifi_.push_back(entry.URL()); | |
| 138 return; | |
| 139 } | |
| 140 | |
| 141 // There is a connection. | |
| 142 if (entry.FailedDownloadCounter() < kNumberOfFailsBeforeWifiOnly) { | |
| 143 // Try to download the page, whatever the connection. | |
| 92 reading_list_model_->SetEntryDistilledState(entry.URL(), | 144 reading_list_model_->SetEntryDistilledState(entry.URL(), |
| 93 ReadingListEntry::PROCESSING); | 145 ReadingListEntry::PROCESSING); |
| 94 url_downloader_->DownloadOfflineURL(entry.URL()); | 146 url_downloader_->DownloadOfflineURL(entry.URL()); |
| 147 | |
| 148 } else if (entry.FailedDownloadCounter() < kNumberOfFailsBeforeStop) { | |
| 149 // Try to download the page only if the connection is wifi. | |
| 150 if (net::NetworkChangeNotifier::GetConnectionType() == | |
| 151 net::NetworkChangeNotifier::CONNECTION_WIFI) { | |
| 152 // The connection is wifi, download the page. | |
| 153 reading_list_model_->SetEntryDistilledState(entry.URL(), | |
| 154 ReadingListEntry::PROCESSING); | |
| 155 url_downloader_->DownloadOfflineURL(entry.URL()); | |
| 156 | |
| 157 } else { | |
| 158 // The connection is not wifi, save it for download when the connection | |
| 159 // changes to wifi. | |
| 160 url_to_download_wifi_.push_back(entry.URL()); | |
| 161 } | |
| 95 } | 162 } |
| 96 } | 163 } |
| 97 | 164 |
| 98 void ReadingListDownloadService::RemoveDownloadedEntry( | 165 void ReadingListDownloadService::RemoveDownloadedEntry( |
| 99 const ReadingListEntry& entry) { | 166 const ReadingListEntry& entry) { |
| 100 DCHECK(reading_list_model_->loaded()); | 167 DCHECK(reading_list_model_->loaded()); |
| 101 url_downloader_->RemoveOfflineURL(entry.URL()); | 168 url_downloader_->RemoveOfflineURL(entry.URL()); |
| 102 } | 169 } |
| 103 | 170 |
| 104 void ReadingListDownloadService::OnDownloadEnd( | 171 void ReadingListDownloadService::OnDownloadEnd( |
| 105 const GURL& url, | 172 const GURL& url, |
| 106 URLDownloader::SuccessState success, | 173 URLDownloader::SuccessState success, |
| 107 const GURL& distilled_url, | 174 const GURL& distilled_url, |
| 108 const std::string& title) { | 175 const std::string& title) { |
| 109 DCHECK(reading_list_model_->loaded()); | 176 DCHECK(reading_list_model_->loaded()); |
| 110 if ((success == URLDownloader::DOWNLOAD_SUCCESS || | 177 if ((success == URLDownloader::DOWNLOAD_SUCCESS || |
| 111 success == URLDownloader::DOWNLOAD_EXISTS) && | 178 success == URLDownloader::DOWNLOAD_EXISTS) && |
| 112 distilled_url.is_valid()) { | 179 distilled_url.is_valid()) { |
| 113 reading_list_model_->SetEntryDistilledURL(url, distilled_url); | 180 reading_list_model_->SetEntryDistilledURL(url, distilled_url); |
| 181 | |
| 114 } else if (success == URLDownloader::ERROR_RETRY) { | 182 } else if (success == URLDownloader::ERROR_RETRY) { |
| 115 reading_list_model_->SetEntryDistilledState(url, | 183 reading_list_model_->SetEntryDistilledState(url, |
| 116 ReadingListEntry::WILL_RETRY); | 184 ReadingListEntry::WILL_RETRY); |
| 185 DownloadEntryFromURL(url); | |
| 186 | |
| 117 } else if (success == URLDownloader::ERROR_PERMANENT) { | 187 } else if (success == URLDownloader::ERROR_PERMANENT) { |
| 118 reading_list_model_->SetEntryDistilledState(url, ReadingListEntry::ERROR); | 188 reading_list_model_->SetEntryDistilledState(url, ReadingListEntry::ERROR); |
| 119 } | 189 } |
| 120 } | 190 } |
| 121 | 191 |
| 122 void ReadingListDownloadService::OnDeleteEnd(const GURL& url, bool success) { | 192 void ReadingListDownloadService::OnDeleteEnd(const GURL& url, bool success) { |
| 123 // Nothing to update as this is only called when deleting reading list entries | 193 // Nothing to update as this is only called when deleting reading list entries |
| 124 } | 194 } |
| 195 | |
| 196 void ReadingListDownloadService::OnConnectionTypeChanged( | |
| 197 net::NetworkChangeNotifier::ConnectionType type) { | |
| 198 if (type == net::NetworkChangeNotifier::CONNECTION_NONE) { | |
| 199 had_connection_ = false; | |
| 200 return; | |
| 201 } | |
| 202 | |
| 203 if (!had_connection_) { | |
| 204 had_connection_ = true; | |
| 205 for (auto& url : url_to_download_cellular_) { | |
| 206 DownloadEntryFromURL(url); | |
| 207 } | |
| 208 } | |
| 209 if (type == net::NetworkChangeNotifier::CONNECTION_WIFI) { | |
| 210 for (auto& url : url_to_download_wifi_) { | |
| 211 DownloadEntryFromURL(url); | |
| 212 } | |
| 213 } | |
| 214 } | |
| OLD | NEW |