1/*
2 * Copyright (C) 2011, 2015 Google Inc. All rights reserved.
3 * Copyright (C) 2016 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "WebCoreTestSupport.h"
29
30#include "Frame.h"
31#include "InternalSettings.h"
32#include "Internals.h"
33#include "JSDocument.h"
34#include "JSInternals.h"
35#include "JSServiceWorkerInternals.h"
36#include "JSWorkerGlobalScope.h"
37#include "LogInitialization.h"
38#include "MockGamepadProvider.h"
39#include "Page.h"
40#include "SWContextManager.h"
41#include "ServiceWorkerGlobalScope.h"
42#include "WheelEventTestTrigger.h"
43#include <JavaScriptCore/APICast.h>
44#include <JavaScriptCore/CallFrame.h>
45#include <JavaScriptCore/IdentifierInlines.h>
46#include <JavaScriptCore/JSValueRef.h>
47#include <wtf/URLParser.h>
48
49#if PLATFORM(COCOA)
50#include "UTIRegistry.h"
51#endif
52
53namespace WebCoreTestSupport {
54using namespace JSC;
55using namespace WebCore;
56
57void injectInternalsObject(JSContextRef context)
58{
59 ExecState* exec = toJS(context);
60 JSLockHolder lock(exec);
61 JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
62 ScriptExecutionContext* scriptContext = globalObject->scriptExecutionContext();
63 if (is<Document>(*scriptContext)) {
64 VM& vm = exec->vm();
65 globalObject->putDirect(vm, Identifier::fromString(&vm, Internals::internalsId), toJS(exec, globalObject, Internals::create(downcast<Document>(*scriptContext))));
66 globalObject->exposeDollarVM(vm);
67 }
68}
69
70void resetInternalsObject(JSContextRef context)
71{
72 ExecState* exec = toJS(context);
73 JSLockHolder lock(exec);
74 JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
75 ScriptExecutionContext* scriptContext = globalObject->scriptExecutionContext();
76 Page* page = downcast<Document>(scriptContext)->frame()->page();
77 Internals::resetToConsistentState(*page);
78 InternalSettings::from(page)->resetToConsistentState();
79}
80
81void monitorWheelEvents(WebCore::Frame& frame)
82{
83 Page* page = frame.page();
84 if (!page)
85 return;
86
87 page->ensureTestTrigger();
88}
89
90void setTestCallbackAndStartNotificationTimer(WebCore::Frame& frame, JSContextRef context, JSObjectRef jsCallbackFunction)
91{
92 Page* page = frame.page();
93 if (!page || !page->expectsWheelEventTriggers())
94 return;
95
96 JSValueProtect(context, jsCallbackFunction);
97
98 page->ensureTestTrigger().setTestCallbackAndStartNotificationTimer([=](void) {
99 JSObjectCallAsFunction(context, jsCallbackFunction, nullptr, 0, nullptr, nullptr);
100 JSValueUnprotect(context, jsCallbackFunction);
101 });
102}
103
104void clearWheelEventTestTrigger(WebCore::Frame& frame)
105{
106 Page* page = frame.page();
107 if (!page)
108 return;
109
110 page->clearTrigger();
111}
112
113void setLogChannelToAccumulate(const String& name)
114{
115#if !LOG_DISABLED
116 WebCore::setLogChannelToAccumulate(name);
117#else
118 UNUSED_PARAM(name);
119#endif
120}
121
122void initializeLogChannelsIfNecessary()
123{
124#if !LOG_DISABLED || !RELEASE_LOG_DISABLED
125 WebCore::initializeLogChannelsIfNecessary();
126#endif
127}
128
129void setAllowsAnySSLCertificate(bool allowAnySSLCertificate)
130{
131 InternalSettings::setAllowsAnySSLCertificate(allowAnySSLCertificate);
132}
133
134void installMockGamepadProvider()
135{
136#if ENABLE(GAMEPAD)
137 GamepadProvider::setSharedProvider(MockGamepadProvider::singleton());
138#endif
139}
140
141void connectMockGamepad(unsigned gamepadIndex)
142{
143#if ENABLE(GAMEPAD)
144 MockGamepadProvider::singleton().connectMockGamepad(gamepadIndex);
145#else
146 UNUSED_PARAM(gamepadIndex);
147#endif
148}
149
150void disconnectMockGamepad(unsigned gamepadIndex)
151{
152#if ENABLE(GAMEPAD)
153 MockGamepadProvider::singleton().disconnectMockGamepad(gamepadIndex);
154#else
155 UNUSED_PARAM(gamepadIndex);
156#endif
157}
158
159void setMockGamepadDetails(unsigned gamepadIndex, const WTF::String& gamepadID, unsigned axisCount, unsigned buttonCount)
160{
161#if ENABLE(GAMEPAD)
162 MockGamepadProvider::singleton().setMockGamepadDetails(gamepadIndex, gamepadID, axisCount, buttonCount);
163#else
164 UNUSED_PARAM(gamepadIndex);
165 UNUSED_PARAM(gamepadID);
166 UNUSED_PARAM(axisCount);
167 UNUSED_PARAM(buttonCount);
168#endif
169}
170
171void setMockGamepadAxisValue(unsigned gamepadIndex, unsigned axisIndex, double axisValue)
172{
173#if ENABLE(GAMEPAD)
174 MockGamepadProvider::singleton().setMockGamepadAxisValue(gamepadIndex, axisIndex, axisValue);
175#else
176 UNUSED_PARAM(gamepadIndex);
177 UNUSED_PARAM(axisIndex);
178 UNUSED_PARAM(axisValue);
179#endif
180}
181
182void setMockGamepadButtonValue(unsigned gamepadIndex, unsigned buttonIndex, double buttonValue)
183{
184#if ENABLE(GAMEPAD)
185 MockGamepadProvider::singleton().setMockGamepadButtonValue(gamepadIndex, buttonIndex, buttonValue);
186#else
187 UNUSED_PARAM(gamepadIndex);
188 UNUSED_PARAM(buttonIndex);
189 UNUSED_PARAM(buttonValue);
190#endif
191}
192
193void setupNewlyCreatedServiceWorker(uint64_t serviceWorkerIdentifier)
194{
195#if ENABLE(SERVICE_WORKER)
196 auto identifier = makeObjectIdentifier<ServiceWorkerIdentifierType>(serviceWorkerIdentifier);
197 SWContextManager::singleton().postTaskToServiceWorker(identifier, [identifier] (ServiceWorkerGlobalScope& globalScope) {
198 auto* script = globalScope.script();
199 if (!script)
200 return;
201
202 auto& state = *globalScope.execState();
203 JSLockHolder locker(state.vm());
204 auto* contextWrapper = script->workerGlobalScopeWrapper();
205 contextWrapper->putDirect(state.vm(), Identifier::fromString(&state, Internals::internalsId), toJS(&state, contextWrapper, ServiceWorkerInternals::create(identifier)));
206 });
207#else
208 UNUSED_PARAM(serviceWorkerIdentifier);
209#endif
210}
211
212#if PLATFORM(COCOA)
213void setAdditionalSupportedImageTypesForTesting(const WTF::String& imageTypes)
214{
215 WebCore::setAdditionalSupportedImageTypesForTesting(imageTypes);
216}
217#endif
218
219}
220