1/* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32#include "WebKit.h" 33 34#include "IDBFactoryBackendProxy.h" 35#include "RuntimeEnabledFeatures.h" 36#include "WebMediaPlayerClientImpl.h" 37#include "WebWorkerClientImpl.h" 38#include "bindings/v8/V8Binding.h" 39#include "bindings/v8/V8RecursionScope.h" 40#include "core/Init.h" 41#include "core/dom/Microtask.h" 42#include "core/page/Frame.h" 43#include "core/page/Page.h" 44#include "core/page/Settings.h" 45#include "core/platform/LayoutTestSupport.h" 46#include "core/platform/Logging.h" 47#include "core/platform/graphics/MediaPlayer.h" 48#include "core/platform/graphics/chromium/ImageDecodingStore.h" 49#include "core/workers/WorkerGlobalScopeProxy.h" 50#include "wtf/Assertions.h" 51#include "wtf/CryptographicallyRandomNumber.h" 52#include "wtf/MainThread.h" 53#include "wtf/UnusedParam.h" 54#include "wtf/WTF.h" 55#include "wtf/text/AtomicString.h" 56#include "wtf/text/TextEncoding.h" 57#include "public/platform/Platform.h" 58#include "public/platform/WebPrerenderingSupport.h" 59#include "public/platform/WebThread.h" 60#include <v8.h> 61 62namespace WebKit { 63 64namespace { 65 66class EndOfTaskRunner : public WebThread::TaskObserver { 67public: 68 virtual void willProcessTask() { } 69 virtual void didProcessTask() 70 { 71 WebCore::Microtask::performCheckpoint(); 72 } 73}; 74 75} // namespace 76 77static WebThread::TaskObserver* s_endOfTaskRunner = 0; 78 79// Make sure we are not re-initialized in the same address space. 80// Doing so may cause hard to reproduce crashes. 81static bool s_webKitInitialized = false; 82 83static bool generateEntropy(unsigned char* buffer, size_t length) 84{ 85 if (Platform::current()) { 86 Platform::current()->cryptographicallyRandomValues(buffer, length); 87 return true; 88 } 89 return false; 90} 91 92#ifndef NDEBUG 93static void assertV8RecursionScope() 94{ 95 ASSERT(!isMainThread() || WebCore::V8RecursionScope::properlyUsed()); 96} 97#endif 98 99void initialize(Platform* platform) 100{ 101 initializeWithoutV8(platform); 102 103 v8::V8::SetEntropySource(&generateEntropy); 104 v8::V8::SetArrayBufferAllocator(WebCore::v8ArrayBufferAllocator()); 105 static const char* kTypedArraysFlag = "--harmony_array_buffer --harmony_typed_arrays"; 106 v8::V8::SetFlagsFromString(kTypedArraysFlag, strlen(kTypedArraysFlag)); 107 v8::V8::Initialize(); 108 WebCore::V8PerIsolateData::ensureInitialized(v8::Isolate::GetCurrent()); 109 110 // currentThread will always be non-null in production, but can be null in Chromium unit tests. 111 if (WebThread* currentThread = platform->currentThread()) { 112#ifndef NDEBUG 113 v8::V8::AddCallCompletedCallback(&assertV8RecursionScope); 114#endif 115 ASSERT(!s_endOfTaskRunner); 116 s_endOfTaskRunner = new EndOfTaskRunner; 117 currentThread->addTaskObserver(s_endOfTaskRunner); 118 } 119} 120 121static double currentTimeFunction() 122{ 123 return Platform::current()->currentTime(); 124} 125 126static double monotonicallyIncreasingTimeFunction() 127{ 128 return Platform::current()->monotonicallyIncreasingTime(); 129} 130 131static void cryptographicallyRandomValues(unsigned char* buffer, size_t length) 132{ 133 Platform::current()->cryptographicallyRandomValues(buffer, length); 134} 135 136static void callOnMainThreadFunction(WTF::MainThreadFunction function, void* context) 137{ 138 Platform::current()->callOnMainThread(function, context); 139} 140 141void initializeWithoutV8(Platform* platform) 142{ 143 ASSERT(!s_webKitInitialized); 144 s_webKitInitialized = true; 145 146 ASSERT(platform); 147 Platform::initialize(platform); 148 149 WTF::setRandomSource(cryptographicallyRandomValues); 150 WTF::initialize(currentTimeFunction, monotonicallyIncreasingTimeFunction); 151 WTF::initializeMainThread(callOnMainThreadFunction); 152 WebCore::init(); 153 WebCore::ImageDecodingStore::initializeOnce(); 154 155 // There are some code paths (for example, running WebKit in the browser 156 // process and calling into LocalStorage before anything else) where the 157 // UTF8 string encoding tables are used on a background thread before 158 // they're set up. This is a problem because their set up routines assert 159 // they're running on the main WebKitThread. It might be possible to make 160 // the initialization thread-safe, but given that so many code paths use 161 // this, initializing this lazily probably doesn't buy us much. 162 WTF::UTF8Encoding(); 163 164 WebCore::setIDBFactoryBackendInterfaceCreateFunction(WebKit::IDBFactoryBackendProxy::create); 165 166 WebCore::MediaPlayer::setMediaEngineCreateFunction(WebKit::WebMediaPlayerClientImpl::create); 167 168 WebCore::WorkerGlobalScopeProxy::setCreateDelegate(WebWorkerClientImpl::createWorkerGlobalScopeProxy); 169} 170 171 172void shutdown() 173{ 174 // currentThread will always be non-null in production, but can be null in Chromium unit tests. 175 if (Platform::current()->currentThread()) { 176 ASSERT(s_endOfTaskRunner); 177#ifndef NDEBUG 178 v8::V8::RemoveCallCompletedCallback(&assertV8RecursionScope); 179#endif 180 Platform::current()->currentThread()->removeTaskObserver(s_endOfTaskRunner); 181 delete s_endOfTaskRunner; 182 s_endOfTaskRunner = 0; 183 } 184 185 shutdownWithoutV8(); 186 187 WebCore::V8PerIsolateData::dispose(v8::Isolate::GetCurrent()); 188 v8::V8::Dispose(); 189} 190 191void shutdownWithoutV8() 192{ 193 ASSERT(!s_endOfTaskRunner); 194 WebCore::ImageDecodingStore::shutdown(); 195 WebCore::shutdown(); 196 WTF::shutdown(); 197 Platform::shutdown(); 198 WebPrerenderingSupport::shutdown(); 199} 200 201void setLayoutTestMode(bool value) 202{ 203 WebCore::setIsRunningLayoutTest(value); 204} 205 206bool layoutTestMode() 207{ 208 return WebCore::isRunningLayoutTest(); 209} 210 211void enableLogChannel(const char* name) 212{ 213#if !LOG_DISABLED 214 WTFLogChannel* channel = WebCore::getChannelFromName(name); 215 if (channel) 216 channel->state = WTFLogChannelOn; 217#else 218 UNUSED_PARAM(name); 219#endif // !LOG_DISABLED 220} 221 222void resetPluginCache(bool reloadPages) 223{ 224 WebCore::Page::refreshPlugins(reloadPages); 225} 226 227} // namespace WebKit 228