Home | History | Annotate | Download | only in web
      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 
     62 namespace WebKit {
     63 
     64 namespace {
     65 
     66 class EndOfTaskRunner : public WebThread::TaskObserver {
     67 public:
     68     virtual void willProcessTask() { }
     69     virtual void didProcessTask()
     70     {
     71         WebCore::Microtask::performCheckpoint();
     72     }
     73 };
     74 
     75 } // namespace
     76 
     77 static 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.
     81 static bool s_webKitInitialized = false;
     82 
     83 static 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
     93 static void assertV8RecursionScope()
     94 {
     95     ASSERT(!isMainThread() || WebCore::V8RecursionScope::properlyUsed());
     96 }
     97 #endif
     98 
     99 void 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 
    121 static double currentTimeFunction()
    122 {
    123     return Platform::current()->currentTime();
    124 }
    125 
    126 static double monotonicallyIncreasingTimeFunction()
    127 {
    128     return Platform::current()->monotonicallyIncreasingTime();
    129 }
    130 
    131 static void cryptographicallyRandomValues(unsigned char* buffer, size_t length)
    132 {
    133     Platform::current()->cryptographicallyRandomValues(buffer, length);
    134 }
    135 
    136 static void callOnMainThreadFunction(WTF::MainThreadFunction function, void* context)
    137 {
    138     Platform::current()->callOnMainThread(function, context);
    139 }
    140 
    141 void 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 
    172 void 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 
    191 void shutdownWithoutV8()
    192 {
    193     ASSERT(!s_endOfTaskRunner);
    194     WebCore::ImageDecodingStore::shutdown();
    195     WebCore::shutdown();
    196     WTF::shutdown();
    197     Platform::shutdown();
    198     WebPrerenderingSupport::shutdown();
    199 }
    200 
    201 void setLayoutTestMode(bool value)
    202 {
    203     WebCore::setIsRunningLayoutTest(value);
    204 }
    205 
    206 bool layoutTestMode()
    207 {
    208     return WebCore::isRunningLayoutTest();
    209 }
    210 
    211 void 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 
    222 void resetPluginCache(bool reloadPages)
    223 {
    224     WebCore::Page::refreshPlugins(reloadPages);
    225 }
    226 
    227 } // namespace WebKit
    228