blob: e6cc496442fc8f6870da8a5db8a932d6eccf1826 [file] [log] [blame]
/*
* Copyright (C) 2011, 2015 Google Inc. All rights reserved.
* Copyright (C) 2016-2022 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "WebCoreTestSupport.h"
#include "DeprecatedGlobalSettings.h"
#include "Frame.h"
#include "FrameDestructionObserverInlines.h"
#include "InternalSettings.h"
#include "Internals.h"
#include "JSDocument.h"
#include "JSInternals.h"
#include "JSServiceWorkerInternals.h"
#include "JSWorkerGlobalScope.h"
#include "LogInitialization.h"
#include "Logging.h"
#include "MockGamepadProvider.h"
#include "Page.h"
#include "SWContextManager.h"
#include "ServiceWorkerGlobalScope.h"
#include "WheelEventTestMonitor.h"
#include <JavaScriptCore/APICast.h>
#include <JavaScriptCore/CallFrame.h>
#include <JavaScriptCore/IdentifierInlines.h>
#include <JavaScriptCore/JITOperationList.h>
#include <JavaScriptCore/JSValueRef.h>
#include <wtf/URLParser.h>
#if PLATFORM(COCOA)
#include "UTIRegistry.h"
#include <wtf/cocoa/RuntimeApplicationChecksCocoa.h>
#endif
namespace WebCoreTestSupport {
using namespace JSC;
using namespace WebCore;
void injectInternalsObject(JSContextRef context)
{
JSGlobalObject* lexicalGlobalObject = toJS(context);
VM& vm = lexicalGlobalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
JSLockHolder lock(vm);
JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(lexicalGlobalObject);
ScriptExecutionContext* scriptContext = globalObject->scriptExecutionContext();
if (is<Document>(*scriptContext)) {
globalObject->putDirect(vm, Identifier::fromString(vm, Internals::internalsId), toJS(lexicalGlobalObject, globalObject, Internals::create(downcast<Document>(*scriptContext))));
Options::useDollarVM() = true;
globalObject->exposeDollarVM(vm);
}
EXCEPTION_ASSERT_UNUSED(scope, !scope.exception());
}
void resetInternalsObject(JSContextRef context)
{
JSGlobalObject* lexicalGlobalObject = toJS(context);
JSLockHolder lock(lexicalGlobalObject);
JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(lexicalGlobalObject);
ScriptExecutionContext* scriptContext = globalObject->scriptExecutionContext();
Page* page = downcast<Document>(scriptContext)->frame()->page();
Internals::resetToConsistentState(*page);
InternalSettings::from(page)->resetToConsistentState();
}
void monitorWheelEvents(WebCore::Frame& frame, bool clearLatchingState)
{
Page* page = frame.page();
if (!page)
return;
page->startMonitoringWheelEvents(clearLatchingState);
}
void setWheelEventMonitorTestCallbackAndStartMonitoring(bool expectWheelEndOrCancel, bool expectMomentumEnd, WebCore::Frame& frame, JSContextRef context, JSObjectRef jsCallbackFunction)
{
Page* page = frame.page();
if (!page || !page->isMonitoringWheelEvents())
return;
JSValueProtect(context, jsCallbackFunction);
if (auto wheelEventTestMonitor = page->wheelEventTestMonitor()) {
wheelEventTestMonitor->setTestCallbackAndStartMonitoring(expectWheelEndOrCancel, expectMomentumEnd, [=](void) {
JSObjectCallAsFunction(context, jsCallbackFunction, nullptr, 0, nullptr, nullptr);
JSValueUnprotect(context, jsCallbackFunction);
});
}
}
void clearWheelEventTestMonitor(WebCore::Frame& frame)
{
Page* page = frame.page();
if (!page)
return;
page->clearWheelEventTestMonitor();
}
void setLogChannelToAccumulate(const String& name)
{
#if !LOG_DISABLED
logChannels().setLogChannelToAccumulate(name);
#else
UNUSED_PARAM(name);
#endif
}
void clearAllLogChannelsToAccumulate()
{
#if !LOG_DISABLED
logChannels().clearAllLogChannelsToAccumulate();
#endif
}
void initializeLogChannelsIfNecessary()
{
#if !LOG_DISABLED || !RELEASE_LOG_DISABLED
logChannels().initializeLogChannelsIfNecessary();
#endif
}
void setAllowsAnySSLCertificate(bool allowAnySSLCertificate)
{
DeprecatedGlobalSettings::setAllowsAnySSLCertificate(allowAnySSLCertificate);
}
void setLinkedOnOrAfterEverythingForTesting()
{
#if PLATFORM(COCOA)
enableAllSDKAlignedBehaviors();
#endif
}
void installMockGamepadProvider()
{
#if ENABLE(GAMEPAD)
GamepadProvider::setSharedProvider(MockGamepadProvider::singleton());
#endif
}
void connectMockGamepad(unsigned gamepadIndex)
{
#if ENABLE(GAMEPAD)
MockGamepadProvider::singleton().connectMockGamepad(gamepadIndex);
#else
UNUSED_PARAM(gamepadIndex);
#endif
}
void disconnectMockGamepad(unsigned gamepadIndex)
{
#if ENABLE(GAMEPAD)
MockGamepadProvider::singleton().disconnectMockGamepad(gamepadIndex);
#else
UNUSED_PARAM(gamepadIndex);
#endif
}
void setMockGamepadDetails(unsigned gamepadIndex, const String& gamepadID, const String& mapping, unsigned axisCount, unsigned buttonCount)
{
#if ENABLE(GAMEPAD)
MockGamepadProvider::singleton().setMockGamepadDetails(gamepadIndex, gamepadID, mapping, axisCount, buttonCount);
#else
UNUSED_PARAM(gamepadIndex);
UNUSED_PARAM(gamepadID);
UNUSED_PARAM(mapping);
UNUSED_PARAM(axisCount);
UNUSED_PARAM(buttonCount);
#endif
}
void setMockGamepadAxisValue(unsigned gamepadIndex, unsigned axisIndex, double axisValue)
{
#if ENABLE(GAMEPAD)
MockGamepadProvider::singleton().setMockGamepadAxisValue(gamepadIndex, axisIndex, axisValue);
#else
UNUSED_PARAM(gamepadIndex);
UNUSED_PARAM(axisIndex);
UNUSED_PARAM(axisValue);
#endif
}
void setMockGamepadButtonValue(unsigned gamepadIndex, unsigned buttonIndex, double buttonValue)
{
#if ENABLE(GAMEPAD)
MockGamepadProvider::singleton().setMockGamepadButtonValue(gamepadIndex, buttonIndex, buttonValue);
#else
UNUSED_PARAM(gamepadIndex);
UNUSED_PARAM(buttonIndex);
UNUSED_PARAM(buttonValue);
#endif
}
void setupNewlyCreatedServiceWorker(uint64_t serviceWorkerIdentifier)
{
#if ENABLE(SERVICE_WORKER)
auto identifier = makeObjectIdentifier<ServiceWorkerIdentifierType>(serviceWorkerIdentifier);
SWContextManager::singleton().postTaskToServiceWorker(identifier, [identifier] (ServiceWorkerGlobalScope& globalScope) {
auto* script = globalScope.script();
if (!script)
return;
auto& globalObject = *globalScope.globalObject();
auto& vm = globalObject.vm();
JSLockHolder locker(vm);
auto* contextWrapper = script->globalScopeWrapper();
contextWrapper->putDirect(vm, Identifier::fromString(vm, Internals::internalsId), toJS(&globalObject, contextWrapper, ServiceWorkerInternals::create(globalScope, identifier)));
});
#else
UNUSED_PARAM(serviceWorkerIdentifier);
#endif
}
#if PLATFORM(COCOA)
void setAdditionalSupportedImageTypesForTesting(const String& imageTypes)
{
WebCore::setAdditionalSupportedImageTypesForTesting(imageTypes);
}
#endif
#if ENABLE(JIT_OPERATION_VALIDATION) || ENABLE(JIT_OPERATION_DISASSEMBLY)
extern const JSC::JITOperationAnnotation startOfJITOperationsInWebCoreTestSupport __asm("section$start$__DATA_CONST$__jsc_ops");
extern const JSC::JITOperationAnnotation endOfJITOperationsInWebCoreTestSupport __asm("section$end$__DATA_CONST$__jsc_ops");
#if ENABLE(JIT_OPERATION_VALIDATION)
void populateJITOperations()
{
static std::once_flag onceKey;
std::call_once(onceKey, [] {
JSC::JITOperationList::populatePointersInEmbedder(&startOfJITOperationsInWebCoreTestSupport, &endOfJITOperationsInWebCoreTestSupport);
});
#if ENABLE(JIT_OPERATION_DISASSEMBLY)
if (UNLIKELY(JSC::Options::needDisassemblySupport()))
populateDisassemblyLabels();
#endif
}
#endif // ENABLE(JIT_OPERATION_VALIDATION)
#if ENABLE(JIT_OPERATION_DISASSEMBLY)
void populateDisassemblyLabels()
{
static std::once_flag onceKey;
std::call_once(onceKey, [] {
JSC::JITOperationList::populateDisassemblyLabelsInEmbedder(&startOfJITOperationsInWebCoreTestSupport, &endOfJITOperationsInWebCoreTestSupport);
});
}
#endif // ENABLE(JIT_OPERATION_DISASSEMBLY)
#endif // ENABLE(JIT_OPERATION_VALIDATION) || ENABLE(JIT_OPERATION_DISASSEMBLY)
} // namespace WebCoreTestSupport