Home | History | Annotate | Download | only in InjectedBundle
      1 /*
      2  * Copyright (C) 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 "config.h"
     27 #include "InjectedBundle.h"
     28 
     29 #include "ActivateFonts.h"
     30 #include "InjectedBundlePage.h"
     31 #include "StringFunctions.h"
     32 #include <WebKit2/WKBundle.h>
     33 #include <WebKit2/WKBundlePage.h>
     34 #include <WebKit2/WKBundlePagePrivate.h>
     35 #include <WebKit2/WKBundlePrivate.h>
     36 #include <WebKit2/WKRetainPtr.h>
     37 #include <WebKit2/WebKit2.h>
     38 #include <wtf/PassOwnPtr.h>
     39 #include <wtf/Vector.h>
     40 
     41 namespace WTR {
     42 
     43 InjectedBundle& InjectedBundle::shared()
     44 {
     45     static InjectedBundle& shared = *new InjectedBundle;
     46     return shared;
     47 }
     48 
     49 InjectedBundle::InjectedBundle()
     50     : m_bundle(0)
     51     , m_topLoadingFrame(0)
     52     , m_state(Idle)
     53     , m_dumpPixels(false)
     54 {
     55 }
     56 
     57 void InjectedBundle::didCreatePage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo)
     58 {
     59     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didCreatePage(page);
     60 }
     61 
     62 void InjectedBundle::willDestroyPage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo)
     63 {
     64     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->willDestroyPage(page);
     65 }
     66 
     67 void InjectedBundle::didInitializePageGroup(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, const void* clientInfo)
     68 {
     69     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didInitializePageGroup(pageGroup);
     70 }
     71 
     72 void InjectedBundle::didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo)
     73 {
     74     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didReceiveMessage(messageName, messageBody);
     75 }
     76 
     77 void InjectedBundle::initialize(WKBundleRef bundle, WKTypeRef initializationUserData)
     78 {
     79     m_bundle = bundle;
     80 
     81     WKBundleClient client = {
     82         0,
     83         this,
     84         didCreatePage,
     85         willDestroyPage,
     86         didInitializePageGroup,
     87         didReceiveMessage
     88     };
     89     WKBundleSetClient(m_bundle, &client);
     90 
     91     platformInitialize(initializationUserData);
     92 
     93     activateFonts();
     94     WKBundleActivateMacFontAscentHack(m_bundle);
     95 }
     96 
     97 void InjectedBundle::didCreatePage(WKBundlePageRef page)
     98 {
     99     m_pages.append(adoptPtr(new InjectedBundlePage(page)));
    100 }
    101 
    102 void InjectedBundle::willDestroyPage(WKBundlePageRef page)
    103 {
    104     size_t size = m_pages.size();
    105     for (size_t i = 0; i < size; ++i) {
    106         if (m_pages[i]->page() == page) {
    107             m_pages.remove(i);
    108             break;
    109         }
    110     }
    111 }
    112 
    113 void InjectedBundle::didInitializePageGroup(WKBundlePageGroupRef pageGroup)
    114 {
    115     m_pageGroup = pageGroup;
    116 }
    117 
    118 InjectedBundlePage* InjectedBundle::page() const
    119 {
    120     // It might be better to have the UI process send over a reference to the main
    121     // page instead of just assuming it's the first one.
    122     return m_pages[0].get();
    123 }
    124 
    125 void InjectedBundle::resetLocalSettings()
    126 {
    127     setlocale(LC_ALL, "");
    128 }
    129 
    130 void InjectedBundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody)
    131 {
    132     if (WKStringIsEqualToUTF8CString(messageName, "BeginTest")) {
    133         ASSERT(messageBody);
    134         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
    135         m_dumpPixels = WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody));
    136 
    137         WKRetainPtr<WKStringRef> ackMessageName(AdoptWK, WKStringCreateWithUTF8CString("Ack"));
    138         WKRetainPtr<WKStringRef> ackMessageBody(AdoptWK, WKStringCreateWithUTF8CString("BeginTest"));
    139         WKBundlePostMessage(m_bundle, ackMessageName.get(), ackMessageBody.get());
    140 
    141         beginTesting();
    142         return;
    143     } else if (WKStringIsEqualToUTF8CString(messageName, "Reset")) {
    144         m_state = Idle;
    145         m_dumpPixels = false;
    146 
    147         resetLocalSettings();
    148 
    149         return;
    150     }
    151 
    152     WKRetainPtr<WKStringRef> errorMessageName(AdoptWK, WKStringCreateWithUTF8CString("Error"));
    153     WKRetainPtr<WKStringRef> errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString("Unknown"));
    154     WKBundlePostMessage(m_bundle, errorMessageName.get(), errorMessageBody.get());
    155 }
    156 
    157 void InjectedBundle::beginTesting()
    158 {
    159     m_state = Testing;
    160 
    161     m_outputStream.str("");
    162     m_pixelResult.clear();
    163 
    164     m_layoutTestController = LayoutTestController::create();
    165     m_gcController = GCController::create();
    166     m_eventSendingController = EventSendingController::create();
    167 
    168     WKBundleSetShouldTrackVisitedLinks(m_bundle, false);
    169     WKBundleRemoveAllVisitedLinks(m_bundle);
    170     WKBundleOverrideAllowUniversalAccessFromFileURLsForTestRunner(m_bundle, m_pageGroup, true);
    171 
    172     WKBundleRemoveAllUserContent(m_bundle, m_pageGroup);
    173 
    174     page()->reset();
    175 
    176     WKBundleClearAllDatabases(m_bundle);
    177 }
    178 
    179 void InjectedBundle::done()
    180 {
    181     m_state = Stopping;
    182 
    183     page()->stopLoading();
    184     setTopLoadingFrame(0);
    185 
    186     WKRetainPtr<WKStringRef> doneMessageName(AdoptWK, WKStringCreateWithUTF8CString("Done"));
    187     WKRetainPtr<WKMutableDictionaryRef> doneMessageBody(AdoptWK, WKMutableDictionaryCreate());
    188 
    189     WKRetainPtr<WKStringRef> textOutputKey(AdoptWK, WKStringCreateWithUTF8CString("TextOutput"));
    190     WKRetainPtr<WKStringRef> textOutput(AdoptWK, WKStringCreateWithUTF8CString(m_outputStream.str().c_str()));
    191     WKDictionaryAddItem(doneMessageBody.get(), textOutputKey.get(), textOutput.get());
    192 
    193     WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult"));
    194     WKDictionaryAddItem(doneMessageBody.get(), pixelResultKey.get(), m_pixelResult.get());
    195 
    196     WKBundlePostMessage(m_bundle, doneMessageName.get(), doneMessageBody.get());
    197 
    198     closeOtherPages();
    199 
    200     m_state = Idle;
    201 }
    202 
    203 void InjectedBundle::closeOtherPages()
    204 {
    205     Vector<WKBundlePageRef> pagesToClose;
    206     size_t size = m_pages.size();
    207     for (size_t i = 1; i < size; ++i)
    208         pagesToClose.append(m_pages[i]->page());
    209     size = pagesToClose.size();
    210     for (size_t i = 0; i < size; ++i)
    211         WKBundlePageClose(pagesToClose[i]);
    212 }
    213 
    214 void InjectedBundle::dumpBackForwardListsForAllPages()
    215 {
    216     size_t size = m_pages.size();
    217     for (size_t i = 0; i < size; ++i)
    218         m_pages[i]->dumpBackForwardList();
    219 }
    220 
    221 } // namespace WTR
    222