Diff
Modified: trunk/Source/WebCore/ChangeLog (243001 => 243002)
--- trunk/Source/WebCore/ChangeLog 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/ChangeLog 2019-03-15 18:18:36 UTC (rev 243002)
@@ -1,3 +1,56 @@
+2019-03-15 Per Arne Vollan <[email protected]>
+
+ [macOS] Broker access to Speech Synthesis
+ https://bugs.webkit.org/show_bug.cgi?id=195645
+ <rdar://problem/35369026>
+
+ Reviewed by Brent Fulgham.
+
+ To be able to close the connection to the speech synthesis daemon in the WebContent process,
+ speech synthesis should be performed in the UI process. This patch forwards speech synthesis
+ requests to the UI process by sending messages. On the UI process side, the speech synthesis
+ is performed by simply using the existing platform speech synthesizer. Speech synthesis
+ events are sent back to the WebContent process. All messages are async, except for the
+ message to get the list of available voices.
+
+ No new tests, covered by existing tests.
+
+ * Modules/speech/DOMWindowSpeechSynthesis.cpp:
+ (WebCore::DOMWindowSpeechSynthesis::speechSynthesis):
+ * Modules/speech/SpeechSynthesis.cpp:
+ (WebCore::SpeechSynthesis::create):
+ (WebCore::SpeechSynthesis::SpeechSynthesis):
+ (WebCore::SpeechSynthesis::setPlatformSynthesizer):
+ (WebCore::SpeechSynthesis::getVoices):
+ (WebCore::SpeechSynthesis::startSpeakingImmediately):
+ (WebCore::SpeechSynthesis::cancel):
+ (WebCore::SpeechSynthesis::pause):
+ (WebCore::SpeechSynthesis::resume):
+ (WebCore::SpeechSynthesis::boundaryEventOccurred):
+ (WebCore::SpeechSynthesis::didStartSpeaking):
+ (WebCore::SpeechSynthesis::didFinishSpeaking):
+ (WebCore::SpeechSynthesis::didPauseSpeaking):
+ (WebCore::SpeechSynthesis::didResumeSpeaking):
+ (WebCore::SpeechSynthesis::speakingErrorOccurred):
+ (WebCore::SpeechSynthesis::voicesChanged):
+ * Modules/speech/SpeechSynthesis.h:
+ * WebCore.xcodeproj/project.pbxproj:
+ * page/Page.cpp:
+ (WebCore::Page::Page):
+ * page/Page.h:
+ (WebCore::Page::speechSynthesisClient const):
+ * page/PageConfiguration.cpp:
+ * page/PageConfiguration.h:
+ * page/SpeechSynthesisClient.h: Added.
+ * platform/PlatformSpeechSynthesisUtterance.h:
+ * platform/PlatformSpeechSynthesizer.h:
+ * platform/ios/PlatformSpeechSynthesizerIOS.mm:
+ (-[WebSpeechSynthesisWrapper speechSynthesizer:willSpeakRangeOfSpeechString:utterance:]):
+ * platform/mac/PlatformSpeechSynthesizerMac.mm:
+ (-[WebSpeechSynthesisWrapper speechSynthesizer:willSpeakWord:ofString:]):
+ * platform/mock/PlatformSpeechSynthesizerMock.cpp:
+ (WebCore::PlatformSpeechSynthesizerMock::speak):
+
2019-03-15 Antti Koivisto <[email protected]>
Try to fix watchOS build.
Modified: trunk/Source/WebCore/Modules/speech/DOMWindowSpeechSynthesis.cpp (243001 => 243002)
--- trunk/Source/WebCore/Modules/speech/DOMWindowSpeechSynthesis.cpp 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/Modules/speech/DOMWindowSpeechSynthesis.cpp 2019-03-15 18:18:36 UTC (rev 243002)
@@ -70,7 +70,7 @@
SpeechSynthesis* DOMWindowSpeechSynthesis::speechSynthesis()
{
if (!m_speechSynthesis && frame())
- m_speechSynthesis = SpeechSynthesis::create();
+ m_speechSynthesis = SpeechSynthesis::create(makeWeakPtr(frame()->page()->speechSynthesisClient()));
return m_speechSynthesis.get();
}
Modified: trunk/Source/WebCore/Modules/speech/SpeechSynthesis.cpp (243001 => 243002)
--- trunk/Source/WebCore/Modules/speech/SpeechSynthesis.cpp 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/Modules/speech/SpeechSynthesis.cpp 2019-03-15 18:18:36 UTC (rev 243002)
@@ -38,18 +38,21 @@
namespace WebCore {
-Ref<SpeechSynthesis> SpeechSynthesis::create()
+Ref<SpeechSynthesis> SpeechSynthesis::create(WeakPtr<SpeechSynthesisClient> client)
{
- return adoptRef(*new SpeechSynthesis);
+ return adoptRef(*new SpeechSynthesis(client));
}
-SpeechSynthesis::SpeechSynthesis()
+SpeechSynthesis::SpeechSynthesis(WeakPtr<SpeechSynthesisClient> client)
: m_currentSpeechUtterance(nullptr)
, m_isPaused(false)
#if PLATFORM(IOS_FAMILY)
, m_restrictions(RequireUserGestureForSpeechStartRestriction)
#endif
+ , m_speechSynthesisClient(client)
{
+ if (m_speechSynthesisClient)
+ m_speechSynthesisClient->setObserver(makeWeakPtr(this));
}
void SpeechSynthesis::setPlatformSynthesizer(std::unique_ptr<PlatformSpeechSynthesizer> synthesizer)
@@ -59,6 +62,7 @@
m_currentSpeechUtterance = nullptr;
m_utteranceQueue.clear();
m_isPaused = false;
+ m_speechSynthesisClient = nullptr;
}
void SpeechSynthesis::voicesDidChange()
@@ -66,16 +70,20 @@
m_voiceList.clear();
}
+PlatformSpeechSynthesizer& SpeechSynthesis::ensurePlatformSpeechSynthesizer()
+{
+ if (!m_platformSpeechSynthesizer)
+ m_platformSpeechSynthesizer = std::make_unique<PlatformSpeechSynthesizer>(this);
+ return *m_platformSpeechSynthesizer;
+}
+
const Vector<Ref<SpeechSynthesisVoice>>& SpeechSynthesis::getVoices()
{
- if (m_voiceList.size())
+ if (!m_voiceList.isEmpty())
return m_voiceList;
- if (!m_platformSpeechSynthesizer)
- m_platformSpeechSynthesizer = std::make_unique<PlatformSpeechSynthesizer>(this);
-
// If the voiceList is empty, that's the cue to get the voices from the platform again.
- for (auto& voice : m_platformSpeechSynthesizer->voiceList())
+ for (auto& voice : m_speechSynthesisClient ? m_speechSynthesisClient->voiceList() : ensurePlatformSpeechSynthesizer().voiceList())
m_voiceList.append(SpeechSynthesisVoice::create(*voice));
return m_voiceList;
@@ -113,9 +121,10 @@
return;
}
- if (!m_platformSpeechSynthesizer)
- m_platformSpeechSynthesizer = std::make_unique<PlatformSpeechSynthesizer>(this);
- m_platformSpeechSynthesizer->speak(utterance.platformUtterance());
+ if (m_speechSynthesisClient)
+ m_speechSynthesisClient->speak(utterance.platformUtterance());
+ else
+ ensurePlatformSpeechSynthesizer().speak(utterance.platformUtterance());
}
void SpeechSynthesis::speak(SpeechSynthesisUtterance& utterance)
@@ -141,7 +150,9 @@
// Hold on to the current utterance so the platform synthesizer can have a chance to clean up.
RefPtr<SpeechSynthesisUtterance> current = m_currentSpeechUtterance;
m_utteranceQueue.clear();
- if (m_platformSpeechSynthesizer)
+ if (m_speechSynthesisClient)
+ m_speechSynthesisClient->cancel();
+ else if (m_platformSpeechSynthesizer)
m_platformSpeechSynthesizer->cancel();
current = nullptr;
@@ -151,14 +162,22 @@
void SpeechSynthesis::pause()
{
- if (!m_isPaused && m_platformSpeechSynthesizer)
- m_platformSpeechSynthesizer->pause();
+ if (!m_isPaused) {
+ if (m_speechSynthesisClient)
+ m_speechSynthesisClient->pause();
+ else if (m_platformSpeechSynthesizer)
+ m_platformSpeechSynthesizer->pause();
+ }
}
void SpeechSynthesis::resume()
{
- if (m_currentSpeechUtterance && m_platformSpeechSynthesizer)
- m_platformSpeechSynthesizer->resume();
+ if (m_currentSpeechUtterance) {
+ if (m_speechSynthesisClient)
+ m_speechSynthesisClient->resume();
+ else if (m_platformSpeechSynthesizer)
+ m_platformSpeechSynthesizer->resume();
+ }
}
void SpeechSynthesis::fireEvent(const AtomicString& type, SpeechSynthesisUtterance& utterance, unsigned long charIndex, const String& name)
@@ -193,10 +212,10 @@
ASSERT(utterance.client());
switch (boundary) {
- case SpeechWordBoundary:
+ case SpeechBoundary::SpeechWordBoundary:
fireEvent(eventNames().boundaryEvent, static_cast<SpeechSynthesisUtterance&>(*utterance.client()), charIndex, wordBoundaryString);
break;
- case SpeechSentenceBoundary:
+ case SpeechBoundary::SpeechSentenceBoundary:
fireEvent(eventNames().boundaryEvent, static_cast<SpeechSynthesisUtterance&>(*utterance.client()), charIndex, sentenceBoundaryString);
break;
default:
@@ -204,6 +223,41 @@
}
}
+void SpeechSynthesis::didStartSpeaking()
+{
+ didStartSpeaking(*m_currentSpeechUtterance->platformUtterance());
+}
+
+void SpeechSynthesis::didFinishSpeaking()
+{
+ didFinishSpeaking(*m_currentSpeechUtterance->platformUtterance());
+}
+
+void SpeechSynthesis::didPauseSpeaking()
+{
+ didPauseSpeaking(*m_currentSpeechUtterance->platformUtterance());
+}
+
+void SpeechSynthesis::didResumeSpeaking()
+{
+ didResumeSpeaking(*m_currentSpeechUtterance->platformUtterance());
+}
+
+void SpeechSynthesis::speakingErrorOccurred()
+{
+ speakingErrorOccurred(*m_currentSpeechUtterance->platformUtterance());
+}
+
+void SpeechSynthesis::boundaryEventOccurred(bool wordBoundary, unsigned charIndex)
+{
+ boundaryEventOccurred(*m_currentSpeechUtterance->platformUtterance(), wordBoundary ? SpeechBoundary::SpeechWordBoundary : SpeechBoundary::SpeechSentenceBoundary, charIndex);
+}
+
+void SpeechSynthesis::voicesChanged()
+{
+ voicesDidChange();
+}
+
void SpeechSynthesis::didStartSpeaking(PlatformSpeechSynthesisUtterance& utterance)
{
if (utterance.client())
Modified: trunk/Source/WebCore/Modules/speech/SpeechSynthesis.h (243001 => 243002)
--- trunk/Source/WebCore/Modules/speech/SpeechSynthesis.h 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/Modules/speech/SpeechSynthesis.h 2019-03-15 18:18:36 UTC (rev 243002)
@@ -29,6 +29,7 @@
#include "PlatformSpeechSynthesisUtterance.h"
#include "PlatformSpeechSynthesizer.h"
+#include "SpeechSynthesisClient.h"
#include "SpeechSynthesisUtterance.h"
#include "SpeechSynthesisVoice.h"
#include <wtf/Deque.h>
@@ -39,9 +40,9 @@
class PlatformSpeechSynthesizerClient;
class SpeechSynthesisVoice;
-class SpeechSynthesis : public PlatformSpeechSynthesizerClient, public RefCounted<SpeechSynthesis> {
+class SpeechSynthesis : public PlatformSpeechSynthesizerClient, public SpeechSynthesisClientObserver, public RefCounted<SpeechSynthesis> {
public:
- static Ref<SpeechSynthesis> create();
+ static Ref<SpeechSynthesis> create(WeakPtr<SpeechSynthesisClient>);
bool pending() const;
bool speaking() const;
@@ -58,7 +59,7 @@
WEBCORE_EXPORT void setPlatformSynthesizer(std::unique_ptr<PlatformSpeechSynthesizer>);
private:
- SpeechSynthesis();
+ SpeechSynthesis(WeakPtr<SpeechSynthesisClient>);
// PlatformSpeechSynthesizerClient override methods.
void voicesDidChange() override;
@@ -69,6 +70,15 @@
void speakingErrorOccurred(PlatformSpeechSynthesisUtterance&) override;
void boundaryEventOccurred(PlatformSpeechSynthesisUtterance&, SpeechBoundary, unsigned charIndex) override;
+ // SpeechSynthesisClient override methods
+ void didStartSpeaking() override;
+ void didFinishSpeaking() override;
+ void didPauseSpeaking() override;
+ void didResumeSpeaking() override;
+ void speakingErrorOccurred() override;
+ void boundaryEventOccurred(bool wordBoundary, unsigned charIndex) override;
+ void voicesChanged() override;
+
void startSpeakingImmediately(SpeechSynthesisUtterance&);
void handleSpeakingCompleted(SpeechSynthesisUtterance&, bool errorOccurred);
void fireEvent(const AtomicString& type, SpeechSynthesisUtterance&, unsigned long charIndex, const String& name);
@@ -84,6 +94,8 @@
bool userGestureRequiredForSpeechStart() const { return m_restrictions & RequireUserGestureForSpeechStartRestriction; }
void removeBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions &= ~restriction; }
#endif
+ PlatformSpeechSynthesizer& ensurePlatformSpeechSynthesizer();
+
std::unique_ptr<PlatformSpeechSynthesizer> m_platformSpeechSynthesizer;
Vector<Ref<SpeechSynthesisVoice>> m_voiceList;
SpeechSynthesisUtterance* m_currentSpeechUtterance;
@@ -92,6 +104,7 @@
#if PLATFORM(IOS_FAMILY)
BehaviorRestrictions m_restrictions;
#endif
+ WeakPtr<SpeechSynthesisClient> m_speechSynthesisClient;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (243001 => 243002)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2019-03-15 18:18:36 UTC (rev 243002)
@@ -711,9 +711,9 @@
2936BF5C21D69E4B004A8FC9 /* AccessibilityObjectInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 2936BF5A21D6999E004A8FC9 /* AccessibilityObjectInterface.h */; settings = {ATTRIBUTES = (Private, ); }; };
293EAE1F1356B2FE0067ACF9 /* RuntimeApplicationChecks.h in Headers */ = {isa = PBXBuildFile; fileRef = 293EAE1E1356B2FE0067ACF9 /* RuntimeApplicationChecks.h */; settings = {ATTRIBUTES = (Private, ); }; };
29489FC712C00F0300D83F0F /* AccessibilityScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 29489FC512C00F0300D83F0F /* AccessibilityScrollView.h */; };
- 297BE3D516C03C08003316BD /* PlatformSpeechSynthesisUtterance.h in Headers */ = {isa = PBXBuildFile; fileRef = 2527CC9116BF8BA1009DDAC0 /* PlatformSpeechSynthesisUtterance.h */; };
- 297BE3D616C03C0B003316BD /* PlatformSpeechSynthesisVoice.h in Headers */ = {isa = PBXBuildFile; fileRef = 2527CC9216BF90B4009DDAC0 /* PlatformSpeechSynthesisVoice.h */; };
- 297BE3D716C03C0E003316BD /* PlatformSpeechSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 29E4D8DF16B0940F00C84704 /* PlatformSpeechSynthesizer.h */; };
+ 297BE3D516C03C08003316BD /* PlatformSpeechSynthesisUtterance.h in Headers */ = {isa = PBXBuildFile; fileRef = 2527CC9116BF8BA1009DDAC0 /* PlatformSpeechSynthesisUtterance.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 297BE3D616C03C0B003316BD /* PlatformSpeechSynthesisVoice.h in Headers */ = {isa = PBXBuildFile; fileRef = 2527CC9216BF90B4009DDAC0 /* PlatformSpeechSynthesisVoice.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 297BE3D716C03C0E003316BD /* PlatformSpeechSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 29E4D8DF16B0940F00C84704 /* PlatformSpeechSynthesizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
29A8122B0FBB9C1D00510293 /* AccessibilityTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 29A8120D0FBB9C1D00510293 /* AccessibilityTable.h */; };
29A8122C0FBB9C1D00510293 /* AccessibilityList.h in Headers */ = {isa = PBXBuildFile; fileRef = 29A8120E0FBB9C1D00510293 /* AccessibilityList.h */; };
29A8122E0FBB9C1D00510293 /* AccessibilityARIAGridCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 29A812100FBB9C1D00510293 /* AccessibilityARIAGridCell.h */; };
@@ -4002,6 +4002,7 @@
C0F2A44113869AAB0066C534 /* preprocessor.pm in Headers */ = {isa = PBXBuildFile; fileRef = C0F2A43F13869A280066C534 /* preprocessor.pm */; settings = {ATTRIBUTES = (Private, ); }; };
C105DA640F3AA6B8001DD44F /* TextEncodingDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = C105DA630F3AA6B8001DD44F /* TextEncodingDetector.h */; };
C11A9ECE21403A5C00CFB20A /* SwitchingGPUClient.h in Headers */ = {isa = PBXBuildFile; fileRef = C11A9ECD21403A5C00CFB20A /* SwitchingGPUClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ C14938072234551A000CD707 /* SpeechSynthesisClient.h in Headers */ = {isa = PBXBuildFile; fileRef = C149380522342719000CD707 /* SpeechSynthesisClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
C1E1D236203DF15400584665 /* ScreenProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = C1E1D235203DF15400584665 /* ScreenProperties.h */; settings = {ATTRIBUTES = (Private, ); }; };
C2015C0A1BE6FEB200822389 /* FontVariantBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = C2015C091BE6FE2C00822389 /* FontVariantBuilder.h */; };
C21DF2EA1D9E4E9900F5B24C /* CSSFontVariationValue.h in Headers */ = {isa = PBXBuildFile; fileRef = C21DF2E81D9E4E9900F5B24C /* CSSFontVariationValue.h */; };
@@ -13351,6 +13352,7 @@
C105DA630F3AA6B8001DD44F /* TextEncodingDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextEncodingDetector.h; sourceTree = "<group>"; };
C11A9ECD21403A5C00CFB20A /* SwitchingGPUClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwitchingGPUClient.h; sourceTree = "<group>"; };
C11A9ED22140578B00CFB20A /* SwitchingGPUClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SwitchingGPUClient.cpp; sourceTree = "<group>"; };
+ C149380522342719000CD707 /* SpeechSynthesisClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SpeechSynthesisClient.h; sourceTree = "<group>"; };
C1E1D235203DF15400584665 /* ScreenProperties.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScreenProperties.h; sourceTree = "<group>"; };
C2015C091BE6FE2C00822389 /* FontVariantBuilder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontVariantBuilder.h; sourceTree = "<group>"; };
C20F4F6421DFBE5C0070C45A /* WHLSLTypeReference.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLTypeReference.cpp; sourceTree = "<group>"; };
@@ -20556,6 +20558,7 @@
5C7C88D71D0F1F2B009D2F6D /* SocketProvider.h */,
626CDE0C1140424C001E5A68 /* SpatialNavigation.cpp */,
626CDE0D1140424C001E5A68 /* SpatialNavigation.h */,
+ C149380522342719000CD707 /* SpeechSynthesisClient.h */,
62C1217A11AB9E76003C462C /* SuspendableTimer.cpp */,
62C1217B11AB9E77003C462C /* SuspendableTimer.h */,
2D4F96F11A1ECC240098BF88 /* TextIndicator.cpp */,
@@ -31709,6 +31712,7 @@
626CDE0F1140424C001E5A68 /* SpatialNavigation.h in Headers */,
657AFAFC20047A2900509464 /* SpectreGadget.h in Headers */,
AA2A5AD416A4861100975A25 /* SpeechSynthesis.h in Headers */,
+ C14938072234551A000CD707 /* SpeechSynthesisClient.h in Headers */,
AA2A5AD216A4860A00975A25 /* SpeechSynthesisEvent.h in Headers */,
AA2A5AD016A4860400975A25 /* SpeechSynthesisUtterance.h in Headers */,
AA2A5ACE16A485FD00975A25 /* SpeechSynthesisVoice.h in Headers */,
Modified: trunk/Source/WebCore/page/Page.cpp (243001 => 243002)
--- trunk/Source/WebCore/page/Page.cpp 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/page/Page.cpp 2019-03-15 18:18:36 UTC (rev 243002)
@@ -230,6 +230,9 @@
, m_diagnosticLoggingClient(WTFMove(pageConfiguration.diagnosticLoggingClient))
, m_performanceLoggingClient(WTFMove(pageConfiguration.performanceLoggingClient))
, m_webGLStateTracker(WTFMove(pageConfiguration.webGLStateTracker))
+#if ENABLE(SPEECH_SYNTHESIS)
+ , m_speechSynthesisClient(WTFMove(pageConfiguration.speechSynthesisClient))
+#endif
, m_libWebRTCProvider(WTFMove(pageConfiguration.libWebRTCProvider))
, m_verticalScrollElasticity(ScrollElasticityAllowed)
, m_horizontalScrollElasticity(ScrollElasticityAllowed)
Modified: trunk/Source/WebCore/page/Page.h (243001 => 243002)
--- trunk/Source/WebCore/page/Page.h 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/page/Page.h 2019-03-15 18:18:36 UTC (rev 243002)
@@ -145,6 +145,7 @@
class ActivityStateChangeObserver;
class VisitedLinkStore;
class WebGLStateTracker;
+class SpeechSynthesisClient;
class WheelEventDeltaFilter;
typedef uint64_t SharedStringHash;
@@ -682,6 +683,10 @@
WebGLStateTracker* webGLStateTracker() const { return m_webGLStateTracker.get(); }
+#if ENABLE(SPEECH_SYNTHESIS)
+ SpeechSynthesisClient* speechSynthesisClient() const { return m_speechSynthesisClient.get(); }
+#endif
+
bool isOnlyNonUtilityPage() const;
bool isUtilityPage() const { return m_isUtilityPage; }
@@ -778,6 +783,10 @@
std::unique_ptr<WebGLStateTracker> m_webGLStateTracker;
+#if ENABLE(SPEECH_SYNTHESIS)
+ std::unique_ptr<SpeechSynthesisClient> m_speechSynthesisClient;
+#endif
+
UniqueRef<LibWebRTCProvider> m_libWebRTCProvider;
RTCController m_rtcController;
Modified: trunk/Source/WebCore/page/PageConfiguration.cpp (243001 => 243002)
--- trunk/Source/WebCore/page/PageConfiguration.cpp 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/page/PageConfiguration.cpp 2019-03-15 18:18:36 UTC (rev 243002)
@@ -36,6 +36,7 @@
#include "PerformanceLoggingClient.h"
#include "PluginInfoProvider.h"
#include "SocketProvider.h"
+#include "SpeechSynthesisClient.h"
#include "StorageNamespaceProvider.h"
#include "UserContentController.h"
#include "ValidationMessageClient.h"
Modified: trunk/Source/WebCore/page/PageConfiguration.h (243001 => 243002)
--- trunk/Source/WebCore/page/PageConfiguration.h 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/page/PageConfiguration.h 2019-03-15 18:18:36 UTC (rev 243002)
@@ -62,6 +62,7 @@
class ValidationMessageClient;
class VisitedLinkStore;
class WebGLStateTracker;
+class SpeechSynthesisClient;
class PageConfiguration {
WTF_MAKE_NONCOPYABLE(PageConfiguration); WTF_MAKE_FAST_ALLOCATED;
@@ -102,6 +103,9 @@
std::unique_ptr<DiagnosticLoggingClient> diagnosticLoggingClient;
std::unique_ptr<PerformanceLoggingClient> performanceLoggingClient;
std::unique_ptr<WebGLStateTracker> webGLStateTracker;
+#if ENABLE(SPEECH_SYNTHESIS)
+ std::unique_ptr<SpeechSynthesisClient> speechSynthesisClient;
+#endif
RefPtr<ApplicationCacheStorage> applicationCacheStorage;
RefPtr<DatabaseProvider> databaseProvider;
Added: trunk/Source/WebCore/page/SpeechSynthesisClient.h (0 => 243002)
--- trunk/Source/WebCore/page/SpeechSynthesisClient.h (rev 0)
+++ trunk/Source/WebCore/page/SpeechSynthesisClient.h 2019-03-15 18:18:36 UTC (rev 243002)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 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 INC. 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 INC. 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.
+ */
+
+#pragma once
+
+#if ENABLE(SPEECH_SYNTHESIS)
+
+#include <wtf/WeakPtr.h>
+
+namespace WebCore {
+
+class PlatformSpeechSynthesisUtterance;
+class SpeechSynthesisClientObserver;
+class PlatformSpeechSynthesisVoice;
+
+class SpeechSynthesisClient : public CanMakeWeakPtr<SpeechSynthesisClient> {
+public:
+ virtual ~SpeechSynthesisClient() = default;
+
+ virtual void setObserver(WeakPtr<SpeechSynthesisClientObserver>) = 0;
+ virtual WeakPtr<SpeechSynthesisClientObserver> observer() const = 0;
+
+ virtual const Vector<RefPtr<PlatformSpeechSynthesisVoice>>& voiceList() = 0;
+ virtual void speak(RefPtr<PlatformSpeechSynthesisUtterance>) = 0;
+ virtual void cancel() = 0;
+ virtual void pause() = 0;
+ virtual void resume() = 0;
+
+};
+
+class SpeechSynthesisClientObserver : public CanMakeWeakPtr<SpeechSynthesisClientObserver> {
+public:
+ virtual ~SpeechSynthesisClientObserver() = default;
+
+ virtual void didStartSpeaking() = 0;
+ virtual void didFinishSpeaking() = 0;
+ virtual void didPauseSpeaking() = 0;
+ virtual void didResumeSpeaking() = 0;
+ virtual void speakingErrorOccurred() = 0;
+ virtual void boundaryEventOccurred(bool wordBoundary, unsigned charIndex) = 0;
+ virtual void voicesChanged() = 0;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SPEECH_SYNTHESIS)
Modified: trunk/Source/WebCore/platform/PlatformSpeechSynthesisUtterance.h (243001 => 243002)
--- trunk/Source/WebCore/platform/PlatformSpeechSynthesisUtterance.h 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/platform/PlatformSpeechSynthesisUtterance.h 2019-03-15 18:18:36 UTC (rev 243002)
@@ -37,7 +37,7 @@
class PlatformSpeechSynthesisUtterance : public RefCounted<PlatformSpeechSynthesisUtterance> {
public:
- static Ref<PlatformSpeechSynthesisUtterance> create(PlatformSpeechSynthesisUtteranceClient&);
+ WEBCORE_EXPORT static Ref<PlatformSpeechSynthesisUtterance> create(PlatformSpeechSynthesisUtteranceClient&);
const String& text() const { return m_text; }
void setText(const String& text) { m_text = text; }
Modified: trunk/Source/WebCore/platform/PlatformSpeechSynthesizer.h (243001 => 243002)
--- trunk/Source/WebCore/platform/PlatformSpeechSynthesizer.h 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/platform/PlatformSpeechSynthesizer.h 2019-03-15 18:18:36 UTC (rev 243002)
@@ -38,7 +38,7 @@
namespace WebCore {
-enum SpeechBoundary {
+enum class SpeechBoundary : uint8_t {
SpeechWordBoundary,
SpeechSentenceBoundary
};
Modified: trunk/Source/WebCore/platform/ios/PlatformSpeechSynthesizerIOS.mm (243001 => 243002)
--- trunk/Source/WebCore/platform/ios/PlatformSpeechSynthesizerIOS.mm 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/platform/ios/PlatformSpeechSynthesizerIOS.mm 2019-03-15 18:18:36 UTC (rev 243002)
@@ -225,7 +225,7 @@
return;
// iOS only supports word boundaries.
- m_synthesizerObject->client()->boundaryEventOccurred(*m_utterance, WebCore::SpeechWordBoundary, characterRange.location);
+ m_synthesizerObject->client()->boundaryEventOccurred(*m_utterance, WebCore::SpeechBoundary::SpeechWordBoundary, characterRange.location);
}
@end
Modified: trunk/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm (243001 => 243002)
--- trunk/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm 2019-03-15 18:18:36 UTC (rev 243002)
@@ -197,7 +197,7 @@
return;
// Mac platform only supports word boundaries.
- m_synthesizerObject->client()->boundaryEventOccurred(*m_utterance, WebCore::SpeechWordBoundary, characterRange.location);
+ m_synthesizerObject->client()->boundaryEventOccurred(*m_utterance, WebCore::SpeechBoundary::SpeechWordBoundary, characterRange.location);
}
@end
Modified: trunk/Source/WebCore/platform/mock/PlatformSpeechSynthesizerMock.cpp (243001 => 243002)
--- trunk/Source/WebCore/platform/mock/PlatformSpeechSynthesizerMock.cpp 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebCore/platform/mock/PlatformSpeechSynthesizerMock.cpp 2019-03-15 18:18:36 UTC (rev 243002)
@@ -62,8 +62,8 @@
client()->didStartSpeaking(*m_utterance);
// Fire a fake word and then sentence boundary event.
- client()->boundaryEventOccurred(*m_utterance, SpeechWordBoundary, 0);
- client()->boundaryEventOccurred(*m_utterance, SpeechSentenceBoundary, m_utterance->text().length());
+ client()->boundaryEventOccurred(*m_utterance, SpeechBoundary::SpeechWordBoundary, 0);
+ client()->boundaryEventOccurred(*m_utterance, SpeechBoundary::SpeechSentenceBoundary, m_utterance->text().length());
// Give the fake speech job some time so that pause and other functions have time to be called.
m_speakingFinishedTimer.startOneShot(100_ms);
Modified: trunk/Source/WebKit/ChangeLog (243001 => 243002)
--- trunk/Source/WebKit/ChangeLog 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/ChangeLog 2019-03-15 18:18:36 UTC (rev 243002)
@@ -1,3 +1,59 @@
+2019-03-15 Per Arne Vollan <[email protected]>
+
+ [macOS] Broker access to Speech Synthesis
+ https://bugs.webkit.org/show_bug.cgi?id=195645
+ <rdar://problem/35369026>
+
+ Reviewed by Brent Fulgham.
+
+ To be able to close the connection to the speech synthesis daemon in the WebContent process,
+ speech synthesis should be performed in the UI process. This patch forwards speech synthesis
+ requests to the UI process by sending messages. On the UI process side, the speech synthesis
+ is performed by simply using the existing platform speech synthesizer. Speech synthesis
+ events are sent back to the WebContent process. All messages are async, except for the
+ message to get the list of available voices.
+
+ * Sources.txt:
+ * UIProcess/Cocoa/WebPageProxyCocoa.mm:
+ (WebKit::WebPageProxy::didStartSpeaking):
+ (WebKit::WebPageProxy::didFinishSpeaking):
+ (WebKit::WebPageProxy::didPauseSpeaking):
+ (WebKit::WebPageProxy::didResumeSpeaking):
+ (WebKit::WebPageProxy::speakingErrorOccurred):
+ (WebKit::WebPageProxy::boundaryEventOccurred):
+ (WebKit::WebPageProxy::voicesDidChange):
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::ensureSpeechSynthesisData):
+ (WebKit::WebPageProxy::speechSynthesisVoiceList):
+ (WebKit::WebPageProxy::speechSynthesisSpeak):
+ (WebKit::WebPageProxy::speechSynthesisCancel):
+ (WebKit::WebPageProxy::speechSynthesisPause):
+ (WebKit::WebPageProxy::speechSynthesisResume):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.messages.in:
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/WebCoreSupport/WebSpeechSynthesisClient.cpp: Added.
+ (WebKit::WebSpeechSynthesisClient::voiceList):
+ (WebKit::WebSpeechSynthesisClient::speak):
+ (WebKit::WebSpeechSynthesisClient::cancel):
+ (WebKit::WebSpeechSynthesisClient::pause):
+ (WebKit::WebSpeechSynthesisClient::resume):
+ * WebProcess/WebCoreSupport/WebSpeechSynthesisClient.h: Added.
+ (WebKit::WebSpeechSynthesisClient::WebSpeechSynthesisClient):
+ (WebKit::WebSpeechSynthesisClient::~WebSpeechSynthesisClient):
+ * WebProcess/WebCoreSupport/WebSpeechSynthesisVoice.h: Added.
+ (WebKit::WebSpeechSynthesisVoice::encode const):
+ (WebKit::WebSpeechSynthesisVoice::decode):
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::m_hostFileDescriptor):
+ (WebKit::WebPage::speakingErrorOccurred):
+ (WebKit::WebPage::boundaryEventOccurred):
+ (WebKit::WebPage::voicesDidChange):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+ * WebProcess/com.apple.WebProcess.sb.in:
+ * WebProcess/glib/WebProcessGLib.cpp:
+
2019-03-15 Antti Koivisto <[email protected]>
Optimize Region for single rectangle case
Modified: trunk/Source/WebKit/Sources.txt (243001 => 243002)
--- trunk/Source/WebKit/Sources.txt 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/Sources.txt 2019-03-15 18:18:36 UTC (rev 243002)
@@ -540,6 +540,7 @@
WebProcess/WebCoreSupport/WebProgressTrackerClient.cpp
WebProcess/WebCoreSupport/WebSearchPopupMenu.cpp
WebProcess/WebCoreSupport/WebUserMediaClient.cpp
+WebProcess/WebCoreSupport/WebSpeechSynthesisClient.cpp
WebProcess/WebPage/DrawingArea.cpp
WebProcess/WebPage/EventDispatcher.cpp
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm (243001 => 243002)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm 2019-03-15 18:18:36 UTC (rev 243002)
@@ -244,4 +244,40 @@
#endif
+#if ENABLE(SPEECH_SYNTHESIS)
+void WebPageProxy::didStartSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
+{
+}
+
+void WebPageProxy::didFinishSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
+{
+ m_speechSynthesisData->speakingFinishedCompletionHandler();
+}
+
+void WebPageProxy::didPauseSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
+{
+ m_speechSynthesisData->speakingPausedCompletionHandler();
+}
+
+void WebPageProxy::didResumeSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
+{
+ m_speechSynthesisData->speakingResumedCompletionHandler();
+}
+
+void WebPageProxy::speakingErrorOccurred(WebCore::PlatformSpeechSynthesisUtterance&)
+{
+ process().send(Messages::WebPage::SpeakingErrorOccurred(), m_pageID);
+}
+
+void WebPageProxy::boundaryEventOccurred(WebCore::PlatformSpeechSynthesisUtterance&, WebCore::SpeechBoundary speechBoundary, unsigned charIndex)
+{
+ process().send(Messages::WebPage::BoundaryEventOccurred(speechBoundary == WebCore::SpeechBoundary::SpeechWordBoundary, charIndex), m_pageID);
+}
+
+void WebPageProxy::voicesDidChange()
+{
+ process().send(Messages::WebPage::VoicesDidChange(), m_pageID);
+}
+#endif // ENABLE(SPEECH_SYNTHESIS)
+
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (243001 => 243002)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2019-03-15 18:18:36 UTC (rev 243002)
@@ -8812,6 +8812,57 @@
m_process->processPool().clearAdClickAttribution(m_websiteDataStore->sessionID(), WTFMove(completionHandler));
}
+#if ENABLE(SPEECH_SYNTHESIS)
+WebPageProxy::SpeechSynthesisData& WebPageProxy::speechSynthesisData()
+{
+ if (!m_speechSynthesisData)
+ m_speechSynthesisData = SpeechSynthesisData { std::make_unique<PlatformSpeechSynthesizer>(this), nullptr, nullptr, nullptr, nullptr };
+ return *m_speechSynthesisData;
+}
+
+void WebPageProxy::speechSynthesisVoiceList(Vector<WebSpeechSynthesisVoice>& result)
+{
+ auto& voiceList = speechSynthesisData().synthesizer->voiceList();
+ for (auto& voice : voiceList) {
+ WebSpeechSynthesisVoice v { voice->voiceURI(), voice->name(), voice->lang(), voice->localService(), voice->isDefault() };
+ result.append(WTFMove(v));
+ }
+}
+
+void WebPageProxy::speechSynthesisSpeak(const String& text, const String& lang, float volume, float rate, float pitch, MonotonicTime startTime, const String& voiceURI, const String& voiceName, const String& voiceLang, bool localService, bool defaultVoice, CompletionHandler<void()>&& completionHandler)
+{
+ auto voice = WebCore::PlatformSpeechSynthesisVoice::create(voiceURI, voiceName, voiceLang, localService, defaultVoice);
+ auto utterance = WebCore::PlatformSpeechSynthesisUtterance::create(*this);
+ utterance->setText(text);
+ utterance->setLang(lang);
+ utterance->setVolume(volume);
+ utterance->setRate(rate);
+ utterance->setPitch(pitch);
+ utterance->setVoice(&voice.get());
+
+ speechSynthesisData().utterance = WTFMove(utterance);
+ speechSynthesisData().speakingFinishedCompletionHandler = WTFMove(completionHandler);
+ speechSynthesisData().synthesizer->speak(m_speechSynthesisData->utterance.get());
+}
+
+void WebPageProxy::speechSynthesisCancel()
+{
+ speechSynthesisData().synthesizer->cancel();
+}
+
+void WebPageProxy::speechSynthesisPause(CompletionHandler<void()>&& completionHandler)
+{
+ speechSynthesisData().speakingPausedCompletionHandler = WTFMove(completionHandler);
+ speechSynthesisData().synthesizer->pause();
+}
+
+void WebPageProxy::speechSynthesisResume(CompletionHandler<void()>&& completionHandler)
+{
+ speechSynthesisData().speakingResumedCompletionHandler = WTFMove(completionHandler);
+ speechSynthesisData().synthesizer->resume();
+}
+#endif // ENABLE(SPEECH_SYNTHESIS)
+
void WebPageProxy::addObserver(WebViewDidMoveToWindowObserver& observer)
{
auto result = m_webViewDidMoveToWindowObservers.add(&observer, makeWeakPtr(observer));
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (243001 => 243002)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2019-03-15 18:18:36 UTC (rev 243002)
@@ -82,6 +82,8 @@
#include <WebCore/MediaProducer.h>
#include <WebCore/PlatformEvent.h>
#include <WebCore/PlatformScreen.h>
+#include <WebCore/PlatformSpeechSynthesisUtterance.h>
+#include <WebCore/PlatformSpeechSynthesizer.h>
#include <WebCore/PointerID.h>
#include <WebCore/RegistrableDomain.h>
#include <WebCore/ScrollTypes.h>
@@ -361,6 +363,10 @@
, public WebPopupMenuProxy::Client
, public IPC::MessageReceiver
, public IPC::MessageSender
+#if ENABLE(SPEECH_SYNTHESIS)
+ , public WebCore::PlatformSpeechSynthesisUtteranceClient
+ , public WebCore::PlatformSpeechSynthesizerClient
+#endif
, public CanMakeWeakPtr<WebPageProxy> {
public:
static Ref<WebPageProxy> create(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&);
@@ -1485,6 +1491,14 @@
void dumpAdClickAttribution(CompletionHandler<void(const String&)>&&);
void clearAdClickAttribution(CompletionHandler<void()>&&);
+#if ENABLE(SPEECH_SYNTHESIS)
+ void speechSynthesisVoiceList(Vector<WebSpeechSynthesisVoice>& result);
+ void speechSynthesisSpeak(const String&, const String&, float volume, float rate, float pitch, MonotonicTime startTime, const String& voiceURI, const String& voiceName, const String& voiceLang, bool localService, bool defaultVoice, CompletionHandler<void()>&&);
+ void speechSynthesisCancel();
+ void speechSynthesisPause(CompletionHandler<void()>&&);
+ void speechSynthesisResume(CompletionHandler<void()>&&);
+#endif
+
void addObserver(WebViewDidMoveToWindowObserver&);
void removeObserver(WebViewDidMoveToWindowObserver&);
void webViewDidMoveToWindow();
@@ -2013,6 +2027,19 @@
NSWindow *paymentCoordinatorPresentingWindow(const WebPaymentCoordinatorProxy&) final;
#endif
+#if ENABLE(SPEECH_SYNTHESIS)
+ void didStartSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) override;
+ void didFinishSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) override;
+ void didPauseSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) override;
+ void didResumeSpeaking(WebCore::PlatformSpeechSynthesisUtterance&) override;
+ void speakingErrorOccurred(WebCore::PlatformSpeechSynthesisUtterance&) override;
+ void boundaryEventOccurred(WebCore::PlatformSpeechSynthesisUtterance&, WebCore::SpeechBoundary, unsigned charIndex) override;
+ void voicesDidChange() override;
+
+ struct SpeechSynthesisData;
+ SpeechSynthesisData& speechSynthesisData();
+#endif
+
WeakPtr<PageClient> m_pageClient;
Ref<API::PageConfiguration> m_configuration;
@@ -2432,6 +2459,17 @@
#endif
HashMap<WebViewDidMoveToWindowObserver*, WeakPtr<WebViewDidMoveToWindowObserver>> m_webViewDidMoveToWindowObservers;
+
+#if ENABLE(SPEECH_SYNTHESIS)
+ struct SpeechSynthesisData {
+ std::unique_ptr<WebCore::PlatformSpeechSynthesizer> synthesizer;
+ RefPtr<WebCore::PlatformSpeechSynthesisUtterance> utterance;
+ CompletionHandler<void()> speakingFinishedCompletionHandler;
+ CompletionHandler<void()> speakingPausedCompletionHandler;
+ CompletionHandler<void()> speakingResumedCompletionHandler;
+ };
+ Optional<SpeechSynthesisData> m_speechSynthesisData;
+#endif
};
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (243001 => 243002)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2019-03-15 18:18:36 UTC (rev 243002)
@@ -551,4 +551,11 @@
SignedPublicKeyAndChallengeString(unsigned keySizeIndex, String challengeString, URL url) -> (String result) LegacySync
+#if ENABLE(SPEECH_SYNTHESIS)
+ SpeechSynthesisVoiceList() -> (Vector<WebKit::WebSpeechSynthesisVoice> voiceList) LegacySync
+ SpeechSynthesisSpeak(String text, String lang, float volume, float rate, float pitch, MonotonicTime startTime, String voiceURI, String voiceName, String voiceLang, bool localService, bool defaultVoice) -> () Async
+ SpeechSynthesisCancel()
+ SpeechSynthesisPause() -> () Async
+ SpeechSynthesisResume() -> () Async
+#endif
}
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (243001 => 243002)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-03-15 18:18:36 UTC (rev 243002)
@@ -1531,6 +1531,7 @@
C0E3AA7C1209E83C00A49D01 /* Module.h in Headers */ = {isa = PBXBuildFile; fileRef = C0E3AA441209E2BA00A49D01 /* Module.h */; };
C11A9ECC214035F800CFB20A /* WebSwitchingGPUClient.h in Headers */ = {isa = PBXBuildFile; fileRef = C11A9ECB214035F800CFB20A /* WebSwitchingGPUClient.h */; };
C11E1694212B87C500985FF6 /* WKMockDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = C11E1692212B87C500985FF6 /* WKMockDisplay.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ C149380922347104000CD707 /* WebSpeechSynthesisClient.h in Headers */ = {isa = PBXBuildFile; fileRef = C149380222341C60000CD707 /* WebSpeechSynthesisClient.h */; };
C18173612058424700DFDA65 /* DisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = C18173602058424700DFDA65 /* DisplayLink.h */; };
C1E123BA20A11573002646F4 /* PDFContextMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = C1E123B920A11572002646F4 /* PDFContextMenu.h */; };
C517388112DF8F4F00EE3F47 /* DragControllerAction.h in Headers */ = {isa = PBXBuildFile; fileRef = C517388012DF8F4F00EE3F47 /* DragControllerAction.h */; };
@@ -4347,6 +4348,9 @@
C11A9ED021403B4000CFB20A /* WebSwitchingGPUClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebSwitchingGPUClient.cpp; sourceTree = "<group>"; };
C11E1692212B87C500985FF6 /* WKMockDisplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKMockDisplay.h; sourceTree = "<group>"; };
C11E1693212B87C500985FF6 /* WKMockDisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKMockDisplay.cpp; sourceTree = "<group>"; };
+ C149380222341C60000CD707 /* WebSpeechSynthesisClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebSpeechSynthesisClient.h; sourceTree = "<group>"; };
+ C149380322341DF7000CD707 /* WebSpeechSynthesisClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebSpeechSynthesisClient.cpp; sourceTree = "<group>"; };
+ C149380A223853BE000CD707 /* WebSpeechSynthesisVoice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebSpeechSynthesisVoice.h; sourceTree = "<group>"; };
C181735E205839F600DFDA65 /* DrawingAreaMac.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DrawingAreaMac.cpp; sourceTree = "<group>"; };
C18173602058424700DFDA65 /* DisplayLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayLink.h; sourceTree = "<group>"; };
C1817362205844A900DFDA65 /* DisplayLink.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayLink.cpp; sourceTree = "<group>"; };
@@ -7297,6 +7301,9 @@
1A1E093218861D3800D2DC49 /* WebProgressTrackerClient.h */,
D3B9484411FF4B6500032B39 /* WebSearchPopupMenu.cpp */,
D3B9484511FF4B6500032B39 /* WebSearchPopupMenu.h */,
+ C149380322341DF7000CD707 /* WebSpeechSynthesisClient.cpp */,
+ C149380222341C60000CD707 /* WebSpeechSynthesisClient.h */,
+ C149380A223853BE000CD707 /* WebSpeechSynthesisVoice.h */,
4A410F4819AF7B80002EBAB5 /* WebUserMediaClient.cpp */,
4A410F4919AF7B80002EBAB5 /* WebUserMediaClient.h */,
83EE57591DB7D60600C74C50 /* WebValidationMessageClient.cpp */,
@@ -9645,6 +9652,7 @@
1A53C2AA1A325730004E8C70 /* WebsiteDataStore.h in Headers */,
511F7D411EB1BCF500E47B83 /* WebsiteDataStoreParameters.h in Headers */,
0EDE85032004E75D00030560 /* WebsitePopUpPolicy.h in Headers */,
+ C149380922347104000CD707 /* WebSpeechSynthesisClient.h in Headers */,
836034A01ACB34D600626549 /* WebSQLiteDatabaseTracker.h in Headers */,
1A52C0F81A38CDC70016160A /* WebStorageNamespaceProvider.h in Headers */,
9356F2DC2152B6B500E6D5DF /* WebSWClientConnection.h in Headers */,
Added: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebSpeechSynthesisClient.cpp (0 => 243002)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebSpeechSynthesisClient.cpp (rev 0)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebSpeechSynthesisClient.cpp 2019-03-15 18:18:36 UTC (rev 243002)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2019 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 INC. ``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 INC. OR
+ * 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 "WebSpeechSynthesisClient.h"
+
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include "WebSpeechSynthesisVoice.h"
+
+#if ENABLE(SPEECH_SYNTHESIS)
+
+namespace WebKit {
+
+const Vector<RefPtr<WebCore::PlatformSpeechSynthesisVoice>>& WebSpeechSynthesisClient::voiceList()
+{
+ // FIXME: this message should not be sent synchronously. Instead, the UI process should
+ // get the list of voices and pass it on to the WebContent processes, see
+ // https://bugs.webkit.org/show_bug.cgi?id=195723
+ Vector<WebSpeechSynthesisVoice> voiceList;
+ m_page.sendSync(Messages::WebPageProxy::SpeechSynthesisVoiceList(), voiceList);
+
+ m_voices.clear();
+ for (auto& voice : voiceList) {
+ m_voices.append(WebCore::PlatformSpeechSynthesisVoice::create(voice.voiceURI, voice.name, voice.lang, voice.localService, voice.defaultLang));
+
+ }
+ return m_voices;
+}
+
+void WebSpeechSynthesisClient::speak(RefPtr<WebCore::PlatformSpeechSynthesisUtterance> utterance)
+{
+ WTF::CompletionHandler<void()> completionHandler = [this, weakThis = makeWeakPtr(*this)]() mutable {
+ if (weakThis)
+ m_page.corePage()->speechSynthesisClient()->observer()->didFinishSpeaking();
+ };
+
+ auto voice = utterance->voice();
+ m_page.sendWithAsyncReply(Messages::WebPageProxy::SpeechSynthesisSpeak(utterance->text(), utterance->lang(), utterance->volume(), utterance->rate(), utterance->pitch(), utterance->startTime(), voice->voiceURI(), voice->name(), voice->lang(), voice->localService(), voice->isDefault()), WTFMove(completionHandler));
+
+ m_page.corePage()->speechSynthesisClient()->observer()->didStartSpeaking();
+}
+
+void WebSpeechSynthesisClient::cancel()
+{
+ m_page.send(Messages::WebPageProxy::SpeechSynthesisCancel());
+}
+
+void WebSpeechSynthesisClient::pause()
+{
+ WTF::CompletionHandler<void()> completionHandler = [this, weakThis = makeWeakPtr(*this)]() mutable {
+ if (weakThis)
+ m_page.corePage()->speechSynthesisClient()->observer()->didPauseSpeaking();
+ };
+
+ m_page.sendWithAsyncReply(Messages::WebPageProxy::SpeechSynthesisPause(), WTFMove(completionHandler));
+}
+
+void WebSpeechSynthesisClient::resume()
+{
+ WTF::CompletionHandler<void()> completionHandler = [this, weakThis = makeWeakPtr(*this)]() mutable {
+ if (weakThis)
+ m_page.corePage()->speechSynthesisClient()->observer()->didResumeSpeaking();
+ };
+
+ m_page.sendWithAsyncReply(Messages::WebPageProxy::SpeechSynthesisResume(), WTFMove(completionHandler));
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(SPEECH_SYNTHESIS)
Added: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebSpeechSynthesisClient.h (0 => 243002)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebSpeechSynthesisClient.h (rev 0)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebSpeechSynthesisClient.h 2019-03-15 18:18:36 UTC (rev 243002)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 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 INC. ``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 INC. OR
+ * 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.
+ */
+
+#pragma once
+
+#if ENABLE(SPEECH_SYNTHESIS)
+
+#include <WebCore/PlatformSpeechSynthesisUtterance.h>
+#include <WebCore/PlatformSpeechSynthesisVoice.h>
+#include <WebCore/SpeechSynthesisClient.h>
+
+namespace WebKit {
+
+class WebPage;
+
+class WebSpeechSynthesisClient : public WebCore::SpeechSynthesisClient {
+public:
+ WebSpeechSynthesisClient(WebPage& page)
+ : m_page(page)
+ {
+ }
+
+ virtual ~WebSpeechSynthesisClient() { }
+
+ const Vector<RefPtr<WebCore::PlatformSpeechSynthesisVoice>>& voiceList() override;
+ void speak(RefPtr<WebCore::PlatformSpeechSynthesisUtterance>) override;
+ void cancel() override;
+ void pause() override;
+ void resume() override;
+
+ void setObserver(WeakPtr<WebCore::SpeechSynthesisClientObserver> observer) override { m_observer = observer; }
+ WeakPtr<WebCore::SpeechSynthesisClientObserver> observer() const override { return m_observer; }
+
+
+private:
+ WebPage& m_page;
+ WeakPtr<WebCore::SpeechSynthesisClientObserver> m_observer;
+ Vector<RefPtr<WebCore::PlatformSpeechSynthesisVoice>> m_voices;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(SPEECH_SYNTHESIS)
Added: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebSpeechSynthesisVoice.h (0 => 243002)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebSpeechSynthesisVoice.h (rev 0)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebSpeechSynthesisVoice.h 2019-03-15 18:18:36 UTC (rev 243002)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 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 INC. ``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 INC. OR
+ * 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.
+ */
+
+#pragma once
+
+#if ENABLE(SPEECH_SYNTHESIS)
+
+namespace WebKit {
+
+struct WebSpeechSynthesisVoice {
+ String voiceURI;
+ String name;
+ String lang;
+ bool localService { false };
+ bool defaultLang { false };
+
+ template<class Encoder> void encode(Encoder&) const;
+ template<class Decoder> static Optional<WebSpeechSynthesisVoice> decode(Decoder&);
+};
+
+template<class Encoder>
+void WebSpeechSynthesisVoice::encode(Encoder& encoder) const
+{
+ encoder << voiceURI
+ << name
+ << lang
+ << localService
+ << defaultLang;
+}
+
+template<class Decoder>
+Optional<WebSpeechSynthesisVoice> WebSpeechSynthesisVoice::decode(Decoder& decoder)
+{
+ Optional<String> voiceURI;
+ decoder >> voiceURI;
+ if (!voiceURI)
+ return WTF::nullopt;
+
+ Optional<String> name;
+ decoder >> name;
+ if (!name)
+ return WTF::nullopt;
+
+ Optional<String> lang;
+ decoder >> lang;
+ if (!lang)
+ return WTF::nullopt;
+
+ Optional<bool> localService;
+ decoder >> localService;
+ if (!localService)
+ return WTF::nullopt;
+
+ Optional<bool> defaultLang;
+ decoder >> defaultLang;
+ if (!defaultLang)
+ return WTF::nullopt;
+
+ return {{ WTFMove(*voiceURI), WTFMove(*name), WTFMove(*lang), WTFMove(*localService), WTFMove(*defaultLang) }};}
+
+} // namespace WebKit
+
+#endif // ENABLE(SPEECH_SYNTHESIS)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (243001 => 243002)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2019-03-15 18:18:36 UTC (rev 243002)
@@ -120,6 +120,7 @@
#include "WebProcessProxyMessages.h"
#include "WebProgressTrackerClient.h"
#include "WebSocketProvider.h"
+#include "WebSpeechSynthesisClient.h"
#include "WebStorageNamespaceProvider.h"
#include "WebURLSchemeHandlerProxy.h"
#include "WebUndoStep.h"
@@ -452,6 +453,10 @@
send(Messages::WebPageProxy::SetIsUsingHighPerformanceWebGL(isUsingHighPerformanceWebGL));
});
+#if ENABLE(SPEECH_SYNTHESIS)
+ pageConfiguration.speechSynthesisClient = std::make_unique<WebSpeechSynthesisClient>(*this);
+#endif
+
#if PLATFORM(COCOA)
pageConfiguration.validationMessageClient = std::make_unique<WebValidationMessageClient>(*this);
#endif
@@ -6406,6 +6411,23 @@
#endif
}
+#if ENABLE(SPEECH_SYNTHESIS)
+void WebPage::speakingErrorOccurred()
+{
+ corePage()->speechSynthesisClient()->observer()->speakingErrorOccurred();
+}
+
+void WebPage::boundaryEventOccurred(bool wordBoundary, unsigned charIndex)
+{
+ corePage()->speechSynthesisClient()->observer()->boundaryEventOccurred(wordBoundary, charIndex);
+}
+
+void WebPage::voicesDidChange()
+{
+ corePage()->speechSynthesisClient()->observer()->voicesChanged();
+}
+#endif
+
#if ENABLE(ATTACHMENT_ELEMENT)
void WebPage::insertAttachment(const String& identifier, Optional<uint64_t>&& fileSize, const String& fileName, const String& contentType, CallbackID callbackID)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (243001 => 243002)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2019-03-15 18:18:36 UTC (rev 243002)
@@ -1504,6 +1504,12 @@
void simulateDeviceOrientationChange(double alpha, double beta, double gamma);
+#if ENABLE(SPEECH_SYNTHESIS)
+ void speakingErrorOccurred();
+ void boundaryEventOccurred(bool wordBoundary, unsigned charIndex);
+ void voicesDidChange();
+#endif
+
void frameBecameRemote(uint64_t frameID, WebCore::GlobalFrameIdentifier&& remoteFrameIdentifier, WebCore::GlobalWindowIdentifier&& remoteWindowIdentifier);
void registerURLSchemeHandler(uint64_t identifier, const String& scheme);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (243001 => 243002)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2019-03-15 18:18:36 UTC (rev 243002)
@@ -549,6 +549,12 @@
UpdateCurrentModifierState(OptionSet<WebCore::PlatformEvent::Modifier> modifiers)
SimulateDeviceOrientationChange(double alpha, double beta, double gamma)
+#if ENABLE(SPEECH_SYNTHESIS)
+ SpeakingErrorOccurred()
+ BoundaryEventOccurred(bool wordBoundary, unsigned charIndex)
+ VoicesDidChange()
+#endif
+
TextInputContextsInRect(WebCore::FloatRect rect) -> (Vector<struct WebKit::TextInputContext> contexts) Async
FocusTextInputContext(struct WebKit::TextInputContext context) -> (bool success) Async
}
Modified: trunk/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in (243001 => 243002)
--- trunk/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in 2019-03-15 18:18:36 UTC (rev 243002)
@@ -603,7 +603,6 @@
(global-name "com.apple.lsd.mapdb")
(global-name "com.apple.mobileassetd")
(global-name "com.apple.powerlog.plxpclogger.xpc")
- (global-name "com.apple.speech.speechsynthesisd")
(global-name "com.apple.system.logger")
(global-name "com.apple.tccd")
(global-name "com.apple.tccd.system")
Modified: trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp (243001 => 243002)
--- trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp 2019-03-15 18:07:32 UTC (rev 243001)
+++ trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp 2019-03-15 18:18:36 UTC (rev 243002)
@@ -42,6 +42,8 @@
namespace WebKit {
+using namespace WebCore;
+
void WebProcess::platformSetCacheModel(CacheModel cacheModel)
{
WebCore::MemoryCache::singleton().setDisabled(cacheModel == CacheModel::DocumentViewer);