|  | // Copyright (c) 2012 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 "content/browser/renderer_host/render_widget_helper.h" | 
|  |  | 
|  | #include "base/bind.h" | 
|  | #include "base/callback_helpers.h" | 
|  | #include "base/lazy_instance.h" | 
|  | #include "base/posix/eintr_wrapper.h" | 
|  | #include "base/threading/thread.h" | 
|  | #include "base/threading/thread_restrictions.h" | 
|  | #include "content/browser/renderer_host/render_view_host_impl.h" | 
|  | #include "content/public/browser/browser_task_traits.h" | 
|  |  | 
|  | namespace content { | 
|  | namespace { | 
|  |  | 
|  | typedef std::map<int, RenderWidgetHelper*> WidgetHelperMap; | 
|  | base::LazyInstance<WidgetHelperMap>::DestructorAtExit g_widget_helpers = | 
|  | LAZY_INSTANCE_INITIALIZER; | 
|  |  | 
|  | void AddWidgetHelper(int render_process_id, | 
|  | const scoped_refptr<RenderWidgetHelper>& widget_helper) { | 
|  | DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
|  | // We don't care if RenderWidgetHelpers overwrite an existing process_id. Just | 
|  | // want this to be up to date. | 
|  | g_widget_helpers.Get()[render_process_id] = widget_helper.get(); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | RenderWidgetHelper::FrameTokens::FrameTokens( | 
|  | const blink::LocalFrameToken& frame_token, | 
|  | const base::UnguessableToken& devtools_frame_token) | 
|  | : frame_token(frame_token), devtools_frame_token(devtools_frame_token) {} | 
|  |  | 
|  | RenderWidgetHelper::FrameTokens::FrameTokens(const FrameTokens& other) = | 
|  | default; | 
|  |  | 
|  | RenderWidgetHelper::FrameTokens& RenderWidgetHelper::FrameTokens::operator=( | 
|  | const FrameTokens& other) = default; | 
|  |  | 
|  | RenderWidgetHelper::FrameTokens::~FrameTokens() = default; | 
|  |  | 
|  | RenderWidgetHelper::RenderWidgetHelper() : render_process_id_(-1) {} | 
|  |  | 
|  | RenderWidgetHelper::~RenderWidgetHelper() { | 
|  | DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
|  |  | 
|  | // Delete this RWH from the map if it is found. | 
|  | WidgetHelperMap& widget_map = g_widget_helpers.Get(); | 
|  | auto it = widget_map.find(render_process_id_); | 
|  | if (it != widget_map.end() && it->second == this) | 
|  | widget_map.erase(it); | 
|  | } | 
|  |  | 
|  | void RenderWidgetHelper::Init(int render_process_id) { | 
|  | render_process_id_ = render_process_id; | 
|  |  | 
|  | GetIOThreadTaskRunner({})->PostTask( | 
|  | FROM_HERE, base::BindOnce(&AddWidgetHelper, render_process_id_, | 
|  | base::WrapRefCounted(this))); | 
|  | } | 
|  |  | 
|  | int RenderWidgetHelper::GetNextRoutingID() { | 
|  | return next_routing_id_.GetNext() + 1; | 
|  | } | 
|  |  | 
|  | bool RenderWidgetHelper::TakeFrameTokensForFrameRoutingID( | 
|  | int32_t routing_id, | 
|  | blink::LocalFrameToken& frame_token, | 
|  | base::UnguessableToken& devtools_frame_token) { | 
|  | base::AutoLock lock(frame_token_map_lock_); | 
|  | auto iter = frame_token_routing_id_map_.find(routing_id); | 
|  | if (iter == frame_token_routing_id_map_.end()) | 
|  | return false; | 
|  | frame_token = iter->second.frame_token; | 
|  | devtools_frame_token = iter->second.devtools_frame_token; | 
|  | frame_token_routing_id_map_.erase(iter); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void RenderWidgetHelper::StoreNextFrameRoutingID( | 
|  | int32_t routing_id, | 
|  | const blink::LocalFrameToken& frame_token, | 
|  | const base::UnguessableToken& devtools_frame_token) { | 
|  | base::AutoLock lock(frame_token_map_lock_); | 
|  | bool result = | 
|  | frame_token_routing_id_map_ | 
|  | .emplace(routing_id, FrameTokens(frame_token, devtools_frame_token)) | 
|  | .second; | 
|  | DCHECK(result); | 
|  | } | 
|  |  | 
|  | // static | 
|  | RenderWidgetHelper* RenderWidgetHelper::FromProcessHostID( | 
|  | int render_process_host_id) { | 
|  | DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
|  | WidgetHelperMap::const_iterator ci = g_widget_helpers.Get().find( | 
|  | render_process_host_id); | 
|  | return (ci == g_widget_helpers.Get().end())? NULL : ci->second; | 
|  | } | 
|  |  | 
|  | }  // namespace content |