| /* |
| * Copyright (C) 2012 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following disclaimer |
| * in the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "third_party/blink/public/platform/platform.h" |
| |
| #include <memory> |
| |
| #include "base/single_thread_task_runner.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "base/trace_event/memory_dump_manager.h" |
| #include "build/build_config.h" |
| #include "services/service_manager/public/cpp/connector.h" |
| #include "services/service_manager/public/cpp/interface_provider.h" |
| #include "third_party/blink/public/platform/interface_provider.h" |
| #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h" |
| #include "third_party/blink/public/platform/web_canvas_capture_handler.h" |
| #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" |
| #include "third_party/blink/public/platform/web_image_capture_frame_grabber.h" |
| #include "third_party/blink/public/platform/web_media_recorder_handler.h" |
| #include "third_party/blink/public/platform/web_media_stream_center.h" |
| #include "third_party/blink/public/platform/web_prerendering_support.h" |
| #include "third_party/blink/public/platform/web_rtc_certificate_generator.h" |
| #include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h" |
| #include "third_party/blink/public/platform/web_storage_namespace.h" |
| #include "third_party/blink/public/platform/websocket_handshake_throttle.h" |
| #include "third_party/blink/renderer/platform/cross_thread_functional.h" |
| #include "third_party/blink/renderer/platform/font_family_names.h" |
| #include "third_party/blink/renderer/platform/fonts/font_cache_memory_dump_provider.h" |
| #include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h" |
| #include "third_party/blink/renderer/platform/heap/gc_task_runner.h" |
| #include "third_party/blink/renderer/platform/histogram.h" |
| #include "third_party/blink/renderer/platform/instance_counters_memory_dump_provider.h" |
| #include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h" |
| #include "third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.h" |
| #include "third_party/blink/renderer/platform/language.h" |
| #include "third_party/blink/renderer/platform/memory_coordinator.h" |
| #include "third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.h" |
| #include "third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h" |
| #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" |
| #include "third_party/blink/renderer/platform/scheduler/public/thread.h" |
| #include "third_party/blink/renderer/platform/wtf/hash_map.h" |
| #include "third_party/webrtc/api/rtpparameters.h" |
| #include "third_party/webrtc/p2p/base/portallocator.h" |
| |
| namespace blink { |
| |
| namespace { |
| |
| class DefaultConnector { |
| public: |
| DefaultConnector() { |
| service_manager::mojom::ConnectorRequest request; |
| connector_ = service_manager::Connector::Create(&request); |
| } |
| |
| service_manager::Connector* Get() { return connector_.get(); } |
| |
| private: |
| std::unique_ptr<service_manager::Connector> connector_; |
| }; |
| |
| } // namespace |
| |
| static Platform* g_platform = nullptr; |
| |
| static GCTaskRunner* g_gc_task_runner = nullptr; |
| |
| static void MaxObservedSizeFunction(size_t size_in_mb) { |
| const size_t kSupportedMaxSizeInMB = 4 * 1024; |
| if (size_in_mb >= kSupportedMaxSizeInMB) |
| size_in_mb = kSupportedMaxSizeInMB - 1; |
| |
| // Send a UseCounter only when we see the highest memory usage |
| // we've ever seen. |
| DEFINE_STATIC_LOCAL(EnumerationHistogram, committed_size_histogram, |
| ("PartitionAlloc.CommittedSize", kSupportedMaxSizeInMB)); |
| committed_size_histogram.Count(size_in_mb); |
| } |
| |
| static void CallOnMainThreadFunction(WTF::MainThreadFunction function, |
| void* context) { |
| PostCrossThreadTask( |
| *Thread::MainThread()->GetTaskRunner(), FROM_HERE, |
| CrossThreadBind(function, CrossThreadUnretained(context))); |
| } |
| |
| Platform::Platform() { |
| WTF::Partitions::Initialize(MaxObservedSizeFunction); |
| } |
| |
| Platform::~Platform() = default; |
| |
| namespace { |
| |
| class SimpleMainThread : public Thread { |
| public: |
| // We rely on base::ThreadTaskRunnerHandle for tasks posted on the main |
| // thread. The task runner handle may not be available on Blink's startup |
| // (== on SimpleMainThread's construction), because some tests like |
| // blink_platform_unittests do not set up a global task environment. |
| // In those cases, a task environment is set up on a test fixture's |
| // creation, and GetTaskRunner() returns the right task runner during |
| // a test. |
| // |
| // If GetTaskRunner() can be called from a non-main thread (including |
| // a worker thread running Mojo callbacks), we need to somehow get a task |
| // runner for the main thread. This is not possible with |
| // ThreadTaskRunnerHandle. We currently deal with this issue by setting |
| // the main thread task runner on the test startup and clearing it on |
| // the test tear-down. This is what SetMainThreadTaskRunnerForTesting() for. |
| // This function is called from Platform::SetMainThreadTaskRunnerForTesting() |
| // and Platform::UnsetMainThreadTaskRunnerForTesting(). |
| |
| ThreadScheduler* Scheduler() override { return &scheduler_; } |
| scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override { |
| if (main_thread_task_runner_for_testing_) |
| return main_thread_task_runner_for_testing_; |
| DCHECK(WTF::IsMainThread()); |
| return base::ThreadTaskRunnerHandle::Get(); |
| } |
| |
| void SetMainThreadTaskRunnerForTesting( |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
| main_thread_task_runner_for_testing_ = std::move(task_runner); |
| } |
| |
| private: |
| bool IsSimpleMainThread() const override { return true; } |
| |
| scheduler::SimpleThreadScheduler scheduler_; |
| scoped_refptr<base::SingleThreadTaskRunner> |
| main_thread_task_runner_for_testing_; |
| }; |
| |
| } // namespace |
| |
| void Platform::Initialize( |
| Platform* platform, |
| scheduler::WebThreadScheduler* main_thread_scheduler) { |
| DCHECK(!g_platform); |
| DCHECK(platform); |
| g_platform = platform; |
| InitializeCommon(platform, main_thread_scheduler->CreateMainThread()); |
| } |
| |
| void Platform::CreateMainThreadAndInitialize(Platform* platform) { |
| DCHECK(!g_platform); |
| DCHECK(platform); |
| g_platform = platform; |
| InitializeCommon(platform, std::make_unique<SimpleMainThread>()); |
| } |
| |
| void Platform::InitializeCommon(Platform* platform, |
| std::unique_ptr<Thread> main_thread) { |
| WTF::Initialize(CallOnMainThreadFunction); |
| |
| Thread::SetMainThread(std::move(main_thread)); |
| |
| ProcessHeap::Init(); |
| MemoryCoordinator::Initialize(); |
| if (base::ThreadTaskRunnerHandle::IsSet()) { |
| base::trace_event::MemoryDumpProvider::Options options; |
| base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| BlinkGCMemoryDumpProvider::Instance(), "BlinkGC", |
| base::ThreadTaskRunnerHandle::Get(), options); |
| } |
| |
| ThreadState::AttachMainThread(); |
| |
| // font_family_names are used by platform/fonts and are initialized by core. |
| // In case core is not available (like on PPAPI plugins), we need to init |
| // them here. |
| font_family_names::Init(); |
| InitializePlatformLanguage(); |
| |
| DCHECK(!g_gc_task_runner); |
| g_gc_task_runner = new GCTaskRunner(Thread::MainThread()); |
| base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| PartitionAllocMemoryDumpProvider::Instance(), "PartitionAlloc", |
| base::ThreadTaskRunnerHandle::Get()); |
| base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| FontCacheMemoryDumpProvider::Instance(), "FontCaches", |
| base::ThreadTaskRunnerHandle::Get()); |
| base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| MemoryCacheDumpProvider::Instance(), "MemoryCache", |
| base::ThreadTaskRunnerHandle::Get()); |
| base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| InstanceCountersMemoryDumpProvider::Instance(), "BlinkObjectCounters", |
| base::ThreadTaskRunnerHandle::Get()); |
| |
| RendererResourceCoordinator::Initialize(); |
| } |
| |
| void Platform::SetCurrentPlatformForTesting(Platform* platform) { |
| DCHECK(platform); |
| g_platform = platform; |
| } |
| |
| void Platform::CreateMainThreadForTesting() { |
| DCHECK(!Thread::MainThread()); |
| Thread::SetMainThread(std::make_unique<SimpleMainThread>()); |
| } |
| |
| void Platform::SetMainThreadTaskRunnerForTesting() { |
| DCHECK(WTF::IsMainThread()); |
| DCHECK(Thread::MainThread()->IsSimpleMainThread()); |
| static_cast<SimpleMainThread*>(Thread::MainThread()) |
| ->SetMainThreadTaskRunnerForTesting(base::ThreadTaskRunnerHandle::Get()); |
| } |
| |
| void Platform::UnsetMainThreadTaskRunnerForTesting() { |
| DCHECK(WTF::IsMainThread()); |
| DCHECK(Thread::MainThread()->IsSimpleMainThread()); |
| static_cast<SimpleMainThread*>(Thread::MainThread()) |
| ->SetMainThreadTaskRunnerForTesting(nullptr); |
| } |
| |
| Platform* Platform::Current() { |
| return g_platform; |
| } |
| |
| Thread* Platform::MainThread() { |
| return Thread::MainThread(); |
| } |
| |
| Thread* Platform::CurrentThread() { |
| return Thread::Current(); |
| } |
| |
| service_manager::Connector* Platform::GetConnector() { |
| DEFINE_STATIC_LOCAL(DefaultConnector, connector, ()); |
| return connector.Get(); |
| } |
| |
| InterfaceProvider* Platform::GetInterfaceProvider() { |
| return InterfaceProvider::GetEmptyInterfaceProvider(); |
| } |
| |
| std::unique_ptr<WebStorageNamespace> Platform::CreateLocalStorageNamespace() { |
| return nullptr; |
| } |
| |
| std::unique_ptr<WebStorageNamespace> Platform::CreateSessionStorageNamespace( |
| base::StringPiece namespace_id) { |
| return nullptr; |
| } |
| |
| std::unique_ptr<Thread> Platform::CreateThread( |
| const ThreadCreationParams& params) { |
| return Thread::CreateThread(params); |
| } |
| |
| std::unique_ptr<Thread> Platform::CreateWebAudioThread() { |
| return Thread::CreateWebAudioThread(); |
| } |
| |
| void Platform::CreateAndSetCompositorThread() { |
| Thread::CreateAndSetCompositorThread(); |
| } |
| |
| Thread* Platform::CompositorThread() { |
| return Thread::CompositorThread(); |
| } |
| |
| scoped_refptr<base::SingleThreadTaskRunner> |
| Platform::CompositorThreadTaskRunner() { |
| if (Thread* compositor_thread = CompositorThread()) |
| return compositor_thread->GetTaskRunner(); |
| return nullptr; |
| } |
| |
| std::unique_ptr<WebGraphicsContext3DProvider> |
| Platform::CreateOffscreenGraphicsContext3DProvider( |
| const Platform::ContextAttributes&, |
| const WebURL& top_document_url, |
| Platform::GraphicsInfo*) { |
| return nullptr; |
| } |
| |
| std::unique_ptr<WebGraphicsContext3DProvider> |
| Platform::CreateSharedOffscreenGraphicsContext3DProvider() { |
| return nullptr; |
| } |
| |
| std::unique_ptr<WebGraphicsContext3DProvider> |
| Platform::CreateWebGPUGraphicsContext3DProvider(const WebURL& top_document_url, |
| GraphicsInfo*) { |
| return nullptr; |
| } |
| |
| std::unique_ptr<WebRTCPeerConnectionHandler> |
| Platform::CreateRTCPeerConnectionHandler( |
| WebRTCPeerConnectionHandlerClient*, |
| scoped_refptr<base::SingleThreadTaskRunner>) { |
| return nullptr; |
| } |
| |
| std::unique_ptr<cricket::PortAllocator> Platform::CreateWebRtcPortAllocator( |
| WebLocalFrame* frame) { |
| return nullptr; |
| } |
| |
| std::unique_ptr<WebMediaRecorderHandler> Platform::CreateMediaRecorderHandler( |
| scoped_refptr<base::SingleThreadTaskRunner>) { |
| return nullptr; |
| } |
| |
| std::unique_ptr<WebRTCCertificateGenerator> |
| Platform::CreateRTCCertificateGenerator() { |
| return nullptr; |
| } |
| |
| std::unique_ptr<WebMediaStreamCenter> Platform::CreateMediaStreamCenter() { |
| return nullptr; |
| } |
| |
| std::unique_ptr<WebCanvasCaptureHandler> Platform::CreateCanvasCaptureHandler( |
| const WebSize&, |
| double, |
| WebMediaStreamTrack*) { |
| return nullptr; |
| } |
| |
| std::unique_ptr<WebImageCaptureFrameGrabber> |
| Platform::CreateImageCaptureFrameGrabber() { |
| return nullptr; |
| } |
| |
| std::unique_ptr<webrtc::RtpCapabilities> Platform::GetRtpSenderCapabilities( |
| const WebString& kind) { |
| return nullptr; |
| } |
| |
| std::unique_ptr<webrtc::RtpCapabilities> Platform::GetRtpReceiverCapabilities( |
| const WebString& kind) { |
| return nullptr; |
| } |
| |
| } // namespace blink |