| OLD | NEW |
| 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/task_thread_proxy.h" |
| 28 #include "remoting/base/util.h" |
| 27 #include "remoting/client/client_config.h" | 29 #include "remoting/client/client_config.h" |
| 28 #include "remoting/client/chromoting_client.h" | 30 #include "remoting/client/chromoting_client.h" |
| 29 #include "remoting/client/rectangle_update_decoder.h" | 31 #include "remoting/client/rectangle_update_decoder.h" |
| 30 #include "remoting/client/plugin/chromoting_scriptable_object.h" | 32 #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" | 33 #include "remoting/client/plugin/pepper_input_handler.h" |
| 33 #include "remoting/client/plugin/pepper_port_allocator_session.h" | 34 #include "remoting/client/plugin/pepper_port_allocator_session.h" |
| 34 #include "remoting/client/plugin/pepper_view.h" | 35 #include "remoting/client/plugin/pepper_view.h" |
| 35 #include "remoting/client/plugin/pepper_view_proxy.h" | 36 #include "remoting/client/plugin/pepper_view_proxy.h" |
| 36 #include "remoting/client/plugin/pepper_util.h" | 37 #include "remoting/client/plugin/pepper_util.h" |
| 37 #include "remoting/client/plugin/pepper_xmpp_proxy.h" | 38 #include "remoting/client/plugin/pepper_xmpp_proxy.h" |
| 38 #include "remoting/jingle_glue/jingle_thread.h" | 39 #include "remoting/jingle_glue/jingle_thread.h" |
| 39 #include "remoting/proto/auth.pb.h" | 40 #include "remoting/proto/auth.pb.h" |
| 40 #include "remoting/protocol/connection_to_host.h" | 41 #include "remoting/protocol/connection_to_host.h" |
| 41 #include "remoting/protocol/host_stub.h" | 42 #include "remoting/protocol/host_stub.h" |
| 42 // TODO(sergeyu): This is a hack: plugin should not depend on webkit | 43 // TODO(sergeyu): This is a hack: plugin should not depend on webkit |
| 43 // glue. It is used here to get P2PPacketDispatcher corresponding to | 44 // glue. It is used here to get P2PPacketDispatcher corresponding to |
| 44 // the current RenderView. Use P2P Pepper API for connection and | 45 // the current RenderView. Use P2P Pepper API for connection and |
| 45 // remove these includes. | 46 // remove these includes. |
| 46 // crbug.com/74951 | 47 // crbug.com/74951 |
| 47 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 48 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 48 #include "webkit/plugins/ppapi/resource_tracker.h" | 49 #include "webkit/plugins/ppapi/resource_tracker.h" |
| 49 | 50 |
| 50 namespace remoting { | 51 namespace remoting { |
| 51 | 52 |
| 53 // This flag blocks LOGs to the UI if we're already in the middle of logging |
| 54 // to the UI. This prevents a potential infinite loop if we encounter an error |
| 55 // while sending the log message to the UI. |
| 56 static bool g_logging_to_plugin = false; |
| 57 static ChromotingInstance* g_logging_instance = NULL; |
| 58 static logging::LogMessageHandlerFunction g_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 scale_to_fit_(false), | 65 scale_to_fit_(false) { |
| 58 logger_(this) { | |
| 59 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL); | 66 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL); |
| 60 RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); | 67 RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); |
| 68 |
| 69 log_proxy_ = new TaskThreadProxy(MessageLoop::current()); |
| 70 |
| 71 // Set up log message handler. |
| 72 // Note that this approach doesn't quite support having multiple instances |
| 73 // of Chromoting running. In that case, the most recently opened tab will |
| 74 // grab all the debug log messages, and when any Chromoting tab is closed |
| 75 // the logging handler will go away. |
| 76 // Since having multiple Chromoting tabs is not a primary use case, and this |
| 77 // is just debug logging, we're punting improving debug log support for that |
| 78 // case. |
| 79 if (g_logging_old_handler == NULL) |
| 80 g_logging_old_handler = logging::GetLogMessageHandler(); |
| 81 logging::SetLogMessageHandler(&LogToUI); |
| 82 g_logging_instance = this; |
| 61 } | 83 } |
| 62 | 84 |
| 63 ChromotingInstance::~ChromotingInstance() { | 85 ChromotingInstance::~ChromotingInstance() { |
| 64 DCHECK(CurrentlyOnPluginThread()); | 86 DCHECK(CurrentlyOnPluginThread()); |
| 65 | 87 |
| 88 // Detach the log proxy so we don't log anything else to the UI. |
| 89 log_proxy_->Detach(); |
| 90 |
| 91 // Remove log message handler. |
| 92 logging::SetLogMessageHandler(g_logging_old_handler); |
| 93 g_logging_old_handler = NULL; |
| 94 g_logging_instance = NULL; |
| 95 |
| 66 if (client_.get()) { | 96 if (client_.get()) { |
| 67 base::WaitableEvent done_event(true, false); | 97 base::WaitableEvent done_event(true, false); |
| 68 client_->Stop(base::Bind(&base::WaitableEvent::Signal, | 98 client_->Stop(base::Bind(&base::WaitableEvent::Signal, |
| 69 base::Unretained(&done_event))); | 99 base::Unretained(&done_event))); |
| 70 done_event.Wait(); | 100 done_event.Wait(); |
| 71 } | 101 } |
| 72 | 102 |
| 73 // Stopping the context shutdown all chromoting threads. This is a requirement | 103 // Stopping the context shutdown all chromoting threads. This is a requirement |
| 74 // before we can call Detach() on |view_proxy_|. | 104 // before we can call Detach() on |view_proxy_|. |
| 75 context_.Stop(); | 105 context_.Stop(); |
| 76 | 106 |
| 77 view_proxy_->Detach(); | 107 view_proxy_->Detach(); |
| 78 } | 108 } |
| 79 | 109 |
| 80 bool ChromotingInstance::Init(uint32_t argc, | 110 bool ChromotingInstance::Init(uint32_t argc, |
| 81 const char* argn[], | 111 const char* argn[], |
| 82 const char* argv[]) { | 112 const char* argv[]) { |
| 83 CHECK(!initialized_); | 113 CHECK(!initialized_); |
| 84 initialized_ = true; | 114 initialized_ = true; |
| 85 | 115 |
| 86 logger_.VLog(1, "Started ChromotingInstance::Init"); | 116 VLOG(1) << "Started ChromotingInstance::Init"; |
| 87 | 117 |
| 88 // Start all the threads. | 118 // Start all the threads. |
| 89 context_.Start(); | 119 context_.Start(); |
| 90 | 120 |
| 91 webkit::ppapi::PluginInstance* plugin_instance = | 121 webkit::ppapi::PluginInstance* plugin_instance = |
| 92 webkit::ppapi::ResourceTracker::Get()->GetInstance(pp_instance()); | 122 webkit::ppapi::ResourceTracker::Get()->GetInstance(pp_instance()); |
| 93 | 123 |
| 94 P2PSocketDispatcher* socket_dispatcher = | 124 P2PSocketDispatcher* socket_dispatcher = |
| 95 plugin_instance->delegate()->GetP2PSocketDispatcher(); | 125 plugin_instance->delegate()->GetP2PSocketDispatcher(); |
| 96 IpcNetworkManager* network_manager = NULL; | 126 IpcNetworkManager* network_manager = NULL; |
| 97 IpcPacketSocketFactory* socket_factory = NULL; | 127 IpcPacketSocketFactory* socket_factory = NULL; |
| 98 PortAllocatorSessionFactory* session_factory = | 128 PortAllocatorSessionFactory* session_factory = |
| 99 CreatePepperPortAllocatorSessionFactory(this); | 129 CreatePepperPortAllocatorSessionFactory(this); |
| 100 | 130 |
| 101 // If we don't have socket dispatcher for IPC (e.g. P2P API is | 131 // If we don't have socket dispatcher for IPC (e.g. P2P API is |
| 102 // disabled), then JingleSessionManager will try to use physical sockets. | 132 // disabled), then JingleSessionManager will try to use physical sockets. |
| 103 if (socket_dispatcher) { | 133 if (socket_dispatcher) { |
| 104 logger_.VLog(1, "Creating IpcNetworkManager and IpcPacketSocketFactory."); | 134 VLOG(1) << "Creating IpcNetworkManager and IpcPacketSocketFactory."; |
| 105 network_manager = new IpcNetworkManager(socket_dispatcher); | 135 network_manager = new IpcNetworkManager(socket_dispatcher); |
| 106 socket_factory = new IpcPacketSocketFactory(socket_dispatcher); | 136 socket_factory = new IpcPacketSocketFactory(socket_dispatcher); |
| 107 } | 137 } |
| 108 | 138 |
| 109 // Create the chromoting objects. | 139 // Create the chromoting objects. |
| 110 // TODO(sergeyu): Use firewall traversal policy settings here. | 140 // TODO(sergeyu): Use firewall traversal policy settings here. |
| 111 host_connection_.reset(new protocol::ConnectionToHost( | 141 host_connection_.reset(new protocol::ConnectionToHost( |
| 112 context_.network_message_loop(), network_manager, socket_factory, | 142 context_.network_message_loop(), network_manager, socket_factory, |
| 113 session_factory, false)); | 143 session_factory, false)); |
| 114 view_.reset(new PepperView(this, &context_)); | 144 view_.reset(new PepperView(this, &context_)); |
| 115 view_proxy_ = new PepperViewProxy(this, view_.get()); | 145 view_proxy_ = new PepperViewProxy(this, view_.get()); |
| 116 rectangle_decoder_ = new RectangleUpdateDecoder( | 146 rectangle_decoder_ = new RectangleUpdateDecoder( |
| 117 context_.decode_message_loop(), view_proxy_); | 147 context_.decode_message_loop(), view_proxy_); |
| 118 input_handler_.reset(new PepperInputHandler(&context_, | 148 input_handler_.reset(new PepperInputHandler(&context_, |
| 119 host_connection_.get(), | 149 host_connection_.get(), |
| 120 view_proxy_)); | 150 view_proxy_)); |
| 121 | 151 |
| 122 // Default to a medium grey. | 152 // Default to a medium grey. |
| 123 view_->SetSolidFill(0xFFCDCDCD); | 153 view_->SetSolidFill(0xFFCDCDCD); |
| 124 | 154 |
| 125 return true; | 155 return true; |
| 126 } | 156 } |
| 127 | 157 |
| 128 void ChromotingInstance::Connect(const ClientConfig& config) { | 158 void ChromotingInstance::Connect(const ClientConfig& config) { |
| 129 DCHECK(CurrentlyOnPluginThread()); | 159 DCHECK(CurrentlyOnPluginThread()); |
| 130 | 160 |
| 131 client_.reset(new ChromotingClient(config, &context_, host_connection_.get(), | 161 client_.reset(new ChromotingClient(config, &context_, host_connection_.get(), |
| 132 view_proxy_, rectangle_decoder_.get(), | 162 view_proxy_, rectangle_decoder_.get(), |
| 133 input_handler_.get(), &logger_, NULL)); | 163 input_handler_.get(), NULL)); |
| 134 | 164 |
| 135 logger_.Log(logging::LOG_INFO, "Connecting."); | 165 LOG(INFO) << "Connecting."; |
| 136 | 166 |
| 137 // Setup the XMPP Proxy. | 167 // Setup the XMPP Proxy. |
| 138 ChromotingScriptableObject* scriptable_object = GetScriptableObject(); | 168 ChromotingScriptableObject* scriptable_object = GetScriptableObject(); |
| 139 scoped_refptr<PepperXmppProxy> xmpp_proxy = | 169 scoped_refptr<PepperXmppProxy> xmpp_proxy = |
| 140 new PepperXmppProxy(scriptable_object->AsWeakPtr(), | 170 new PepperXmppProxy(scriptable_object->AsWeakPtr(), |
| 141 context_.jingle_thread()->message_loop()); | 171 context_.jingle_thread()->message_loop()); |
| 142 scriptable_object->AttachXmppProxy(xmpp_proxy); | 172 scriptable_object->AttachXmppProxy(xmpp_proxy); |
| 143 | 173 |
| 144 // Kick off the connection. | 174 // Kick off the connection. |
| 145 client_->Start(xmpp_proxy); | 175 client_->Start(xmpp_proxy); |
| 146 | 176 |
| 147 logger_.Log(logging::LOG_INFO, "Connection status: Initializing"); | 177 LOG(INFO) << "Connection status: Initializing"; |
| 148 GetScriptableObject()->SetConnectionInfo(STATUS_INITIALIZING, | 178 GetScriptableObject()->SetConnectionInfo(STATUS_INITIALIZING, |
| 149 QUALITY_UNKNOWN); | 179 QUALITY_UNKNOWN); |
| 150 } | 180 } |
| 151 | 181 |
| 152 void ChromotingInstance::Disconnect() { | 182 void ChromotingInstance::Disconnect() { |
| 153 DCHECK(CurrentlyOnPluginThread()); | 183 DCHECK(CurrentlyOnPluginThread()); |
| 154 | 184 |
| 155 logger_.Log(logging::LOG_INFO, "Disconnecting from host."); | 185 LOG(INFO) << "Disconnecting from host."; |
| 156 if (client_.get()) { | 186 if (client_.get()) { |
| 157 // TODO(sergeyu): Should we disconnect asynchronously? | 187 // TODO(sergeyu): Should we disconnect asynchronously? |
| 158 base::WaitableEvent done_event(true, false); | 188 base::WaitableEvent done_event(true, false); |
| 159 client_->Stop(base::Bind(&base::WaitableEvent::Signal, | 189 client_->Stop(base::Bind(&base::WaitableEvent::Signal, |
| 160 base::Unretained(&done_event))); | 190 base::Unretained(&done_event))); |
| 161 done_event.Wait(); | 191 done_event.Wait(); |
| 162 } | 192 } |
| 163 | 193 |
| 164 GetScriptableObject()->SetConnectionInfo(STATUS_CLOSED, QUALITY_UNKNOWN); | 194 GetScriptableObject()->SetConnectionInfo(STATUS_CLOSED, QUALITY_UNKNOWN); |
| 165 } | 195 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 } | 242 } |
| 213 | 243 |
| 214 case PP_INPUTEVENT_TYPE_CONTEXTMENU: { | 244 case PP_INPUTEVENT_TYPE_CONTEXTMENU: { |
| 215 // We need to return true here or else we'll get a local (plugin) context | 245 // We need to return true here or else we'll get a local (plugin) context |
| 216 // menu instead of the mouseup event for the right click. | 246 // menu instead of the mouseup event for the right click. |
| 217 return true; | 247 return true; |
| 218 } | 248 } |
| 219 | 249 |
| 220 case PP_INPUTEVENT_TYPE_KEYDOWN: { | 250 case PP_INPUTEVENT_TYPE_KEYDOWN: { |
| 221 pp::KeyboardInputEvent key = pp::KeyboardInputEvent(event); | 251 pp::KeyboardInputEvent key = pp::KeyboardInputEvent(event); |
| 222 logger_.VLog(3, "PP_INPUTEVENT_TYPE_KEYDOWN key=%d", key.GetKeyCode()); | 252 VLOG(3) << "PP_INPUTEVENT_TYPE_KEYDOWN" << " key=" << key.GetKeyCode(); |
| 223 pih->HandleKeyEvent(true, key); | 253 pih->HandleKeyEvent(true, key); |
| 224 return true; | 254 return true; |
| 225 } | 255 } |
| 226 | 256 |
| 227 case PP_INPUTEVENT_TYPE_KEYUP: { | 257 case PP_INPUTEVENT_TYPE_KEYUP: { |
| 228 pp::KeyboardInputEvent key = pp::KeyboardInputEvent(event); | 258 pp::KeyboardInputEvent key = pp::KeyboardInputEvent(event); |
| 229 logger_.VLog(3, "PP_INPUTEVENT_TYPE_KEYUP key=%d", key.GetKeyCode()); | 259 VLOG(3) << "PP_INPUTEVENT_TYPE_KEYUP" << " key=" << key.GetKeyCode(); |
| 230 pih->HandleKeyEvent(false, key); | 260 pih->HandleKeyEvent(false, key); |
| 231 return true; | 261 return true; |
| 232 } | 262 } |
| 233 | 263 |
| 234 case PP_INPUTEVENT_TYPE_CHAR: { | 264 case PP_INPUTEVENT_TYPE_CHAR: { |
| 235 pih->HandleCharacterEvent(pp::KeyboardInputEvent(event)); | 265 pih->HandleCharacterEvent(pp::KeyboardInputEvent(event)); |
| 236 return true; | 266 return true; |
| 237 } | 267 } |
| 238 | 268 |
| 239 default: { | 269 default: { |
| 240 LOG(INFO) << "Unhandled input event: " << event.GetType(); | 270 LOG(INFO) << "Unhandled input event: " << event.GetType(); |
| 241 break; | 271 break; |
| 242 } | 272 } |
| 243 } | 273 } |
| 244 | 274 |
| 245 return false; | 275 return false; |
| 246 } | 276 } |
| 247 | 277 |
| 248 ChromotingScriptableObject* ChromotingInstance::GetScriptableObject() { | 278 ChromotingScriptableObject* ChromotingInstance::GetScriptableObject() { |
| 249 pp::VarPrivate object = GetInstanceObject(); | 279 pp::VarPrivate object = GetInstanceObject(); |
| 250 if (!object.is_undefined()) { | 280 if (!object.is_undefined()) { |
| 251 pp::deprecated::ScriptableObject* so = object.AsScriptableObject(); | 281 pp::deprecated::ScriptableObject* so = object.AsScriptableObject(); |
| 252 DCHECK(so != NULL); | 282 DCHECK(so != NULL); |
| 253 return static_cast<ChromotingScriptableObject*>(so); | 283 return static_cast<ChromotingScriptableObject*>(so); |
| 254 } | 284 } |
| 255 logger_.Log(logging::LOG_ERROR, | 285 LOG(ERROR) << "Unable to get ScriptableObject for Chromoting plugin."; |
| 256 "Unable to get ScriptableObject for Chromoting plugin."); | |
| 257 return NULL; | 286 return NULL; |
| 258 } | 287 } |
| 259 | 288 |
| 260 void ChromotingInstance::SubmitLoginInfo(const std::string& username, | 289 void ChromotingInstance::SubmitLoginInfo(const std::string& username, |
| 261 const std::string& password) { | 290 const std::string& password) { |
| 262 if (host_connection_->state() != | 291 if (host_connection_->state() != |
| 263 protocol::ConnectionToHost::STATE_CONNECTED) { | 292 protocol::ConnectionToHost::STATE_CONNECTED) { |
| 264 logger_.Log(logging::LOG_INFO, | 293 LOG(INFO) << "Client not connected or already authenticated."; |
| 265 "Client not connected or already authenticated."); | |
| 266 return; | 294 return; |
| 267 } | 295 } |
| 268 | 296 |
| 269 protocol::LocalLoginCredentials* credentials = | 297 protocol::LocalLoginCredentials* credentials = |
| 270 new protocol::LocalLoginCredentials(); | 298 new protocol::LocalLoginCredentials(); |
| 271 credentials->set_type(protocol::PASSWORD); | 299 credentials->set_type(protocol::PASSWORD); |
| 272 credentials->set_username(username); | 300 credentials->set_username(username); |
| 273 credentials->set_credential(password.data(), password.length()); | 301 credentials->set_credential(password.data(), password.length()); |
| 274 | 302 |
| 275 host_connection_->host_stub()->BeginSessionRequest( | 303 host_connection_->host_stub()->BeginSessionRequest( |
| (...skipping 10 matching lines...) Expand all Loading... |
| 286 scale_to_fit_ = scale_to_fit; | 314 scale_to_fit_ = scale_to_fit; |
| 287 if (scale_to_fit) { | 315 if (scale_to_fit) { |
| 288 rectangle_decoder_->SetScaleRatios(view_->GetHorizontalScaleRatio(), | 316 rectangle_decoder_->SetScaleRatios(view_->GetHorizontalScaleRatio(), |
| 289 view_->GetVerticalScaleRatio()); | 317 view_->GetVerticalScaleRatio()); |
| 290 } else { | 318 } else { |
| 291 rectangle_decoder_->SetScaleRatios(1.0, 1.0); | 319 rectangle_decoder_->SetScaleRatios(1.0, 1.0); |
| 292 } | 320 } |
| 293 rectangle_decoder_->RefreshFullFrame(); | 321 rectangle_decoder_->RefreshFullFrame(); |
| 294 } | 322 } |
| 295 | 323 |
| 296 void ChromotingInstance::Log(int severity, const char* format, ...) { | 324 // static |
| 297 va_list ap; | 325 bool ChromotingInstance::LogToUI(int severity, const char* file, int line, |
| 298 va_start(ap, format); | 326 size_t message_start, |
| 299 logger_.va_Log(severity, format, ap); | 327 const std::string& str) { |
| 300 va_end(ap); | 328 if (g_logging_instance) { |
| 329 std::string message = remoting::GetTimestampString(); |
| 330 message += (str.c_str() + message_start); |
| 331 g_logging_instance->log_proxy_->Call( |
| 332 base::Bind(&ChromotingInstance::ProcessLogToUI, |
| 333 base::Unretained(g_logging_instance), message)); |
| 334 } |
| 335 |
| 336 if (g_logging_old_handler) |
| 337 return (g_logging_old_handler)(severity, file, line, message_start, str); |
| 338 return false; |
| 301 } | 339 } |
| 302 | 340 |
| 303 void ChromotingInstance::VLog(int verboselevel, const char* format, ...) { | 341 void ChromotingInstance::ProcessLogToUI(const std::string& message) { |
| 304 va_list ap; | 342 if (!g_logging_to_plugin) { |
| 305 va_start(ap, format); | 343 ChromotingScriptableObject* cso = GetScriptableObject(); |
| 306 logger_.va_VLog(verboselevel, format, ap); | 344 if (cso) { |
| 307 va_end(ap); | 345 g_logging_to_plugin = true; |
| 346 cso->LogDebugInfo(message); |
| 347 g_logging_to_plugin = false; |
| 348 } |
| 349 } |
| 308 } | 350 } |
| 309 | 351 |
| 310 pp::Var ChromotingInstance::GetInstanceObject() { | 352 pp::Var ChromotingInstance::GetInstanceObject() { |
| 311 if (instance_object_.is_undefined()) { | 353 if (instance_object_.is_undefined()) { |
| 312 ChromotingScriptableObject* object = new ChromotingScriptableObject(this); | 354 ChromotingScriptableObject* object = new ChromotingScriptableObject(this); |
| 313 object->Init(); | 355 object->Init(); |
| 314 | 356 |
| 315 // The pp::Var takes ownership of object here. | 357 // The pp::Var takes ownership of object here. |
| 316 instance_object_ = pp::VarPrivate(this, object); | 358 instance_object_ = pp::VarPrivate(this, object); |
| 317 } | 359 } |
| 318 | 360 |
| 319 return instance_object_; | 361 return instance_object_; |
| 320 } | 362 } |
| 321 | 363 |
| 322 ChromotingStats* ChromotingInstance::GetStats() { | 364 ChromotingStats* ChromotingInstance::GetStats() { |
| 323 if (!client_.get()) | 365 if (!client_.get()) |
| 324 return NULL; | 366 return NULL; |
| 325 return client_->GetStats(); | 367 return client_->GetStats(); |
| 326 } | 368 } |
| 327 | 369 |
| 328 void ChromotingInstance::ReleaseAllKeys() { | 370 void ChromotingInstance::ReleaseAllKeys() { |
| 329 input_handler_->ReleaseAllKeys(); | 371 input_handler_->ReleaseAllKeys(); |
| 330 } | 372 } |
| 331 | 373 |
| 332 } // namespace remoting | 374 } // namespace remoting |
| OLD | NEW |