In short, the existing content API does not notify the embedder about
whether we
are
entering fullscreen for a video element or not and the WebView needs to know
this.
First, let me explain the background behind this change and hopefully clear
your confusion. Also, I will propose an alternative solution that I'd be
happy
to implement if you prefer.
Currently, the Android WebView does only support fullscreen for video
elements.
Whenever we want to enter/exit fullscreen we notify the app by calling
WebChromeClient.onShowCustomView/onHideCustomView:
http://developer.android.com/reference/android/webkit/WebChromeClient.html
The app then decides where they want to place the custom view, it might
occupy
the whole screen, or just a part of it. Note that the WebView does not own
the
view
hierarchy so we'are not allowed to modify it (this is different to Clank).
In
the
WebView it is up to the app to decide what to do when entering fullscreen.
As you noted, in order to support the MSE/EME extensions we need hardware
acceleration. For
that we create the ContentVideoView. So to enter fullscreen we call
onShowCustomView and pass
a ViewGroup containing the ContentVideoView (to render the video frames)
and a
FullscreenView
(to render the html5 video controls).
Now we want to add support for fullscreen for non-video elements and we
need to
ensure that:
- the above still applies, only the app can choose where to place the custom
view
- the same API is shared between video and non-video
- support for non-video does not break backwards compatibility
- (nice to have) support for non-video works out of the box and does not
require
modifications
to the apps
Given those constraints we'd like to reuse the existing WebView API. So for
non-video we will need to call onShowCustomView and pass just a
FullscreenView
(to render the
non-video element in fullscreen). So in summary, THE WEBVIEW NEEDS TO KNOW
WHETHER WE ARE GOING
FULLSCREEN ON A VIDEO ELEMENT OR NOT BECAUSE:
- for video we need to call onShowCustomView with a ViewGroup containing a
FullscreenView and
a ContentVideoView
- for non-video we need to call onShowCustomView with just a FullscreenView.
With the existing content API we don't know whether we are going fullscreen
on a
video element
or not. I could modify the ToggleFullscreenMode API to take an extra
argument
(bool isVideo) as
shown here:
https://codereview.chromium.org/652673002/
https://codereview.chromium.org/646403002/
Let me know if you prefer that solution and I'd happily implement it here.
It is
not a clear-cut
decision, but there are reasons why I prefer the approach in this patch.
Let me
explain those.
With the current approach only ContentViewCore needs to be aware of the
distinction between
video and non-video. I believe that this makes the code simpler and easier
to
understand. It also
makes the order of events consistent:
1. toggleFullscreenMode is called
2. didEnterFullscreenMode is called
3. (only for video) ContentVideoView is created
4. and finally onShowCustomView is called
If instead we modify the ToggleFullscreenMode API then we need to propagate
the
isVideo argument
from blink to the embedder, which means that blink, IPCs, etc. also need to
be
aware of the distinction.
It also makes the order in which events happen inconsistent between video
and
non video:
- for video:
1. ToggleFullscreen is called
2. DidEnterFullscreen is called
3. ContentVideoView is created
3. onShowCustomView is called
- for non-video:
1. ToggleFullscreen is called
2. onShowCustomView is called
3. DidEnterFullscreen is called
So in summary I think that the current approach makes the code simpler. But
if
you prefer
I could modify the ToggleFullscreen API instead. A different solution that I
haven't explored is
to create the ContentVideoView before
AwWebContentsDelegate.toggleFullscreenModeForTab is called,
but I suspect that that's not possible because we should only create the
ContentVideoView when
FullscreenController.didEnterFullscreen is called.
Please do let me know if things are clearer now.
https://codereview.chromium.org/618013003/