Commit bacf2a1a authored by tommycli's avatar tommycli Committed by Commit bot

Plugin Power Saver: Implement srcset syntax for posters.

The objective of the patch is that the poster attribute for plugins can support high-dpi images via the img srcset syntax, i.e.

<param name="poster" value="poster1x.png 1x, poster2x.png 2x" />

BUG=457333

Review URL: https://codereview.chromium.org/981623003

Cr-Commit-Position: refs/heads/master@{#319689}
parent 078a2199
...@@ -318,17 +318,17 @@ void TrackPosterParamPresence(const blink::WebPluginParams& params, ...@@ -318,17 +318,17 @@ void TrackPosterParamPresence(const blink::WebPluginParams& params,
RecordPosterParamPresence(POSTER_PRESENCE_NO_PARAM_PPS_DISABLED); RecordPosterParamPresence(POSTER_PRESENCE_NO_PARAM_PPS_DISABLED);
} }
GURL GetPluginInstancePosterImage(const blink::WebPluginParams& params, std::string GetPluginInstancePosterAttribute(
const GURL& page_base_url) { const blink::WebPluginParams& params) {
DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size());
for (size_t i = 0; i < params.attributeNames.size(); ++i) { for (size_t i = 0; i < params.attributeNames.size(); ++i) {
if (params.attributeNames[i].utf8() == "poster" && if (params.attributeNames[i].utf8() == "poster" &&
!params.attributeValues[i].isEmpty()) { !params.attributeValues[i].isEmpty()) {
return page_base_url.Resolve(params.attributeValues[i].utf8()); return params.attributeValues[i].utf8();
} }
} }
return GURL(); return std::string();
} }
#endif #endif
...@@ -796,10 +796,10 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( ...@@ -796,10 +796,10 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
auto create_blocked_plugin = auto create_blocked_plugin =
[&render_frame, &frame, &params, &info, &identifier, &group_name]( [&render_frame, &frame, &params, &info, &identifier, &group_name](
int template_id, const base::string16& message) { int template_id, const base::string16& message) {
return ChromePluginPlaceholder::CreateBlockedPlugin( return ChromePluginPlaceholder::CreateBlockedPlugin(
render_frame, frame, params, info, identifier, group_name, render_frame, frame, params, info, identifier, group_name,
template_id, message, GURL()); template_id, message, std::string(), GURL());
}; };
switch (status_value) { switch (status_value) {
case ChromeViewHostMsg_GetPluginInfo_Status::kNotFound: { case ChromeViewHostMsg_GetPluginInfo_Status::kNotFound: {
NOTREACHED(); NOTREACHED();
...@@ -878,11 +878,9 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( ...@@ -878,11 +878,9 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
if (info.name == ASCIIToUTF16(content::kFlashPluginName)) if (info.name == ASCIIToUTF16(content::kFlashPluginName))
TrackPosterParamPresence(params, power_saver_enabled); TrackPosterParamPresence(params, power_saver_enabled);
GURL poster_url; std::string poster_attribute;
if (power_saver_enabled) { if (power_saver_enabled)
poster_url = poster_attribute = GetPluginInstancePosterAttribute(params);
GetPluginInstancePosterImage(params, frame->document().url());
}
// Delay loading plugins if prerendering. // Delay loading plugins if prerendering.
// TODO(mmenke): In the case of prerendering, feed into // TODO(mmenke): In the case of prerendering, feed into
...@@ -891,13 +889,13 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( ...@@ -891,13 +889,13 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
bool is_prerendering = bool is_prerendering =
prerender::PrerenderHelper::IsPrerendering(render_frame); prerender::PrerenderHelper::IsPrerendering(render_frame);
if (blocked_for_background_tab || is_prerendering || if (blocked_for_background_tab || is_prerendering ||
poster_url.is_valid()) { !poster_attribute.empty()) {
placeholder = ChromePluginPlaceholder::CreateBlockedPlugin( placeholder = ChromePluginPlaceholder::CreateBlockedPlugin(
render_frame, frame, params, info, identifier, group_name, render_frame, frame, params, info, identifier, group_name,
poster_url.is_valid() ? IDR_PLUGIN_POSTER_HTML poster_attribute.empty() ? IDR_BLOCKED_PLUGIN_HTML
: IDR_BLOCKED_PLUGIN_HTML, : IDR_PLUGIN_POSTER_HTML,
l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name), l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name),
poster_url); poster_attribute, frame->document().url());
placeholder->set_blocked_for_background_tab( placeholder->set_blocked_for_background_tab(
blocked_for_background_tab); blocked_for_background_tab);
placeholder->set_blocked_for_prerendering(is_prerendering); placeholder->set_blocked_for_prerendering(is_prerendering);
......
...@@ -153,14 +153,17 @@ ChromePluginPlaceholder* ChromePluginPlaceholder::CreateBlockedPlugin( ...@@ -153,14 +153,17 @@ ChromePluginPlaceholder* ChromePluginPlaceholder::CreateBlockedPlugin(
const base::string16& name, const base::string16& name,
int template_id, int template_id,
const base::string16& message, const base::string16& message,
const GURL& poster_url) { const std::string& poster_attribute,
const GURL& base_url) {
base::DictionaryValue values; base::DictionaryValue values;
values.SetString("message", message); values.SetString("message", message);
values.SetString("name", name); values.SetString("name", name);
values.SetString("hide", l10n_util::GetStringUTF8(IDS_PLUGIN_HIDE)); values.SetString("hide", l10n_util::GetStringUTF8(IDS_PLUGIN_HIDE));
if (poster_url.is_valid()) if (!poster_attribute.empty()) {
values.SetString("background", "url('" + poster_url.spec() + "')"); values.SetString("poster", poster_attribute);
values.SetString("baseurl", base_url.spec());
}
const base::StringPiece template_html( const base::StringPiece template_html(
ResourceBundle::GetSharedInstance().GetRawDataResource(template_id)); ResourceBundle::GetSharedInstance().GetRawDataResource(template_id));
...@@ -174,7 +177,7 @@ ChromePluginPlaceholder* ChromePluginPlaceholder::CreateBlockedPlugin( ...@@ -174,7 +177,7 @@ ChromePluginPlaceholder* ChromePluginPlaceholder::CreateBlockedPlugin(
render_frame, frame, params, html_data, name); render_frame, frame, params, html_data, name);
#if defined(ENABLE_PLUGINS) #if defined(ENABLE_PLUGINS)
if (poster_url.is_valid()) if (!poster_attribute.empty())
blocked_plugin->BlockForPowerSaverPoster(); blocked_plugin->BlockForPowerSaverPoster();
#endif #endif
blocked_plugin->SetPluginInfo(info); blocked_plugin->SetPluginInfo(info);
......
...@@ -17,6 +17,8 @@ class ChromePluginPlaceholder : public plugins::LoadablePluginPlaceholder, ...@@ -17,6 +17,8 @@ class ChromePluginPlaceholder : public plugins::LoadablePluginPlaceholder,
public: public:
static const char kPluginPlaceholderDataURL[]; static const char kPluginPlaceholderDataURL[];
// If |poster_attribute| contains relative paths, |base_url| must be
// non-empty. This is so the placeholder can resolve the relative paths.
static ChromePluginPlaceholder* CreateBlockedPlugin( static ChromePluginPlaceholder* CreateBlockedPlugin(
content::RenderFrame* render_frame, content::RenderFrame* render_frame,
blink::WebLocalFrame* frame, blink::WebLocalFrame* frame,
...@@ -26,7 +28,8 @@ class ChromePluginPlaceholder : public plugins::LoadablePluginPlaceholder, ...@@ -26,7 +28,8 @@ class ChromePluginPlaceholder : public plugins::LoadablePluginPlaceholder,
const base::string16& name, const base::string16& name,
int resource_id, int resource_id,
const base::string16& message, const base::string16& message,
const GURL& poster_url); const std::string& poster_attribute,
const GURL& base_url);
// Creates a new WebViewPlugin with a MissingPlugin as a delegate. // Creates a new WebViewPlugin with a MissingPlugin as a delegate.
static ChromePluginPlaceholder* CreateMissingPlugin( static ChromePluginPlaceholder* CreateMissingPlugin(
......
...@@ -61,7 +61,7 @@ void PluginPreroller::OnThrottleStateChange() { ...@@ -61,7 +61,7 @@ void PluginPreroller::OnThrottleStateChange() {
ChromePluginPlaceholder* placeholder = ChromePluginPlaceholder* placeholder =
ChromePluginPlaceholder::CreateBlockedPlugin( ChromePluginPlaceholder::CreateBlockedPlugin(
render_frame(), frame_, params_, info_, identifier_, name_, render_frame(), frame_, params_, info_, identifier_, name_,
IDR_PLUGIN_POSTER_HTML, message_, keyframe_data_url_); IDR_PLUGIN_POSTER_HTML, message_, keyframe_data_url_.spec(), GURL());
placeholder->SetPremadePlugin(throttler_); placeholder->SetPremadePlugin(throttler_);
placeholder->set_power_saver_enabled(true); placeholder->set_power_saver_enabled(true);
placeholder->set_allow_loading(true); placeholder->set_allow_loading(true);
......
...@@ -19,18 +19,19 @@ document.onkeydown = function(e) { ...@@ -19,18 +19,19 @@ document.onkeydown = function(e) {
<link rel="stylesheet" href="plugin_placeholders.css"></link> <link rel="stylesheet" href="plugin_placeholders.css"></link>
<style> <style>
#outer { #outer {
position: relative;
border: none; border: none;
cursor: pointer; cursor: pointer;
background-position: center;
background-repeat: no-repeat;
background-size: contain;
} }
#shielding { #shielding {
background-color: rgba(0, 0, 0, 0.5); background-color: rgba(0, 0, 0, 0.5);
height: 100%;
position: absolute; position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%; width: 100%;
z-index: 2;
} }
#plugin_icon { #plugin_icon {
...@@ -41,15 +42,22 @@ document.onkeydown = function(e) { ...@@ -41,15 +42,22 @@ document.onkeydown = function(e) {
opacity: 0.95; opacity: 0.95;
} }
#poster {
height: 100%;
width: 100%;
z-index: 1;
}
#inner { #inner {
margin-top: -25px; margin-top: -25px;
} }
</style> </style>
<base i18n-values="href:baseurl">
</head> </head>
<body onload="notifyDidFinishLoading();"> <body onload="notifyDidFinishLoading();">
<div i18n-values="title:name;.style.background-image:background" id="outer" <div i18n-values="title:name" id="outer" onclick="plugin.load()">
onclick="plugin.load()"> <img id="poster" i18n-values="srcset:poster">
<div id="shielding"> <div id="shielding">
<div id="inner"> <div id="inner">
<div><img id="plugin_icon" src="plugin_power_saver_play.png" /></div> <div><img id="plugin_icon" src="plugin_power_saver_play.png" /></div>
......
...@@ -22,6 +22,8 @@ PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame, ...@@ -22,6 +22,8 @@ PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame,
render_frame->GetWebkitPreferences(), render_frame->GetWebkitPreferences(),
html_data, html_data,
placeholderDataUrl)) { placeholderDataUrl)) {
DCHECK(placeholderDataUrl.is_valid())
<< "Blink requires the placeholder to have a valid URL.";
} }
PluginPlaceholder::~PluginPlaceholder() {} PluginPlaceholder::~PluginPlaceholder() {}
......
...@@ -109,8 +109,13 @@ WebPluginContainer* WebViewPlugin::container() const { return container_; } ...@@ -109,8 +109,13 @@ WebPluginContainer* WebViewPlugin::container() const { return container_; }
bool WebViewPlugin::initialize(WebPluginContainer* container) { bool WebViewPlugin::initialize(WebPluginContainer* container) {
container_ = container; container_ = container;
if (container_) if (container_) {
old_title_ = container_->element().getAttribute("title"); old_title_ = container_->element().getAttribute("title");
// Propagate device scale to inner webview to load the correct resource
// when images have a "srcset" attribute.
web_view_->setDeviceScaleFactor(container_->deviceScaleFactor());
}
return true; return true;
} }
...@@ -136,8 +141,14 @@ void WebViewPlugin::paint(WebCanvas* canvas, const WebRect& rect) { ...@@ -136,8 +141,14 @@ void WebViewPlugin::paint(WebCanvas* canvas, const WebRect& rect) {
paint_rect.Offset(-rect_.x(), -rect_.y()); paint_rect.Offset(-rect_.x(), -rect_.y());
canvas->translate(SkIntToScalar(rect_.x()), SkIntToScalar(rect_.y()));
canvas->save(); canvas->save();
canvas->translate(SkIntToScalar(rect_.x()), SkIntToScalar(rect_.y()));
// Apply inverse device scale factor, as the outer webview has already
// applied it, and the inner webview will apply it again.
SkScalar inverse_scale =
SkFloatToScalar(1.0 / container_->deviceScaleFactor());
canvas->scale(inverse_scale, inverse_scale);
web_view_->layout(); web_view_->layout();
web_view_->paint(canvas, paint_rect); web_view_->paint(canvas, paint_rect);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment