Changeset 271205 in webkit


Ignore:
Timestamp:
Jan 6, 2021 11:22:03 AM (19 months ago)
Author:
commit-queue@webkit.org
Message:

Stop speech recognition if page becomes invisible
https://bugs.webkit.org/show_bug.cgi?id=220073
<rdar://problem/72710704>

Patch by Sihui Liu <sihui_liu@appe.com> on 2021-01-06
Reviewed by Youenn Fablet.

Source/WebKit:

We should not allow speech recognition on page invisible to user, because page may get content of captured audio
without user's notice. To do this, we should:

  1. deny speech recognition request on invisibile page
  2. abort ongoing speech recognition if page becomes invisible

API test: WebKit2.SpeechRecognitionPageBecomesInvisible

  • UIProcess/SpeechRecognitionPermissionManager.cpp:

(WebKit::SpeechRecognitionPermissionManager::continueProcessingRequest):

  • UIProcess/SpeechRecognitionServer.cpp:

(WebKit::SpeechRecognitionServer::abortForPageIsBecomingInvisible):

  • UIProcess/SpeechRecognitionServer.h:
  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::dispatchActivityStateChange):

  • UIProcess/WebProcessProxy.cpp:

(WebKit::WebProcessProxy::pageIsBecomingInvisible):

  • UIProcess/WebProcessProxy.h:

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/SpeechRecognition.mm: updated

WebKit2.SpeechRecognitionErrorWhenStartingAudioCaptureOnDifferentPage for updated behavior.
(TestWebKitAPI::TEST):

  • TestWebKitAPI/cocoa/TestWKWebView.mm:

(-[TestWKWebView _setUpTestWindow:]): set the origin of host window to be the origin of frame of TestWKWebView.

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r271201 r271205  
     12021-01-06  Sihui Liu  <sihui_liu@appe.com>
     2
     3        Stop speech recognition if page becomes invisible
     4        https://bugs.webkit.org/show_bug.cgi?id=220073
     5        <rdar://problem/72710704>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        We should not allow speech recognition on page invisible to user, because page may get content of captured audio
     10        without user's notice. To do this, we should:
     11        1. deny speech recognition request on invisibile page
     12        2. abort ongoing speech recognition if page becomes invisible
     13
     14        API test: WebKit2.SpeechRecognitionPageBecomesInvisible
     15
     16        * UIProcess/SpeechRecognitionPermissionManager.cpp:
     17        (WebKit::SpeechRecognitionPermissionManager::continueProcessingRequest):
     18        * UIProcess/SpeechRecognitionServer.cpp:
     19        (WebKit::SpeechRecognitionServer::abortForPageIsBecomingInvisible):
     20        * UIProcess/SpeechRecognitionServer.h:
     21        * UIProcess/WebPageProxy.cpp:
     22        (WebKit::WebPageProxy::dispatchActivityStateChange):
     23        * UIProcess/WebProcessProxy.cpp:
     24        (WebKit::WebProcessProxy::pageIsBecomingInvisible):
     25        * UIProcess/WebProcessProxy.h:
     26
    1272021-01-06  Alex Christensen  <achristensen@webkit.org>
    228
  • trunk/Source/WebKit/UIProcess/SpeechRecognitionPermissionManager.cpp

    r271174 r271205  
    162162    ASSERT(m_userPermissionCheck == CheckResult::Granted);
    163163
     164    if (!m_page.isViewVisible()) {
     165        completeCurrentRequest(SpeechRecognitionPermissionDecision::Deny);
     166        return;
     167    }
     168
    164169    completeCurrentRequest(SpeechRecognitionPermissionDecision::Grant);
    165170}
  • trunk/Source/WebKit/UIProcess/SpeechRecognitionServer.cpp

    r271174 r271205  
    169169}
    170170
     171void SpeechRecognitionServer::abortForPageIsBecomingInvisible()
     172{
     173    if (!m_recognizer)
     174        return;
     175
     176    auto currentClientIdentifier = m_recognizer->currentClientIdentifier();
     177    if (!currentClientIdentifier)
     178        return;
     179
     180    auto error = WebCore::SpeechRecognitionError { WebCore::SpeechRecognitionErrorType::Aborted, "Page is no longer visible"_s };
     181    sendUpdate(*currentClientIdentifier, WebCore::SpeechRecognitionUpdateType::Error, error);
     182    m_recognizer->reset();
     183}
     184
    171185void SpeechRecognitionServer::sendUpdate(WebCore::SpeechRecognitionConnectionClientIdentifier clientIdentifier, WebCore::SpeechRecognitionUpdateType type, Optional<WebCore::SpeechRecognitionError> error, Optional<Vector<WebCore::SpeechRecognitionResultData>> result)
    172186{
  • trunk/Source/WebKit/UIProcess/SpeechRecognitionServer.h

    r271174 r271205  
    6565    void invalidate(WebCore::SpeechRecognitionConnectionClientIdentifier);
    6666    void mute();
     67    void abortForPageIsBecomingInvisible();
    6768
    6869private:
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r271193 r271205  
    19961996        updateCurrentModifierState();
    19971997
    1998     if ((m_potentiallyChangedActivityStateFlags & ActivityState::IsVisible) && isViewVisible())
    1999         viewIsBecomingVisible();
     1998    if ((m_potentiallyChangedActivityStateFlags & ActivityState::IsVisible)) {
     1999        if (isViewVisible())
     2000            viewIsBecomingVisible();
     2001        else
     2002            m_process->pageIsBecomingInvisible(m_webPageID);
     2003    }
    20002004
    20012005    bool isNowInWindow = (changed & ActivityState::IsInWindow) && isInWindow();
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp

    r271174 r271205  
    17891789}
    17901790
     1791void WebProcessProxy::pageIsBecomingInvisible(WebCore::PageIdentifier identifier)
     1792{
     1793    if (auto server = m_speechRecognitionServerMap.get(identifier))
     1794        server->abortForPageIsBecomingInvisible();
     1795}
     1796
    17911797#if PLATFORM(WATCHOS)
    17921798
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.h

    r271174 r271205  
    406406#endif
    407407    void pageMutedStateChanged(WebCore::PageIdentifier, WebCore::MediaProducer::MutedStateFlags);
     408    void pageIsBecomingInvisible(WebCore::PageIdentifier);
    408409
    409410protected:
  • trunk/Tools/ChangeLog

    r271203 r271205  
     12021-01-06  Sihui Liu  <sihui_liu@appe.com>
     2
     3        Stop speech recognition if page becomes invisible
     4        https://bugs.webkit.org/show_bug.cgi?id=220073
     5        <rdar://problem/72710704>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        * TestWebKitAPI/Tests/WebKitCocoa/SpeechRecognition.mm: updated
     10        WebKit2.SpeechRecognitionErrorWhenStartingAudioCaptureOnDifferentPage for updated behavior.
     11        (TestWebKitAPI::TEST):
     12        * TestWebKitAPI/cocoa/TestWKWebView.mm:
     13        (-[TestWKWebView _setUpTestWindow:]): set the origin of host window to be the origin of frame of TestWKWebView.
     14
    1152021-01-06  Jonathan Bedard <jbedard@apple.com>
    216
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/SpeechRecognition.mm

    r271174 r271205  
    129129    preferences._mediaCaptureRequiresSecureConnection = NO;
    130130    auto delegate = adoptNS([[SpeechRecognitionPermissionUIDelegate alloc] init]);
    131     auto firstWebView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
     131    auto firstWebView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 100, 100) configuration:configuration.get()]);
    132132    [firstWebView setUIDelegate:delegate.get()];
    133     auto secondWebView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
     133    auto secondWebView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(100, 0, 100, 100) configuration:configuration.get()]);
    134134    [secondWebView setUIDelegate:delegate.get()];
    135135
     
    168168}
    169169
     170// FIXME: enable this test on iOS when https://webkit.org/b/175204 is fixed.
     171#if PLATFORM(MAC)
     172
     173TEST(WebKit2, SpeechRecognitionPageBecomesInvisible)
     174{
     175    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     176    auto handler = adoptNS([[SpeechRecognitionMessageHandler alloc] init]);
     177    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
     178    auto preferences = [configuration preferences];
     179    preferences._mockCaptureDevicesEnabled = YES;
     180    preferences._speechRecognitionEnabled = YES;
     181    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
     182    auto delegate = adoptNS([[SpeechRecognitionPermissionUIDelegate alloc] init]);
     183    [webView setUIDelegate:delegate.get()];
     184
     185    // Page is visible.
     186    shouldGrantPermissionRequest = true;
     187    receivedScriptMessage = false;
     188    [webView synchronouslyLoadTestPageNamed:@"speechrecognition-basic"];
     189    [webView stringByEvaluatingJavaScript:@"start()"];
     190    TestWebKitAPI::Util::run(&receivedScriptMessage);
     191    EXPECT_WK_STREQ(@"Start", [lastScriptMessage body]);
     192
     193    // Hide page.
     194    receivedScriptMessage = false;
     195#if PLATFORM(MAC)
     196    [webView.get().window setIsVisible:NO];
     197#else
     198    webView.get().window.hidden = YES;
     199#endif
     200    TestWebKitAPI::Util::run(&receivedScriptMessage);
     201    EXPECT_WK_STREQ(@"Error: aborted - Page is no longer visible", [lastScriptMessage body]);
     202
     203    // Page is invisible.
     204    receivedScriptMessage = false;
     205    [webView evaluateJavaScript:@"start()" completionHandler:nil];
     206    TestWebKitAPI::Util::run(&receivedScriptMessage);
     207    EXPECT_WK_STREQ(@"Error: not-allowed - Permission check failed", [lastScriptMessage body]);
     208}
     209
     210#endif
     211
    170212} // namespace TestWebKitAPI
  • trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm

    r268086 r271205  
    463463#if PLATFORM(MAC)
    464464    _hostWindow = adoptNS([[TestWKWebViewHostWindow alloc] initWithWebView:self contentRect:frame styleMask:(NSWindowStyleMaskBorderless | NSWindowStyleMaskMiniaturizable) backing:NSBackingStoreBuffered defer:NO]);
    465     [_hostWindow setFrameOrigin:NSMakePoint(0, 0)];
     465    [_hostWindow setFrameOrigin:frame.origin];
    466466    [_hostWindow setIsVisible:YES];
    467467    [_hostWindow contentView].wantsLayer = YES;
Note: See TracChangeset for help on using the changeset viewer.