Changeset 247755 in webkit


Ignore:
Timestamp:
Jul 23, 2019 4:24:58 PM (5 years ago)
Author:
Chris Fleizach
Message:

AX: CrashTracer: com.apple.WebKit.WebContent at WebKit: WebKit::WebSpeechSynthesisClient::speak
https://bugs.webkit.org/show_bug.cgi?id=199988

Reviewed by Per Arne Vollan.

Source/WebCore:

Implement the reset state to cancel current speech jobs.

  • Modules/speech/SpeechSynthesis.cpp:

(WebCore::SpeechSynthesis::startSpeakingImmediately):
(WebCore::SpeechSynthesis::cancel):

  • platform/PlatformSpeechSynthesizer.h:
  • platform/ios/PlatformSpeechSynthesizerIOS.mm:

(WebCore::PlatformSpeechSynthesizer::resetState):

  • platform/mac/PlatformSpeechSynthesizerMac.mm:

(WebCore::PlatformSpeechSynthesizer::resetState):

Source/WebKit:

Improvements to WebSpeechSynthesis to avoid crashing and improve correctness.

  • Reset and cancel speech jobs on page close or reload (otherwise the synthesizer keeps talking after your page is gone)
  • Have a separate speech finish callback mechanism, use the start speaking callback when the synthesizer tells us.
  • Move an assert on utterance state to only apply when we use the in process synthesizer.
  • UIProcess/Cocoa/WebPageProxyCocoa.mm:

(WebKit::WebPageProxy::didStartSpeaking):

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::reload):
(WebKit::WebPageProxy::resetState):
(WebKit::WebPageProxy::resetSpeechSynthesizer):
(WebKit::WebPageProxy::speechSynthesisSetFinishedCallback):
(WebKit::WebPageProxy::speechSynthesisSpeak):

  • UIProcess/WebPageProxy.h:
  • UIProcess/WebPageProxy.messages.in:
  • WebProcess/WebCoreSupport/WebSpeechSynthesisClient.cpp:

(WebKit::WebSpeechSynthesisClient::speak):

Location:
trunk/Source
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r247746 r247755  
     12019-07-23  Chris Fleizach  <cfleizach@apple.com>
     2
     3        AX: CrashTracer: com.apple.WebKit.WebContent at WebKit: WebKit::WebSpeechSynthesisClient::speak
     4        https://bugs.webkit.org/show_bug.cgi?id=199988
     5
     6        Reviewed by Per Arne Vollan.
     7
     8        Implement the reset state to cancel current speech jobs.
     9
     10        * Modules/speech/SpeechSynthesis.cpp:
     11        (WebCore::SpeechSynthesis::startSpeakingImmediately):
     12        (WebCore::SpeechSynthesis::cancel):
     13        * platform/PlatformSpeechSynthesizer.h:
     14        * platform/ios/PlatformSpeechSynthesizerIOS.mm:
     15        (WebCore::PlatformSpeechSynthesizer::resetState):
     16        * platform/mac/PlatformSpeechSynthesizerMac.mm:
     17        (WebCore::PlatformSpeechSynthesizer::resetState):
     18
    1192019-07-23  Zalan Bujtas  <zalan@apple.com>
    220
  • trunk/Source/WebCore/Modules/speech/SpeechSynthesis.cpp

    r247620 r247755  
    111111void SpeechSynthesis::startSpeakingImmediately(SpeechSynthesisUtterance& utterance)
    112112{
    113     ASSERT(!m_currentSpeechUtterance);
    114113    utterance.setStartTime(MonotonicTime::now());
    115114    m_currentSpeechUtterance = &utterance;
     
    153152    if (m_speechSynthesisClient)
    154153        m_speechSynthesisClient->cancel();
    155     else if (m_platformSpeechSynthesizer)
     154    else if (m_platformSpeechSynthesizer) {
    156155        m_platformSpeechSynthesizer->cancel();
     156        // The platform should have called back immediately and cleared the current utterance.
     157        ASSERT(!m_currentSpeechUtterance);
     158    }
    157159    current = nullptr;
    158 
    159     // The platform should have called back immediately and cleared the current utterance.
    160     ASSERT(!m_currentSpeechUtterance);
    161160}
    162161
  • trunk/Source/WebCore/platform/PlatformSpeechSynthesizer.h

    r243002 r247755  
    7474    virtual void cancel();
    7575
     76    void resetState();
    7677    PlatformSpeechSynthesizerClient* client() const { return m_speechSynthesizerClient; }
    7778
  • trunk/Source/WebCore/platform/ios/PlatformSpeechSynthesizerIOS.mm

    r244704 r247755  
    292292}
    293293
     294void PlatformSpeechSynthesizer::resetState()
     295{
     296    [m_platformSpeechWrapper.get() cancel];
     297}
     298
    294299} // namespace WebCore
    295300
  • trunk/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm

    r243002 r247755  
    278278}
    279279
     280void PlatformSpeechSynthesizer::resetState()
     281{
     282    [m_platformSpeechWrapper.get() cancel];
     283}
     284
    280285} // namespace WebCore
    281286
  • trunk/Source/WebKit/ChangeLog

    r247748 r247755  
     12019-07-23  Chris Fleizach  <cfleizach@apple.com>
     2
     3        AX: CrashTracer: com.apple.WebKit.WebContent at WebKit: WebKit::WebSpeechSynthesisClient::speak
     4        https://bugs.webkit.org/show_bug.cgi?id=199988
     5
     6        Reviewed by Per Arne Vollan.
     7
     8        Improvements to WebSpeechSynthesis to avoid crashing and improve correctness.
     9        - Reset and cancel speech jobs on page close or reload (otherwise the synthesizer keeps talking after your page is gone)
     10        - Have a separate speech finish callback mechanism, use the start speaking callback when the synthesizer tells us.
     11        - Move an assert on utterance state to only apply when we use the in process synthesizer.
     12
     13        * UIProcess/Cocoa/WebPageProxyCocoa.mm:
     14        (WebKit::WebPageProxy::didStartSpeaking):
     15        * UIProcess/WebPageProxy.cpp:
     16        (WebKit::WebPageProxy::reload):
     17        (WebKit::WebPageProxy::resetState):
     18        (WebKit::WebPageProxy::resetSpeechSynthesizer):
     19        (WebKit::WebPageProxy::speechSynthesisSetFinishedCallback):
     20        (WebKit::WebPageProxy::speechSynthesisSpeak):
     21        * UIProcess/WebPageProxy.h:
     22        * UIProcess/WebPageProxy.messages.in:
     23        * WebProcess/WebCoreSupport/WebSpeechSynthesisClient.cpp:
     24        (WebKit::WebSpeechSynthesisClient::speak):
     25
    1262019-07-23  Chris Dumez  <cdumez@apple.com>
    227
  • trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm

    r246413 r247755  
    259259void WebPageProxy::didStartSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
    260260{
     261    if (speechSynthesisData().speakingStartedCompletionHandler)
     262        speechSynthesisData().speakingStartedCompletionHandler();
    261263}
    262264
    263265void WebPageProxy::didFinishSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
    264266{
    265     m_speechSynthesisData->speakingFinishedCompletionHandler();
     267    if (speechSynthesisData().speakingFinishedCompletionHandler)
     268        speechSynthesisData().speakingFinishedCompletionHandler();
    266269}
    267270
    268271void WebPageProxy::didPauseSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
    269272{
    270     m_speechSynthesisData->speakingPausedCompletionHandler();
     273    if (speechSynthesisData().speakingPausedCompletionHandler)
     274        speechSynthesisData().speakingPausedCompletionHandler();
    271275}
    272276
    273277void WebPageProxy::didResumeSpeaking(WebCore::PlatformSpeechSynthesisUtterance&)
    274278{
    275     m_speechSynthesisData->speakingResumedCompletionHandler();
     279    if (speechSynthesisData().speakingResumedCompletionHandler)
     280        speechSynthesisData().speakingResumedCompletionHandler();
    276281}
    277282
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r247695 r247755  
    13601360    m_process->responsivenessTimer().start();
    13611361
     1362#if ENABLE(SPEECH_SYNTHESIS)
     1363    resetSpeechSynthesizer();
     1364#endif
     1365
    13621366    return navigation;
    13631367}
     
    70537057#if ENABLE(POINTER_LOCK)
    70547058    requestPointerUnlock();
     7059#endif
     7060   
     7061#if ENABLE(SPEECH_SYNTHESIS)
     7062    resetSpeechSynthesizer();
    70557063#endif
    70567064}
     
    91279135
    91289136#if ENABLE(SPEECH_SYNTHESIS)
     9137
     9138void WebPageProxy::resetSpeechSynthesizer()
     9139{
     9140    if (!m_speechSynthesisData)
     9141        return;
     9142   
     9143    auto& synthesisData = speechSynthesisData();
     9144    synthesisData.speakingFinishedCompletionHandler = nullptr;
     9145    synthesisData.speakingStartedCompletionHandler = nullptr;
     9146    synthesisData.speakingPausedCompletionHandler = nullptr;
     9147    synthesisData.speakingResumedCompletionHandler = nullptr;
     9148    if (synthesisData.synthesizer)
     9149        synthesisData.synthesizer->resetState();
     9150}
     9151
    91299152WebPageProxy::SpeechSynthesisData& WebPageProxy::speechSynthesisData()
    91309153{
    91319154    if (!m_speechSynthesisData)
    9132         m_speechSynthesisData = SpeechSynthesisData { std::make_unique<PlatformSpeechSynthesizer>(this), nullptr, nullptr, nullptr, nullptr };
     9155        m_speechSynthesisData = SpeechSynthesisData { std::make_unique<PlatformSpeechSynthesizer>(this), nullptr, nullptr, nullptr, nullptr, nullptr };
    91339156    return *m_speechSynthesisData;
    91349157}
     
    91429165        result.uncheckedAppend(WebSpeechSynthesisVoice { voice->voiceURI(), voice->name(), voice->lang(), voice->localService(), voice->isDefault() });
    91439166    completionHandler(WTFMove(result));
     9167}
     9168
     9169void WebPageProxy::speechSynthesisSetFinishedCallback(CompletionHandler<void()>&& completionHandler)
     9170{
     9171    speechSynthesisData().speakingFinishedCompletionHandler = WTFMove(completionHandler);
    91449172}
    91459173
     
    91559183    utterance->setVoice(&voice.get());
    91569184
     9185    speechSynthesisData().speakingStartedCompletionHandler = WTFMove(completionHandler);
    91579186    speechSynthesisData().utterance = WTFMove(utterance);
    9158     speechSynthesisData().speakingFinishedCompletionHandler = WTFMove(completionHandler);
    91599187    speechSynthesisData().synthesizer->speak(m_speechSynthesisData->utterance.get());
    91609188}
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r247662 r247755  
    15341534    void speechSynthesisVoiceList(CompletionHandler<void(Vector<WebSpeechSynthesisVoice>&&)>&&);
    15351535    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()>&&);
     1536    void speechSynthesisSetFinishedCallback(CompletionHandler<void()>&&);
    15361537    void speechSynthesisCancel();
    15371538    void speechSynthesisPause(CompletionHandler<void()>&&);
     
    20972098    struct SpeechSynthesisData;
    20982099    SpeechSynthesisData& speechSynthesisData();
     2100    void resetSpeechSynthesizer();
    20992101#endif
    21002102
     
    25342536        std::unique_ptr<WebCore::PlatformSpeechSynthesizer> synthesizer;
    25352537        RefPtr<WebCore::PlatformSpeechSynthesisUtterance> utterance;
     2538        CompletionHandler<void()> speakingStartedCompletionHandler;
    25362539        CompletionHandler<void()> speakingFinishedCompletionHandler;
    25372540        CompletionHandler<void()> speakingPausedCompletionHandler;
  • trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in

    r247460 r247755  
    559559    SpeechSynthesisVoiceList() -> (Vector<WebKit::WebSpeechSynthesisVoice> voiceList) Synchronous
    560560    SpeechSynthesisSpeak(String text, String lang, float volume, float rate, float pitch, MonotonicTime startTime, String voiceURI, String voiceName, String voiceLang, bool localService, bool defaultVoice) -> () Async
     561    SpeechSynthesisSetFinishedCallback() -> () Async
    561562    SpeechSynthesisCancel()
    562563    SpeechSynthesisPause() -> () Async
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebSpeechSynthesisClient.cpp

    r247192 r247755  
    5858void WebSpeechSynthesisClient::speak(RefPtr<WebCore::PlatformSpeechSynthesisUtterance> utterance)
    5959{
    60     WTF::CompletionHandler<void()> completionHandler = [this, weakThis = makeWeakPtr(*this)]() mutable {
     60    WTF::CompletionHandler<void()> startedCompletionHandler = [this, weakThis = makeWeakPtr(*this)]() mutable {
     61        if (!weakThis)
     62            return;
     63        if (auto observer = corePageObserver())
     64            observer->didStartSpeaking();
     65    };
     66
     67    WTF::CompletionHandler<void()> finishedCompletionHandler = [this, weakThis = makeWeakPtr(*this)]() mutable {
    6168        if (!weakThis)
    6269            return;
     
    7178    auto localService = voice ? voice->localService() : false;
    7279    auto isDefault = voice ? voice->isDefault() : false;
    73 
    74     m_page.sendWithAsyncReply(Messages::WebPageProxy::SpeechSynthesisSpeak(utterance->text(), utterance->lang(), utterance->volume(), utterance->rate(), utterance->pitch(), utterance->startTime(), voiceURI, name, lang, localService, isDefault), WTFMove(completionHandler));
    75     if (auto observer = corePageObserver())
    76         observer->didStartSpeaking();
     80   
     81    m_page.sendWithAsyncReply(Messages::WebPageProxy::SpeechSynthesisSetFinishedCallback(), WTFMove(finishedCompletionHandler));
     82    m_page.sendWithAsyncReply(Messages::WebPageProxy::SpeechSynthesisSpeak(utterance->text(), utterance->lang(), utterance->volume(), utterance->rate(), utterance->pitch(), utterance->startTime(), voiceURI, name, lang, localService, isDefault), WTFMove(startedCompletionHandler));
    7783}
    7884
Note: See TracChangeset for help on using the changeset viewer.