Changeset 182648 in webkit


Ignore:
Timestamp:
Apr 10, 2015 6:45:04 PM (9 years ago)
Author:
weinig@apple.com
Message:

Allow LaunchServices to handle URLs on link navigations
<rdar://problem/19446826>
https://bugs.webkit.org/show_bug.cgi?id=143544

Reviewed by Anders Carlsson.

Source/WebCore:

  • WebCore.xcodeproj/project.pbxproj:
  • platform/spi/ios/LaunchServicesSPI.h: Added.

Add new SPI header.

Source/WebKit/mac:

  • Configurations/WebKitLegacy.xcconfig:

Link MobileCoreServices.

  • WebCoreSupport/WebFrameLoaderClient.h:
  • WebCoreSupport/WebFrameLoaderClient.mm:

(shouldTryAppLink):
(WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction):
(WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
(WebFrameLoaderClient::setUpPolicyListener):
Only let LaunchServices have a crack at the URL if the navigation is:

1) a main frame navigation
2) a result of a user gesture

Source/WebKit2:

  • UIProcess/Cocoa/NavigationState.mm:

(WebKit::tryAppLink):
(WebKit::NavigationState::NavigationClient::decidePolicyForNavigationAction):
Only let LaunchServices have a crack at the URL if the navigation is:

1) a main frame navigation
2) a result of a user gesture

Source/WTF:

  • wtf/Platform.h:

Add HAVE macro for this functionality.

Location:
trunk/Source
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r182623 r182648  
     12015-04-08  Sam Weinig  <sam@webkit.org>
     2
     3        Allow LaunchServices to handle URLs on link navigations
     4        <rdar://problem/19446826>
     5        https://bugs.webkit.org/show_bug.cgi?id=143544
     6
     7        Reviewed by Anders Carlsson.
     8
     9        * wtf/Platform.h:
     10        Add HAVE macro for this functionality.
     11
    1122015-04-09  Andy Estes  <aestes@apple.com>
    213
  • trunk/Source/WTF/wtf/Platform.h

    r182623 r182648  
    539539#define WTF_USE_QUICK_LOOK 1
    540540
     541#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000
     542#define HAVE_APP_LINKS 1
     543#endif
     544
    541545#if CPU(ARM64)
    542546#define ENABLE_JIT_CONSTANT_BLINDING 0
  • trunk/Source/WebCore/ChangeLog

    r182642 r182648  
     12015-04-08  Sam Weinig  <sam@webkit.org>
     2
     3        Allow LaunchServices to handle URLs on link navigations
     4        <rdar://problem/19446826>
     5        https://bugs.webkit.org/show_bug.cgi?id=143544
     6
     7        Reviewed by Anders Carlsson.
     8
     9        * WebCore.xcodeproj/project.pbxproj:
     10        * platform/spi/ios/LaunchServicesSPI.h: Added.
     11        Add new SPI header.
     12
    1132015-04-10  Bem Jones-Bey  <bjonesbe@adobe.com>
    214
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r182630 r182648  
    25092509                7C4C96DE1AD4483500365A50 /* JSReadableStreamReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4C96DA1AD4483500365A50 /* JSReadableStreamReader.cpp */; };
    25102510                7C4C96DF1AD4483500365A50 /* JSReadableStreamReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C4C96DB1AD4483500365A50 /* JSReadableStreamReader.h */; };
     2511                7C4C96E31AD44ABF00365A50 /* LaunchServicesSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C4C96E21AD44ABF00365A50 /* LaunchServicesSPI.h */; };
    25112512                7C4EDD741A7B607800198C4D /* FontCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7C4EDD731A7B607800198C4D /* FontCocoa.mm */; };
    25122513                7C522D4B15B477E8009B7C95 /* InspectorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C522D4915B477E8009B7C95 /* InspectorOverlay.cpp */; };
     
    58545855                CE12523D1A1676CD00864480 /* QuartzCoreSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE12523C1A1676CD00864480 /* QuartzCoreSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
    58555856                CE1252411A16B1B600864480 /* MediaPlayerSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252401A16B1B600864480 /* MediaPlayerSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
    5856                 CE1252431A16C01A00864480 /* CoreUISPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252421A16C01A00864480 /* CoreUISPI.h */; };
     5857                CE1252431A16C01A00864480 /* CoreUISPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252421A16C01A00864480 /* CoreUISPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
    58575858                CE1252451A16C22500864480 /* DynamicLinkerSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252441A16C22500864480 /* DynamicLinkerSPI.h */; };
    58585859                CE1252471A16C2C200864480 /* NSPointerFunctionsSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252461A16C2C200864480 /* NSPointerFunctionsSPI.h */; };
     
    97609761                7C4C96DA1AD4483500365A50 /* JSReadableStreamReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSReadableStreamReader.cpp; sourceTree = "<group>"; };
    97619762                7C4C96DB1AD4483500365A50 /* JSReadableStreamReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSReadableStreamReader.h; sourceTree = "<group>"; };
     9763                7C4C96E21AD44ABF00365A50 /* LaunchServicesSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LaunchServicesSPI.h; path = ios/LaunchServicesSPI.h; sourceTree = "<group>"; };
    97629764                7C4EDD731A7B607800198C4D /* FontCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FontCocoa.mm; sourceTree = "<group>"; };
    97639765                7C522D4915B477E8009B7C95 /* InspectorOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorOverlay.cpp; sourceTree = "<group>"; };
     
    1873218734                                CE1252421A16C01A00864480 /* CoreUISPI.h */,
    1873318735                                CEC337AE1A46086D009B8523 /* GraphicsServicesSPI.h */,
     18736                                7C4C96E21AD44ABF00365A50 /* LaunchServicesSPI.h */,
     18737                                CE1252401A16B1B600864480 /* MediaPlayerSPI.h */,
    1873418738                                CE1252481A16C3BC00864480 /* MobileGestaltSPI.h */,
    18735                                 CE1252401A16B1B600864480 /* MediaPlayerSPI.h */,
     18739                                6FAD4A561A9D0FAE009F7D3C /* OpenGLESSPI.h */,
    1873618740                                CE1252381A166FA000864480 /* QuickLookSPI.h */,
    18737                                 6FAD4A561A9D0FAE009F7D3C /* OpenGLESSPI.h */,
    1873818741                        );
    1873918742                        name = ios;
     
    2547925482                                B2FA3DD10AB75A6F000E5AC4 /* JSSVGPathSegLinetoHorizontalAbs.h in Headers */,
    2548025483                                B2FA3DD30AB75A6F000E5AC4 /* JSSVGPathSegLinetoHorizontalRel.h in Headers */,
     25484                                7C4C96E31AD44ABF00365A50 /* LaunchServicesSPI.h in Headers */,
    2548125485                                B2FA3DD50AB75A6F000E5AC4 /* JSSVGPathSegLinetoRel.h in Headers */,
    2548225486                                B2FA3DD70AB75A6F000E5AC4 /* JSSVGPathSegLinetoVerticalAbs.h in Headers */,
  • trunk/Source/WebKit/mac/ChangeLog

    r182638 r182648  
     12015-04-08  Sam Weinig  <sam@webkit.org>
     2
     3        Allow LaunchServices to handle URLs on link navigations
     4        <rdar://problem/19446826>
     5        https://bugs.webkit.org/show_bug.cgi?id=143544
     6
     7        Reviewed by Anders Carlsson.
     8
     9        * Configurations/WebKitLegacy.xcconfig:
     10        Link MobileCoreServices.
     11
     12        * WebCoreSupport/WebFrameLoaderClient.h:
     13        * WebCoreSupport/WebFrameLoaderClient.mm:
     14        (shouldTryAppLink):
     15        (WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction):
     16        (WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
     17        (WebFrameLoaderClient::setUpPolicyListener):
     18        Only let LaunchServices have a crack at the URL if the navigation is:
     19            1) a main frame navigation
     20            2) a result of a user gesture
     21
    1222015-04-10  Alexey Proskuryakov  <ap@apple.com>
    223
  • trunk/Source/WebKit/mac/Configurations/WebKitLegacy.xcconfig

    r181273 r182648  
    7272UMBRELLA_FRAMEWORKS_DIR = $(PRODUCTION_FRAMEWORKS_DIR)/WebKit.framework/Versions/A/Frameworks;
    7373
    74 OTHER_LDFLAGS[sdk=iphone*] = $(inherited) -lobjc -lsqlite3 -framework CFNetwork -framework CoreFoundation -framework CoreGraphics -framework CoreText -framework Foundation -framework GraphicsServices -framework ImageIO -framework OpenGLES -lMobileGestalt;
     74OTHER_LDFLAGS[sdk=iphone*] = $(inherited) -lobjc -lsqlite3 -framework CFNetwork -framework CoreFoundation -framework CoreGraphics -framework CoreText -framework Foundation -framework GraphicsServices -framework ImageIO -framework OpenGLES -framework MobileCoreServices -lMobileGestalt;
    7575OTHER_LDFLAGS[sdk=macosx*] = $(inherited) -framework Carbon -framework Cocoa -framework DiskArbitration -framework IOKit -framework OpenGL;
    7676
  • trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.h

    r182032 r182648  
    222222    virtual RemoteAXObjectRef accessibilityRemoteObject() override { return 0; }
    223223   
    224     RetainPtr<WebFramePolicyListener> setUpPolicyListener(WebCore::FramePolicyFunction);
     224    RetainPtr<WebFramePolicyListener> setUpPolicyListener(WebCore::FramePolicyFunction, NSURL *appLinkURL = nil);
    225225
    226226    NSDictionary *actionDictionary(const WebCore::NavigationAction&, PassRefPtr<WebCore::FormState>) const;
  • trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm

    r181791 r182648  
    152152#endif
    153153
     154#if HAVE(APP_LINKS)
     155#import <WebCore/LaunchServicesSPI.h>
     156#import <WebCore/WebCoreThreadRun.h>
     157#endif
     158
    154159#if ENABLE(CONTENT_FILTERING)
    155160#import <WebCore/PolicyChecker.h>
     
    173178    RefPtr<Frame> _frame;
    174179    FramePolicyFunction _policyFunction;
     180#if HAVE(APP_LINKS)
     181    RetainPtr<NSURL> _appLinkURL;
     182#endif
    175183}
    176184
    177185- (id)initWithFrame:(Frame*)frame policyFunction:(FramePolicyFunction)policyFunction;
     186#if HAVE(APP_LINKS)
     187- (id)initWithFrame:(Frame*)frame policyFunction:(FramePolicyFunction)policyFunction appLinkURL:(NSURL *)url;
     188#endif
     189
    178190- (void)invalidate;
    179191
     
    872884}
    873885
     886
     887static BOOL shouldTryAppLink(WebView *webView, const NavigationAction& action, Frame* targetFrame)
     888{
     889#if HAVE(APP_LINKS)
     890    BOOL mainFrameNavigation = !targetFrame || targetFrame->isMainFrame();
     891    if (!mainFrameNavigation)
     892        return NO;
     893
     894    if (!action.processingUserGesture())
     895        return NO;
     896
     897    return YES;
     898#else
     899    return NO;
     900#endif
     901}
     902
    874903void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, FramePolicyFunction function)
    875904{
    876905    WebView *webView = getWebView(m_webFrame.get());
     906    BOOL tryAppLink = shouldTryAppLink(webView, action, nullptr);
     907
    877908    [[webView _policyDelegateForwarder] webView:webView
    878909            decidePolicyForNewWindowAction:actionDictionary(action, formState)
    879910                                   request:request.nsURLRequest(UpdateHTTPBody)
    880911                              newFrameName:frameName
    881                           decisionListener:setUpPolicyListener(WTF::move(function)).get()];
     912                          decisionListener:setUpPolicyListener(WTF::move(function), tryAppLink ? (NSURL *)request.url() : nil).get()];
    882913}
    883914
     
    885916{
    886917    WebView *webView = getWebView(m_webFrame.get());
     918    BOOL tryAppLink = shouldTryAppLink(webView, action, core(m_webFrame.get()));
     919
    887920    [[webView _policyDelegateForwarder] webView:webView
    888921                decidePolicyForNavigationAction:actionDictionary(action, formState)
    889922                                        request:request.nsURLRequest(UpdateHTTPBody)
    890923                                          frame:m_webFrame.get()
    891                                decisionListener:setUpPolicyListener(WTF::move(function)).get()];
     924                               decisionListener:setUpPolicyListener(WTF::move(function), tryAppLink ? (NSURL *)request.url() : nil).get()];
    892925}
    893926
     
    14731506}
    14741507
    1475 RetainPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(FramePolicyFunction function)
     1508RetainPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(FramePolicyFunction function, NSURL *appLinkURL)
    14761509{
    14771510    // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
    14781511    [m_policyListener invalidate];
    14791512
    1480     m_policyListener = adoptNS([[WebFramePolicyListener alloc] initWithFrame:core(m_webFrame.get()) policyFunction:function]);
     1513#if HAVE(APP_LINKS)
     1514    if (appLinkURL)
     1515        m_policyListener = adoptNS([[WebFramePolicyListener alloc] initWithFrame:core(m_webFrame.get()) policyFunction:function appLinkURL:appLinkURL]);
     1516    else
     1517#endif
     1518        m_policyListener = adoptNS([[WebFramePolicyListener alloc] initWithFrame:core(m_webFrame.get()) policyFunction:function]);
    14811519
    14821520    return m_policyListener;
     
    22722310}
    22732311
     2312#if HAVE(APP_LINKS)
     2313- (id)initWithFrame:(Frame*)frame policyFunction:(FramePolicyFunction)policyFunction appLinkURL:(NSURL *)appLinkURL
     2314{
     2315    self = [self initWithFrame:frame policyFunction:policyFunction];
     2316    if (!self)
     2317        return nil;
     2318
     2319    _appLinkURL = appLinkURL;
     2320
     2321    return self;
     2322}
     2323#endif
     2324
    22742325- (void)invalidate
    22752326{
     
    23102361- (void)use
    23112362{
     2363#if HAVE(APP_LINKS)
     2364    if (_appLinkURL && _frame) {
     2365        [LSAppLink openWithURL:_appLinkURL.get() completionHandler:^(BOOL success, NSError *) {
     2366            WebThreadRun(^{
     2367                if (success)
     2368                    [self receivedPolicyDecision:PolicyIgnore];
     2369                else
     2370                    [self receivedPolicyDecision:PolicyUse];
     2371            });
     2372        }];
     2373        return;
     2374    }
     2375#endif
     2376
    23122377    [self receivedPolicyDecision:PolicyUse];
    23132378}
  • trunk/Source/WebKit2/ChangeLog

    r182640 r182648  
     12015-04-08  Sam Weinig  <sam@webkit.org>
     2
     3        Allow LaunchServices to handle URLs on link navigations
     4        <rdar://problem/19446826>
     5        https://bugs.webkit.org/show_bug.cgi?id=143544
     6
     7        Reviewed by Anders Carlsson.
     8
     9        * UIProcess/Cocoa/NavigationState.mm:
     10        (WebKit::tryAppLink):
     11        (WebKit::NavigationState::NavigationClient::decidePolicyForNavigationAction):
     12        Only let LaunchServices have a crack at the URL if the navigation is:
     13            1) a main frame navigation
     14            2) a result of a user gesture
     15
    1162015-04-10  Tim Horton  <timothy_horton@apple.com>
    217
  • trunk/Source/WebKit2/UIProcess/Cocoa/NavigationState.mm

    r179786 r182648  
    6565#import <wtf/NeverDestroyed.h>
    6666
     67#if HAVE(APP_LINKS)
     68#import <WebCore/LaunchServicesSPI.h>
     69#endif
     70
    6771#if USE(QUICK_LOOK)
    6872#import "QuickLookDocumentData.h"
     
    225229}
    226230
     231static void tryAppLink(RefPtr<API::NavigationAction> navigationAction, std::function<void (bool)> completionHandler)
     232{
     233#if HAVE(APP_LINKS)
     234    bool mainFrameNavigation = !navigationAction->targetFrame() || navigationAction->targetFrame()->isMainFrame();
     235    bool isProcessingUserGesture = navigationAction->isProcessingUserGesture();
     236    if (mainFrameNavigation && isProcessingUserGesture) {
     237        auto* localCompletionHandler = new std::function<void (bool)>(WTF::move(completionHandler));
     238        [LSAppLink openWithURL:navigationAction->request().url() completionHandler:[localCompletionHandler](BOOL success, NSError *) {
     239            dispatch_async(dispatch_get_main_queue(), [localCompletionHandler, success] {
     240                (*localCompletionHandler)(success);
     241                delete localCompletionHandler;
     242            });
     243        }];
     244        return;
     245    }
     246#endif
     247
     248    completionHandler(false);
     249}
     250
    227251void NavigationState::NavigationClient::decidePolicyForNavigationAction(WebPageProxy&, API::NavigationAction& navigationAction, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData)
    228252{
    229253    if (!m_navigationState.m_navigationDelegateMethods.webViewDecidePolicyForNavigationActionDecisionHandler) {
    230         RetainPtr<NSURLRequest> nsURLRequest = adoptNS(wrapper(*API::URLRequest::create(navigationAction.request()).leakRef()));
    231 
    232         if (!navigationAction.targetFrame()) {
    233             listener->use();
    234             return;
    235         }
    236 
    237         if ([NSURLConnection canHandleRequest:nsURLRequest.get()]) {
    238             listener->use();
    239             return;
    240         }
     254        RefPtr<API::NavigationAction> localNavigationAction = &navigationAction;
     255        RefPtr<WebFramePolicyListenerProxy> localListener = WTF::move(listener);
     256
     257        tryAppLink(localNavigationAction, [localListener, localNavigationAction] (bool followedLinkToApp) {
     258            if (followedLinkToApp) {
     259                localListener->ignore();
     260                return;
     261            }
     262
     263            if (!localNavigationAction->targetFrame()) {
     264                localListener->use();
     265                return;
     266            }
     267
     268            RetainPtr<NSURLRequest> nsURLRequest = adoptNS(wrapper(*API::URLRequest::create(localNavigationAction->request()).leakRef()));
     269            if ([NSURLConnection canHandleRequest:nsURLRequest.get()]) {
     270                localListener->use();
     271                return;
     272            }
    241273
    242274#if PLATFORM(MAC)
    243         // A file URL shouldn't fall through to here, but if it did,
    244         // it would be a security risk to open it.
    245         if (![[nsURLRequest URL] isFileURL])
    246             [[NSWorkspace sharedWorkspace] openURL:[nsURLRequest URL]];
     275            // A file URL shouldn't fall through to here, but if it did,
     276            // it would be a security risk to open it.
     277            if (![[nsURLRequest URL] isFileURL])
     278                [[NSWorkspace sharedWorkspace] openURL:[nsURLRequest URL]];
    247279#endif
    248         listener->ignore();
     280            localListener->ignore();
     281        });
     282
    249283        return;
    250284    }
     
    254288        return;
    255289
     290    RefPtr<API::NavigationAction> localNavigationAction = &navigationAction;
    256291    RefPtr<WebFramePolicyListenerProxy> localListener = WTF::move(listener);
    257292    RefPtr<CompletionHandlerCallChecker> checker = CompletionHandlerCallChecker::create(navigationDelegate.get(), @selector(webView:decidePolicyForNavigationAction:decisionHandler:));
    258     [navigationDelegate webView:m_navigationState.m_webView decidePolicyForNavigationAction:wrapper(navigationAction) decisionHandler:[localListener, checker](WKNavigationActionPolicy actionPolicy) {
     293    [navigationDelegate webView:m_navigationState.m_webView decidePolicyForNavigationAction:wrapper(navigationAction) decisionHandler:[localListener, localNavigationAction, checker](WKNavigationActionPolicy actionPolicy) {
    259294        checker->didCallCompletionHandler();
    260295
    261296        switch (actionPolicy) {
    262297        case WKNavigationActionPolicyAllow:
    263             localListener->use();
     298            tryAppLink(localNavigationAction, [localListener](bool followedLinkToApp) {
     299                if (followedLinkToApp) {
     300                    localListener->ignore();
     301                    return;
     302                }
     303
     304                localListener->use();
     305            });
     306       
    264307            break;
    265308
Note: See TracChangeset for help on using the changeset viewer.