renderer_main_platform_delegate_win.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/renderer_main_platform_delegate.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/win/scoped_comptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/win_util.h"
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/win/windows_version.h"
14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/common/sandbox_win.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/injection_test_win.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_thread.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/render_thread_impl.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "skia/ext/vector_platform_device_emf_win.h"
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "third_party/WebKit/public/web/win/WebFontRendering.h"
22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/i18n/unicode/timezone.h"
23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "third_party/skia/include/ports/SkFontMgr.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/ports/SkTypeface_win.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifdef ENABLE_VTUNE_JIT_INTERFACE
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "v8/src/third_party/vtune/v8-vtune.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <dwrite.h>
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows-only skia sandbox support
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// These are used for GDI-path rendering.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SkiaPreCacheFont(const LOGFONT& logfont) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderThread* render_thread = RenderThread::Get();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (render_thread) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    render_thread->PreCacheFont(logfont);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SkiaPreCacheFontCharacters(const LOGFONT& logfont,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const wchar_t* text,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                unsigned int text_length) {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderThreadImpl* render_thread_impl = RenderThreadImpl::current();
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (render_thread_impl) {
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_thread_impl->PreCacheFontCharacters(
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        logfont,
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        base::string16(text, text_length));
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Windows-only DirectWrite support. These warm up the DirectWrite paths
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// before sandbox lock down to allow Skia access to the Font Manager service.
57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid CreateDirectWriteFactory(IDWriteFactory** factory) {
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc;
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DWriteCreateFactoryProc dwrite_create_factory_proc =
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      reinterpret_cast<DWriteCreateFactoryProc>(
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory"));
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  CHECK(dwrite_create_factory_proc);
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  CHECK(SUCCEEDED(
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      dwrite_create_factory_proc(DWRITE_FACTORY_TYPE_ISOLATED,
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                 __uuidof(IDWriteFactory),
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                 reinterpret_cast<IUnknown**>(factory))));
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid WarmupDirectWrite() {
70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // The objects used here are intentionally not freed as we want the Skia
71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // code to use these objects after warmup.
72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  IDWriteFactory* factory;
73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  CreateDirectWriteFactory(&factory);
74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  blink::WebFontRendering::setDirectWriteFactory(factory);
75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SkFontMgr* fontmgr = SkFontMgr_New_DirectWrite(factory);
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SkTypeface* typeface = fontmgr->legacyCreateTypeface("Times New Roman", 0);
77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SkPaint paint_warmup;
78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  paint_warmup.setTypeface(typeface);
79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  wchar_t glyph = L'S';
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  paint_warmup.measureText(&glyph, 2);
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RendererMainPlatformDelegate::RendererMainPlatformDelegate(
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MainFunctionParams& parameters)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : parameters_(parameters),
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sandbox_test_module_(NULL) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RendererMainPlatformDelegate::~RendererMainPlatformDelegate() {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RendererMainPlatformDelegate::PlatformInitialize() {
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const CommandLine& command_line = parameters_.command_line;
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifdef ENABLE_VTUNE_JIT_INTERFACE
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (command_line.HasSwitch(switches::kEnableVtune))
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    vTune::InitializeVtuneForV8();
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Be mindful of what resources you acquire here. They can be used by
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // malicious code if the renderer gets compromised.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool no_sandbox = command_line.HasSwitch(switches::kNoSandbox);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool use_direct_write = ShouldUseDirectWrite();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!no_sandbox) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ICU DateFormat class (used in base/time_format.cc) needs to get the
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Olson timezone ID by accessing the registry keys under
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After TimeZone::createDefault is called once here, the timezone ID is
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cached and there's no more need to access the registry. If the sandbox
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // is disabled, we don't have to make this dummy call.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<icu::TimeZone> zone(icu::TimeZone::createDefault());
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (use_direct_write) {
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      WarmupDirectWrite();
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    } else {
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      SkTypeface_SetEnsureLOGFONTAccessibleProc(SkiaPreCacheFont);
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      skia::SetSkiaEnsureTypefaceCharactersAccessible(
121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          SkiaPreCacheFontCharacters);
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  blink::WebFontRendering::setUseDirectWrite(use_direct_write);
125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  blink::WebFontRendering::setUseSubpixelPositioning(use_direct_write);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RendererMainPlatformDelegate::PlatformUninitialize() {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RendererMainPlatformDelegate::InitSandboxTests(bool no_sandbox) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CommandLine& command_line = parameters_.command_line;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Started renderer with " << command_line.GetCommandLineString();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sandbox::TargetServices* target_services =
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parameters_.sandbox_info->target_services;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (target_services && !no_sandbox) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::wstring test_dll_name =
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          command_line.GetSwitchValueNative(switches::kTestSandbox);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!test_dll_name.empty()) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sandbox_test_module_ = LoadLibrary(test_dll_name.c_str());
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(sandbox_test_module_);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!sandbox_test_module_) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RendererMainPlatformDelegate::EnableSandbox() {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sandbox::TargetServices* target_services =
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parameters_.sandbox_info->target_services;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (target_services) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Cause advapi32 to load before the sandbox is turned on.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int dummy_rand;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rand_s(&dummy_rand);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Warm up language subsystems before the sandbox is turned on.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::GetUserDefaultLangID();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::GetUserDefaultLCID();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target_services->LowerToken();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RendererMainPlatformDelegate::RunSandboxTests(bool no_sandbox) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sandbox_test_module_) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunRendererTests run_security_tests =
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<RunRendererTests>(GetProcAddress(sandbox_test_module_,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          kRenderTestCall));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(run_security_tests);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (run_security_tests) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int test_count = 0;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Running renderer security tests";
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BOOL result = run_security_tests(&test_count);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(result) << "Test number " << test_count << " has failed.";
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
187