| // 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. |
| |
| #ifndef COMPONENTS_CAST_RECEIVER_BROWSER_RUNTIME_APPLICATION_DISPATCHER_IMPL_H_ |
| #define COMPONENTS_CAST_RECEIVER_BROWSER_RUNTIME_APPLICATION_DISPATCHER_IMPL_H_ |
| |
| #include <memory> |
| |
| #include "base/containers/flat_map.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/raw_ref.h" |
| #include "base/sequence_checker.h" |
| #include "components/cast_receiver/browser/application_client.h" |
| #include "components/cast_receiver/browser/public/application_config.h" |
| #include "components/cast_receiver/browser/public/runtime_application_dispatcher.h" |
| #include "components/cast_receiver/browser/runtime_application_base.h" |
| #include "components/cast_receiver/browser/streaming_runtime_application.h" |
| #include "components/cast_receiver/browser/web_runtime_application.h" |
| #include "components/cast_streaming/common/public/app_ids.h" |
| |
| namespace cast_receiver { |
| |
| template <typename TEmbedderApplication> |
| class RuntimeApplicationDispatcherImpl |
| : public RuntimeApplicationDispatcher<TEmbedderApplication> { |
| public: |
| // |application_client| is expected to persist for the lifetime of this |
| // instance. |
| explicit RuntimeApplicationDispatcherImpl( |
| ApplicationClient& application_client); |
| ~RuntimeApplicationDispatcherImpl() override = default; |
| |
| RuntimeApplicationDispatcherImpl(RuntimeApplicationDispatcherImpl& other) = |
| delete; |
| RuntimeApplicationDispatcherImpl& operator=( |
| RuntimeApplicationDispatcherImpl& other) = delete; |
| |
| private: |
| using EmbedderApplicationFactory = typename RuntimeApplicationDispatcher< |
| TEmbedderApplication>::EmbedderApplicationFactory; |
| |
| // RuntimeApplicationDispatcher implementation. |
| TEmbedderApplication* CreateApplication( |
| std::string session_id, |
| ApplicationConfig app_config, |
| EmbedderApplicationFactory factory) override; |
| TEmbedderApplication* GetApplication(const std::string& session_id) override; |
| std::unique_ptr<TEmbedderApplication> DestroyApplication( |
| const std::string& session_id) override; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| raw_ref<ApplicationClient> const application_client_; |
| |
| base::flat_map<std::string, std::unique_ptr<TEmbedderApplication>> |
| loaded_apps_; |
| }; |
| |
| template <typename TEmbedderApplication> |
| RuntimeApplicationDispatcherImpl<TEmbedderApplication>:: |
| RuntimeApplicationDispatcherImpl(ApplicationClient& application_client) |
| : application_client_(application_client) {} |
| |
| template <typename TEmbedderApplication> |
| TEmbedderApplication* |
| RuntimeApplicationDispatcherImpl<TEmbedderApplication>::CreateApplication( |
| std::string session_id, |
| ApplicationConfig app_config, |
| EmbedderApplicationFactory factory) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| |
| std::unique_ptr<RuntimeApplicationBase> app; |
| if (cast_streaming::IsStreamingReceiverAppId(app_config.app_id)) { |
| app = std::make_unique<StreamingRuntimeApplication>( |
| session_id, std::move(app_config), *application_client_); |
| } else { |
| app = std::make_unique<WebRuntimeApplication>( |
| session_id, std::move(app_config), *application_client_); |
| } |
| |
| // TODO(b/232140331): Call this only when foreground app changes. |
| application_client_->OnForegroundApplicationChanged(app.get()); |
| |
| auto* app_ptr = app.get(); |
| std::unique_ptr<TEmbedderApplication> embedder_app = |
| std::move(factory).Run(std::move(app)); |
| app_ptr->SetEmbedderApplication(*embedder_app); |
| |
| auto [iter, success] = |
| loaded_apps_.emplace(std::move(session_id), std::move(embedder_app)); |
| DCHECK(success); |
| return iter->second.get(); |
| } |
| |
| template <typename TEmbedderApplication> |
| TEmbedderApplication* |
| RuntimeApplicationDispatcherImpl<TEmbedderApplication>::GetApplication( |
| const std::string& session_id) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| |
| auto iter = loaded_apps_.find(session_id); |
| return iter == loaded_apps_.end() ? nullptr : iter->second.get(); |
| } |
| |
| template <typename TEmbedderApplication> |
| std::unique_ptr<TEmbedderApplication> |
| RuntimeApplicationDispatcherImpl<TEmbedderApplication>::DestroyApplication( |
| const std::string& session_id) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| |
| auto iter = loaded_apps_.find(session_id); |
| if (iter == loaded_apps_.end()) { |
| return nullptr; |
| } |
| |
| auto app = std::move(iter->second); |
| loaded_apps_.erase(iter); |
| |
| // TODO(b/232140331): Call this only when foreground app changes. |
| application_client_->OnForegroundApplicationChanged(nullptr); |
| return app; |
| } |
| |
| } // namespace cast_receiver |
| |
| #endif // COMPONENTS_CAST_RECEIVER_BROWSER_RUNTIME_APPLICATION_DISPATCHER_IMPL_H_ |