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

Side by Side Diff: remoting/host/plugin/host_script_object.cc

Issue 7355011: Modify Chromoting logging to hook into base logging. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: time Created 9 years, 4 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
« no previous file with comments | « remoting/host/plugin/host_script_object.h ('k') | remoting/host/simple_host_process.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/host/plugin/host_script_object.h" 5 #include "remoting/host/plugin/host_script_object.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/threading/platform_thread.h" 9 #include "base/threading/platform_thread.h"
10 #include "remoting/base/auth_token_util.h" 10 #include "remoting/base/auth_token_util.h"
11 #include "remoting/base/util.h"
11 #include "remoting/host/chromoting_host.h" 12 #include "remoting/host/chromoting_host.h"
12 #include "remoting/host/chromoting_host_context.h" 13 #include "remoting/host/chromoting_host_context.h"
13 #include "remoting/host/desktop_environment.h" 14 #include "remoting/host/desktop_environment.h"
14 #include "remoting/host/host_config.h" 15 #include "remoting/host/host_config.h"
15 #include "remoting/host/host_key_pair.h" 16 #include "remoting/host/host_key_pair.h"
16 #include "remoting/host/in_memory_host_config.h" 17 #include "remoting/host/in_memory_host_config.h"
17 #include "remoting/host/plugin/host_plugin_utils.h" 18 #include "remoting/host/plugin/host_plugin_utils.h"
18 #include "remoting/host/register_support_host_request.h" 19 #include "remoting/host/register_support_host_request.h"
19 #include "remoting/host/support_access_verifier.h" 20 #include "remoting/host/support_access_verifier.h"
20 21
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; 58 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE";
58 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; 59 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE";
59 const char* kAttrNameConnected = "CONNECTED"; 60 const char* kAttrNameConnected = "CONNECTED";
60 const char* kAttrNameAffirmingConnection = "AFFIRMING_CONNECTION"; 61 const char* kAttrNameAffirmingConnection = "AFFIRMING_CONNECTION";
61 const char* kAttrNameError = "ERROR"; 62 const char* kAttrNameError = "ERROR";
62 63
63 const int kMaxLoginAttempts = 5; 64 const int kMaxLoginAttempts = 5;
64 65
65 } // namespace 66 } // namespace
66 67
68 // This flag blocks LOGs to the UI if we're already in the middle of logging
69 // to the UI. This prevents a potential infinite loop if we encounter an error
70 // while sending the log message to the UI.
71 static bool g_logging_to_plugin = false;
72 static HostNPScriptObject* g_logging_scriptable_object = NULL;
73 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL;
74
67 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) 75 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent)
68 : plugin_(plugin), 76 : plugin_(plugin),
69 parent_(parent), 77 parent_(parent),
70 state_(kDisconnected), 78 state_(kDisconnected),
71 log_debug_info_func_(NULL), 79 log_debug_info_func_(NULL),
72 on_state_changed_func_(NULL), 80 on_state_changed_func_(NULL),
73 np_thread_id_(base::PlatformThread::CurrentId()), 81 np_thread_id_(base::PlatformThread::CurrentId()),
74 failed_login_attempts_(0), 82 failed_login_attempts_(0),
75 disconnected_event_(true, false) { 83 disconnected_event_(true, false) {
76 logger_.reset(new HostPluginLogger(this)); 84 // Set up log message handler.
77 logger_->VLog(2, "HostNPScriptObject"); 85 // Note that this approach doesn't quite support having multiple instances
86 // of Chromoting running. In that case, the most recently opened tab will
87 // grab all the debug log messages, and when any Chromoting tab is closed
88 // the logging handler will go away.
89 // Since having multiple Chromoting tabs is not a primary use case, and this
90 // is just debug logging, we're punting improving debug log support for that
91 // case.
92 if (g_logging_old_handler == NULL)
93 g_logging_old_handler = logging::GetLogMessageHandler();
94 logging::SetLogMessageHandler(&LogToUI);
95 g_logging_scriptable_object = this;
96
97 VLOG(2) << "HostNPScriptObject";
78 host_context_.SetUITaskPostFunction(base::Bind( 98 host_context_.SetUITaskPostFunction(base::Bind(
79 &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this))); 99 &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this)));
80 } 100 }
81 101
82 HostNPScriptObject::~HostNPScriptObject() { 102 HostNPScriptObject::~HostNPScriptObject() {
83 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 103 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
84 104
85 // Shutdown DesktopEnvironment first so that it doesn't try to post 105 // Shutdown DesktopEnvironment first so that it doesn't try to post
86 // tasks on the UI thread while we are stopping the host. 106 // tasks on the UI thread while we are stopping the host.
87 desktop_environment_->Shutdown(); 107 desktop_environment_->Shutdown();
88 108
109 logging::SetLogMessageHandler(g_logging_old_handler_);
110 g_logging_old_handler_ = NULL;
Wez 2011/08/02 23:45:26 This code isn't symmetric with the constructor; if
111 g_logging_scriptable_object_ = NULL;
112
89 // Disconnect synchronously. We cannot disconnect asynchronously 113 // Disconnect synchronously. We cannot disconnect asynchronously
90 // here because |host_context_| needs to be stopped on the plugin 114 // here because |host_context_| needs to be stopped on the plugin
91 // thread, but the plugin thread may not exist after the instance 115 // thread, but the plugin thread may not exist after the instance
92 // is destroyed. 116 // is destroyed.
93 destructing_.Set(); 117 destructing_.Set();
94 disconnected_event_.Reset(); 118 disconnected_event_.Reset();
95 DisconnectInternal(); 119 DisconnectInternal();
96 disconnected_event_.Wait(); 120 disconnected_event_.Wait();
97 121
98 // Stop all threads. 122 // Stop all threads.
99 host_context_.Stop(); 123 host_context_.Stop();
100 124
101 if (log_debug_info_func_) { 125 if (log_debug_info_func_) {
102 g_npnetscape_funcs->releaseobject(log_debug_info_func_); 126 g_npnetscape_funcs->releaseobject(log_debug_info_func_);
103 } 127 }
104 if (on_state_changed_func_) { 128 if (on_state_changed_func_) {
105 g_npnetscape_funcs->releaseobject(on_state_changed_func_); 129 g_npnetscape_funcs->releaseobject(on_state_changed_func_);
106 } 130 }
107 } 131 }
108 132
109 bool HostNPScriptObject::Init() { 133 bool HostNPScriptObject::Init() {
110 logger_->VLog(2, "Init"); 134 VLOG(2) << "Init";
111 // TODO(wez): This starts a bunch of threads, which might fail. 135 // TODO(wez): This starts a bunch of threads, which might fail.
112 host_context_.Start(); 136 host_context_.Start();
113 return true; 137 return true;
114 } 138 }
115 139
116 bool HostNPScriptObject::HasMethod(const std::string& method_name) { 140 bool HostNPScriptObject::HasMethod(const std::string& method_name) {
117 logger_->VLog(2, "HasMethod %s", method_name.c_str()); 141 VLOG(2) << "HasMethod " << method_name;
118 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 142 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
119 return (method_name == kFuncNameConnect || 143 return (method_name == kFuncNameConnect ||
120 method_name == kFuncNameDisconnect); 144 method_name == kFuncNameDisconnect);
121 } 145 }
122 146
123 bool HostNPScriptObject::InvokeDefault(const NPVariant* args, 147 bool HostNPScriptObject::InvokeDefault(const NPVariant* args,
124 uint32_t argCount, 148 uint32_t argCount,
125 NPVariant* result) { 149 NPVariant* result) {
126 logger_->VLog(2, "InvokeDefault"); 150 VLOG(2) << "InvokeDefault";
127 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 151 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
128 SetException("exception during default invocation"); 152 SetException("exception during default invocation");
129 return false; 153 return false;
130 } 154 }
131 155
132 bool HostNPScriptObject::Invoke(const std::string& method_name, 156 bool HostNPScriptObject::Invoke(const std::string& method_name,
133 const NPVariant* args, 157 const NPVariant* args,
134 uint32_t argCount, 158 uint32_t argCount,
135 NPVariant* result) { 159 NPVariant* result) {
136 logger_->VLog(2, "Invoke %s", method_name.c_str()); 160 VLOG(2) << "Invoke " << method_name;
137 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 161 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
138 if (method_name == kFuncNameConnect) { 162 if (method_name == kFuncNameConnect) {
139 return Connect(args, argCount, result); 163 return Connect(args, argCount, result);
140 } else if (method_name == kFuncNameDisconnect) { 164 } else if (method_name == kFuncNameDisconnect) {
141 return Disconnect(args, argCount, result); 165 return Disconnect(args, argCount, result);
142 } else { 166 } else {
143 SetException("Invoke: unknown method " + method_name); 167 SetException("Invoke: unknown method " + method_name);
144 return false; 168 return false;
145 } 169 }
146 } 170 }
147 171
148 bool HostNPScriptObject::HasProperty(const std::string& property_name) { 172 bool HostNPScriptObject::HasProperty(const std::string& property_name) {
149 logger_->VLog(2, "HasProperty %s", property_name.c_str()); 173 VLOG(2) << "HasProperty " << property_name;
150 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 174 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
151 return (property_name == kAttrNameAccessCode || 175 return (property_name == kAttrNameAccessCode ||
152 property_name == kAttrNameAccessCodeLifetime || 176 property_name == kAttrNameAccessCodeLifetime ||
153 property_name == kAttrNameState || 177 property_name == kAttrNameState ||
154 property_name == kAttrNameLogDebugInfo || 178 property_name == kAttrNameLogDebugInfo ||
155 property_name == kAttrNameOnStateChanged || 179 property_name == kAttrNameOnStateChanged ||
156 property_name == kAttrNameDisconnected || 180 property_name == kAttrNameDisconnected ||
157 property_name == kAttrNameRequestedAccessCode || 181 property_name == kAttrNameRequestedAccessCode ||
158 property_name == kAttrNameReceivedAccessCode || 182 property_name == kAttrNameReceivedAccessCode ||
159 property_name == kAttrNameConnected || 183 property_name == kAttrNameConnected ||
160 property_name == kAttrNameAffirmingConnection || 184 property_name == kAttrNameAffirmingConnection ||
161 property_name == kAttrNameError); 185 property_name == kAttrNameError);
162 } 186 }
163 187
164 bool HostNPScriptObject::GetProperty(const std::string& property_name, 188 bool HostNPScriptObject::GetProperty(const std::string& property_name,
165 NPVariant* result) { 189 NPVariant* result) {
166 logger_->VLog(2, "GetProperty %s", property_name.c_str()); 190 VLOG(2) << "GetProperty " << property_name;
167 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 191 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
168 if (!result) { 192 if (!result) {
169 SetException("GetProperty: NULL result"); 193 SetException("GetProperty: NULL result");
170 return false; 194 return false;
171 } 195 }
172 196
173 if (property_name == kAttrNameOnStateChanged) { 197 if (property_name == kAttrNameOnStateChanged) {
174 OBJECT_TO_NPVARIANT(on_state_changed_func_, *result); 198 OBJECT_TO_NPVARIANT(on_state_changed_func_, *result);
175 return true; 199 return true;
176 } else if (property_name == kAttrNameLogDebugInfo) { 200 } else if (property_name == kAttrNameLogDebugInfo) {
(...skipping 27 matching lines...) Expand all
204 INT32_TO_NPVARIANT(kError, *result); 228 INT32_TO_NPVARIANT(kError, *result);
205 return true; 229 return true;
206 } else { 230 } else {
207 SetException("GetProperty: unsupported property " + property_name); 231 SetException("GetProperty: unsupported property " + property_name);
208 return false; 232 return false;
209 } 233 }
210 } 234 }
211 235
212 bool HostNPScriptObject::SetProperty(const std::string& property_name, 236 bool HostNPScriptObject::SetProperty(const std::string& property_name,
213 const NPVariant* value) { 237 const NPVariant* value) {
214 logger_->VLog(2, "SetProperty %s", property_name.c_str()); 238 VLOG(2) << "SetProperty " << property_name;
215 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 239 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
216 240
217 if (property_name == kAttrNameOnStateChanged) { 241 if (property_name == kAttrNameOnStateChanged) {
218 if (NPVARIANT_IS_OBJECT(*value)) { 242 if (NPVARIANT_IS_OBJECT(*value)) {
219 if (on_state_changed_func_) { 243 if (on_state_changed_func_) {
220 g_npnetscape_funcs->releaseobject(on_state_changed_func_); 244 g_npnetscape_funcs->releaseobject(on_state_changed_func_);
221 } 245 }
222 on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value); 246 on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value);
223 if (on_state_changed_func_) { 247 if (on_state_changed_func_) {
224 g_npnetscape_funcs->retainobject(on_state_changed_func_); 248 g_npnetscape_funcs->retainobject(on_state_changed_func_);
(...skipping 20 matching lines...) Expand all
245 SetException("SetProperty: unexpected type for property " + 269 SetException("SetProperty: unexpected type for property " +
246 property_name); 270 property_name);
247 } 271 }
248 return false; 272 return false;
249 } 273 }
250 274
251 return false; 275 return false;
252 } 276 }
253 277
254 bool HostNPScriptObject::RemoveProperty(const std::string& property_name) { 278 bool HostNPScriptObject::RemoveProperty(const std::string& property_name) {
255 logger_->VLog(2, "RemoveProperty %s", property_name.c_str()); 279 VLOG(2) << "RemoveProperty " << property_name;
256 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 280 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
257 return false; 281 return false;
258 } 282 }
259 283
260 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { 284 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) {
261 logger_->VLog(2, "Enumerate"); 285 VLOG(2) << "Enumerate";
262 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 286 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
263 const char* entries[] = { 287 const char* entries[] = {
264 kAttrNameAccessCode, 288 kAttrNameAccessCode,
265 kAttrNameState, 289 kAttrNameState,
266 kAttrNameLogDebugInfo, 290 kAttrNameLogDebugInfo,
267 kAttrNameOnStateChanged, 291 kAttrNameOnStateChanged,
268 kFuncNameConnect, 292 kFuncNameConnect,
269 kFuncNameDisconnect, 293 kFuncNameDisconnect,
270 kAttrNameDisconnected, 294 kAttrNameDisconnected,
271 kAttrNameRequestedAccessCode, 295 kAttrNameRequestedAccessCode,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 329
306 OnStateChanged(kDisconnected); 330 OnStateChanged(kDisconnected);
307 } 331 }
308 332
309 // string uid, string auth_token 333 // string uid, string auth_token
310 bool HostNPScriptObject::Connect(const NPVariant* args, 334 bool HostNPScriptObject::Connect(const NPVariant* args,
311 uint32_t arg_count, 335 uint32_t arg_count,
312 NPVariant* result) { 336 NPVariant* result) {
313 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 337 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
314 338
315 LogDebugInfo("Connecting..."); 339 LOG(INFO) << "Connecting...";
316 340
317 if (arg_count != 2) { 341 if (arg_count != 2) {
318 SetException("connect: bad number of arguments"); 342 SetException("connect: bad number of arguments");
319 return false; 343 return false;
320 } 344 }
321 345
322 std::string uid = StringFromNPVariant(args[0]); 346 std::string uid = StringFromNPVariant(args[0]);
323 if (uid.empty()) { 347 if (uid.empty()) {
324 SetException("connect: bad uid argument"); 348 SetException("connect: bad uid argument");
325 return false; 349 return false;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 return; 499 return;
476 500
477 if (!host_context_.IsUIThread()) { 501 if (!host_context_.IsUIThread()) {
478 host_context_.PostTaskToUIThread( 502 host_context_.PostTaskToUIThread(
479 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged, 503 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged,
480 base::Unretained(this), state)); 504 base::Unretained(this), state));
481 return; 505 return;
482 } 506 }
483 state_ = state; 507 state_ = state;
484 if (on_state_changed_func_) { 508 if (on_state_changed_func_) {
485 logger_->VLog(2, "Calling state changed %s", state); 509 VLOG(2) << "Calling state changed " << state;
486 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_, NULL, 0); 510 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_, NULL, 0);
487 LOG_IF(ERROR, !is_good) << "OnStateChanged failed"; 511 LOG_IF(ERROR, !is_good) << "OnStateChanged failed";
488 } 512 }
489 } 513 }
490 514
515 // static
516 bool HostNPScriptObject::LogToUI(int severity, const char* file, int line,
517 size_t message_start,
518 const std::string& str) {
519 if (g_logging_scriptable_object) {
520 std::string message = remoting::GetTimestampString();
521 message += (str.c_str() + message_start);
522 g_logging_scriptable_object->LogDebugInfo(message);
523 }
524 if (g_logging_old_handler)
525 return (g_logging_old_handler)(severity, file, line, message_start, str);
526 return false;
527 }
528
491 void HostNPScriptObject::LogDebugInfo(const std::string& message) { 529 void HostNPScriptObject::LogDebugInfo(const std::string& message) {
492 if (destructing_.IsSet()) 530 if (destructing_.IsSet())
493 return; 531 return;
494 532
495 if (!host_context_.IsUIThread()) { 533 if (!host_context_.IsUIThread()) {
496 host_context_.PostTaskToUIThread( 534 host_context_.PostTaskToUIThread(
497 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo, 535 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo,
498 base::Unretained(this), message)); 536 base::Unretained(this), message));
499 return; 537 return;
500 } 538 }
501 if (log_debug_info_func_) { 539 if (log_debug_info_func_ && !g_logging_to_plugin) {
Sergey Ulanov 2011/08/02 18:15:52 Not sure why we need |g_logging_to_plugin| here. C
garykac 2011/08/02 23:09:51 Added comments and moved it into the static LogToU
502 NPVariant* arg = new NPVariant(); 540 NPVariant* arg = new NPVariant();
503 STRINGZ_TO_NPVARIANT(message.c_str(), *arg); 541 STRINGZ_TO_NPVARIANT(message.c_str(), *arg);
542 g_logging_to_plugin = true;
504 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_, arg, 1); 543 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_, arg, 1);
544 g_logging_to_plugin = false;
505 LOG_IF(ERROR, !is_good) << "LogDebugInfo failed"; 545 LOG_IF(ERROR, !is_good) << "LogDebugInfo failed";
506 } 546 }
507 } 547 }
508 548
509 void HostNPScriptObject::SetException(const std::string& exception_string) { 549 void HostNPScriptObject::SetException(const std::string& exception_string) {
510 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 550 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
511 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); 551 g_npnetscape_funcs->setexception(parent_, exception_string.c_str());
512 LogDebugInfo(exception_string); 552 LOG(INFO) << exception_string;
513 } 553 }
514 554
515 bool HostNPScriptObject::InvokeAndIgnoreResult(NPObject* func, 555 bool HostNPScriptObject::InvokeAndIgnoreResult(NPObject* func,
516 const NPVariant* args, 556 const NPVariant* args,
517 uint32_t argCount) { 557 uint32_t argCount) {
518 NPVariant np_result; 558 NPVariant np_result;
519 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, 559 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args,
520 argCount, &np_result); 560 argCount, &np_result);
521 if (is_good) 561 if (is_good)
522 g_npnetscape_funcs->releasevariantvalue(&np_result); 562 g_npnetscape_funcs->releasevariantvalue(&np_result);
(...skipping 15 matching lines...) Expand all
538 } 578 }
539 579
540 // static 580 // static
541 void HostNPScriptObject::NPTaskSpringboard(void* task) { 581 void HostNPScriptObject::NPTaskSpringboard(void* task) {
542 base::Closure* real_task = reinterpret_cast<base::Closure*>(task); 582 base::Closure* real_task = reinterpret_cast<base::Closure*>(task);
543 real_task->Run(); 583 real_task->Run();
544 delete real_task; 584 delete real_task;
545 } 585 }
546 586
547 } // namespace remoting 587 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/plugin/host_script_object.h ('k') | remoting/host/simple_host_process.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698