Changeset 271031 in webkit


Ignore:
Timestamp:
Dec 21, 2020 11:35:24 AM (19 months ago)
Author:
sihui_liu@apple.com
Message:

Check availability of speech recognition service before requesting permissions
https://bugs.webkit.org/show_bug.cgi?id=220033

Reviewed by Youenn Fablet.

If speech recognition service is not available for target language (maybe the language is not supported, user
turns off dictation in system settings, etc), let's just fail the speech recognition request without prompting.

Manually tested with MiniBrowser.

  • UIProcess/Cocoa/MediaPermissionUtilities.mm:

(WebKit::requestSpeechRecognitionAccess):
(WebKit::checkSpeechRecognitionServiceAccess):
(WebKit::checkSpeechRecognitionServiceAvailability):

  • UIProcess/MediaPermissionUtilities.h:
  • UIProcess/SpeechRecognitionPermissionManager.cpp:

(WebKit::SpeechRecognitionPermissionManager::request):
(WebKit::SpeechRecognitionPermissionManager::startProcessingRequest):

  • UIProcess/SpeechRecognitionPermissionManager.h:
  • UIProcess/SpeechRecognitionPermissionRequest.h:

(WebKit::SpeechRecognitionPermissionRequest::create):
(WebKit::SpeechRecognitionPermissionRequest::lang const):
(WebKit::SpeechRecognitionPermissionRequest::SpeechRecognitionPermissionRequest):

  • UIProcess/SpeechRecognitionServer.cpp:

(WebKit::SpeechRecognitionServer::requestPermissionForRequest):

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

(WebKit::WebPageProxy::requestSpeechRecognitionPermission):

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

(WebKit::WebProcessProxy::createSpeechRecognitionServer):

Location:
trunk/Source/WebKit
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r271024 r271031  
     12020-12-21  Sihui Liu  <sihui_liu@apple.com>
     2
     3        Check availability of speech recognition service before requesting permissions
     4        https://bugs.webkit.org/show_bug.cgi?id=220033
     5
     6        Reviewed by Youenn Fablet.
     7
     8        If speech recognition service is not available for target language (maybe the language is not supported, user
     9        turns off dictation in system settings, etc), let's just fail the speech recognition request without prompting.
     10
     11        Manually tested with MiniBrowser.
     12
     13        * UIProcess/Cocoa/MediaPermissionUtilities.mm:
     14        (WebKit::requestSpeechRecognitionAccess):
     15        (WebKit::checkSpeechRecognitionServiceAccess):
     16        (WebKit::checkSpeechRecognitionServiceAvailability):
     17        * UIProcess/MediaPermissionUtilities.h:
     18        * UIProcess/SpeechRecognitionPermissionManager.cpp:
     19        (WebKit::SpeechRecognitionPermissionManager::request):
     20        (WebKit::SpeechRecognitionPermissionManager::startProcessingRequest):
     21        * UIProcess/SpeechRecognitionPermissionManager.h:
     22        * UIProcess/SpeechRecognitionPermissionRequest.h:
     23        (WebKit::SpeechRecognitionPermissionRequest::create):
     24        (WebKit::SpeechRecognitionPermissionRequest::lang const):
     25        (WebKit::SpeechRecognitionPermissionRequest::SpeechRecognitionPermissionRequest):
     26        * UIProcess/SpeechRecognitionServer.cpp:
     27        (WebKit::SpeechRecognitionServer::requestPermissionForRequest):
     28        * UIProcess/SpeechRecognitionServer.h:
     29        * UIProcess/WebPageProxy.cpp:
     30        (WebKit::WebPageProxy::requestSpeechRecognitionPermission):
     31        * UIProcess/WebPageProxy.h:
     32        * UIProcess/WebProcessProxy.cpp:
     33        (WebKit::WebProcessProxy::createSpeechRecognitionServer):
     34
    1352020-12-21  Alicia Boya García  <aboya@igalia.com>
    236
  • trunk/Source/WebKit/UIProcess/Cocoa/MediaPermissionUtilities.mm

    r270844 r271031  
    3939#import <wtf/spi/darwin/SandboxSPI.h>
    4040
    41 #if HAVE(SPEECHRECOGNIZER)
    42 #import <Speech/Speech.h>
    43 
    44 SOFT_LINK_FRAMEWORK(Speech)
    45 SOFT_LINK_CLASS(Speech, SFSpeechRecognizer)
    46 #endif
    47 
    4841#import <pal/cocoa/AVFoundationSoftLink.h>
     42#import <pal/cocoa/SpeechSoftLink.h>
    4943
    5044SOFT_LINK_PRIVATE_FRAMEWORK(TCC)
     
    255249        completionHandler(authorized);
    256250    });
    257     [getSFSpeechRecognizerClass() requestAuthorization:decisionHandler.get()];
     251    [PAL::getSFSpeechRecognizerClass() requestAuthorization:decisionHandler.get()];
    258252}
    259253
    260254MediaPermissionResult checkSpeechRecognitionServiceAccess()
    261255{
    262     auto authorizationStatus = [getSFSpeechRecognizerClass() authorizationStatus];
     256    auto authorizationStatus = [PAL::getSFSpeechRecognizerClass() authorizationStatus];
    263257    if (authorizationStatus == SFSpeechRecognizerAuthorizationStatusDenied || authorizationStatus == SFSpeechRecognizerAuthorizationStatusRestricted)
    264258        return MediaPermissionResult::Denied;
     
    268262}
    269263
     264bool checkSpeechRecognitionServiceAvailability(const String& localeIdentifier)
     265{
     266    auto recognizer = localeIdentifier.isEmpty() ? adoptNS([PAL::allocSFSpeechRecognizerInstance() init]) : adoptNS([PAL::allocSFSpeechRecognizerInstance() initWithLocale:[NSLocale localeWithLocaleIdentifier:localeIdentifier]]);
     267    return recognizer && [recognizer isAvailable];
     268}
     269
    270270#endif // HAVE(SPEECHRECOGNIZER)
    271271
  • trunk/Source/WebKit/UIProcess/MediaPermissionUtilities.h

    r269918 r271031  
    6969void requestSpeechRecognitionAccess(CompletionHandler<void(bool authorized)>&&);
    7070MediaPermissionResult checkSpeechRecognitionServiceAccess();
     71bool checkSpeechRecognitionServiceAvailability(const String& localeIdentifier);
    7172#endif
    7273
  • trunk/Source/WebKit/UIProcess/SpeechRecognitionPermissionManager.cpp

    r270986 r271031  
    7676}
    7777   
    78 void SpeechRecognitionPermissionManager::request(const WebCore::ClientOrigin& origin, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&& completiontHandler)
    79 {
    80     m_requests.append(SpeechRecognitionPermissionRequest::create(origin, WTFMove(completiontHandler)));
     78void SpeechRecognitionPermissionManager::request(const String& lang, const WebCore::ClientOrigin& origin, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&& completiontHandler)
     79{
     80    m_requests.append(SpeechRecognitionPermissionRequest::create(lang, origin, WTFMove(completiontHandler)));
    8181    if (m_requests.size() == 1)
    8282        startNextRequest();
     
    105105
    106106    m_page.syncIfMockDevicesEnabledChanged();
    107     if (m_page.preferences().mockCaptureDevicesEnabled()) {
     107    bool mockCaptureDevicesEnabled = m_page.preferences().mockCaptureDevicesEnabled();
     108    if (mockCaptureDevicesEnabled) {
    108109        m_microphoneCheck = CheckResult::Granted;
    109110        m_speechRecognitionServiceCheck = CheckResult::Granted;
     111    }
     112
     113#if HAVE(SPEECHRECOGNIZER)
     114    if (!mockCaptureDevicesEnabled && m_speechRecognitionServiceCheck != CheckResult::Denied) {
     115        // Speech recognition service can be unavailable when user does not enable dictation in system settings.
     116        // Let's avoid prompting user in that case.
     117        if (!checkSpeechRecognitionServiceAvailability(m_requests.first()->lang()))
     118            m_speechRecognitionServiceCheck = CheckResult::Denied;
     119    }
     120#endif
     121
     122    if (m_microphoneCheck == CheckResult::Denied || m_speechRecognitionServiceCheck == CheckResult::Denied) {
     123        completeCurrentRequest(SpeechRecognitionPermissionDecision::Deny);
     124        return;
    110125    }
    111126
     
    119134    }
    120135
    121     if (m_microphoneCheck == CheckResult::Denied || m_speechRecognitionServiceCheck == CheckResult::Denied || m_userPermissionCheck == CheckResult::Denied) {
     136    if (m_userPermissionCheck == CheckResult::Denied) {
    122137        completeCurrentRequest(SpeechRecognitionPermissionDecision::Deny);
    123138        return;
  • trunk/Source/WebKit/UIProcess/SpeechRecognitionPermissionManager.h

    r269918 r271031  
    4040    explicit SpeechRecognitionPermissionManager(WebPageProxy&);
    4141    ~SpeechRecognitionPermissionManager();
    42     void request(const WebCore::ClientOrigin&, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&&);
     42    void request(const String& lang, const WebCore::ClientOrigin&, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&&);
    4343
    4444    void decideByDefaultAction(const WebCore::SecurityOrigin&, CompletionHandler<void(bool)>&&);
  • trunk/Source/WebKit/UIProcess/SpeechRecognitionPermissionRequest.h

    r269810 r271031  
    3636class SpeechRecognitionPermissionRequest : public RefCounted<SpeechRecognitionPermissionRequest> {
    3737public:
    38     static Ref<SpeechRecognitionPermissionRequest> create(const WebCore::ClientOrigin& origin, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&& completionHandler)
     38    static Ref<SpeechRecognitionPermissionRequest> create(const String& lang, const WebCore::ClientOrigin& origin, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&& completionHandler)
    3939    {
    40         return adoptRef(*new SpeechRecognitionPermissionRequest(origin, WTFMove(completionHandler)));
     40        return adoptRef(*new SpeechRecognitionPermissionRequest(lang, origin, WTFMove(completionHandler)));
    4141    }
    4242
     
    4848
    4949    const WebCore::ClientOrigin& origin() const { return m_origin; }
     50    const String& lang() const { return m_lang; }
    5051
    5152private:
    52     SpeechRecognitionPermissionRequest(const WebCore::ClientOrigin& origin, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&& completionHandler)
    53         : m_origin(origin)
     53    SpeechRecognitionPermissionRequest(const String& lang, const WebCore::ClientOrigin& origin, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&& completionHandler)
     54        : m_lang(lang)
     55        , m_origin(origin)
    5456        , m_completionHandler(WTFMove(completionHandler))
    5557    { }
    5658
     59    String m_lang;
    5760    WebCore::ClientOrigin m_origin;
    5861    CompletionHandler<void(SpeechRecognitionPermissionDecision)> m_completionHandler;
  • trunk/Source/WebKit/UIProcess/SpeechRecognitionServer.cpp

    r270986 r271031  
    3737namespace WebKit {
    3838
    39 
    4039SpeechRecognitionServer::SpeechRecognitionServer(Ref<IPC::Connection>&& connection, SpeechRecognitionServerIdentifier identifier, SpeechRecognitionPermissionChecker&& permissionChecker, SpeechRecognitionCheckIfMockSpeechRecognitionEnabled&& checkIfEnabled
    4140#if ENABLE(MEDIA_STREAM)
     
    6564void SpeechRecognitionServer::requestPermissionForRequest(WebCore::SpeechRecognitionRequest& request)
    6665{
    67     m_permissionChecker(request.clientOrigin(), [this, weakThis = makeWeakPtr(this), weakRequest = makeWeakPtr(request)](SpeechRecognitionPermissionDecision decision) mutable {
     66    m_permissionChecker(request.lang(), request.clientOrigin(), [this, weakThis = makeWeakPtr(this), weakRequest = makeWeakPtr(request)](auto decision) mutable {
    6867        if (!weakThis)
    6968            return;
  • trunk/Source/WebKit/UIProcess/SpeechRecognitionServer.h

    r270986 r271031  
    4747
    4848using SpeechRecognitionServerIdentifier = WebCore::PageIdentifier;
    49 using SpeechRecognitionPermissionChecker = Function<void(const WebCore::ClientOrigin&, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&&)>;
     49using SpeechRecognitionPermissionChecker = Function<void(const String&, const WebCore::ClientOrigin&, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&&)>;
    5050using SpeechRecognitionCheckIfMockSpeechRecognitionEnabled = Function<bool()>;
    5151
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r270962 r271031  
    1034410344}
    1034510345
    10346 void WebPageProxy::requestSpeechRecognitionPermission(const WebCore::ClientOrigin& clientOrigin, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&& completionHandler)
     10346void WebPageProxy::requestSpeechRecognitionPermission(const String& lang, const WebCore::ClientOrigin& clientOrigin, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&& completionHandler)
    1034710347{
    1034810348    if (!m_speechRecognitionPermissionManager)
    1034910349        m_speechRecognitionPermissionManager = makeUnique<SpeechRecognitionPermissionManager>(*this);
    1035010350
    10351     m_speechRecognitionPermissionManager->request(clientOrigin, WTFMove(completionHandler));
     10351    m_speechRecognitionPermissionManager->request(lang, clientOrigin, WTFMove(completionHandler));
    1035210352}
    1035310353
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r270946 r271031  
    18301830    size_t suspendMediaPlaybackCounter() { return m_suspendMediaPlaybackCounter; }
    18311831
    1832     void requestSpeechRecognitionPermission(const WebCore::ClientOrigin&, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&&);
     1832    void requestSpeechRecognitionPermission(const String& lang, const WebCore::ClientOrigin&, CompletionHandler<void(SpeechRecognitionPermissionDecision)>&&);
    18331833    void requestSpeechRecognitionPermissionByDefaultAction(const WebCore::SecurityOrigin&, CompletionHandler<void(bool)>&&);
    18341834
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp

    r270793 r271031  
    17231723    ASSERT(!m_speechRecognitionServerMap.contains(identifier));
    17241724    auto& speechRecognitionServer = m_speechRecognitionServerMap.add(identifier, nullptr).iterator->value;
    1725     auto permissionChecker = [weakPage = makeWeakPtr(targetPage)](auto& origin, auto&& completionHandler) mutable {
     1725    auto permissionChecker = [weakPage = makeWeakPtr(targetPage)](auto& lang, auto& origin, auto&& completionHandler) mutable {
    17261726        if (!weakPage) {
    17271727            completionHandler(SpeechRecognitionPermissionDecision::Deny);
     
    17291729        }
    17301730
    1731         weakPage->requestSpeechRecognitionPermission(origin, WTFMove(completionHandler));
     1731        weakPage->requestSpeechRecognitionPermission(lang, origin, WTFMove(completionHandler));
    17321732    };
    17331733    auto checkIfMockCaptureDevicesEnabled = [weakPage = makeWeakPtr(targetPage)]() {
Note: See TracChangeset for help on using the changeset viewer.