• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
shared()43 InjectedBundle& InjectedBundle::shared()
44 {
45     static InjectedBundle& shared = *new InjectedBundle;
46     return shared;
47 }
48 
InjectedBundle()49 InjectedBundle::InjectedBundle()
50     : m_bundle(0)
51     , m_topLoadingFrame(0)
52     , m_state(Idle)
53     , m_dumpPixels(false)
54 {
55 }
56 
didCreatePage(WKBundleRef bundle,WKBundlePageRef page,const void * clientInfo)57 void InjectedBundle::didCreatePage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo)
58 {
59     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didCreatePage(page);
60 }
61 
willDestroyPage(WKBundleRef bundle,WKBundlePageRef page,const void * clientInfo)62 void InjectedBundle::willDestroyPage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo)
63 {
64     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->willDestroyPage(page);
65 }
66 
didInitializePageGroup(WKBundleRef bundle,WKBundlePageGroupRef pageGroup,const void * clientInfo)67 void InjectedBundle::didInitializePageGroup(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, const void* clientInfo)
68 {
69     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didInitializePageGroup(pageGroup);
70 }
71 
didReceiveMessage(WKBundleRef bundle,WKStringRef messageName,WKTypeRef messageBody,const void * clientInfo)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 
initialize(WKBundleRef bundle,WKTypeRef initializationUserData)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 
didCreatePage(WKBundlePageRef page)97 void InjectedBundle::didCreatePage(WKBundlePageRef page)
98 {
99     m_pages.append(adoptPtr(new InjectedBundlePage(page)));
100 }
101 
willDestroyPage(WKBundlePageRef page)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 
didInitializePageGroup(WKBundlePageGroupRef pageGroup)113 void InjectedBundle::didInitializePageGroup(WKBundlePageGroupRef pageGroup)
114 {
115     m_pageGroup = pageGroup;
116 }
117 
page() const118 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 
resetLocalSettings()125 void InjectedBundle::resetLocalSettings()
126 {
127     setlocale(LC_ALL, "");
128 }
129 
didReceiveMessage(WKStringRef messageName,WKTypeRef messageBody)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 
beginTesting()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 
done()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 
closeOtherPages()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 
dumpBackForwardListsForAllPages()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