Context menus should not offer the "Download video" option for videos that cannot
authorbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Nov 2014 00:46:53 +0000 (00:46 +0000)
committerbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Nov 2014 00:46:53 +0000 (00:46 +0000)
be downloaded
https://bugs.webkit.org/show_bug.cgi?id=138530
-and corresponding-
rdar://problem/18919130

Patch by Eric Carlson <eric.carlson@apple.com> on 2014-11-13
Reviewed by Tim Horton.

Source/WebCore:

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::parseAttribute):
* html/HTMLMediaElement.h:
* page/ContextMenuController.cpp:
(WebCore::ContextMenuController::populate):
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::canSaveMediaData):
(WebCore::MediaPlayer::supportsSave): Deleted.
* platform/graphics/MediaPlayer.h:
* platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::supportsFullscreen):
(WebCore::MediaPlayerPrivateInterface::canSaveMediaData):
(WebCore::MediaPlayerPrivateInterface::supportsSave): Deleted.
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
(WebCore::MediaPlayerPrivateAVFoundation::resolvedURL):
(WebCore::MediaPlayerPrivateAVFoundation::canSaveMediaData):
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::resolvedURL):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::canSaveMediaData):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
* platform/graphics/mac/MediaPlayerPrivateQTKit.h:
* platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
(WebCore::MediaPlayerPrivateQTKit::canSaveMediaData):
* rendering/HitTestResult.cpp:
(WebCore::HitTestResult::isDownloadableMedia):

Source/WebKit2:

Expose isDownloadableMedia() to the InjectedBundleHitTestResult.
* WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.cpp:
(WKBundleHitTestResultIsDownloadableMedia):
* WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.h:
* WebProcess/InjectedBundle/InjectedBundleHitTestResult.cpp:
(WebKit::InjectedBundleHitTestResult::isDownloadableMedia):
* WebProcess/InjectedBundle/InjectedBundleHitTestResult.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@176108 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/page/ContextMenuController.cpp
Source/WebCore/platform/graphics/MediaPlayer.cpp
Source/WebCore/platform/graphics/MediaPlayer.h
Source/WebCore/platform/graphics/MediaPlayerPrivate.h
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
Source/WebCore/rendering/HitTestResult.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.cpp
Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.h
Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleHitTestResult.cpp
Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleHitTestResult.h

index afac390..773c7e1 100644 (file)
@@ -1,3 +1,42 @@
+2014-11-13  Eric Carlson  <eric.carlson@apple.com>
+
+        Context menus should not offer the "Download video" option for videos that cannot 
+        be downloaded
+        https://bugs.webkit.org/show_bug.cgi?id=138530
+        -and corresponding-
+        rdar://problem/18919130
+
+        Reviewed by Tim Horton.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::parseAttribute):
+        * html/HTMLMediaElement.h:
+        * page/ContextMenuController.cpp:
+        (WebCore::ContextMenuController::populate):
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::canSaveMediaData):
+        (WebCore::MediaPlayer::supportsSave): Deleted.
+        * platform/graphics/MediaPlayer.h:
+        * platform/graphics/MediaPlayerPrivate.h:
+        (WebCore::MediaPlayerPrivateInterface::supportsFullscreen):
+        (WebCore::MediaPlayerPrivateInterface::canSaveMediaData):
+        (WebCore::MediaPlayerPrivateInterface::supportsSave): Deleted.
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
+        (WebCore::MediaPlayerPrivateAVFoundation::resolvedURL):
+        (WebCore::MediaPlayerPrivateAVFoundation::canSaveMediaData):
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::resolvedURL):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivateGStreamer::canSaveMediaData):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+        (WebCore::MediaPlayerPrivateQTKit::canSaveMediaData):
+        * rendering/HitTestResult.cpp:
+        (WebCore::HitTestResult::isDownloadableMedia):
+
 2014-11-02  Tim Horton  <timothy_horton@apple.com>
 
         [mac] Keep around more decoded image data, since it's purgeable
index e643593..d47d64a 100644 (file)
@@ -2269,11 +2269,6 @@ void HTMLMediaElement::addPlayedRange(const MediaTime& start, const MediaTime& e
     m_playedTimeRanges->ranges().add(start, end);
 }  
 
-bool HTMLMediaElement::supportsSave() const
-{
-    return m_player ? m_player->supportsSave() : false;
-}
-
 bool HTMLMediaElement::supportsScanning() const
 {
     return m_player ? m_player->supportsScanning() : false;
@@ -6117,9 +6112,17 @@ bool HTMLMediaElement::doesHaveAttribute(const AtomicString& attribute, AtomicSt
 void HTMLMediaElement::setShouldBufferData(bool shouldBuffer)
 {
     if (m_player)
-        return m_player->setShouldBufferData(shouldBuffer);
+        m_player->setShouldBufferData(shouldBuffer);
 }
-    
+
+bool HTMLMediaElement::canSaveMediaData() const
+{
+    if (m_player)
+        return m_player->canSaveMediaData();
+
+    return false;
+}
+
 }
 
 #endif
index 50e7f56..719d716 100644 (file)
@@ -118,9 +118,10 @@ public:
     // Eventually overloaded in HTMLVideoElement
     virtual bool supportsFullscreen() const override { return false; };
 
-    virtual bool supportsSave() const;
     virtual bool supportsScanning() const override;
-    
+
+    bool canSaveMediaData() const;
+
     virtual bool doesHaveAttribute(const AtomicString&, AtomicString* value = nullptr) const override;
 
     WEBCORE_EXPORT PlatformMedia platformMedia() const;
index 4c429a5..7ea8197 100644 (file)
@@ -890,7 +890,7 @@ void ContextMenuController::populate()
             appendItem(*separatorItem(), m_contextMenu.get());
             appendItem(CopyMediaLinkItem, m_contextMenu.get());
             appendItem(OpenMediaInNewWindowItem, m_contextMenu.get());
-            if (loader.client().canHandleRequest(ResourceRequest(mediaURL)))
+            if (m_context.hitTestResult().isDownloadableMedia() && loader.client().canHandleRequest(ResourceRequest(mediaURL)))
                 appendItem(DownloadMediaItem, m_contextMenu.get());
         }
 
index f891858..fd31e7a 100644 (file)
@@ -552,9 +552,9 @@ bool MediaPlayer::supportsFullscreen() const
     return m_private->supportsFullscreen();
 }
 
-bool MediaPlayer::supportsSave() const
+bool MediaPlayer::canSaveMediaData() const
 {
-    return m_private->supportsSave();
+    return m_private->canSaveMediaData();
 }
 
 bool MediaPlayer::supportsScanning() const
index ae16695..d4b89c1 100644 (file)
@@ -293,8 +293,8 @@ public:
     static bool supportsKeySystem(const String& keySystem, const String& mimeType);
 
     bool supportsFullscreen() const;
-    bool supportsSave() const;
     bool supportsScanning() const;
+    bool canSaveMediaData() const;
     bool requiresImmediateCompositing() const;
     bool doesHaveAttribute(const AtomicString&, AtomicString* value = nullptr) const;
     PlatformMedia platformMedia() const;
index 2d58a07..16361e8 100644 (file)
@@ -70,10 +70,11 @@ public:
     virtual void setShouldBufferData(bool) { }
 
     virtual bool supportsFullscreen() const { return false; }
-    virtual bool supportsSave() const { return false; }
     virtual bool supportsScanning() const { return false; }
     virtual bool requiresImmediateCompositing() const { return false; }
 
+    virtual bool canSaveMediaData() const { return false; }
+
     virtual IntSize naturalSize() const = 0;
 
     virtual bool hasVideo() const = 0;
index 30e194e..f8c5518 100644 (file)
@@ -1047,6 +1047,30 @@ bool MediaPlayerPrivateAVFoundation::extractKeyURIKeyIDAndCertificateFromInitDat
 }
 #endif
 
+URL MediaPlayerPrivateAVFoundation::resolvedURL() const
+{
+    if (!m_assetURL.length())
+        return URL();
+
+    return URL(ParsedURLString, m_assetURL);
+}
+
+bool MediaPlayerPrivateAVFoundation::canSaveMediaData() const
+{
+    URL url = resolvedURL();
+
+    if (url.isLocalFile())
+        return true;
+
+    if (!url.protocolIsInHTTPFamily())
+        return false;
+
+    if (isLiveStream())
+        return false;
+
+    return true;
+}
+
 } // namespace WebCore
 
 #endif
index 703c3ed..80e1467 100644 (file)
@@ -191,6 +191,7 @@ protected:
     virtual void acceleratedRenderingStateChanged() override;
     virtual bool shouldMaintainAspectRatio() const override { return m_shouldMaintainAspectRatio; }
     virtual void setShouldMaintainAspectRatio(bool) override;
+    virtual bool canSaveMediaData() const override;
 
     virtual MediaPlayer::MovieLoadType movieLoadType() const;
     virtual void prepareForRendering();
@@ -303,6 +304,8 @@ protected:
     void clearTextTracks();
     Vector<RefPtr<InbandTextTrackPrivateAVF>> m_textTracks;
 
+virtual URL resolvedURL() const;
+
 private:
     MediaPlayer* m_player;
 
index 196a1f2..b861638 100644 (file)
@@ -281,6 +281,8 @@ private:
     virtual double maxFastForwardRate() const override { return m_cachedCanPlayFastForward ? std::numeric_limits<double>::infinity() : 2.0; }
     virtual double minFastReverseRate() const override { return m_cachedCanPlayFastReverse ? -std::numeric_limits<double>::infinity() : 0.0; }
 
+    virtual URL resolvedURL() const override;
+
     WeakPtrFactory<MediaPlayerPrivateAVFoundationObjC> m_weakPtrFactory;
 
     RetainPtr<AVURLAsset> m_avAsset;
index 50681de..4547b02 100644 (file)
@@ -2845,6 +2845,14 @@ void MediaPlayerPrivateAVFoundationObjC::canPlayFastReverseDidChange(bool newVal
     m_cachedCanPlayFastReverse = newValue;
 }
 
+URL MediaPlayerPrivateAVFoundationObjC::resolvedURL() const
+{
+    if (!m_avAsset)
+        return MediaPlayerPrivateAVFoundation::resolvedURL();
+
+    return URL([m_avAsset resolvedURL]);
+}
+
 NSArray* assetMetadataKeyNames()
 {
     static NSArray* keys;
index ba3c7af..59e7451 100644 (file)
@@ -1920,6 +1920,20 @@ bool MediaPlayerPrivateGStreamer::didPassCORSAccessCheck() const
     return false;
 }
 
+bool MediaPlayerPrivateGStreamer::canSaveMediaData() const
+{
+    if (isLiveStream())
+        return false;
+
+    if (m_url.isLocalFile())
+        return true;
+
+    if (m_url.protocolIsInHTTPFamily())
+        return true;
+    
+    return false;
+}
+
 }
 
 #endif // USE(GSTREAMER)
index 056134e..6a79b4a 100644 (file)
@@ -164,6 +164,7 @@ private:
     virtual String engineDescription() const { return "GStreamer"; }
     virtual bool isLiveStream() const { return m_isStreaming; }
     virtual bool didPassCORSAccessCheck() const;
+    virtual bool canSaveMediaData() const override;
 
 private:
     GRefPtr<GstElement> m_playBin;
index 1662f9e..ea35e20 100644 (file)
@@ -135,6 +135,8 @@ private:
     bool hasSingleSecurityOrigin() const;
     MediaPlayer::MovieLoadType movieLoadType() const;
 
+    virtual bool canSaveMediaData() const override;
+
     void createQTMovie(const String& url);
     void createQTMovie(NSURL *, NSDictionary *movieAttributes);
 
index f374d20..56b3d2f 100644 (file)
@@ -1517,6 +1517,27 @@ void MediaPlayerPrivateQTKit::setPrivateBrowsingMode(bool privateBrowsing)
     [m_qtMovie.get() setAttribute:[NSNumber numberWithBool:!privateBrowsing] forKey:@"QTMovieAllowPersistentCacheAttribute"];
 }
 
+bool MediaPlayerPrivateQTKit::canSaveMediaData() const
+{
+    URL url;
+
+    if (durationMediaTime().isPositiveInfinite())
+        return false;
+
+    if (m_qtMovie)
+        url = URL(wkQTMovieResolvedURL(m_qtMovie.get()));
+    else
+        url = URL(ParsedURLString, m_movieURL);
+
+    if (url.isLocalFile())
+        return true;
+
+    if (url.protocolIsInHTTPFamily())
+        return true;
+    
+    return false;
+}
+
 } // namespace WebCore
 
 @implementation WebCoreMovieObserver
index 6331ffb..1c37713 100644 (file)
@@ -507,9 +507,12 @@ void HitTestResult::toggleMediaMuteState() const
 
 bool HitTestResult::isDownloadableMedia() const
 {
-    // FIXME: We should actually answer instead of always returning true for media elements.
-    // https://bugs.webkit.org/show_bug.cgi?id=138530
-    return mediaElement() ? true : false;
+#if ENABLE(VIDEO)
+    if (HTMLMediaElement* mediaElt = mediaElement())
+        return mediaElt->canSaveMediaData();
+#endif
+
+    return false;
 }
 
 URL HitTestResult::absoluteLinkURL() const
index 0db7026..78100ad 100644 (file)
@@ -1,3 +1,21 @@
+2014-11-13  Eric Carlson  <eric.carlson@apple.com>
+
+        Context menus should not offer the "Download video" option for videos that cannot 
+        be downloaded
+        https://bugs.webkit.org/show_bug.cgi?id=138530
+        -and corresponding-
+        rdar://problem/18919130
+
+        Reviewed by Tim Horton.
+
+        Expose isDownloadableMedia() to the InjectedBundleHitTestResult.
+        * WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.cpp:
+        (WKBundleHitTestResultIsDownloadableMedia):
+        * WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.h:
+        * WebProcess/InjectedBundle/InjectedBundleHitTestResult.cpp:
+        (WebKit::InjectedBundleHitTestResult::isDownloadableMedia):
+        * WebProcess/InjectedBundle/InjectedBundleHitTestResult.h:
+
 2014-11-13  Daniel Bates  <dabates@apple.com>
 
         [iOS] NSGeometry data types are not available in the public SDK
index 5b9a011..b6dc379 100644 (file)
@@ -90,6 +90,11 @@ bool WKBundleHitTestResultMediaHasAudio(WKBundleHitTestResultRef hitTestResultRe
     return toImpl(hitTestResultRef)->mediaHasAudio();
 }
 
+bool WKBundleHitTestResultIsDownloadableMedia(WKBundleHitTestResultRef hitTestResultRef)
+{
+    return toImpl(hitTestResultRef)->isDownloadableMedia();
+}
+
 WKBundleHitTestResultMediaType WKBundleHitTestResultGetMediaType(WKBundleHitTestResultRef hitTestResultRef)
 {
     return toAPI(toImpl(hitTestResultRef)->mediaType());
index 40d3ccf..941beca 100644 (file)
@@ -54,6 +54,7 @@ WK_EXPORT WKURLRef WKBundleHitTestResultCopyAbsoluteLinkURL(WKBundleHitTestResul
 WK_EXPORT WKURLRef WKBundleHitTestResultCopyAbsoluteMediaURL(WKBundleHitTestResultRef hitTestResult);
 WK_EXPORT bool WKBundleHitTestResultMediaIsInFullscreen(WKBundleHitTestResultRef hitTestResult);
 WK_EXPORT bool WKBundleHitTestResultMediaHasAudio(WKBundleHitTestResultRef hitTestResult);
+WK_EXPORT bool WKBundleHitTestResultIsDownloadableMedia(WKBundleHitTestResultRef hitTestResultRef);
 WK_EXPORT WKBundleHitTestResultMediaType WKBundleHitTestResultGetMediaType(WKBundleHitTestResultRef hitTestResult);
 
 WK_EXPORT WKRect WKBundleHitTestResultGetImageRect(WKBundleHitTestResultRef hitTestResult);
index a4a5306..366fa33 100644 (file)
@@ -108,6 +108,11 @@ bool InjectedBundleHitTestResult::mediaHasAudio() const
     return m_hitTestResult.mediaHasAudio();
 }
 
+bool InjectedBundleHitTestResult::isDownloadableMedia() const
+{
+    return m_hitTestResult.isDownloadableMedia();
+}
+
 BundleHitTestResultMediaType InjectedBundleHitTestResult::mediaType() const
 {
 #if !ENABLE(VIDEO)
index 2c7e0e5..bb112dc 100644 (file)
@@ -55,6 +55,7 @@ public:
     String absoluteMediaURL() const;
     bool mediaIsInFullscreen() const;
     bool mediaHasAudio() const;
+    bool isDownloadableMedia() const;
     BundleHitTestResultMediaType mediaType() const;
 
     String linkLabel() const;