| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/ui/pdf/pdf_browsertest_base.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/path_service.h" | |
| 12 #include "base/strings/string_number_conversions.h" | |
| 13 #include "base/strings/utf_string_conversions.h" | |
| 14 #include "chrome/browser/chrome_notification_types.h" | |
| 15 #include "chrome/browser/ui/browser.h" | |
| 16 #include "chrome/browser/ui/browser_window.h" | |
| 17 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
| 18 #include "chrome/common/chrome_paths.h" | |
| 19 #include "chrome/common/chrome_switches.h" | |
| 20 #include "chrome/test/base/ui_test_utils.h" | |
| 21 #include "content/public/browser/render_view_host.h" | |
| 22 #include "content/public/browser/web_contents.h" | |
| 23 #include "third_party/skia/include/core/SkBitmap.h" | |
| 24 #include "ui/gfx/codec/png_codec.h" | |
| 25 #include "ui/gfx/screen.h" | |
| 26 | |
| 27 #if defined(OS_LINUX) | |
| 28 #include "content/public/common/content_switches.h" | |
| 29 #endif | |
| 30 | |
| 31 #if defined(OS_CHROMEOS) | |
| 32 #include "ui/compositor/compositor_switches.h" | |
| 33 #endif | |
| 34 | |
| 35 namespace { | |
| 36 | |
| 37 // Include things like browser frame and scrollbar and make sure we're bigger | |
| 38 // than the test pdf document. | |
| 39 const int kBrowserWidth = 1000; | |
| 40 const int kBrowserHeight = 600; | |
| 41 | |
| 42 } // namespace | |
| 43 | |
| 44 PDFBrowserTest::PDFBrowserTest() | |
| 45 : snapshot_different_(true), | |
| 46 next_dummy_search_value_(0), | |
| 47 load_stop_notification_count_(0) { | |
| 48 base::FilePath src_dir; | |
| 49 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir)); | |
| 50 pdf_test_server_.ServeFilesFromDirectory(src_dir.AppendASCII( | |
| 51 "chrome/test/data/pdf_private")); | |
| 52 } | |
| 53 | |
| 54 PDFBrowserTest::~PDFBrowserTest() { | |
| 55 } | |
| 56 | |
| 57 void PDFBrowserTest::Load() { | |
| 58 // Make sure to set the window size before rendering, as otherwise rendering | |
| 59 // to a smaller window and then expanding leads to slight anti-aliasing | |
| 60 // differences of the text and the pixel comparison fails. | |
| 61 gfx::Rect bounds(gfx::Rect(0, 0, kBrowserWidth, kBrowserHeight)); | |
| 62 gfx::Rect screen_bounds = | |
| 63 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().bounds(); | |
| 64 ASSERT_GT(screen_bounds.width(), kBrowserWidth); | |
| 65 ASSERT_GT(screen_bounds.height(), kBrowserHeight); | |
| 66 browser()->window()->SetBounds(bounds); | |
| 67 | |
| 68 GURL url(ui_test_utils::GetTestUrl( | |
| 69 base::FilePath(FILE_PATH_LITERAL("pdf_private")), | |
| 70 base::FilePath(FILE_PATH_LITERAL("pdf_browsertest.pdf")))); | |
| 71 ui_test_utils::NavigateToURL(browser(), url); | |
| 72 } | |
| 73 | |
| 74 void PDFBrowserTest::WaitForResponse() { | |
| 75 // Even if the plugin has loaded the data or scrolled, because of how | |
| 76 // pepper painting works, we might not have the data. One way to force this | |
| 77 // to be flushed is to do a find operation, since on this two-page test | |
| 78 // document, it'll wait for us to flush the renderer message loop twice and | |
| 79 // also the browser's once, at which point we're guaranteed to have updated | |
| 80 // the backingstore. Hacky, but it works. | |
| 81 // Note that we need to change the text each time, because if we don't the | |
| 82 // renderer code will think the second message is to go to next result, but | |
| 83 // there are none so the plugin will assert. | |
| 84 | |
| 85 base::string16 query = base::UTF8ToUTF16( | |
| 86 std::string("xyzxyz" + base::IntToString(next_dummy_search_value_++))); | |
| 87 ASSERT_EQ(0, ui_test_utils::FindInPage( | |
| 88 browser()->tab_strip_model()->GetActiveWebContents(), | |
| 89 query, true, false, NULL, NULL)); | |
| 90 } | |
| 91 | |
| 92 bool PDFBrowserTest::VerifySnapshot(const std::string& expected_filename) { | |
| 93 snapshot_different_ = true; | |
| 94 expected_filename_ = expected_filename; | |
| 95 content::WebContents* web_contents = | |
| 96 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 97 DCHECK(web_contents); | |
| 98 | |
| 99 content::RenderWidgetHost* rwh = web_contents->GetRenderViewHost(); | |
| 100 rwh->CopyFromBackingStore( | |
| 101 gfx::Rect(), | |
| 102 gfx::Size(), | |
| 103 base::Bind(&PDFBrowserTest::CopyFromBackingStoreCallback, this), | |
| 104 kN32_SkColorType); | |
| 105 | |
| 106 content::RunMessageLoop(); | |
| 107 | |
| 108 if (snapshot_different_) { | |
| 109 LOG(INFO) << "Rendering didn't match, see result " | |
| 110 << snapshot_filename_.value(); | |
| 111 } | |
| 112 return !snapshot_different_; | |
| 113 } | |
| 114 | |
| 115 void PDFBrowserTest::CopyFromBackingStoreCallback( | |
| 116 const SkBitmap& bitmap, | |
| 117 content::ReadbackResponse response) { | |
| 118 base::MessageLoopForUI::current()->Quit(); | |
| 119 ASSERT_EQ(response, content::READBACK_SUCCESS); | |
| 120 base::FilePath reference = ui_test_utils::GetTestFilePath( | |
| 121 base::FilePath(FILE_PATH_LITERAL("pdf_private")), | |
| 122 base::FilePath().AppendASCII(expected_filename_)); | |
| 123 base::File::Info info; | |
| 124 ASSERT_TRUE(base::GetFileInfo(reference, &info)); | |
| 125 int size = static_cast<size_t>(info.size); | |
| 126 scoped_ptr<char[]> data(new char[size]); | |
| 127 ASSERT_EQ(size, base::ReadFile(reference, data.get(), size)); | |
| 128 | |
| 129 int w, h; | |
| 130 std::vector<unsigned char> decoded; | |
| 131 ASSERT_TRUE(gfx::PNGCodec::Decode( | |
| 132 reinterpret_cast<unsigned char*>(data.get()), size, | |
| 133 gfx::PNGCodec::FORMAT_BGRA, &decoded, &w, &h)); | |
| 134 int32* ref_pixels = reinterpret_cast<int32*>(&decoded[0]); | |
| 135 | |
| 136 SkAutoLockPixels lock_image(bitmap); | |
| 137 int32* pixels = static_cast<int32*>(bitmap.getPixels()); | |
| 138 | |
| 139 // Get the background color, and use it to figure out the x-offsets in | |
| 140 // each image. The reason is that depending on the theme in the OS, the | |
| 141 // same browser width can lead to slightly different plugin sizes, so the | |
| 142 // pdf content will start at different x offsets. | |
| 143 // Also note that the images we saved are cut off before the scrollbar, as | |
| 144 // that'll change depending on the theme, and also cut off vertically so | |
| 145 // that the ui controls don't show up, as those fade-in and so the timing | |
| 146 // will affect their transparency. | |
| 147 int32 bg_color = ref_pixels[0]; | |
| 148 int ref_x_offset, snapshot_x_offset; | |
| 149 for (ref_x_offset = 0; ref_x_offset < w; ++ref_x_offset) { | |
| 150 if (ref_pixels[ref_x_offset] != bg_color) | |
| 151 break; | |
| 152 } | |
| 153 | |
| 154 for (snapshot_x_offset = 0; snapshot_x_offset < bitmap.width(); | |
| 155 ++snapshot_x_offset) { | |
| 156 if (pixels[snapshot_x_offset] != bg_color) | |
| 157 break; | |
| 158 } | |
| 159 | |
| 160 int x_max = std::min(w - ref_x_offset, bitmap.width() - snapshot_x_offset); | |
| 161 int y_max = std::min(h, bitmap.height()); | |
| 162 int stride = bitmap.rowBytes(); | |
| 163 snapshot_different_ = false; | |
| 164 for (int y = 0; y < y_max && !snapshot_different_; ++y) { | |
| 165 for (int x = 0; x < x_max && !snapshot_different_; ++x) { | |
| 166 if (pixels[y * stride / sizeof(int32) + x + snapshot_x_offset] != | |
| 167 ref_pixels[y * w + x + ref_x_offset]) | |
| 168 snapshot_different_ = true; | |
| 169 } | |
| 170 } | |
| 171 | |
| 172 if (snapshot_different_) { | |
| 173 std::vector<unsigned char> png_data; | |
| 174 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &png_data); | |
| 175 if (base::CreateTemporaryFile(&snapshot_filename_)) { | |
| 176 base::WriteFile(snapshot_filename_, | |
| 177 reinterpret_cast<char*>(&png_data[0]), png_data.size()); | |
| 178 } | |
| 179 } | |
| 180 } | |
| 181 | |
| 182 void PDFBrowserTest::Observe(int type, | |
| 183 const content::NotificationSource& source, | |
| 184 const content::NotificationDetails& details) { | |
| 185 DCHECK_EQ(content::NOTIFICATION_LOAD_STOP, type); | |
| 186 load_stop_notification_count_++; | |
| 187 } | |
| 188 | |
| 189 void PDFBrowserTest::SetUpCommandLine(base::CommandLine* command_line) { | |
| 190 // Due to the changed architecture of the OOP PDF plugin, these tests don't | |
| 191 // pass and need to be reworked. crbug.com/436444. | |
| 192 command_line->AppendSwitch(switches::kDisableOutOfProcessPdf); | |
| 193 | |
| 194 #if defined(OS_LINUX) | |
| 195 // Calling RenderWidgetHost::CopyFromBackingStore() with the GPU enabled | |
| 196 // fails on Linux. | |
| 197 command_line->AppendSwitch(switches::kDisableGpu); | |
| 198 #endif | |
| 199 | |
| 200 #if defined(OS_CHROMEOS) | |
| 201 // Also need on CrOS in addition to disabling the GPU above. | |
| 202 command_line->AppendSwitch(switches::kUIDisableThreadedCompositing); | |
| 203 #endif | |
| 204 } | |
| OLD | NEW |