1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/public/test/mock_render_thread.h" 6 7#include "base/message_loop/message_loop_proxy.h" 8#include "content/common/frame_messages.h" 9#include "content/common/view_messages.h" 10#include "content/public/renderer/render_process_observer.h" 11#include "content/renderer/render_view_impl.h" 12#include "ipc/ipc_message_utils.h" 13#include "ipc/ipc_sync_message.h" 14#include "ipc/message_filter.h" 15#include "testing/gtest/include/gtest/gtest.h" 16#include "third_party/WebKit/public/web/WebScriptController.h" 17 18namespace content { 19 20MockRenderThread::MockRenderThread() 21 : routing_id_(0), 22 surface_id_(0), 23 opener_id_(0), 24 new_window_routing_id_(0), 25 new_window_main_frame_routing_id_(0), 26 new_frame_routing_id_(0) { 27} 28 29MockRenderThread::~MockRenderThread() { 30 while (!filters_.empty()) { 31 scoped_refptr<IPC::MessageFilter> filter = filters_.back(); 32 filters_.pop_back(); 33 filter->OnFilterRemoved(); 34 } 35} 36 37// Called by the Widget. Used to send messages to the browser. 38// We short-circuit the mechanism and handle the messages right here on this 39// class. 40bool MockRenderThread::Send(IPC::Message* msg) { 41 // We need to simulate a synchronous channel, thus we are going to receive 42 // through this function messages, messages with reply and reply messages. 43 // We can only handle one synchronous message at a time. 44 if (msg->is_reply()) { 45 if (reply_deserializer_) { 46 reply_deserializer_->SerializeOutputParameters(*msg); 47 reply_deserializer_.reset(); 48 } 49 } else { 50 if (msg->is_sync()) { 51 // We actually need to handle deleting the reply deserializer for sync 52 // messages. 53 reply_deserializer_.reset( 54 static_cast<IPC::SyncMessage*>(msg)->GetReplyDeserializer()); 55 } 56 if (msg->routing_id() == MSG_ROUTING_CONTROL) 57 OnControlMessageReceived(*msg); 58 else 59 OnMessageReceived(*msg); 60 } 61 delete msg; 62 return true; 63} 64 65base::MessageLoop* MockRenderThread::GetMessageLoop() { 66 return NULL; 67} 68 69IPC::SyncChannel* MockRenderThread::GetChannel() { 70 return NULL; 71} 72 73std::string MockRenderThread::GetLocale() { 74 return "en-US"; 75} 76 77IPC::SyncMessageFilter* MockRenderThread::GetSyncMessageFilter() { 78 return NULL; 79} 80 81scoped_refptr<base::MessageLoopProxy> 82 MockRenderThread::GetIOMessageLoopProxy() { 83 return scoped_refptr<base::MessageLoopProxy>(); 84} 85 86void MockRenderThread::AddRoute(int32 routing_id, IPC::Listener* listener) { 87} 88 89void MockRenderThread::RemoveRoute(int32 routing_id) { 90} 91 92int MockRenderThread::GenerateRoutingID() { 93 NOTREACHED(); 94 return MSG_ROUTING_NONE; 95} 96 97void MockRenderThread::AddFilter(IPC::MessageFilter* filter) { 98 filter->OnFilterAdded(&sink()); 99 // Add this filter to a vector so the MockRenderThread::RemoveFilter function 100 // can check if this filter is added. 101 filters_.push_back(make_scoped_refptr(filter)); 102} 103 104void MockRenderThread::RemoveFilter(IPC::MessageFilter* filter) { 105 // Emulate the IPC::ChannelProxy::OnRemoveFilter function. 106 for (size_t i = 0; i < filters_.size(); ++i) { 107 if (filters_[i].get() == filter) { 108 filter->OnFilterRemoved(); 109 filters_.erase(filters_.begin() + i); 110 return; 111 } 112 } 113 NOTREACHED() << "filter to be removed not found"; 114} 115 116void MockRenderThread::AddObserver(RenderProcessObserver* observer) { 117 observers_.AddObserver(observer); 118} 119 120void MockRenderThread::RemoveObserver(RenderProcessObserver* observer) { 121 observers_.RemoveObserver(observer); 122} 123 124void MockRenderThread::SetResourceDispatcherDelegate( 125 ResourceDispatcherDelegate* delegate) { 126} 127 128void MockRenderThread::EnsureWebKitInitialized() { 129} 130 131void MockRenderThread::RecordAction(const base::UserMetricsAction& action) { 132} 133 134void MockRenderThread::RecordComputedAction(const std::string& action) { 135} 136 137scoped_ptr<base::SharedMemory> 138 MockRenderThread::HostAllocateSharedMemoryBuffer( 139 size_t buffer_size) { 140 scoped_ptr<base::SharedMemory> shared_buf(new base::SharedMemory); 141 if (!shared_buf->CreateAnonymous(buffer_size)) { 142 NOTREACHED() << "Cannot map shared memory buffer"; 143 return scoped_ptr<base::SharedMemory>(); 144 } 145 146 return scoped_ptr<base::SharedMemory>(shared_buf.release()); 147} 148 149void MockRenderThread::RegisterExtension(v8::Extension* extension) { 150 blink::WebScriptController::registerExtension(extension); 151} 152 153void MockRenderThread::ScheduleIdleHandler(int64 initial_delay_ms) { 154} 155 156void MockRenderThread::IdleHandler() { 157} 158 159int64 MockRenderThread::GetIdleNotificationDelayInMs() const { 160 return 0; 161} 162 163void MockRenderThread::SetIdleNotificationDelayInMs( 164 int64 idle_notification_delay_in_ms) { 165} 166 167void MockRenderThread::UpdateHistograms(int sequence_number) { 168} 169 170int MockRenderThread::PostTaskToAllWebWorkers(const base::Closure& closure) { 171 return 0; 172} 173 174bool MockRenderThread::ResolveProxy(const GURL& url, std::string* proxy_list) { 175 return false; 176} 177 178base::WaitableEvent* MockRenderThread::GetShutdownEvent() { 179 return NULL; 180} 181 182#if defined(OS_WIN) 183void MockRenderThread::PreCacheFont(const LOGFONT& log_font) { 184} 185 186void MockRenderThread::ReleaseCachedFonts() { 187} 188 189#endif // OS_WIN 190 191ServiceRegistry* MockRenderThread::GetServiceRegistry() { 192 return NULL; 193} 194 195void MockRenderThread::SendCloseMessage() { 196 ViewMsg_Close msg(routing_id_); 197 RenderViewImpl::FromRoutingID(routing_id_)->OnMessageReceived(msg); 198} 199 200// The Widget expects to be returned valid route_id. 201void MockRenderThread::OnCreateWidget(int opener_id, 202 blink::WebPopupType popup_type, 203 int* route_id, 204 int* surface_id) { 205 opener_id_ = opener_id; 206 *route_id = routing_id_; 207 *surface_id = surface_id_; 208} 209 210// The View expects to be returned a valid route_id different from its own. 211void MockRenderThread::OnCreateWindow( 212 const ViewHostMsg_CreateWindow_Params& params, 213 int* route_id, 214 int* main_frame_route_id, 215 int* surface_id, 216 int64* cloned_session_storage_namespace_id) { 217 *route_id = new_window_routing_id_; 218 *main_frame_route_id = new_window_main_frame_routing_id_; 219 *surface_id = surface_id_; 220 *cloned_session_storage_namespace_id = 0; 221} 222 223// The Frame expects to be returned a valid route_id different from its own. 224void MockRenderThread::OnCreateChildFrame(int new_frame_routing_id, 225 const std::string& frame_name, 226 int* new_render_frame_id) { 227 *new_render_frame_id = new_frame_routing_id_++; 228} 229 230bool MockRenderThread::OnControlMessageReceived(const IPC::Message& msg) { 231 ObserverListBase<RenderProcessObserver>::Iterator it(observers_); 232 RenderProcessObserver* observer; 233 while ((observer = it.GetNext()) != NULL) { 234 if (observer->OnControlMessageReceived(msg)) 235 return true; 236 } 237 return OnMessageReceived(msg); 238} 239 240bool MockRenderThread::OnMessageReceived(const IPC::Message& msg) { 241 // Save the message in the sink. 242 sink_.OnMessageReceived(msg); 243 244 bool handled = true; 245 IPC_BEGIN_MESSAGE_MAP(MockRenderThread, msg) 246 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnCreateWidget) 247 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnCreateWindow) 248 IPC_MESSAGE_HANDLER(FrameHostMsg_CreateChildFrame, OnCreateChildFrame) 249 IPC_MESSAGE_UNHANDLED(handled = false) 250 IPC_END_MESSAGE_MAP() 251 return handled; 252} 253 254#if defined(OS_WIN) 255void MockRenderThread::OnDuplicateSection( 256 base::SharedMemoryHandle renderer_handle, 257 base::SharedMemoryHandle* browser_handle) { 258 // We don't have to duplicate the input handles since RenderViewTest does not 259 // separate a browser process from a renderer process. 260 *browser_handle = renderer_handle; 261} 262#endif // defined(OS_WIN) 263 264} // namespace content 265