WebKit2/WebProcess/WebProcess.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2009, 2010 Apple 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
       
     6  * are met:
       
     7  * 1. Redistributions of source code must retain the above copyright
       
     8  *    notice, this list of conditions and the following disclaimer.
       
     9  * 2. Redistributions in binary form must reproduce the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer in the
       
    11  *    documentation and/or other materials provided with the distribution.
       
    12  *
       
    13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
       
    14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
       
    15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
       
    17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
       
    18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
       
    19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
       
    20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
       
    21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
       
    22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
       
    23  * THE POSSIBILITY OF SUCH DAMAGE.
       
    24  */
       
    25 
       
    26 #include "WebProcess.h"
       
    27 
       
    28 #include "InjectedBundle.h"
       
    29 #if PLATFORM(MAC)
       
    30 #include "MachPort.h"
       
    31 #endif
       
    32 #include "RunLoop.h"
       
    33 #include "WebCoreArgumentCoders.h"
       
    34 #include "WebFrame.h"
       
    35 #include "WebPage.h"
       
    36 #include "WebPlatformStrategies.h"
       
    37 #include "WebPreferencesStore.h"
       
    38 #include "WebProcessMessageKinds.h"
       
    39 #include <WebCore/ApplicationCacheStorage.h>
       
    40 #include <wtf/PassRefPtr.h>
       
    41 
       
    42 #ifndef NDEBUG
       
    43 #include <WebCore/Cache.h>
       
    44 #include <WebCore/GCController.h>
       
    45 #endif
       
    46 
       
    47 using namespace WebCore;
       
    48 
       
    49 namespace WebKit {
       
    50 
       
    51 WebProcess& WebProcess::shared()
       
    52 {
       
    53     static WebProcess& process = *new WebProcess;
       
    54     return process;
       
    55 }
       
    56 
       
    57 WebProcess::WebProcess()
       
    58     : m_inDidClose(false)
       
    59 #if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC)
       
    60     , m_compositingRenderServerPort(MACH_PORT_NULL)
       
    61 #endif
       
    62 {
       
    63 #if USE(PLATFORM_STRATEGIES)
       
    64     // Initialize our platform strategies.
       
    65     WebPlatformStrategies::initialize();
       
    66 #endif // USE(PLATFORM_STRATEGIES)
       
    67 }
       
    68 
       
    69 void WebProcess::initialize(CoreIPC::Connection::Identifier serverIdentifier, RunLoop* runLoop)
       
    70 {
       
    71     ASSERT(!m_connection);
       
    72 
       
    73     m_connection = CoreIPC::Connection::createClientConnection(serverIdentifier, this, runLoop);
       
    74     m_connection->open();
       
    75 
       
    76     m_runLoop = runLoop;
       
    77 }
       
    78 
       
    79 #if ENABLE(WEB_PROCESS_SANDBOX)
       
    80 void WebProcess::loadInjectedBundle(const String& path, const String& token)
       
    81 #else
       
    82 void WebProcess::loadInjectedBundle(const String& path)
       
    83 #endif
       
    84 {
       
    85     ASSERT(m_pageMap.isEmpty());
       
    86     ASSERT(!path.isEmpty());
       
    87 
       
    88     m_injectedBundle = InjectedBundle::create(path);
       
    89 #if ENABLE(WEB_PROCESS_SANDBOX)
       
    90     m_injectedBundle->setSandboxToken(token);
       
    91 #endif
       
    92 
       
    93     if (!m_injectedBundle->load()) {
       
    94         // Don't keep around the InjectedBundle reference if the load fails.
       
    95         m_injectedBundle.clear();
       
    96     }
       
    97 }
       
    98 
       
    99 void WebProcess::setApplicationCacheDirectory(const String& directory)
       
   100 {
       
   101     cacheStorage().setCacheDirectory(directory);
       
   102 }
       
   103 
       
   104 void WebProcess::forwardMessageToInjectedBundle(const String& message)
       
   105 {
       
   106     if (!m_injectedBundle)
       
   107         return;
       
   108 
       
   109     m_injectedBundle->didRecieveMessage(message);
       
   110 }
       
   111 
       
   112 WebPage* WebProcess::webPage(uint64_t pageID) const
       
   113 {
       
   114     return m_pageMap.get(pageID).get();
       
   115 }
       
   116 
       
   117 WebPage* WebProcess::createWebPage(uint64_t pageID, const IntSize& viewSize, const WebPreferencesStore& store, DrawingArea::Type drawingAreaType)
       
   118 {
       
   119     // It is necessary to check for page existence here since during a window.open() (or targeted
       
   120     // link) the WebPage gets created both in the synchronous handler and through the normal way. 
       
   121     std::pair<HashMap<uint64_t, RefPtr<WebPage> >::iterator, bool> result = m_pageMap.add(pageID, 0);
       
   122     if (result.second) {
       
   123         ASSERT(!result.first->second);
       
   124         result.first->second = WebPage::create(pageID, viewSize, store, drawingAreaType);
       
   125     }
       
   126 
       
   127     ASSERT(result.first->second);
       
   128     return result.first->second.get();
       
   129 }
       
   130 
       
   131 void WebProcess::removeWebPage(uint64_t pageID)
       
   132 {
       
   133     m_pageMap.remove(pageID);
       
   134 
       
   135     // If we don't have any pages left, shut down.
       
   136     if (m_pageMap.isEmpty() && !m_inDidClose)
       
   137         shutdown();
       
   138 }
       
   139 
       
   140 bool WebProcess::isSeparateProcess() const
       
   141 {
       
   142     // If we're running on the main run loop, we assume that we're in a separate process.
       
   143     return m_runLoop == RunLoop::main();
       
   144 }
       
   145  
       
   146 void WebProcess::shutdown()
       
   147 {
       
   148     // Keep running forever if we're running in the same process.
       
   149     if (!isSeparateProcess())
       
   150         return;
       
   151 
       
   152 #ifndef NDEBUG
       
   153     gcController().garbageCollectNow();
       
   154     cache()->setDisabled(true);
       
   155 #endif
       
   156 
       
   157     // Invalidate our connection.
       
   158     m_connection->invalidate();
       
   159     m_connection = 0;
       
   160 
       
   161     m_runLoop->stop();
       
   162 }
       
   163 
       
   164 void WebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
       
   165 {
       
   166     if (messageID.is<CoreIPC::MessageClassWebProcess>()) {
       
   167         switch (messageID.get<WebProcessMessage::Kind>()) {
       
   168             case WebProcessMessage::LoadInjectedBundle: {
       
   169                 String path;
       
   170 
       
   171 #if ENABLE(WEB_PROCESS_SANDBOX)
       
   172                 String token;
       
   173                 if (!arguments->decode(CoreIPC::Out(path, token)))
       
   174                     return;
       
   175 
       
   176                 loadInjectedBundle(path, token);
       
   177                 return;
       
   178 #else
       
   179                 if (!arguments->decode(CoreIPC::Out(path)))
       
   180                     return;
       
   181 
       
   182                 loadInjectedBundle(path);
       
   183                 return;
       
   184 #endif
       
   185             }
       
   186             case WebProcessMessage::SetApplicationCacheDirectory: {
       
   187                 String directory;
       
   188                 if (!arguments->decode(CoreIPC::Out(directory)))
       
   189                     return;
       
   190                 
       
   191                 setApplicationCacheDirectory(directory);
       
   192                 return;
       
   193             }
       
   194             case WebProcessMessage::Create: {
       
   195                 uint64_t pageID = arguments->destinationID();
       
   196                 IntSize viewSize;
       
   197                 WebPreferencesStore store;
       
   198                 uint32_t drawingAreaType;
       
   199                 if (!arguments->decode(CoreIPC::Out(viewSize, store, drawingAreaType)))
       
   200                     return;
       
   201 
       
   202                 createWebPage(pageID, viewSize, store, static_cast<DrawingArea::Type>(drawingAreaType));
       
   203                 return;
       
   204             }
       
   205             case WebProcessMessage::PostMessage: {
       
   206                 String message;
       
   207                 if (!arguments->decode(CoreIPC::Out(message)))
       
   208                     return;
       
   209 
       
   210                 forwardMessageToInjectedBundle(message);
       
   211                 return;
       
   212             }
       
   213 #if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC)
       
   214             case WebProcessMessage::SetupAcceleratedCompositingPort: {
       
   215                 CoreIPC::MachPort port;
       
   216                 if (!arguments->decode(port))
       
   217                     return;
       
   218 
       
   219                 m_compositingRenderServerPort = port.port();
       
   220                 return;
       
   221             }
       
   222 #endif
       
   223         }
       
   224     }
       
   225 
       
   226     uint64_t pageID = arguments->destinationID();
       
   227     if (!pageID)
       
   228         return;
       
   229     
       
   230     WebPage* page = webPage(pageID);
       
   231     if (!page)
       
   232         return;
       
   233     
       
   234     page->didReceiveMessage(connection, messageID, *arguments);    
       
   235 }
       
   236 
       
   237 void WebProcess::didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*)
       
   238 {
       
   239     // The web process should never ever get sync messages.
       
   240     ASSERT_NOT_REACHED();
       
   241 }
       
   242 
       
   243 void WebProcess::didClose(CoreIPC::Connection*)
       
   244 {
       
   245     // When running in the same process the connection will never be closed.
       
   246     ASSERT(isSeparateProcess());
       
   247 
       
   248 #ifndef NDEBUG
       
   249     m_inDidClose = true;
       
   250 
       
   251     // Close all the live pages.
       
   252     Vector<RefPtr<WebPage> > pages;
       
   253     copyValuesToVector(m_pageMap, pages);
       
   254     for (size_t i = 0; i < pages.size(); ++i)
       
   255         pages[i]->close();
       
   256     pages.clear();
       
   257 
       
   258     gcController().garbageCollectNow();
       
   259     cache()->setDisabled(true);
       
   260 #endif    
       
   261 
       
   262     // The UI process closed this connection, shut down.
       
   263     m_runLoop->stop();
       
   264 }
       
   265 
       
   266 } // namespace WebKit