| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/cast_receiver/browser/streaming_runtime_application.h" |
| |
| #include "base/strings/stringprintf.h" |
| #include "components/cast/message_port/platform_message_port.h" |
| #include "components/cast_receiver/browser/application_client.h" |
| #include "components/cast_receiver/browser/public/embedder_application.h" |
| #include "components/cast_receiver/browser/public/message_port_service.h" |
| #include "components/cast_streaming/common/public/app_ids.h" |
| #include "components/cast_streaming/common/public/cast_streaming_url.h" |
| #include "content/public/browser/navigation_handle.h" |
| #include "content/public/browser/web_contents.h" |
| #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" |
| |
| namespace cast_receiver { |
| namespace { |
| |
| constexpr char kCastTransportBindingName[] = "cast.__platform__.cast_transport"; |
| |
| constexpr char kStreamingPageUrlTemplate[] = |
| "data:text/html;charset=UTF-8, <video style='position:absolute; " |
| "top:50%%; left:50%%; transform:translate(-50%%,-50%%); " |
| "max-width:100%%; max-height:100%%; min-width: 100%%; min-height: 100%%' " |
| "src='%s'></video>"; |
| |
| } // namespace |
| |
| StreamingRuntimeApplication::StreamingRuntimeApplication( |
| std::string cast_session_id, |
| ApplicationConfig app_config, |
| ApplicationClient& application_client) |
| : RuntimeApplicationBase(std::move(cast_session_id), |
| std::move(app_config), |
| application_client) {} |
| |
| StreamingRuntimeApplication::~StreamingRuntimeApplication() { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| StopApplication(EmbedderApplication::ApplicationStopReason::kUserRequest, |
| net::OK); |
| } |
| |
| void StreamingRuntimeApplication::OnStreamingSessionStarted() { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| OnPageNavigationComplete(); |
| } |
| |
| void StreamingRuntimeApplication::OnError() { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| LOG(WARNING) << "Streaming session for " << *this << " has hit an error!"; |
| StopApplication(EmbedderApplication::ApplicationStopReason::kRuntimeError, |
| net::ERR_FAILED); |
| } |
| |
| void StreamingRuntimeApplication::Launch(StatusCallback callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| |
| DCHECK(embedder_application().GetWebContents()); |
| SetContentPermissions(*embedder_application().GetWebContents()); |
| |
| // Bind Cast Transport. |
| auto* message_port_service = embedder_application().GetMessagePortService(); |
| DCHECK(message_port_service); |
| std::unique_ptr<cast_api_bindings::MessagePort> server_port; |
| std::unique_ptr<cast_api_bindings::MessagePort> client_port; |
| cast_api_bindings::CreatePlatformMessagePortPair(&client_port, &server_port); |
| message_port_service->ConnectToPortAsync(kCastTransportBindingName, |
| std::move(client_port)); |
| |
| // Initialize the streaming receiver. |
| receiver_session_client_ = std::make_unique<StreamingReceiverSessionClient>( |
| task_runner(), application_client().network_context_getter(), |
| std::move(server_port), embedder_application().GetWebContents(), this, |
| embedder_application().GetStreamingConfigManager(), |
| /* supports_audio= */ GetAppId() != |
| cast_streaming::GetIosAppStreamingAudioVideoAppId(), |
| /* supports_video= */ true); |
| receiver_session_client_->LaunchStreamingReceiverAsync(); |
| |
| // Application is initialized now - we can load the URL. |
| NavigateToPage(GURL(base::StringPrintf( |
| kStreamingPageUrlTemplate, |
| cast_streaming::GetCastStreamingMediaSourceUrl().spec().c_str()))); |
| |
| // Signal that application is launching. |
| std::move(callback).Run(OkStatus()); |
| } |
| |
| void StreamingRuntimeApplication::StopApplication( |
| EmbedderApplication::ApplicationStopReason stop_reason, |
| net::Error net_error_code) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| if (!receiver_session_client_) { |
| DLOG(WARNING) << "Streaming session never started prior to " << *this |
| << " stop."; |
| } |
| |
| receiver_session_client_.reset(); |
| RuntimeApplicationBase::StopApplication(stop_reason, net_error_code); |
| } |
| |
| bool StreamingRuntimeApplication::IsStreamingApplication() const { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| return true; |
| } |
| |
| } // namespace cast_receiver |