| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "third_party/blink/renderer/core/html/media/media_remoting_interstitial.h" |
| |
| #include "third_party/blink/public/platform/web_localized_string.h" |
| #include "third_party/blink/renderer/core/dom/document.h" |
| #include "third_party/blink/renderer/core/html/html_image_element.h" |
| #include "third_party/blink/renderer/core/html/media/html_video_element.h" |
| #include "third_party/blink/renderer/platform/bindings/exception_state.h" |
| #include "third_party/blink/renderer/platform/text/platform_locale.h" |
| |
| namespace { |
| |
| constexpr TimeDelta kStyleChangeTransitionDuration = |
| TimeDelta::FromMilliseconds(200); |
| constexpr TimeDelta kHiddenAnimationDuration = TimeDelta::FromMilliseconds(300); |
| constexpr TimeDelta kShowToastDuration = TimeDelta::FromSeconds(5); |
| |
| } // namespace |
| |
| namespace blink { |
| |
| MediaRemotingInterstitial::MediaRemotingInterstitial( |
| HTMLVideoElement& videoElement) |
| : HTMLDivElement(videoElement.GetDocument()), |
| toggle_interstitial_timer_( |
| videoElement.GetDocument().GetTaskRunner(TaskType::kInternalMedia), |
| this, |
| &MediaRemotingInterstitial::ToggleInterstitialTimerFired), |
| video_element_(&videoElement) { |
| SetShadowPseudoId(AtomicString("-internal-media-interstitial")); |
| background_image_ = HTMLImageElement::Create(GetDocument()); |
| background_image_->SetShadowPseudoId( |
| AtomicString("-internal-media-interstitial-background-image")); |
| background_image_->SetSrc(videoElement.getAttribute(html_names::kPosterAttr)); |
| AppendChild(background_image_); |
| |
| cast_icon_ = HTMLDivElement::Create(GetDocument()); |
| cast_icon_->SetShadowPseudoId( |
| AtomicString("-internal-media-remoting-cast-icon")); |
| AppendChild(cast_icon_); |
| |
| cast_text_message_ = HTMLDivElement::Create(GetDocument()); |
| cast_text_message_->SetShadowPseudoId( |
| AtomicString("-internal-media-interstitial-message")); |
| AppendChild(cast_text_message_); |
| |
| toast_message_ = HTMLDivElement::Create(GetDocument()); |
| toast_message_->SetShadowPseudoId( |
| AtomicString("-internal-media-remoting-toast-message")); |
| AppendChild(toast_message_); |
| } |
| |
| void MediaRemotingInterstitial::Show( |
| const WebString& remote_device_friendly_name) { |
| if (IsVisible()) |
| return; |
| if (remote_device_friendly_name.IsEmpty()) { |
| cast_text_message_->setInnerText( |
| GetVideoElement().GetLocale().QueryString( |
| WebLocalizedString::kMediaRemotingCastToUnknownDeviceText), |
| ASSERT_NO_EXCEPTION); |
| } else { |
| cast_text_message_->setInnerText( |
| GetVideoElement().GetLocale().QueryString( |
| WebLocalizedString::kMediaRemotingCastText, |
| remote_device_friendly_name), |
| ASSERT_NO_EXCEPTION); |
| } |
| if (toggle_interstitial_timer_.IsActive()) |
| toggle_interstitial_timer_.Stop(); |
| state_ = VISIBLE; |
| RemoveInlineStyleProperty(CSSPropertyDisplay); |
| SetInlineStyleProperty(CSSPropertyOpacity, 0, |
| CSSPrimitiveValue::UnitType::kNumber); |
| toggle_interstitial_timer_.StartOneShot(kStyleChangeTransitionDuration, |
| FROM_HERE); |
| } |
| |
| void MediaRemotingInterstitial::Hide(WebLocalizedString::Name error_msg) { |
| if (!IsVisible()) |
| return; |
| if (toggle_interstitial_timer_.IsActive()) |
| toggle_interstitial_timer_.Stop(); |
| if (error_msg == WebLocalizedString::kMediaRemotingStopNoText) { |
| state_ = HIDDEN; |
| } else { |
| String stop_text = GetVideoElement().GetLocale().QueryString( |
| WebLocalizedString::kMediaRemotingStopText); |
| if (error_msg != WebLocalizedString::kMediaRemotingStopText) { |
| stop_text = GetVideoElement().GetLocale().QueryString(error_msg) + ", " + |
| stop_text; |
| } |
| toast_message_->setInnerText(stop_text, ASSERT_NO_EXCEPTION); |
| state_ = TOAST; |
| } |
| SetInlineStyleProperty(CSSPropertyOpacity, 0, |
| CSSPrimitiveValue::UnitType::kNumber); |
| toggle_interstitial_timer_.StartOneShot(kHiddenAnimationDuration, FROM_HERE); |
| } |
| |
| void MediaRemotingInterstitial::ToggleInterstitialTimerFired(TimerBase*) { |
| toggle_interstitial_timer_.Stop(); |
| if (IsVisible()) { |
| // Show interstitial except the |toast_message_|. |
| background_image_->RemoveInlineStyleProperty(CSSPropertyDisplay); |
| cast_icon_->RemoveInlineStyleProperty(CSSPropertyDisplay); |
| cast_text_message_->RemoveInlineStyleProperty(CSSPropertyDisplay); |
| toast_message_->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone); |
| SetInlineStyleProperty(CSSPropertyBackgroundColor, CSSValueBlack); |
| SetInlineStyleProperty(CSSPropertyOpacity, 1, |
| CSSPrimitiveValue::UnitType::kNumber); |
| } else if (state_ == HIDDEN) { |
| SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone); |
| toast_message_->setInnerText(WebString(), ASSERT_NO_EXCEPTION); |
| } else { |
| // Show |toast_message_| only. |
| toast_message_->RemoveInlineStyleProperty(CSSPropertyDisplay); |
| SetInlineStyleProperty(CSSPropertyBackgroundColor, CSSValueTransparent); |
| SetInlineStyleProperty(CSSPropertyOpacity, 1, |
| CSSPrimitiveValue::UnitType::kNumber); |
| background_image_->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone); |
| cast_icon_->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone); |
| cast_text_message_->SetInlineStyleProperty(CSSPropertyDisplay, |
| CSSValueNone); |
| toast_message_->SetInlineStyleProperty( |
| CSSPropertyOpacity, 1, CSSPrimitiveValue::UnitType::kNumber); |
| state_ = HIDDEN; |
| toggle_interstitial_timer_.StartOneShot(kShowToastDuration, FROM_HERE); |
| } |
| } |
| |
| void MediaRemotingInterstitial::DidMoveToNewDocument(Document& old_document) { |
| toggle_interstitial_timer_.MoveToNewTaskRunner( |
| GetDocument().GetTaskRunner(TaskType::kInternalMedia)); |
| |
| HTMLDivElement::DidMoveToNewDocument(old_document); |
| } |
| |
| void MediaRemotingInterstitial::OnPosterImageChanged() { |
| background_image_->SetSrc( |
| GetVideoElement().getAttribute(html_names::kPosterAttr)); |
| } |
| |
| void MediaRemotingInterstitial::Trace(blink::Visitor* visitor) { |
| visitor->Trace(video_element_); |
| visitor->Trace(background_image_); |
| visitor->Trace(cast_icon_); |
| visitor->Trace(cast_text_message_); |
| visitor->Trace(toast_message_); |
| HTMLDivElement::Trace(visitor); |
| } |
| |
| } // namespace blink |