[iPhone] Playing a video on tudou.com plays only sound, no video
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Jul 2016 22:41:57 +0000 (22:41 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Jul 2016 22:41:57 +0000 (22:41 +0000)
commit008223569307c7c0b9f4c2ec9ac96688eb7f1e06
treef91d1516a6c6da776b188a700d5aa5345e801738
parent4c885942f8e2f9f0286ab1e328624b32928986f3
[iPhone] Playing a video on tudou.com plays only sound, no video
https://bugs.webkit.org/show_bug.cgi?id=159967
<rdar://problem/26964090>

Reviewed by Jon Lee.

Source/WebCore:

WebKit recently starting honoring the playsinline and webkit-playsinline
attribute on iPhones. However, because these attributes previously did
nothing, some sites (such as Todou) were setting them on their content
and expecting that they are not honored. In this specific case, the
video is absolutely positioned to be 1 pixel x 1 pixel.

Previously, with iOS 9, apps could set the allowsInlineMediaPlayback
property on their WKWebView, which would honor the webkit-playsinline
attribute. Safari on iPhones didn't do this.

In order to not break these existing apps, it's important that the
allowsInlineMediaPlayback preference still allows webkit-playsinline
videos to play inline in apps using WKWebView. However, in Safari, these
videos should play fullscreen. (Todou videos have webkit-playsinline
but not playsinline.)

Therefore, in Safari, videos with playsinline should be inline, but
videos with webkit-playsinline should be fullscreen. In apps using
WKWebViews, if the app sets allowsInlineMediaPlayback, then videos with
playsinline should be inline, and videos with webkit-playsinline should
also be inline. Videos on iPad and Mac should all be inline by default.

We can create some truth tables for the cases which need to be covered:

All apps on Mac / iPad:
Presence of playsinline | Presence of webkit-playsinline | Result
========================|================================|===========
Not present             | Not present                    | Inline
Present                 | Not present                    | Inline
Not Present             | Present                        | Inline
Present                 | Present                        | Inline

Safari on iPhone:
Presence of playsinline | Presence of webkit-playsinline | Result
========================|================================|===========
Not present             | Not present                    | Fullscreen
Present                 | Not present                    | Inline
Not Present             | Present                        | Fullscreen
Present                 | Present                        | Inline

App on iPhone which sets allowsInlineMediaPlayback:
Presence of playsinline | Presence of webkit-playsinline | Result
========================|================================|===========
Not present             | Not present                    | Fullscreen
Present                 | Not present                    | Inline
Not Present             | Present                        | Inline
Present                 | Present                        | Inline

The way to distinguish Safari from another app is to create an SPI
boolean preference which Safari can set. This is already how the
iPhone and iPad are differentiated using the requiresPlayInlineAttribute
which Safari sets but other apps don't. However, this preference is
no longer sufficient because Safari should now be discriminating
between the playsinline and webkit-playsinline attributes. Therefore,
this preference should be extended to two boolean preferences, which
this patch adds:

allowsInlineMediaPlaybackWithPlaysInlineAttribute
allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute

Safari on iPhone will set
allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute to true,
and allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute to
false. Other apps on iPhone will get their defaults values (because they
are SPI) which means they will both be true. On iPad and Mac, apps will
use the defaults values where both are false.

This patch adds support for these two preferences, but does not remove
the existing inlineMediaPlaybackRequiresPlaysInlineAttribute preference.
I will remove the exising preference as soon as I update Safari to migrate
off of it.

Test: media/video-playsinline.html

* html/MediaElementSession.cpp:
(WebCore::MediaElementSession::requiresFullscreenForVideoPlayback):
* page/Settings.cpp:
* page/Settings.in:
* testing/InternalSettings.cpp:
(WebCore::InternalSettings::Backup::Backup):
(WebCore::InternalSettings::Backup::restoreTo):
(WebCore::InternalSettings::setAllowsInlineMediaPlaybackWithPlaysInlineAttribute):
(WebCore::InternalSettings::setAllowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute):
* testing/InternalSettings.h:
* testing/InternalSettings.idl:

Source/WebKit/mac:

Add the two preferences to WebPreferences.

* WebView/WebPreferenceKeysPrivate.h:
* WebView/WebPreferences.mm:
(+[WebPreferences initialize]):
(-[WebPreferences allowsInlineMediaPlaybackWithPlaysInlineAttribute]):
(-[WebPreferences setAllowsInlineMediaPlaybackWithPlaysInlineAttribute:]):
(-[WebPreferences allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute]):
(-[WebPreferences setAllowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute:]):
* WebView/WebPreferencesPrivate.h:
* WebView/WebView.mm:
(-[WebView _preferencesChanged:]):

Source/WebKit2:

Add the two preferences to WKWebViewConfiguration and WKPreferences to cover both
the Obj-C API and the C SPI.

* Shared/WebPreferencesDefinitions.h:
* UIProcess/API/C/WKPreferences.cpp:
(WKPreferencesSetAllowsInlineMediaPlaybackWithPlaysInlineAttribute):
(WKPreferencesGetAllowsInlineMediaPlaybackWithPlaysInlineAttribute):
(WKPreferencesSetAllowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute):
(WKPreferencesGetAllowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute):
* UIProcess/API/C/WKPreferencesRefPrivate.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _initializeWithConfiguration:]):
* UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
(-[WKWebViewConfiguration init]):
(-[WKWebViewConfiguration copyWithZone:]):
(-[WKWebViewConfiguration _allowsInlineMediaPlaybackWithPlaysInlineAttribute]):
(-[WKWebViewConfiguration _setAllowsInlineMediaPlaybackWithPlaysInlineAttribute:]):
(-[WKWebViewConfiguration _allowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute]):
(-[WKWebViewConfiguration _setAllowsInlineMediaPlaybackWithWebKitPlaysInlineAttribute:]):
* UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::updatePreferences):

LayoutTests:

* media/video-playsinline.html: Updated.
* media/video-webkit-playsinline-expected.txt: Removed.
* media/video-webkit-playsinline.html: Removed.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@203471 268f45cc-cd09-0410-ab3c-d52691b4dbfc
25 files changed:
LayoutTests/ChangeLog
LayoutTests/media/video-playsinline-expected.txt
LayoutTests/media/video-playsinline.html
LayoutTests/media/video-webkit-playsinline-expected.txt [deleted file]
LayoutTests/media/video-webkit-playsinline.html [deleted file]
Source/WebCore/ChangeLog
Source/WebCore/html/MediaElementSession.cpp
Source/WebCore/page/Settings.cpp
Source/WebCore/page/Settings.in
Source/WebCore/testing/InternalSettings.cpp
Source/WebCore/testing/InternalSettings.h
Source/WebCore/testing/InternalSettings.idl
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebPreferenceKeysPrivate.h
Source/WebKit/mac/WebView/WebPreferences.mm
Source/WebKit/mac/WebView/WebPreferencesPrivate.h
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/WebPreferencesDefinitions.h
Source/WebKit2/UIProcess/API/C/WKPreferences.cpp
Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h
Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfiguration.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp