Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: remoting/client/plugin/chromoting_instance.cc

Issue 7355011: Modify Chromoting logging to hook into base logging. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add timestamp Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/client/plugin/chromoting_instance.h" 5 #include "remoting/client/plugin/chromoting_instance.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/stringprintf.h" 13 #include "base/stringprintf.h"
14 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
15 #include "base/task.h" 15 #include "base/task.h"
16 #include "base/threading/thread.h" 16 #include "base/threading/thread.h"
17 // TODO(sergeyu): We should not depend on renderer here. Instead P2P 17 // TODO(sergeyu): We should not depend on renderer here. Instead P2P
18 // Pepper API should be used. Remove this dependency. 18 // Pepper API should be used. Remove this dependency.
19 // crbug.com/74951 19 // crbug.com/74951
20 #include "content/renderer/p2p/ipc_network_manager.h" 20 #include "content/renderer/p2p/ipc_network_manager.h"
21 #include "content/renderer/p2p/ipc_socket_factory.h" 21 #include "content/renderer/p2p/ipc_socket_factory.h"
22 #include "ppapi/cpp/completion_callback.h" 22 #include "ppapi/cpp/completion_callback.h"
23 #include "ppapi/cpp/input_event.h" 23 #include "ppapi/cpp/input_event.h"
24 #include "ppapi/cpp/rect.h" 24 #include "ppapi/cpp/rect.h"
25 // TODO(wez): Remove this when crbug.com/86353 is complete. 25 // TODO(wez): Remove this when crbug.com/86353 is complete.
26 #include "ppapi/cpp/private/var_private.h" 26 #include "ppapi/cpp/private/var_private.h"
27 #include "remoting/base/util.h"
27 #include "remoting/client/client_config.h" 28 #include "remoting/client/client_config.h"
28 #include "remoting/client/chromoting_client.h" 29 #include "remoting/client/chromoting_client.h"
29 #include "remoting/client/rectangle_update_decoder.h" 30 #include "remoting/client/rectangle_update_decoder.h"
30 #include "remoting/client/plugin/chromoting_scriptable_object.h" 31 #include "remoting/client/plugin/chromoting_scriptable_object.h"
31 #include "remoting/client/plugin/pepper_client_logger.h"
32 #include "remoting/client/plugin/pepper_input_handler.h" 32 #include "remoting/client/plugin/pepper_input_handler.h"
33 #include "remoting/client/plugin/pepper_port_allocator_session.h" 33 #include "remoting/client/plugin/pepper_port_allocator_session.h"
34 #include "remoting/client/plugin/pepper_view.h" 34 #include "remoting/client/plugin/pepper_view.h"
35 #include "remoting/client/plugin/pepper_view_proxy.h" 35 #include "remoting/client/plugin/pepper_view_proxy.h"
36 #include "remoting/client/plugin/pepper_util.h" 36 #include "remoting/client/plugin/pepper_util.h"
37 #include "remoting/client/plugin/pepper_xmpp_proxy.h" 37 #include "remoting/client/plugin/pepper_xmpp_proxy.h"
38 #include "remoting/jingle_glue/jingle_thread.h" 38 #include "remoting/jingle_glue/jingle_thread.h"
39 #include "remoting/proto/auth.pb.h" 39 #include "remoting/proto/auth.pb.h"
40 #include "remoting/protocol/connection_to_host.h" 40 #include "remoting/protocol/connection_to_host.h"
41 #include "remoting/protocol/host_stub.h" 41 #include "remoting/protocol/host_stub.h"
42 // TODO(sergeyu): This is a hack: plugin should not depend on webkit 42 // TODO(sergeyu): This is a hack: plugin should not depend on webkit
43 // glue. It is used here to get P2PPacketDispatcher corresponding to 43 // glue. It is used here to get P2PPacketDispatcher corresponding to
44 // the current RenderView. Use P2P Pepper API for connection and 44 // the current RenderView. Use P2P Pepper API for connection and
45 // remove these includes. 45 // remove these includes.
46 // crbug.com/74951 46 // crbug.com/74951
47 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" 47 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
48 #include "webkit/plugins/ppapi/resource_tracker.h" 48 #include "webkit/plugins/ppapi/resource_tracker.h"
49 49
50 namespace remoting { 50 namespace remoting {
51 51
52 // This flag blocks LOGs to the UI if we're already in the middle of logging
53 // to the UI. This prevents a potential infinite loop if we encounter an error
54 // while sending the log message to the UI.
55 static bool logging_to_plugin_ = false;
dmac 2011/07/21 23:37:07 should these be marked with a g in front of them?
garykac 2011/08/02 00:15:37 Done.
56 static ChromotingInstance* logging_instance_ = NULL;
57 static MessageLoop* logging_message_loop_ = NULL;
58 static logging::LogMessageHandlerFunction logging_old_handler_ = NULL;
59
52 const char* ChromotingInstance::kMimeType = "pepper-application/x-chromoting"; 60 const char* ChromotingInstance::kMimeType = "pepper-application/x-chromoting";
53 61
54 ChromotingInstance::ChromotingInstance(PP_Instance pp_instance) 62 ChromotingInstance::ChromotingInstance(PP_Instance pp_instance)
55 : pp::InstancePrivate(pp_instance), 63 : pp::InstancePrivate(pp_instance),
56 initialized_(false), 64 initialized_(false) {
57 logger_(this) {
58 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE); 65 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
59 RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); 66 RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
67 logging_old_handler_ = logging::GetLogMessageHandler();
68 logging::SetLogMessageHandler(&LogToUI);
69 logging_instance_ = this;
70 logging_message_loop_ = MessageLoop::current();
60 } 71 }
61 72
62 ChromotingInstance::~ChromotingInstance() { 73 ChromotingInstance::~ChromotingInstance() {
63 DCHECK(CurrentlyOnPluginThread()); 74 DCHECK(CurrentlyOnPluginThread());
64 75
76 logging::SetLogMessageHandler(logging_old_handler_);
77 logging_old_handler_ = NULL;
78 logging_instance_ = NULL;
79 logging_message_loop_ = NULL;
80
65 if (client_.get()) { 81 if (client_.get()) {
66 base::WaitableEvent done_event(true, false); 82 base::WaitableEvent done_event(true, false);
67 client_->Stop(base::Bind(&base::WaitableEvent::Signal, 83 client_->Stop(base::Bind(&base::WaitableEvent::Signal,
68 base::Unretained(&done_event))); 84 base::Unretained(&done_event)));
69 done_event.Wait(); 85 done_event.Wait();
70 } 86 }
71 87
72 // Stopping the context shutdown all chromoting threads. This is a requirement 88 // Stopping the context shutdown all chromoting threads. This is a requirement
73 // before we can call Detach() on |view_proxy_|. 89 // before we can call Detach() on |view_proxy_|.
74 context_.Stop(); 90 context_.Stop();
75 91
76 view_proxy_->Detach(); 92 view_proxy_->Detach();
77 } 93 }
78 94
79 bool ChromotingInstance::Init(uint32_t argc, 95 bool ChromotingInstance::Init(uint32_t argc,
80 const char* argn[], 96 const char* argn[],
81 const char* argv[]) { 97 const char* argv[]) {
82 CHECK(!initialized_); 98 CHECK(!initialized_);
83 initialized_ = true; 99 initialized_ = true;
84 100
85 logger_.VLog(1, "Started ChromotingInstance::Init"); 101 VLOG(1) << "Started ChromotingInstance::Init";
86 102
87 // Start all the threads. 103 // Start all the threads.
88 context_.Start(); 104 context_.Start();
89 105
90 webkit::ppapi::PluginInstance* plugin_instance = 106 webkit::ppapi::PluginInstance* plugin_instance =
91 webkit::ppapi::ResourceTracker::Get()->GetInstance(pp_instance()); 107 webkit::ppapi::ResourceTracker::Get()->GetInstance(pp_instance());
92 108
93 P2PSocketDispatcher* socket_dispatcher = 109 P2PSocketDispatcher* socket_dispatcher =
94 plugin_instance->delegate()->GetP2PSocketDispatcher(); 110 plugin_instance->delegate()->GetP2PSocketDispatcher();
95 IpcNetworkManager* network_manager = NULL; 111 IpcNetworkManager* network_manager = NULL;
96 IpcPacketSocketFactory* socket_factory = NULL; 112 IpcPacketSocketFactory* socket_factory = NULL;
97 PortAllocatorSessionFactory* session_factory = 113 PortAllocatorSessionFactory* session_factory =
98 CreatePepperPortAllocatorSessionFactory(this); 114 CreatePepperPortAllocatorSessionFactory(this);
99 115
100 // If we don't have socket dispatcher for IPC (e.g. P2P API is 116 // If we don't have socket dispatcher for IPC (e.g. P2P API is
101 // disabled), then JingleSessionManager will try to use physical sockets. 117 // disabled), then JingleSessionManager will try to use physical sockets.
102 if (socket_dispatcher) { 118 if (socket_dispatcher) {
103 logger_.VLog(1, "Creating IpcNetworkManager and IpcPacketSocketFactory."); 119 VLOG(1) << "Creating IpcNetworkManager and IpcPacketSocketFactory.";
104 network_manager = new IpcNetworkManager(socket_dispatcher); 120 network_manager = new IpcNetworkManager(socket_dispatcher);
105 socket_factory = new IpcPacketSocketFactory(socket_dispatcher); 121 socket_factory = new IpcPacketSocketFactory(socket_dispatcher);
106 } 122 }
107 123
108 // Create the chromoting objects. 124 // Create the chromoting objects.
109 host_connection_.reset(new protocol::ConnectionToHost( 125 host_connection_.reset(new protocol::ConnectionToHost(
110 context_.network_message_loop(), network_manager, socket_factory, 126 context_.network_message_loop(), network_manager, socket_factory,
111 session_factory)); 127 session_factory));
112 view_.reset(new PepperView(this, &context_)); 128 view_.reset(new PepperView(this, &context_));
113 view_proxy_ = new PepperViewProxy(this, view_.get()); 129 view_proxy_ = new PepperViewProxy(this, view_.get());
114 rectangle_decoder_ = new RectangleUpdateDecoder( 130 rectangle_decoder_ = new RectangleUpdateDecoder(
115 context_.decode_message_loop(), view_proxy_); 131 context_.decode_message_loop(), view_proxy_);
116 input_handler_.reset(new PepperInputHandler(&context_, 132 input_handler_.reset(new PepperInputHandler(&context_,
117 host_connection_.get(), 133 host_connection_.get(),
118 view_proxy_)); 134 view_proxy_));
119 135
120 // Default to a medium grey. 136 // Default to a medium grey.
121 view_->SetSolidFill(0xFFCDCDCD); 137 view_->SetSolidFill(0xFFCDCDCD);
122 138
123 return true; 139 return true;
124 } 140 }
125 141
126 void ChromotingInstance::Connect(const ClientConfig& config) { 142 void ChromotingInstance::Connect(const ClientConfig& config) {
127 DCHECK(CurrentlyOnPluginThread()); 143 DCHECK(CurrentlyOnPluginThread());
128 144
129 client_.reset(new ChromotingClient(config, &context_, host_connection_.get(), 145 client_.reset(new ChromotingClient(config, &context_, host_connection_.get(),
130 view_proxy_, rectangle_decoder_.get(), 146 view_proxy_, rectangle_decoder_.get(),
131 input_handler_.get(), &logger_, NULL)); 147 input_handler_.get(), NULL));
132 148
133 logger_.Log(logging::LOG_INFO, "Connecting."); 149 LOG(INFO) << "Connecting.";
134 150
135 // Setup the XMPP Proxy. 151 // Setup the XMPP Proxy.
136 ChromotingScriptableObject* scriptable_object = GetScriptableObject(); 152 ChromotingScriptableObject* scriptable_object = GetScriptableObject();
137 scoped_refptr<PepperXmppProxy> xmpp_proxy = 153 scoped_refptr<PepperXmppProxy> xmpp_proxy =
138 new PepperXmppProxy(scriptable_object->AsWeakPtr(), 154 new PepperXmppProxy(scriptable_object->AsWeakPtr(),
139 context_.jingle_thread()->message_loop()); 155 context_.jingle_thread()->message_loop());
140 scriptable_object->AttachXmppProxy(xmpp_proxy); 156 scriptable_object->AttachXmppProxy(xmpp_proxy);
141 157
142 // Kick off the connection. 158 // Kick off the connection.
143 client_->Start(xmpp_proxy); 159 client_->Start(xmpp_proxy);
144 160
145 logger_.Log(logging::LOG_INFO, "Connection status: Initializing"); 161 LOG(INFO) << "Connection status: Initializing";
146 GetScriptableObject()->SetConnectionInfo(STATUS_INITIALIZING, 162 GetScriptableObject()->SetConnectionInfo(STATUS_INITIALIZING,
147 QUALITY_UNKNOWN); 163 QUALITY_UNKNOWN);
148 } 164 }
149 165
150 void ChromotingInstance::Disconnect() { 166 void ChromotingInstance::Disconnect() {
151 DCHECK(CurrentlyOnPluginThread()); 167 DCHECK(CurrentlyOnPluginThread());
152 168
153 logger_.Log(logging::LOG_INFO, "Disconnecting from host."); 169 LOG(INFO) << "Disconnecting from host.";
154 if (client_.get()) { 170 if (client_.get()) {
155 // TODO(sergeyu): Should we disconnect asynchronously? 171 // TODO(sergeyu): Should we disconnect asynchronously?
156 base::WaitableEvent done_event(true, false); 172 base::WaitableEvent done_event(true, false);
157 client_->Stop(base::Bind(&base::WaitableEvent::Signal, 173 client_->Stop(base::Bind(&base::WaitableEvent::Signal,
158 base::Unretained(&done_event))); 174 base::Unretained(&done_event)));
159 done_event.Wait(); 175 done_event.Wait();
160 } 176 }
161 177
162 GetScriptableObject()->SetConnectionInfo(STATUS_CLOSED, QUALITY_UNKNOWN); 178 GetScriptableObject()->SetConnectionInfo(STATUS_CLOSED, QUALITY_UNKNOWN);
163 } 179 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 } 212 }
197 213
198 case PP_INPUTEVENT_TYPE_CONTEXTMENU: { 214 case PP_INPUTEVENT_TYPE_CONTEXTMENU: {
199 // We need to return true here or else we'll get a local (plugin) context 215 // We need to return true here or else we'll get a local (plugin) context
200 // menu instead of the mouseup event for the right click. 216 // menu instead of the mouseup event for the right click.
201 return true; 217 return true;
202 } 218 }
203 219
204 case PP_INPUTEVENT_TYPE_KEYDOWN: { 220 case PP_INPUTEVENT_TYPE_KEYDOWN: {
205 pp::KeyboardInputEvent key = pp::KeyboardInputEvent(event); 221 pp::KeyboardInputEvent key = pp::KeyboardInputEvent(event);
206 logger_.VLog(3, "PP_INPUTEVENT_TYPE_KEYDOWN key=%d", key.GetKeyCode()); 222 VLOG(3) << "PP_INPUTEVENT_TYPE_KEYDOWN" << " key=" << key.GetKeyCode();
207 pih->HandleKeyEvent(true, key); 223 pih->HandleKeyEvent(true, key);
208 return true; 224 return true;
209 } 225 }
210 226
211 case PP_INPUTEVENT_TYPE_KEYUP: { 227 case PP_INPUTEVENT_TYPE_KEYUP: {
212 pp::KeyboardInputEvent key = pp::KeyboardInputEvent(event); 228 pp::KeyboardInputEvent key = pp::KeyboardInputEvent(event);
213 logger_.VLog(3, "PP_INPUTEVENT_TYPE_KEYUP key=%d", key.GetKeyCode()); 229 VLOG(3) << "PP_INPUTEVENT_TYPE_KEYUP" << " key=" << key.GetKeyCode();
214 pih->HandleKeyEvent(false, key); 230 pih->HandleKeyEvent(false, key);
215 return true; 231 return true;
216 } 232 }
217 233
218 case PP_INPUTEVENT_TYPE_CHAR: { 234 case PP_INPUTEVENT_TYPE_CHAR: {
219 pih->HandleCharacterEvent(pp::KeyboardInputEvent(event)); 235 pih->HandleCharacterEvent(pp::KeyboardInputEvent(event));
220 return true; 236 return true;
221 } 237 }
222 238
223 default: { 239 default: {
224 LOG(INFO) << "Unhandled input event: " << event.GetType(); 240 LOG(INFO) << "Unhandled input event: " << event.GetType();
225 break; 241 break;
226 } 242 }
227 } 243 }
228 244
229 return false; 245 return false;
230 } 246 }
231 247
232 ChromotingScriptableObject* ChromotingInstance::GetScriptableObject() { 248 ChromotingScriptableObject* ChromotingInstance::GetScriptableObject() {
233 pp::VarPrivate object = GetInstanceObject(); 249 pp::VarPrivate object = GetInstanceObject();
234 if (!object.is_undefined()) { 250 if (!object.is_undefined()) {
235 pp::deprecated::ScriptableObject* so = object.AsScriptableObject(); 251 pp::deprecated::ScriptableObject* so = object.AsScriptableObject();
236 DCHECK(so != NULL); 252 DCHECK(so != NULL);
237 return static_cast<ChromotingScriptableObject*>(so); 253 return static_cast<ChromotingScriptableObject*>(so);
238 } 254 }
239 logger_.Log(logging::LOG_ERROR, 255 LOG(ERROR) << "Unable to get ScriptableObject for Chromoting plugin.";
240 "Unable to get ScriptableObject for Chromoting plugin.");
241 return NULL; 256 return NULL;
242 } 257 }
243 258
244 void ChromotingInstance::SubmitLoginInfo(const std::string& username, 259 void ChromotingInstance::SubmitLoginInfo(const std::string& username,
245 const std::string& password) { 260 const std::string& password) {
246 if (host_connection_->state() != 261 if (host_connection_->state() !=
247 protocol::ConnectionToHost::STATE_CONNECTED) { 262 protocol::ConnectionToHost::STATE_CONNECTED) {
248 logger_.Log(logging::LOG_INFO, 263 LOG(INFO) << "Client not connected or already authenticated.";
249 "Client not connected or already authenticated.");
250 return; 264 return;
251 } 265 }
252 266
253 protocol::LocalLoginCredentials* credentials = 267 protocol::LocalLoginCredentials* credentials =
254 new protocol::LocalLoginCredentials(); 268 new protocol::LocalLoginCredentials();
255 credentials->set_type(protocol::PASSWORD); 269 credentials->set_type(protocol::PASSWORD);
256 credentials->set_username(username); 270 credentials->set_username(username);
257 credentials->set_credential(password.data(), password.length()); 271 credentials->set_credential(password.data(), password.length());
258 272
259 host_connection_->host_stub()->BeginSessionRequest( 273 host_connection_->host_stub()->BeginSessionRequest(
260 credentials, 274 credentials,
261 new DeleteTask<protocol::LocalLoginCredentials>(credentials)); 275 new DeleteTask<protocol::LocalLoginCredentials>(credentials));
262 } 276 }
263 277
264 void ChromotingInstance::SetScaleToFit(bool scale_to_fit) { 278 void ChromotingInstance::SetScaleToFit(bool scale_to_fit) {
265 view_proxy_->SetScaleToFit(scale_to_fit); 279 view_proxy_->SetScaleToFit(scale_to_fit);
266 } 280 }
267 281
268 void ChromotingInstance::Log(int severity, const char* format, ...) { 282 // static
269 va_list ap; 283 bool ChromotingInstance::LogToUI(int severity, const char* file, int line,
270 va_start(ap, format); 284 size_t message_start,
271 logger_.va_Log(severity, format, ap); 285 const std::string& str) {
272 va_end(ap); 286 if (logging_instance_ && !logging_to_plugin_) {
287 logging_to_plugin_ = true;
dmac 2011/07/21 23:37:07 logging_to_plugin_ race conditions about the globa
garykac 2011/08/02 00:15:37 True. I pushed the check down into the "CorrectThr
288 std::string message = remoting::GetTimestampString();
289 message += (str.c_str() + message_start);
290 logging_instance_->LogToUI_CorrectThread(message);
291 logging_to_plugin_ = false;
292 }
293
294 if (logging_old_handler_)
295 return (logging_old_handler_)(severity, file, line, message_start, str);
296 return false;
273 } 297 }
274 298
275 void ChromotingInstance::VLog(int verboselevel, const char* format, ...) { 299 void ChromotingInstance::LogToUI_CorrectThread(const std::string& message) {
276 va_list ap; 300 if (!logging_message_loop_)
277 va_start(ap, format); 301 return;
278 logger_.va_VLog(verboselevel, format, ap); 302
279 va_end(ap); 303 if (logging_message_loop_ != MessageLoop::current()) {
304 logging_message_loop_->PostTask(
305 FROM_HERE,
306 NewRunnableMethod(this,
307 &ChromotingInstance::LogToUI_CorrectThread, message));
308 return;
309 }
310
311 ChromotingScriptableObject* cso = GetScriptableObject();
312 if (cso) {
313 cso->LogDebugInfo(message);
314 }
280 } 315 }
281 316
282 pp::Var ChromotingInstance::GetInstanceObject() { 317 pp::Var ChromotingInstance::GetInstanceObject() {
283 if (instance_object_.is_undefined()) { 318 if (instance_object_.is_undefined()) {
284 ChromotingScriptableObject* object = new ChromotingScriptableObject(this); 319 ChromotingScriptableObject* object = new ChromotingScriptableObject(this);
285 object->Init(); 320 object->Init();
286 321
287 // The pp::Var takes ownership of object here. 322 // The pp::Var takes ownership of object here.
288 instance_object_ = pp::VarPrivate(this, object); 323 instance_object_ = pp::VarPrivate(this, object);
289 } 324 }
290 325
291 return instance_object_; 326 return instance_object_;
292 } 327 }
293 328
294 ChromotingStats* ChromotingInstance::GetStats() { 329 ChromotingStats* ChromotingInstance::GetStats() {
295 if (!client_.get()) 330 if (!client_.get())
296 return NULL; 331 return NULL;
297 return client_->GetStats(); 332 return client_->GetStats();
298 } 333 }
299 334
300 void ChromotingInstance::ReleaseAllKeys() { 335 void ChromotingInstance::ReleaseAllKeys() {
301 input_handler_->ReleaseAllKeys(); 336 input_handler_->ReleaseAllKeys();
302 } 337 }
303 338
304 } // namespace remoting 339 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698