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

Side by Side Diff: chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc

Issue 2420543004: Improve the page download: (Closed)
Patch Set: 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 | « no previous file | chrome/browser/android/offline_pages/recent_tab_helper.h » ('j') | 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 "chrome/browser/android/offline_pages/downloads/offline_page_download_b ridge.h" 5 #include "chrome/browser/android/offline_pages/downloads/offline_page_download_b ridge.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/android/jni_string.h" 9 #include "base/android/jni_string.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 28 matching lines...) Expand all
39 using base::android::ConvertUTF16ToJavaString; 39 using base::android::ConvertUTF16ToJavaString;
40 using base::android::JavaParamRef; 40 using base::android::JavaParamRef;
41 using base::android::ScopedJavaGlobalRef; 41 using base::android::ScopedJavaGlobalRef;
42 using base::android::ScopedJavaLocalRef; 42 using base::android::ScopedJavaLocalRef;
43 43
44 namespace offline_pages { 44 namespace offline_pages {
45 namespace android { 45 namespace android {
46 46
47 namespace { 47 namespace {
48 48
49 void SavePageCallback(const DownloadUIItem& item,
50 OfflinePageModel::SavePageResult result,
51 int64_t offline_id) {
52 OfflinePageNotificationBridge notification_bridge;
53 if (result == SavePageResult::SUCCESS)
54 notification_bridge.NotifyDownloadSuccessful(item);
55 else
56 notification_bridge.NotifyDownloadFailed(item);
57 }
58
59 // TODO(dewittj): Move to Download UI Adapter. 49 // TODO(dewittj): Move to Download UI Adapter.
60 content::WebContents* GetWebContentsFromJavaTab( 50 content::WebContents* GetWebContentsFromJavaTab(
61 const ScopedJavaGlobalRef<jobject>& j_tab_ref) { 51 const ScopedJavaGlobalRef<jobject>& j_tab_ref) {
62 JNIEnv* env = AttachCurrentThread(); 52 JNIEnv* env = AttachCurrentThread();
63 TabAndroid* tab = TabAndroid::GetNativeTab(env, j_tab_ref); 53 TabAndroid* tab = TabAndroid::GetNativeTab(env, j_tab_ref);
64 if (!tab) 54 if (!tab)
65 return nullptr; 55 return nullptr;
66 56
67 return tab->web_contents(); 57 return tab->web_contents();
68 } 58 }
69 59
70 // TODO(dewittj): Move to Download UI Adapter. 60 // TODO(dewittj): Move to Download UI Adapter.
71 OfflinePageModel* GetOfflinePageModelFromJavaTab( 61 OfflinePageModel* GetOfflinePageModelFromJavaTab(
72 const ScopedJavaGlobalRef<jobject>& j_tab_ref) { 62 const ScopedJavaGlobalRef<jobject>& j_tab_ref) {
73 content::WebContents* web_contents = GetWebContentsFromJavaTab(j_tab_ref); 63 content::WebContents* web_contents = GetWebContentsFromJavaTab(j_tab_ref);
74 if (!web_contents) 64 if (!web_contents)
75 return nullptr; 65 return nullptr;
76 66
77 Profile* profile = 67 Profile* profile =
78 Profile::FromBrowserContext(web_contents->GetBrowserContext()) 68 Profile::FromBrowserContext(web_contents->GetBrowserContext())
79 ->GetOriginalProfile(); 69 ->GetOriginalProfile();
80 70
81 return OfflinePageModelFactory::GetForBrowserContext(profile); 71 return OfflinePageModelFactory::GetForBrowserContext(profile);
82 } 72 }
83 73
84 void SavePageIfNavigatedToURL(const GURL& query_url, 74 void SavePageIfNotNavigatedAway(const GURL& original_url,
85 const ScopedJavaGlobalRef<jobject>& j_tab_ref) { 75 const ScopedJavaGlobalRef<jobject>& j_tab_ref) {
86 content::WebContents* web_contents = GetWebContentsFromJavaTab(j_tab_ref); 76 content::WebContents* web_contents = GetWebContentsFromJavaTab(j_tab_ref);
87 if (!web_contents) 77 if (!web_contents)
88 return; 78 return;
89 79
90 // This doesn't detect navigations to the same URL, only that we are looking 80 // This ignores fragment differences in URLs, bails out only if tab has
91 // at a completely different page. 81 // navigated away and not just scrolled to a fragment.
92 GURL url = web_contents->GetLastCommittedURL(); 82 GURL url = web_contents->GetLastCommittedURL();
93 if (!OfflinePageUtils::EqualsIgnoringFragment(url, query_url)) 83 if (!OfflinePageUtils::EqualsIgnoringFragment(url, original_url))
94 return; 84 return;
95 85
96 offline_pages::ClientId client_id; 86 offline_pages::ClientId client_id;
97 client_id.name_space = offline_pages::kDownloadNamespace; 87 client_id.name_space = offline_pages::kDownloadNamespace;
98 client_id.id = base::GenerateGUID(); 88 client_id.id = base::GenerateGUID();
89 int64_t request_id = OfflinePageModel::kInvalidOfflineId;
99 90
100 Profile* profile = 91 if (offline_pages::IsBackgroundLoaderForDownloadsEnabled()) {
101 Profile::FromBrowserContext(web_contents->GetBrowserContext()) 92 // Post disabled request before passing the download task to the tab helper.
102 ->GetOriginalProfile(); 93 // This will keep the request persisted in case Chrome is evicted from RAM
94 // or closed by the user.
95 // Note: the 'disabled' status is not persisted (stored in memory) so it
96 // automatically resets if Chrome is re-started.
97 offline_pages::RequestCoordinator* request_coordinator =
98 offline_pages::RequestCoordinatorFactory::GetForBrowserContext(
99 web_contents->GetBrowserContext());
100 request_id = request_coordinator->SavePageLater(
101 url, client_id, true,
102 RequestCoordinator::RequestAvailability::DISABLED_FOR_OFFLINER);
103 }
104
105 // Pass request_id to the current tab's helper to attempt download right from
106 // the tab. If unsuccessful, it'll enable the already-queued request for
107 // background offliner. Same will happen if Chrome is terminated since
108 // 'disabled' status of the request is RAM-stored info.
109 offline_pages::RecentTabHelper* tab_helper =
110 RecentTabHelper::FromWebContents(web_contents);
111 if (!tab_helper) {
112 if (request_id != OfflinePageModel::kInvalidOfflineId) {
113 offline_pages::RequestCoordinator* request_coordinator =
114 offline_pages::RequestCoordinatorFactory::GetForBrowserContext(
115 web_contents->GetBrowserContext());
116 request_coordinator->EnableForOffliner(request_id);
117 }
118 return;
119 }
120 tab_helper->ObserveAndDownloadCurrentPage(client_id, request_id);
103 121
104 OfflinePageNotificationBridge notification_bridge; 122 OfflinePageNotificationBridge notification_bridge;
105
106 // If the page is not loaded enough to be captured, submit a background loader
107 // request instead.
108 offline_pages::RecentTabHelper* tab_helper =
109 RecentTabHelper::FromWebContents(web_contents);
110 if (tab_helper && !tab_helper->is_page_ready_for_snapshot() &&
111 offline_pages::IsBackgroundLoaderForDownloadsEnabled()) {
112 // TODO(dimich): Improve this to wait for the page load if it is still going
113 // on. Pre-submit the request and if the load finishes and capture happens,
114 // remove request.
115 offline_pages::RequestCoordinator* request_coordinator =
116 offline_pages::RequestCoordinatorFactory::GetForBrowserContext(profile);
117 request_coordinator->SavePageLater(
118 url, client_id, true,
119 RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER);
120
121 notification_bridge.ShowDownloadingToast();
122 return;
123 }
124
125 // Page is ready, capture it right from the tab.
126 offline_pages::OfflinePageModel* offline_page_model =
127 OfflinePageModelFactory::GetForBrowserContext(profile);
128 if (!offline_page_model)
129 return;
130
131 auto archiver =
132 base::MakeUnique<offline_pages::OfflinePageMHTMLArchiver>(web_contents);
133
134 DownloadUIItem item;
135 item.guid = client_id.id;
136 item.url = url;
137
138 notification_bridge.NotifyDownloadProgress(item);
139
140 notification_bridge.ShowDownloadingToast(); 123 notification_bridge.ShowDownloadingToast();
141 offline_page_model->SavePage(url, client_id, 0l, std::move(archiver),
142 base::Bind(&SavePageCallback, item));
143 } 124 }
144 125
145 void OnDeletePagesForInfoBar(const GURL& query_url, 126 void OnDeletePagesForInfoBar(const GURL& original_url,
146 const ScopedJavaGlobalRef<jobject>& j_tab_ref, 127 const ScopedJavaGlobalRef<jobject>& j_tab_ref,
147 DeletePageResult result) { 128 DeletePageResult result) {
148 SavePageIfNavigatedToURL(query_url, j_tab_ref); 129 SavePageIfNotNavigatedAway(original_url, j_tab_ref);
149 } 130 }
150 131
151 void DeletePagesForOverwrite(const GURL& query_url, 132 void DeletePagesForOverwrite(const GURL& original_url,
152 const ScopedJavaGlobalRef<jobject>& j_tab_ref, 133 const ScopedJavaGlobalRef<jobject>& j_tab_ref,
153 const MultipleOfflinePageItemResult& pages) { 134 const MultipleOfflinePageItemResult& pages) {
154 OfflinePageModel* model = GetOfflinePageModelFromJavaTab(j_tab_ref); 135 OfflinePageModel* model = GetOfflinePageModelFromJavaTab(j_tab_ref);
155 if (!model) 136 if (!model)
156 return; 137 return;
157 138
158 std::vector<int64_t> offline_ids; 139 std::vector<int64_t> offline_ids;
159 for (auto& page : pages) { 140 for (auto& page : pages) {
160 if (page.client_id.name_space == kDownloadNamespace || 141 if (page.client_id.name_space == kDownloadNamespace ||
161 page.client_id.name_space == kAsyncNamespace) { 142 page.client_id.name_space == kAsyncNamespace) {
162 offline_ids.emplace_back(page.offline_id); 143 offline_ids.emplace_back(page.offline_id);
163 } 144 }
164 } 145 }
165 146
166 model->DeletePagesByOfflineId( 147 model->DeletePagesByOfflineId(
167 offline_ids, base::Bind(&OnDeletePagesForInfoBar, query_url, j_tab_ref)); 148 offline_ids, base::Bind(
149 &OnDeletePagesForInfoBar, original_url, j_tab_ref));
168 } 150 }
169 151
170 void OnInfoBarAction(const GURL& query_url, 152 void OnInfoBarAction(const GURL& original_url,
171 const ScopedJavaGlobalRef<jobject>& j_tab_ref, 153 const ScopedJavaGlobalRef<jobject>& j_tab_ref,
172 OfflinePageInfoBarDelegate::Action action) { 154 OfflinePageInfoBarDelegate::Action action) {
173 switch (action) { 155 switch (action) {
174 case OfflinePageInfoBarDelegate::Action::CREATE_NEW: 156 case OfflinePageInfoBarDelegate::Action::CREATE_NEW:
175 SavePageIfNavigatedToURL(query_url, j_tab_ref); 157 SavePageIfNotNavigatedAway(original_url, j_tab_ref);
176 break; 158 break;
177 case OfflinePageInfoBarDelegate::Action::OVERWRITE: 159 case OfflinePageInfoBarDelegate::Action::OVERWRITE:
178 OfflinePageModel* offline_page_model = 160 OfflinePageModel* offline_page_model =
179 GetOfflinePageModelFromJavaTab(j_tab_ref); 161 GetOfflinePageModelFromJavaTab(j_tab_ref);
180 if (!offline_page_model) 162 if (!offline_page_model)
181 return; 163 return;
182 164
183 offline_page_model->GetPagesByOnlineURL( 165 offline_page_model->GetPagesByOnlineURL(
184 query_url, 166 original_url,
185 base::Bind(&DeletePagesForOverwrite, query_url, j_tab_ref)); 167 base::Bind(&DeletePagesForOverwrite, original_url, j_tab_ref));
186 break; 168 break;
187 } 169 }
188 } 170 }
189 171
190 void RequestQueueDuplicateCheckDone( 172 void RequestQueueDuplicateCheckDone(
191 const GURL& query_url, 173 const GURL& original_url,
192 const ScopedJavaGlobalRef<jobject>& j_tab_ref, 174 const ScopedJavaGlobalRef<jobject>& j_tab_ref,
193 bool has_duplicates) { 175 bool has_duplicates) {
194 if (has_duplicates) { 176 if (has_duplicates) {
195 // TODO(fgorski): Additionally we could update existing request's expiration 177 // TODO(fgorski): Additionally we could update existing request's expiration
196 // period, as it is still important. Alternative would be to actually take a 178 // period, as it is still important. Alternative would be to actually take a
197 // snapshot on the spot, but that would only work if the page is loaded 179 // snapshot on the spot, but that would only work if the page is loaded
198 // enough. 180 // enough.
199 // This simply toasts that the item is downloading. 181 // This simply toasts that the item is downloading.
200 OfflinePageNotificationBridge notification_bridge; 182 OfflinePageNotificationBridge notification_bridge;
201 notification_bridge.ShowDownloadingToast(); 183 notification_bridge.ShowDownloadingToast();
202 return; 184 return;
203 } 185 }
204 186
205 SavePageIfNavigatedToURL(query_url, j_tab_ref); 187 SavePageIfNotNavigatedAway(original_url, j_tab_ref);
206 } 188 }
207 189
208 void ModelDuplicateCheckDone(const GURL& query_url, 190 void ModelDuplicateCheckDone(const GURL& original_url,
209 const ScopedJavaGlobalRef<jobject>& j_tab_ref, 191 const ScopedJavaGlobalRef<jobject>& j_tab_ref,
210 const std::string& downloads_label, 192 const std::string& downloads_label,
211 bool has_duplicates) { 193 bool has_duplicates) {
212 content::WebContents* web_contents = GetWebContentsFromJavaTab(j_tab_ref); 194 content::WebContents* web_contents = GetWebContentsFromJavaTab(j_tab_ref);
213 if (!web_contents) 195 if (!web_contents)
214 return; 196 return;
215 197
216 if (has_duplicates) { 198 if (has_duplicates) {
217 OfflinePageInfoBarDelegate::Create( 199 OfflinePageInfoBarDelegate::Create(
218 base::Bind(&OnInfoBarAction, query_url, j_tab_ref), downloads_label, 200 base::Bind(&OnInfoBarAction, original_url, j_tab_ref), downloads_label,
219 query_url.spec(), web_contents); 201 original_url.spec(), web_contents);
220 return; 202 return;
221 } 203 }
222 204
223 OfflinePageUtils::CheckExistenceOfRequestsWithURL( 205 OfflinePageUtils::CheckExistenceOfRequestsWithURL(
224 Profile::FromBrowserContext(web_contents->GetBrowserContext()) 206 Profile::FromBrowserContext(web_contents->GetBrowserContext())
225 ->GetOriginalProfile(), 207 ->GetOriginalProfile(),
226 kDownloadNamespace, query_url, 208 kDownloadNamespace, original_url,
227 base::Bind(&RequestQueueDuplicateCheckDone, query_url, j_tab_ref)); 209 base::Bind(&RequestQueueDuplicateCheckDone, original_url, j_tab_ref));
228 } 210 }
229 211
230 void ToJavaOfflinePageDownloadItemList( 212 void ToJavaOfflinePageDownloadItemList(
231 JNIEnv* env, 213 JNIEnv* env,
232 jobject j_result_obj, 214 jobject j_result_obj,
233 const std::vector<const DownloadUIItem*>& items) { 215 const std::vector<const DownloadUIItem*>& items) {
234 for (const auto item : items) { 216 for (const auto item : items) {
235 Java_OfflinePageDownloadBridge_createDownloadItemAndAddToList( 217 Java_OfflinePageDownloadBridge_createDownloadItemAndAddToList(
236 env, j_result_obj, ConvertUTF8ToJavaString(env, item->guid), 218 env, j_result_obj, ConvertUTF8ToJavaString(env, item->guid),
237 ConvertUTF8ToJavaString(env, item->url.spec()), 219 ConvertUTF8ToJavaString(env, item->url.spec()),
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 477
496 DownloadUIAdapter* adapter = 478 DownloadUIAdapter* adapter =
497 DownloadUIAdapter::FromOfflinePageModel(offline_page_model); 479 DownloadUIAdapter::FromOfflinePageModel(offline_page_model);
498 480
499 return reinterpret_cast<jlong>( 481 return reinterpret_cast<jlong>(
500 new OfflinePageDownloadBridge(env, obj, adapter, browser_context)); 482 new OfflinePageDownloadBridge(env, obj, adapter, browser_context));
501 } 483 }
502 484
503 } // namespace android 485 } // namespace android
504 } // namespace offline_pages 486 } // namespace offline_pages
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/android/offline_pages/recent_tab_helper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698