| // Copyright 2016 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 "chrome/browser/chromeos/arc/video/gpu_arc_video_service_host.h" |
| |
| #include <string> |
| #include <utility> |
| |
| #include "base/location.h" |
| #include "base/logging.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "components/arc/arc_bridge_service.h" |
| #include "components/arc/common/video_decode_accelerator.mojom.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/gpu_service_registry.h" |
| #include "mojo/edk/embedder/embedder.h" |
| #include "mojo/edk/embedder/outgoing_broker_client_invitation.h" |
| #include "mojo/edk/embedder/platform_channel_pair.h" |
| #include "mojo/public/cpp/bindings/strong_binding.h" |
| #include "services/service_manager/public/cpp/interface_provider.h" |
| |
| namespace arc { |
| |
| namespace { |
| |
| void ConnectToVideoDecodeAcceleratorOnIOThread( |
| mojom::VideoDecodeAcceleratorRequest request) { |
| content::BindInterfaceInGpuProcess(std::move(request)); |
| } |
| |
| } // namespace |
| |
| class VideoAcceleratorFactoryService : public mojom::VideoAcceleratorFactory { |
| public: |
| VideoAcceleratorFactoryService() = default; |
| |
| void CreateDecodeAccelerator( |
| mojom::VideoDecodeAcceleratorRequest request) override { |
| content::BrowserThread::PostTask( |
| content::BrowserThread::IO, FROM_HERE, |
| base::BindOnce(&ConnectToVideoDecodeAcceleratorOnIOThread, |
| base::Passed(&request))); |
| } |
| |
| void CreateEncodeAccelerator( |
| mojom::VideoEncodeAcceleratorRequest request) override { |
| // TODO(owenlin): Implement this function. |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(VideoAcceleratorFactoryService); |
| }; |
| |
| GpuArcVideoServiceHost::GpuArcVideoServiceHost(ArcBridgeService* bridge_service) |
| : ArcService(bridge_service), binding_(this) { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| arc_bridge_service()->video()->AddObserver(this); |
| } |
| |
| GpuArcVideoServiceHost::~GpuArcVideoServiceHost() { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| arc_bridge_service()->video()->RemoveObserver(this); |
| } |
| |
| void GpuArcVideoServiceHost::OnInstanceReady() { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| auto* video_instance = |
| ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service()->video(), Init); |
| DCHECK(video_instance); |
| mojom::VideoHostPtr host_proxy; |
| binding_.Bind(mojo::MakeRequest(&host_proxy)); |
| video_instance->Init(std::move(host_proxy)); |
| } |
| |
| void GpuArcVideoServiceHost::OnBootstrapVideoAcceleratorFactory( |
| const OnBootstrapVideoAcceleratorFactoryCallback& callback) { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| |
| // Hardcode pid 0 since it is unused in mojo. |
| const base::ProcessHandle kUnusedChildProcessHandle = |
| base::kNullProcessHandle; |
| mojo::edk::OutgoingBrokerClientInvitation invitation; |
| mojo::edk::PlatformChannelPair channel_pair; |
| std::string token = mojo::edk::GenerateRandomToken(); |
| mojo::ScopedMessagePipeHandle server_pipe = |
| invitation.AttachMessagePipe(token); |
| invitation.Send( |
| kUnusedChildProcessHandle, |
| mojo::edk::ConnectionParams(mojo::edk::TransportProtocol::kLegacy, |
| channel_pair.PassServerHandle())); |
| |
| MojoHandle wrapped_handle; |
| MojoResult wrap_result = mojo::edk::CreatePlatformHandleWrapper( |
| channel_pair.PassClientHandle(), &wrapped_handle); |
| if (wrap_result != MOJO_RESULT_OK) { |
| LOG(ERROR) << "Pipe failed to wrap handles. Closing: " << wrap_result; |
| callback.Run(mojo::ScopedHandle(), std::string()); |
| return; |
| } |
| mojo::ScopedHandle child_handle{mojo::Handle(wrapped_handle)}; |
| |
| callback.Run(std::move(child_handle), token); |
| |
| mojo::MakeStrongBinding( |
| base::MakeUnique<VideoAcceleratorFactoryService>(), |
| mojom::VideoAcceleratorFactoryRequest(std::move(server_pipe))); |
| } |
| |
| } // namespace arc |