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

Side by Side Diff: ios/chrome/browser/reading_list/reading_list_distiller_page.mm

Issue 2635193003: IOS Reading distillation: Handle Google AMP iFrame. (Closed)
Patch Set: Created 3 years, 11 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 | « ios/chrome/browser/reading_list/reading_list_distiller_page.h ('k') | no next file » | 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 "ios/chrome/browser/reading_list/reading_list_distiller_page.h" 5 #include "ios/chrome/browser/reading_list/reading_list_distiller_page.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/strings/utf_string_conversions.h"
8 #include "base/threading/thread_task_runner_handle.h" 9 #include "base/threading/thread_task_runner_handle.h"
9 #include "components/favicon/ios/web_favicon_driver.h" 10 #include "components/favicon/ios/web_favicon_driver.h"
11 #include "components/google/core/browser/google_util.h"
10 #include "ios/chrome/browser/reading_list/favicon_web_state_dispatcher_impl.h" 12 #include "ios/chrome/browser/reading_list/favicon_web_state_dispatcher_impl.h"
13 #import "ios/web/public/navigation_item.h"
14 #import "ios/web/public/navigation_manager.h"
15 #include "ios/web/public/ssl_status.h"
16 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
11 #import "ios/web/public/web_state/web_state.h" 17 #import "ios/web/public/web_state/web_state.h"
18 #import "net/base/mac/url_conversions.h"
19 #include "net/cert/cert_status_flags.h"
20 #include "url/url_constants.h"
12 21
13 namespace { 22 namespace {
14 // The delay between the page load and the distillation in seconds. 23 // The delay between the page load and the distillation in seconds.
15 const int64_t kDistillationDelayInSeconds = 2; 24 const int64_t kDistillationDelayInSeconds = 2;
25 const char* kJavaScriptNavigateToIframe =
jif 2017/01/17 17:43:10 s/kJavaScriptNavigateToIframe/kGetIframeURLJavaScr
Olivier 2017/01/18 09:30:13 mmm, I obviously did not upload my cleaning PS...
26 "document.getElementsByTagName('iframe')[0].src;";
16 } // namespace 27 } // namespace
17 28
18 namespace reading_list { 29 namespace reading_list {
19 30
20 ReadingListDistillerPage::ReadingListDistillerPage( 31 ReadingListDistillerPage::ReadingListDistillerPage(
21 web::BrowserState* browser_state, 32 web::BrowserState* browser_state,
22 FaviconWebStateDispatcher* web_state_dispatcher) 33 FaviconWebStateDispatcher* web_state_dispatcher)
23 : dom_distiller::DistillerPageIOS(browser_state), 34 : dom_distiller::DistillerPageIOS(browser_state),
24 web_state_dispatcher_(web_state_dispatcher), 35 web_state_dispatcher_(web_state_dispatcher),
25 weak_ptr_factory_(this) {} 36 weak_ptr_factory_(this) {}
(...skipping 22 matching lines...) Expand all
48 const base::Value* value) { 59 const base::Value* value) {
49 std::unique_ptr<web::WebState> old_web_state = DetachWebState(); 60 std::unique_ptr<web::WebState> old_web_state = DetachWebState();
50 if (old_web_state) { 61 if (old_web_state) {
51 web_state_dispatcher_->ReturnWebState(std::move(old_web_state)); 62 web_state_dispatcher_->ReturnWebState(std::move(old_web_state));
52 } 63 }
53 DistillerPageIOS::OnDistillationDone(page_url, value); 64 DistillerPageIOS::OnDistillationDone(page_url, value);
54 } 65 }
55 66
56 void ReadingListDistillerPage::OnLoadURLDone( 67 void ReadingListDistillerPage::OnLoadURLDone(
57 web::PageLoadCompletionStatus load_completion_status) { 68 web::PageLoadCompletionStatus load_completion_status) {
58 if (load_completion_status == web::PageLoadCompletionStatus::FAILURE) { 69 if (load_completion_status == web::PageLoadCompletionStatus::FAILURE) {
jif 2017/01/17 17:43:10 If somebody adds a 3rd status to PageLoadCompletio
Olivier 2017/01/18 09:30:13 Any not success is a failure for this feature. So
59 DistillerPageIOS::OnLoadURLDone(load_completion_status); 70 DistillerPageIOS::OnLoadURLDone(load_completion_status);
60 return; 71 return;
61 } 72 }
73 if (HandleGoogleCachedAMP()) {
jif 2017/01/17 17:43:10 How about this: if (IsGoogleCachedAMP()) { // W
Olivier 2017/01/18 09:30:13 Done.
74 // The rest of the distillation will be handled by Google AMP workaround.
75 // Stop distillation here.
76 return;
77 }
78 WaitForPageLoadCompletion();
79 }
80
81 void ReadingListDistillerPage::WaitForPageLoadCompletion() {
62 base::WeakPtr<ReadingListDistillerPage> weak_this = 82 base::WeakPtr<ReadingListDistillerPage> weak_this =
63 weak_ptr_factory_.GetWeakPtr(); 83 weak_ptr_factory_.GetWeakPtr();
64 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 84 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
65 FROM_HERE, base::Bind(&ReadingListDistillerPage::DelayedOnLoadURLDone, 85 FROM_HERE,
66 weak_this, load_completion_status), 86 base::Bind(&ReadingListDistillerPage::DelayedOnLoadURLDone, weak_this),
67 base::TimeDelta::FromSeconds(kDistillationDelayInSeconds)); 87 base::TimeDelta::FromSeconds(kDistillationDelayInSeconds));
68 } 88 }
69 89
70 void ReadingListDistillerPage::DelayedOnLoadURLDone( 90 void ReadingListDistillerPage::DelayedOnLoadURLDone() {
71 web::PageLoadCompletionStatus load_completion_status) { 91 DistillerPageIOS::OnLoadURLDone(web::PageLoadCompletionStatus::SUCCESS);
jif 2017/01/17 17:43:10 There's some funny business going on here.
jif 2017/01/17 17:43:45 Ignore this comment, I forgot to remove it.
Olivier 2017/01/18 09:30:13 Acknowledged.
72 DistillerPageIOS::OnLoadURLDone(load_completion_status);
73 } 92 }
93
94 bool ReadingListDistillerPage::IsGoogleCachedAMP() {
95 // All google AMP pages have URL in the form "https://google_domain/amp/..."
96 // and a valid certificate.
97 // This method checks that this is strictly the case.
98 GURL url = CurrentWebState()->GetLastCommittedURL();
jif 2017/01/17 17:43:10 const GURL &
Olivier 2017/01/18 09:30:13 Done.
99 if (!url.is_valid() || !url.SchemeIs(url::kHttpsScheme)) {
100 return false;
101 }
102 if (!google_util::IsGoogleDomainUrl(
103 url, google_util::DISALLOW_SUBDOMAIN,
104 google_util::DISALLOW_NON_STANDARD_PORTS) ||
105 !url.path().compare(0, 4, "amp/")) {
106 return false;
107 }
108 const web::SSLStatus& ssl_status = CurrentWebState()
109 ->GetNavigationManager()
110 ->GetLastCommittedItem()
111 ->GetSSL();
112 if (!ssl_status.certificate ||
113 (net::IsCertStatusError(ssl_status.cert_status) &&
114 !net::IsCertStatusMinorError(ssl_status.cert_status))) {
115 return false;
116 }
117
118 return true;
119 }
120
121 bool ReadingListDistillerPage::HandleGoogleCachedAMP() {
122 if (!IsGoogleCachedAMP()) {
123 return false;
124 }
125 base::WeakPtr<ReadingListDistillerPage> weak_this =
126 weak_ptr_factory_.GetWeakPtr();
127 [CurrentWebState()->GetJSInjectionReceiver()
128 executeJavaScript:@(kJavaScriptNavigateToIframe)
129 completionHandler:^(id result, NSError* error) {
130 if (!weak_this->HandleGoogleCachedAMPJavaScriptResult(result, error)) {
jif 2017/01/17 17:43:10 weak_this can be null.
Olivier 2017/01/18 09:30:13 Interesting question on what to do if weak_this is
131 // If there is an error on navigation, continue normal distillation.
132 weak_this->WaitForPageLoadCompletion();
133 }
134 // If there is no error, the navigation completion will trigger a new
135 // |OnLoadURLDone| call that will resume the distillation.
136 }];
137 return true;
138 }
139
140 bool ReadingListDistillerPage::HandleGoogleCachedAMPJavaScriptResult(
141 id result,
142 NSError* error) {
143 if (error) {
144 return false;
145 }
146 NSURL* new_url = [NSURL URLWithString:result];
jif 2017/01/17 17:43:10 can you add an DCHECK that verifies that |result|
Olivier 2017/01/18 09:30:13 Added a cast. If result is not a string (which is
147 if (!new_url) {
148 return false;
149 }
150 bool is_cdn_ampproject =
151 [[new_url host] isEqualToString:@"cdn.amproject.org"];
152 bool is_cdn_ampproject_subdomain =
153 [[new_url host] hasSuffix:@".cdn.amproject.org"];
154
155 if (!is_cdn_ampproject && !is_cdn_ampproject_subdomain) {
156 return false;
157 }
158 GURL new_gurl = net::GURLWithNSURL(new_url);
159 if (!new_gurl.is_valid()) {
160 return false;
161 }
162 web::NavigationManager::WebLoadParams params(new_gurl);
163 CurrentWebState()->GetNavigationManager()->LoadURLWithParams(params);
164 return true;
165 }
166
74 } // namespace reading_list 167 } // namespace reading_list
OLDNEW
« no previous file with comments | « ios/chrome/browser/reading_list/reading_list_distiller_page.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698