Commit 86360297 authored by Sebastien Lalancette's avatar Sebastien Lalancette Committed by Commit Bot

[iOS] Disable PDF Generation on App-Specific pages.

CreateFullPagePdf will check if the current page is an about scheme/app
specific page (or an invalid URL), and if so will invoke the completion
callback with nil NSData.

Added a new unit test for the new logic.

Bug: 1103777
Change-Id: I2eebd0d65ffe3c4c368893dff7fb8e1c53276ae1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2340413
Commit-Queue: Sebastien Lalancette <seblalancette@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Reviewed-by: default avatarSebastien Lalancette <seblalancette@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797284}
parent 6c4f46db
...@@ -45,7 +45,7 @@ class ScreenshotDelegateTest : public PlatformTest { ...@@ -45,7 +45,7 @@ class ScreenshotDelegateTest : public PlatformTest {
// Tests that ScreenshotDelegate can be init with browserInterfaceProvider can // Tests that ScreenshotDelegate can be init with browserInterfaceProvider can
// be set and that data can be generated from it. // be set and that data can be generated from it.
TEST_F(ScreenshotDelegateTest, screenshotService) { TEST_F(ScreenshotDelegateTest, ScreenshotService) {
// Expected: Empty NSData. // Expected: Empty NSData.
if (@available(iOS 13, *)) { if (@available(iOS 13, *)) {
auto web_state = std::make_unique<web::TestWebState>(); auto web_state = std::make_unique<web::TestWebState>();
...@@ -80,7 +80,7 @@ TEST_F(ScreenshotDelegateTest, screenshotService) { ...@@ -80,7 +80,7 @@ TEST_F(ScreenshotDelegateTest, screenshotService) {
// Tests that when ScreenshotDelegate's browserInterfaceProvider has a nil // Tests that when ScreenshotDelegate's browserInterfaceProvider has a nil
// Browser screenshotService will return nil. // Browser screenshotService will return nil.
TEST_F(ScreenshotDelegateTest, nilBrowser) { TEST_F(ScreenshotDelegateTest, NilBrowser) {
// Expected: nil NSData. // Expected: nil NSData.
if (@available(iOS 13, *)) { if (@available(iOS 13, *)) {
// Add the StubBrowserInterface with no set Browser to // Add the StubBrowserInterface with no set Browser to
...@@ -104,7 +104,7 @@ TEST_F(ScreenshotDelegateTest, nilBrowser) { ...@@ -104,7 +104,7 @@ TEST_F(ScreenshotDelegateTest, nilBrowser) {
// Tests that when ScreenshotDelegate's browserInterfaceProvider has a nil // Tests that when ScreenshotDelegate's browserInterfaceProvider has a nil
// WebSatate screenshotService will return nil. // WebSatate screenshotService will return nil.
TEST_F(ScreenshotDelegateTest, nilWebState) { TEST_F(ScreenshotDelegateTest, NilWebState) {
// Expected: nil NSData. // Expected: nil NSData.
if (@available(iOS 13, *)) { if (@available(iOS 13, *)) {
TestBrowser browser; TestBrowser browser;
......
...@@ -862,6 +862,15 @@ typedef void (^ViewportStateCompletion)(const web::PageViewportState*); ...@@ -862,6 +862,15 @@ typedef void (^ViewportStateCompletion)(const web::PageViewportState*);
} }
- (void)createFullPagePDFWithCompletion:(void (^)(NSData*))completionBlock { - (void)createFullPagePDFWithCompletion:(void (^)(NSData*))completionBlock {
// Invoke the |completionBlock| with nil rather than a blank PDF for certain
// URLs.
const GURL& URL = self.webState->GetLastCommittedURL();
if (!URL.is_valid() || web::GetWebClient()->IsAppSpecificURL(URL)) {
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(nil);
});
return;
}
web::CreateFullPagePdf(self.webView, base::BindOnce(completionBlock)); web::CreateFullPagePdf(self.webView, base::BindOnce(completionBlock));
} }
......
...@@ -218,18 +218,29 @@ TEST_F(WebStateTest, Snapshot) { ...@@ -218,18 +218,29 @@ TEST_F(WebStateTest, Snapshot) {
} }
// Tests that the create PDF method retuns an PDF of a rendered html page. // Tests that the create PDF method retuns an PDF of a rendered html page.
TEST_F(WebStateTest, CreateFullPagePdf) { TEST_F(WebStateTest, CreateFullPagePdf_ValidURL) {
CGFloat kSaveAreaTopInset = // Load a URL and some HTML in the WebState.
UIApplication.sharedApplication.keyWindow.safeAreaInsets.top; NSString* data_html =
@"<html><div style='background-color:#FF0000; width:50%; "
"height:100%;'></div></html>";
GURL url("https://www.chromium.org");
web_state()->LoadData([data_html dataUsingEncoding:NSUTF8StringEncoding],
@"text/html", url);
NavigationManager::WebLoadParams load_params(url);
web_state()->GetNavigationManager()->LoadURLWithParams(load_params);
ASSERT_TRUE(base::test::ios::WaitUntilConditionOrTimeout(
base::test::ios::kWaitForPageLoadTimeout, ^bool {
return web_state()->GetLastCommittedURL() == url;
}));
ASSERT_TRUE(LoadHtml("<html><div style='background-color:#FF0000; width:50%; " // Add the subview. Since it does not get immediately painted, adding a small
"height:100%;'></div></html>")); // delay is necessary.
[[[UIApplication sharedApplication] keyWindow] [[[UIApplication sharedApplication] keyWindow]
addSubview:web_state()->GetView()]; addSubview:web_state()->GetView()];
// The subview is added but not immediately painted, so a small delay is
// necessary.
base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.2)); base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.2));
// Create a PDF for this page and validate the data.
__block NSData* callback_data = nil; __block NSData* callback_data = nil;
web_state()->CreateFullPagePdf(base::BindOnce(^(NSData* pdf_document_data) { web_state()->CreateFullPagePdf(base::BindOnce(^(NSData* pdf_document_data) {
callback_data = [pdf_document_data copy]; callback_data = [pdf_document_data copy];
...@@ -245,6 +256,8 @@ TEST_F(WebStateTest, CreateFullPagePdf) { ...@@ -245,6 +256,8 @@ TEST_F(WebStateTest, CreateFullPagePdf) {
CGSize pdf_size = CGSize pdf_size =
CGPDFPageGetBoxRect(CGPDFDocumentGetPage(pdf, 1), kCGPDFMediaBox).size; CGPDFPageGetBoxRect(CGPDFDocumentGetPage(pdf, 1), kCGPDFMediaBox).size;
CGFloat kSaveAreaTopInset =
UIApplication.sharedApplication.keyWindow.safeAreaInsets.top;
EXPECT_GE(pdf_size.height, EXPECT_GE(pdf_size.height,
UIScreen.mainScreen.bounds.size.height - kSaveAreaTopInset); UIScreen.mainScreen.bounds.size.height - kSaveAreaTopInset);
EXPECT_GE(pdf_size.width, [[UIScreen mainScreen] bounds].size.width); EXPECT_GE(pdf_size.width, [[UIScreen mainScreen] bounds].size.width);
...@@ -252,6 +265,42 @@ TEST_F(WebStateTest, CreateFullPagePdf) { ...@@ -252,6 +265,42 @@ TEST_F(WebStateTest, CreateFullPagePdf) {
CGPDFDocumentRelease(pdf); CGPDFDocumentRelease(pdf);
} }
// Tests that CreateFullPagePdf invokes completion callback nil when an invalid
// URL is loaded.
TEST_F(WebStateTest, CreateFullPagePdf_InvalidURLs) {
GURL app_specific_url(
base::StringPrintf("%s://app_specific_url", kTestAppSpecificScheme));
// Empty URL and app-specific URLs (e.g. app_specific_url) should get nil
// data through the completion callback.
std::vector<GURL> invalid_urls = {GURL(), app_specific_url};
NSString* data_html = @(kTestPageHTML);
for (auto& url : invalid_urls) {
web_state()->LoadData([data_html dataUsingEncoding:NSUTF8StringEncoding],
@"text/html", url);
NavigationManager::WebLoadParams load_params(url);
web_state()->GetNavigationManager()->LoadURLWithParams(load_params);
ASSERT_TRUE(base::test::ios::WaitUntilConditionOrTimeout(
base::test::ios::kWaitForPageLoadTimeout, ^bool {
return web_state()->GetLastCommittedURL() == url;
}));
__block NSData* callback_data = nil;
__block bool callback_called = false;
web_state()->CreateFullPagePdf(base::BindOnce(^(NSData* pdf_document_data) {
callback_data = [pdf_document_data copy];
callback_called = true;
}));
ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^bool {
return callback_called;
}));
ASSERT_FALSE(callback_data);
}
}
// Tests that message sent from main frame triggers the ScriptCommandCallback // Tests that message sent from main frame triggers the ScriptCommandCallback
// with |is_main_frame| = true. // with |is_main_frame| = true.
TEST_F(WebStateTest, MessageFromMainFrame) { TEST_F(WebStateTest, MessageFromMainFrame) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment