15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/pdf/pdf_browsertest_base.h" 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <algorithm> 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <vector> 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/path_service.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/utf_string_conversions.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/common/chrome_paths.h" 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/test/base/ui_test_utils.h" 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/render_view_host.h" 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/web_contents.h" 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gfx/codec/png_codec.h" 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gfx/screen.h" 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_LINUX) 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/command_line.h" 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/common/content_switches.h" 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_CHROMEOS) 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/compositor/compositor_switches.h" 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace { 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Include things like browser frame and scrollbar and make sure we're bigger 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// than the test pdf document. 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kBrowserWidth = 1000; 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kBrowserHeight = 600; 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)PDFBrowserTest::PDFBrowserTest() 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : snapshot_different_(true), 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) next_dummy_search_value_(0), 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) load_stop_notification_count_(0) { 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::FilePath src_dir; 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir)); 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pdf_test_server_.ServeFilesFromDirectory(src_dir.AppendASCII( 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "chrome/test/data/pdf_private")); 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)PDFBrowserTest::~PDFBrowserTest() { 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PDFBrowserTest::Load() { 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Make sure to set the window size before rendering, as otherwise rendering 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // to a smaller window and then expanding leads to slight anti-aliasing 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // differences of the text and the pixel comparison fails. 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::Rect bounds(gfx::Rect(0, 0, kBrowserWidth, kBrowserHeight)); 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::Rect screen_bounds = 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().bounds(); 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_GT(screen_bounds.width(), kBrowserWidth); 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_GT(screen_bounds.height(), kBrowserHeight); 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) browser()->window()->SetBounds(bounds); 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GURL url(ui_test_utils::GetTestUrl( 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("pdf_private")), 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("pdf_browsertest.pdf")))); 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui_test_utils::NavigateToURL(browser(), url); 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PDFBrowserTest::WaitForResponse() { 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Even if the plugin has loaded the data or scrolled, because of how 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // pepper painting works, we might not have the data. One way to force this 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // to be flushed is to do a find operation, since on this two-page test 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // document, it'll wait for us to flush the renderer message loop twice and 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // also the browser's once, at which point we're guaranteed to have updated 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the backingstore. Hacky, but it works. 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Note that we need to change the text each time, because if we don't the 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // renderer code will think the second message is to go to next result, but 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // there are none so the plugin will assert. 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::string16 query = base::UTF8ToUTF16( 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string("xyzxyz" + base::IntToString(next_dummy_search_value_++))); 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_EQ(0, ui_test_utils::FindInPage( 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents(), 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) query, true, false, NULL, NULL)); 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool PDFBrowserTest::VerifySnapshot(const std::string& expected_filename) { 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) snapshot_different_ = true; 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) expected_filename_ = expected_filename; 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::WebContents* web_contents = 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents(); 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(web_contents); 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::RenderWidgetHost* rwh = web_contents->GetRenderViewHost(); 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rwh->CopyFromBackingStore( 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::Rect(), 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::Size(), 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&PDFBrowserTest::CopyFromBackingStoreCallback, this), 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kN32_SkColorType); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::RunMessageLoop(); 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (snapshot_different_) { 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(INFO) << "Rendering didn't match, see result " 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << snapshot_filename_.value(); 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return !snapshot_different_; 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PDFBrowserTest::CopyFromBackingStoreCallback(bool success, 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SkBitmap& bitmap) { 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::MessageLoopForUI::current()->Quit(); 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_EQ(success, true); 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::FilePath reference = ui_test_utils::GetTestFilePath( 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("pdf_private")), 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::FilePath().AppendASCII(expected_filename_)); 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::File::Info info; 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_TRUE(base::GetFileInfo(reference, &info)); 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int size = static_cast<size_t>(info.size); 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<char[]> data(new char[size]); 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_EQ(size, base::ReadFile(reference, data.get(), size)); 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int w, h; 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<unsigned char> decoded; 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_TRUE(gfx::PNGCodec::Decode( 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reinterpret_cast<unsigned char*>(data.get()), size, 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::PNGCodec::FORMAT_BGRA, &decoded, &w, &h)); 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int32* ref_pixels = reinterpret_cast<int32*>(&decoded[0]); 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int32* pixels = static_cast<int32*>(bitmap.getPixels()); 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Get the background color, and use it to figure out the x-offsets in 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // each image. The reason is that depending on the theme in the OS, the 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // same browser width can lead to slightly different plugin sizes, so the 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // pdf content will start at different x offsets. 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Also note that the images we saved are cut off before the scrollbar, as 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // that'll change depending on the theme, and also cut off vertically so 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // that the ui controls don't show up, as those fade-in and so the timing 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // will affect their transparency. 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int32 bg_color = ref_pixels[0]; 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int ref_x_offset, snapshot_x_offset; 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (ref_x_offset = 0; ref_x_offset < w; ++ref_x_offset) { 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (ref_pixels[ref_x_offset] != bg_color) 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (snapshot_x_offset = 0; snapshot_x_offset < bitmap.width(); 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ++snapshot_x_offset) { 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (pixels[snapshot_x_offset] != bg_color) 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int x_max = std::min(w - ref_x_offset, bitmap.width() - snapshot_x_offset); 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int y_max = std::min(h, bitmap.height()); 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int stride = bitmap.rowBytes(); 1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) snapshot_different_ = false; 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (int y = 0; y < y_max && !snapshot_different_; ++y) { 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (int x = 0; x < x_max && !snapshot_different_; ++x) { 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (pixels[y * stride / sizeof(int32) + x + snapshot_x_offset] != 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ref_pixels[y * w + x + ref_x_offset]) 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) snapshot_different_ = true; 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (snapshot_different_) { 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<unsigned char> png_data; 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &png_data); 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (base::CreateTemporaryFile(&snapshot_filename_)) { 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::WriteFile(snapshot_filename_, 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reinterpret_cast<char*>(&png_data[0]), png_data.size()); 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PDFBrowserTest::Observe(int type, 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const content::NotificationSource& source, 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const content::NotificationDetails& details) { 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(content::NOTIFICATION_LOAD_STOP, type); 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) load_stop_notification_count_++; 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PDFBrowserTest::SetUpCommandLine(base::CommandLine* command_line) { 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_LINUX) 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Calling RenderWidgetHost::CopyFromBackingStore() with the GPU enabled 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // fails on Linux. 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) command_line->AppendSwitch(switches::kDisableGpu); 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_CHROMEOS) 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Also need on CrOS in addition to disabling the GPU above. 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) command_line->AppendSwitch(switches::kUIDisableThreadedCompositing); 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 198