// Copyright 2015 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 "ipc/attachment_broker_unprivileged.h" #include "base/lazy_instance.h" #include "base/metrics/histogram_macros.h" #include "build/build_config.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_endpoint.h" #if defined(OS_WIN) #include "ipc/attachment_broker_unprivileged_win.h" #endif #if defined(OS_MACOSX) && !defined(OS_IOS) #include "ipc/attachment_broker_unprivileged_mac.h" #endif namespace IPC { namespace { // On platforms that support attachment brokering, returns a new instance of // a platform-specific attachment broker. Otherwise returns |nullptr|. // The caller takes ownership of the newly created instance, and is // responsible for ensuring that the attachment broker lives longer than // every IPC::Channel. The new instance automatically registers itself as the // global attachment broker. scoped_ptr CreateBroker() { #if defined(OS_WIN) return scoped_ptr( new IPC::AttachmentBrokerUnprivilegedWin); #elif defined(OS_MACOSX) && !defined(OS_IOS) return scoped_ptr( new IPC::AttachmentBrokerUnprivilegedMac); #else return nullptr; #endif } // This class is wrapped in a LazyInstance to ensure that its constructor is // only called once. The constructor creates an attachment broker and sets it as // the global broker. class AttachmentBrokerMakeOnce { public: AttachmentBrokerMakeOnce() { // Single process tests can cause an attachment broker to already exist. if (AttachmentBroker::GetGlobal()) return; attachment_broker_ = CreateBroker(); } private: scoped_ptr attachment_broker_; }; base::LazyInstance::Leaky g_attachment_broker_make_once = LAZY_INSTANCE_INITIALIZER; } // namespace AttachmentBrokerUnprivileged::AttachmentBrokerUnprivileged() : sender_(nullptr) { IPC::AttachmentBroker::SetGlobal(this); } AttachmentBrokerUnprivileged::~AttachmentBrokerUnprivileged() { IPC::AttachmentBroker::SetGlobal(nullptr); } // static void AttachmentBrokerUnprivileged::CreateBrokerIfNeeded() { g_attachment_broker_make_once.Get(); } void AttachmentBrokerUnprivileged::RegisterBrokerCommunicationChannel( Endpoint* endpoint) { DCHECK(endpoint); DCHECK(!sender_); sender_ = endpoint; endpoint->SetAttachmentBrokerEndpoint(true); } void AttachmentBrokerUnprivileged::DeregisterBrokerCommunicationChannel( Endpoint* endpoint) { DCHECK(endpoint); DCHECK_EQ(endpoint, sender_); sender_ = nullptr; } bool AttachmentBrokerUnprivileged::IsPrivilegedBroker() { return false; } void AttachmentBrokerUnprivileged::LogError(UMAError error) { UMA_HISTOGRAM_ENUMERATION( "IPC.AttachmentBrokerUnprivileged.BrokerAttachmentError", error, ERROR_MAX); } } // namespace IPC