Chromium Code Reviews| 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/logging.h" | |
| 10 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 11 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 12 #include "base/task.h" | 13 #include "base/task.h" |
| 13 #include "base/threading/thread.h" | 14 #include "base/threading/thread.h" |
| 14 // TODO(sergeyu): We should not depend on renderer here. Instead P2P | 15 // TODO(sergeyu): We should not depend on renderer here. Instead P2P |
| 15 // Pepper API should be used. Remove this dependency. | 16 // Pepper API should be used. Remove this dependency. |
| 16 // crbug.com/74951 | 17 // crbug.com/74951 |
| 17 #include "content/renderer/p2p/ipc_network_manager.h" | 18 #include "content/renderer/p2p/ipc_network_manager.h" |
| 18 #include "content/renderer/p2p/ipc_socket_factory.h" | 19 #include "content/renderer/p2p/ipc_socket_factory.h" |
| 19 #include "ppapi/c/pp_input_event.h" | 20 #include "ppapi/c/pp_input_event.h" |
| 20 #include "ppapi/cpp/completion_callback.h" | 21 #include "ppapi/cpp/completion_callback.h" |
| 21 #include "ppapi/cpp/rect.h" | 22 #include "ppapi/cpp/rect.h" |
| 22 #include "remoting/client/client_config.h" | 23 #include "remoting/client/client_config.h" |
| 23 #include "remoting/client/client_util.h" | 24 #include "remoting/client/client_util.h" |
| 24 #include "remoting/client/chromoting_client.h" | 25 #include "remoting/client/chromoting_client.h" |
| 25 #include "remoting/client/rectangle_update_decoder.h" | 26 #include "remoting/client/rectangle_update_decoder.h" |
| 26 #include "remoting/client/plugin/chromoting_scriptable_object.h" | 27 #include "remoting/client/plugin/chromoting_scriptable_object.h" |
| 28 #include "remoting/client/plugin/pepper_client_logger.h" | |
| 27 #include "remoting/client/plugin/pepper_input_handler.h" | 29 #include "remoting/client/plugin/pepper_input_handler.h" |
| 28 #include "remoting/client/plugin/pepper_port_allocator_session.h" | 30 #include "remoting/client/plugin/pepper_port_allocator_session.h" |
| 29 #include "remoting/client/plugin/pepper_view.h" | 31 #include "remoting/client/plugin/pepper_view.h" |
| 30 #include "remoting/client/plugin/pepper_view_proxy.h" | 32 #include "remoting/client/plugin/pepper_view_proxy.h" |
| 31 #include "remoting/client/plugin/pepper_util.h" | 33 #include "remoting/client/plugin/pepper_util.h" |
| 32 #include "remoting/client/plugin/pepper_xmpp_proxy.h" | 34 #include "remoting/client/plugin/pepper_xmpp_proxy.h" |
| 33 #include "remoting/jingle_glue/jingle_thread.h" | 35 #include "remoting/jingle_glue/jingle_thread.h" |
| 34 #include "remoting/proto/auth.pb.h" | 36 #include "remoting/proto/auth.pb.h" |
| 35 #include "remoting/protocol/connection_to_host.h" | 37 #include "remoting/protocol/connection_to_host.h" |
| 36 // TODO(sergeyu): This is a hack: plugin should not depend on webkit | 38 // TODO(sergeyu): This is a hack: plugin should not depend on webkit |
| 37 // glue. It is used here to get P2PPacketDispatcher corresponding to | 39 // glue. It is used here to get P2PPacketDispatcher corresponding to |
| 38 // the current RenderView. Use P2P Pepper API for connection and | 40 // the current RenderView. Use P2P Pepper API for connection and |
| 39 // remove these includes. | 41 // remove these includes. |
| 40 // crbug.com/74951 | 42 // crbug.com/74951 |
| 41 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 43 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 42 #include "webkit/plugins/ppapi/resource_tracker.h" | 44 #include "webkit/plugins/ppapi/resource_tracker.h" |
| 43 | 45 |
| 44 namespace remoting { | 46 namespace remoting { |
| 45 | 47 |
| 46 const char* ChromotingInstance::kMimeType = "pepper-application/x-chromoting"; | 48 const char* ChromotingInstance::kMimeType = "pepper-application/x-chromoting"; |
| 47 | 49 |
| 48 ChromotingInstance::ChromotingInstance(PP_Instance pp_instance) | 50 ChromotingInstance::ChromotingInstance(PP_Instance pp_instance) |
| 49 : pp::Instance(pp_instance), | 51 : pp::Instance(pp_instance), |
| 50 initialized_(false) { | 52 initialized_(false), |
| 53 logger_(new PepperClientLogger(this)) { | |
|
dmac
2011/05/13 23:34:10
does this need to be a ptr?
garykac
2011/05/14 01:09:16
Done.
| |
| 51 } | 54 } |
| 52 | 55 |
| 53 ChromotingInstance::~ChromotingInstance() { | 56 ChromotingInstance::~ChromotingInstance() { |
| 54 if (client_.get()) { | 57 if (client_.get()) { |
| 55 client_->Stop(); | 58 client_->Stop(); |
| 56 } | 59 } |
| 57 | 60 |
| 58 // Stopping the context shutdown all chromoting threads. This is a requirement | 61 // Stopping the context shutdown all chromoting threads. This is a requirement |
| 59 // before we can call Detach() on |view_proxy_|. | 62 // before we can call Detach() on |view_proxy_|. |
| 60 context_.Stop(); | 63 context_.Stop(); |
| 61 | 64 |
| 62 view_proxy_->Detach(); | 65 view_proxy_->Detach(); |
| 63 } | 66 } |
| 64 | 67 |
| 65 bool ChromotingInstance::Init(uint32_t argc, | 68 bool ChromotingInstance::Init(uint32_t argc, |
| 66 const char* argn[], | 69 const char* argn[], |
| 67 const char* argv[]) { | 70 const char* argv[]) { |
| 68 CHECK(!initialized_); | 71 CHECK(!initialized_); |
| 69 initialized_ = true; | 72 initialized_ = true; |
| 70 | 73 |
| 71 VLOG(1) << "Started ChromotingInstance::Init"; | 74 logger_->VLog(1, "Started ChromotingInstance::Init"); |
| 72 | 75 |
| 73 // Start all the threads. | 76 // Start all the threads. |
| 74 context_.Start(); | 77 context_.Start(); |
| 75 | 78 |
| 76 webkit::ppapi::PluginInstance* plugin_instance = | 79 webkit::ppapi::PluginInstance* plugin_instance = |
| 77 webkit::ppapi::ResourceTracker::Get()->GetInstance(pp_instance()); | 80 webkit::ppapi::ResourceTracker::Get()->GetInstance(pp_instance()); |
| 78 | 81 |
| 79 P2PSocketDispatcher* socket_dispatcher = | 82 P2PSocketDispatcher* socket_dispatcher = |
| 80 plugin_instance->delegate()->GetP2PSocketDispatcher(); | 83 plugin_instance->delegate()->GetP2PSocketDispatcher(); |
| 81 IpcNetworkManager* network_manager = NULL; | 84 IpcNetworkManager* network_manager = NULL; |
| 82 IpcPacketSocketFactory* socket_factory = NULL; | 85 IpcPacketSocketFactory* socket_factory = NULL; |
| 83 PortAllocatorSessionFactory* session_factory = | 86 PortAllocatorSessionFactory* session_factory = |
| 84 CreatePepperPortAllocatorSessionFactory(this); | 87 CreatePepperPortAllocatorSessionFactory(this); |
| 85 | 88 |
| 86 // If we don't have socket dispatcher for IPC (e.g. P2P API is | 89 // If we don't have socket dispatcher for IPC (e.g. P2P API is |
| 87 // disabled), then JingleClient will try to use physical sockets. | 90 // disabled), then JingleClient will try to use physical sockets. |
| 88 if (socket_dispatcher) { | 91 if (socket_dispatcher) { |
| 89 VLOG(1) << "Creating IpcNetworkManager and IpcPacketSocketFactory."; | 92 logger_->VLog(1, "Creating IpcNetworkManager and IpcPacketSocketFactory."); |
| 90 network_manager = new IpcNetworkManager(socket_dispatcher); | 93 network_manager = new IpcNetworkManager(socket_dispatcher); |
| 91 socket_factory = new IpcPacketSocketFactory(socket_dispatcher); | 94 socket_factory = new IpcPacketSocketFactory(socket_dispatcher); |
| 92 } | 95 } |
| 93 | 96 |
| 94 // Create the chromoting objects. | 97 // Create the chromoting objects. |
| 95 host_connection_.reset(new protocol::ConnectionToHost( | 98 host_connection_.reset(new protocol::ConnectionToHost( |
| 96 context_.jingle_thread(), network_manager, socket_factory, | 99 context_.jingle_thread(), network_manager, socket_factory, |
| 97 session_factory)); | 100 session_factory)); |
| 98 view_.reset(new PepperView(this, &context_)); | 101 view_.reset(new PepperView(this, &context_)); |
| 99 view_proxy_ = new PepperViewProxy(this, view_.get()); | 102 view_proxy_ = new PepperViewProxy(this, view_.get()); |
| 100 rectangle_decoder_ = new RectangleUpdateDecoder( | 103 rectangle_decoder_ = new RectangleUpdateDecoder( |
| 101 context_.decode_message_loop(), view_proxy_); | 104 context_.decode_message_loop(), view_proxy_); |
| 102 input_handler_.reset(new PepperInputHandler(&context_, | 105 input_handler_.reset(new PepperInputHandler(&context_, |
| 103 host_connection_.get(), | 106 host_connection_.get(), |
| 104 view_proxy_)); | 107 view_proxy_)); |
| 105 | 108 |
| 106 // Default to a medium grey. | 109 // Default to a medium grey. |
| 107 view_->SetSolidFill(0xFFCDCDCD); | 110 view_->SetSolidFill(0xFFCDCDCD); |
| 108 | 111 |
| 109 return true; | 112 return true; |
| 110 } | 113 } |
| 111 | 114 |
| 112 void ChromotingInstance::Connect(const ClientConfig& config) { | 115 void ChromotingInstance::Connect(const ClientConfig& config) { |
| 113 DCHECK(CurrentlyOnPluginThread()); | 116 DCHECK(CurrentlyOnPluginThread()); |
| 114 | 117 |
| 115 LogDebugInfo(base::StringPrintf("Connecting to %s as %s", | 118 logger_->Log(logging::LOG_INFO, "Connecting to %s as %s", |
| 116 config.host_jid.c_str(), | 119 config.host_jid.c_str(), |
| 117 config.username.c_str()).c_str()); | 120 config.username.c_str()); |
| 118 client_.reset(new ChromotingClient(config, | 121 client_.reset(new ChromotingClient(config, |
| 119 &context_, | 122 &context_, |
| 120 host_connection_.get(), | 123 host_connection_.get(), |
| 121 view_proxy_, | 124 view_proxy_, |
| 122 rectangle_decoder_.get(), | 125 rectangle_decoder_.get(), |
| 123 input_handler_.get(), | 126 input_handler_.get(), |
| 127 logger_, | |
| 124 NULL)); | 128 NULL)); |
| 125 | 129 |
| 126 // Kick off the connection. | 130 // Kick off the connection. |
| 127 client_->Start(); | 131 client_->Start(); |
| 128 | 132 |
| 133 logger_->Log(logging::LOG_INFO, "Connection status: Initializing"); | |
| 129 GetScriptableObject()->SetConnectionInfo(STATUS_INITIALIZING, | 134 GetScriptableObject()->SetConnectionInfo(STATUS_INITIALIZING, |
| 130 QUALITY_UNKNOWN); | 135 QUALITY_UNKNOWN); |
| 131 } | 136 } |
| 132 | 137 |
| 133 void ChromotingInstance::ConnectSandboxed(const std::string& your_jid, | 138 void ChromotingInstance::ConnectSandboxed(const std::string& your_jid, |
| 134 const std::string& host_jid, | 139 const std::string& host_jid, |
| 135 const std::string& nonce) { | 140 const std::string& nonce) { |
| 136 // TODO(ajwong): your_jid and host_jid should be moved into ClientConfig. In | 141 // TODO(ajwong): your_jid and host_jid should be moved into ClientConfig. In |
| 137 // fact, this whole function should go away, and Connect() should just look at | 142 // fact, this whole function should go away, and Connect() should just look at |
| 138 // ClientConfig. | 143 // ClientConfig. |
| 139 DCHECK(CurrentlyOnPluginThread()); | 144 DCHECK(CurrentlyOnPluginThread()); |
| 140 | 145 |
| 141 LogDebugInfo("Attempting sandboxed connection"); | 146 logger_->Log(logging::LOG_INFO, "Attempting sandboxed connection."); |
| 142 | 147 |
| 143 // Setup the XMPP Proxy. | 148 // Setup the XMPP Proxy. |
| 144 ChromotingScriptableObject* scriptable_object = GetScriptableObject(); | 149 ChromotingScriptableObject* scriptable_object = GetScriptableObject(); |
| 145 scoped_refptr<PepperXmppProxy> xmpp_proxy = | 150 scoped_refptr<PepperXmppProxy> xmpp_proxy = |
| 146 new PepperXmppProxy(scriptable_object->AsWeakPtr(), | 151 new PepperXmppProxy(scriptable_object->AsWeakPtr(), |
| 147 context_.jingle_thread()->message_loop()); | 152 context_.jingle_thread()->message_loop()); |
| 148 scriptable_object->AttachXmppProxy(xmpp_proxy); | 153 scriptable_object->AttachXmppProxy(xmpp_proxy); |
| 149 | 154 |
| 150 ClientConfig config_; | 155 ClientConfig config_; |
| 151 config_.nonce = nonce; | 156 config_.nonce = nonce; |
| 152 client_.reset(new ChromotingClient(config_, | 157 client_.reset(new ChromotingClient(config_, |
| 153 &context_, | 158 &context_, |
| 154 host_connection_.get(), | 159 host_connection_.get(), |
| 155 view_proxy_, | 160 view_proxy_, |
| 156 rectangle_decoder_.get(), | 161 rectangle_decoder_.get(), |
| 157 input_handler_.get(), | 162 input_handler_.get(), |
| 163 logger_, | |
| 158 NULL)); | 164 NULL)); |
| 159 | 165 |
| 160 // Kick off the connection. | 166 // Kick off the connection. |
| 161 client_->StartSandboxed(xmpp_proxy, your_jid, host_jid); | 167 client_->StartSandboxed(xmpp_proxy, your_jid, host_jid); |
| 162 | 168 |
| 163 GetScriptableObject()->SetConnectionInfo(STATUS_INITIALIZING, | 169 GetScriptableObject()->SetConnectionInfo(STATUS_INITIALIZING, |
| 164 QUALITY_UNKNOWN); | 170 QUALITY_UNKNOWN); |
| 165 } | 171 } |
| 166 | 172 |
| 167 void ChromotingInstance::Disconnect() { | 173 void ChromotingInstance::Disconnect() { |
| 168 DCHECK(CurrentlyOnPluginThread()); | 174 DCHECK(CurrentlyOnPluginThread()); |
| 169 | 175 |
| 170 LogDebugInfo("Disconnecting from host"); | 176 logger_->Log(logging::LOG_INFO, "Disconnecting from host."); |
| 171 if (client_.get()) { | 177 if (client_.get()) { |
| 172 client_->Stop(); | 178 client_->Stop(); |
| 173 } | 179 } |
| 174 | 180 |
| 175 GetScriptableObject()->SetConnectionInfo(STATUS_CLOSED, QUALITY_UNKNOWN); | 181 GetScriptableObject()->SetConnectionInfo(STATUS_CLOSED, QUALITY_UNKNOWN); |
| 176 } | 182 } |
| 177 | 183 |
| 178 void ChromotingInstance::ViewChanged(const pp::Rect& position, | 184 void ChromotingInstance::ViewChanged(const pp::Rect& position, |
| 179 const pp::Rect& clip) { | 185 const pp::Rect& clip) { |
| 180 DCHECK(CurrentlyOnPluginThread()); | 186 DCHECK(CurrentlyOnPluginThread()); |
| 181 | 187 |
| 182 // TODO(ajwong): This is going to be a race condition when the view changes | 188 // TODO(ajwong): This is going to be a race condition when the view changes |
| 183 // and we're in the middle of a Paint(). | 189 // and we're in the middle of a Paint(). |
| 184 VLOG(1) << "ViewChanged " << position.x() << "," << position.y() << "," | 190 logger_->VLog(1, "ViewChanged: %d,%d %dx%d", |
| 185 << position.width() << "," << position.height(); | 191 position.x(), position.y(), |
| 192 position.width(), position.height()); | |
| 186 | 193 |
| 187 view_->SetViewport(position.x(), position.y(), | 194 view_->SetViewport(position.x(), position.y(), |
| 188 position.width(), position.height()); | 195 position.width(), position.height()); |
| 189 view_->Paint(); | 196 view_->Paint(); |
| 190 } | 197 } |
| 191 | 198 |
| 192 void ChromotingInstance::DidChangeView(const pp::Rect& position, | 199 void ChromotingInstance::DidChangeView(const pp::Rect& position, |
| 193 const pp::Rect& clip) { | 200 const pp::Rect& clip) { |
| 194 // This lets |view_| implement scale-to-fit. But it only specifies a | 201 // This lets |view_| implement scale-to-fit. But it only specifies a |
| 195 // sub-rectangle of the plugin window as the rectangle on which the host | 202 // sub-rectangle of the plugin window as the rectangle on which the host |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 219 pih->HandleMouseMoveEvent(event.u.mouse); | 226 pih->HandleMouseMoveEvent(event.u.mouse); |
| 220 return true; | 227 return true; |
| 221 | 228 |
| 222 case PP_INPUTEVENT_TYPE_CONTEXTMENU: | 229 case PP_INPUTEVENT_TYPE_CONTEXTMENU: |
| 223 // We need to return true here or else we'll get a local (plugin) context | 230 // We need to return true here or else we'll get a local (plugin) context |
| 224 // menu instead of the mouseup event for the right click. | 231 // menu instead of the mouseup event for the right click. |
| 225 return true; | 232 return true; |
| 226 | 233 |
| 227 case PP_INPUTEVENT_TYPE_KEYDOWN: | 234 case PP_INPUTEVENT_TYPE_KEYDOWN: |
| 228 case PP_INPUTEVENT_TYPE_KEYUP: | 235 case PP_INPUTEVENT_TYPE_KEYUP: |
| 229 VLOG(3) << "PP_INPUTEVENT_TYPE_KEY" | 236 logger_->VLog(3, "PP_INPUTEVENT_TYPE_KEY%s key=%d", |
| 230 << (event.type==PP_INPUTEVENT_TYPE_KEYDOWN ? "DOWN" : "UP") | 237 (event.type==PP_INPUTEVENT_TYPE_KEYDOWN ? "DOWN" : "UP"), |
| 231 << " key=" << event.u.key.key_code; | 238 event.u.key.key_code); |
| 232 pih->HandleKeyEvent(event.type == PP_INPUTEVENT_TYPE_KEYDOWN, | 239 pih->HandleKeyEvent(event.type == PP_INPUTEVENT_TYPE_KEYDOWN, |
| 233 event.u.key); | 240 event.u.key); |
| 234 return true; | 241 return true; |
| 235 | 242 |
| 236 case PP_INPUTEVENT_TYPE_CHAR: | 243 case PP_INPUTEVENT_TYPE_CHAR: |
| 237 pih->HandleCharacterEvent(event.u.character); | 244 pih->HandleCharacterEvent(event.u.character); |
| 238 return true; | 245 return true; |
| 239 | 246 |
| 240 default: | 247 default: |
| 241 break; | 248 break; |
| 242 } | 249 } |
| 243 | 250 |
| 244 return false; | 251 return false; |
| 245 } | 252 } |
| 246 | 253 |
| 247 ChromotingScriptableObject* ChromotingInstance::GetScriptableObject() { | 254 ChromotingScriptableObject* ChromotingInstance::GetScriptableObject() { |
| 248 pp::Var object = GetInstanceObject(); | 255 pp::Var object = GetInstanceObject(); |
| 249 if (!object.is_undefined()) { | 256 if (!object.is_undefined()) { |
| 250 pp::deprecated::ScriptableObject* so = object.AsScriptableObject(); | 257 pp::deprecated::ScriptableObject* so = object.AsScriptableObject(); |
| 251 DCHECK(so != NULL); | 258 DCHECK(so != NULL); |
| 252 return static_cast<ChromotingScriptableObject*>(so); | 259 return static_cast<ChromotingScriptableObject*>(so); |
| 253 } | 260 } |
| 254 LOG(ERROR) << "Unable to get ScriptableObject for Chromoting plugin."; | 261 logger_->Log(logging::LOG_ERROR, |
| 262 "Unable to get ScriptableObject for Chromoting plugin."); | |
| 255 return NULL; | 263 return NULL; |
| 256 } | 264 } |
| 257 | 265 |
| 258 void ChromotingInstance::SubmitLoginInfo(const std::string& username, | 266 void ChromotingInstance::SubmitLoginInfo(const std::string& username, |
| 259 const std::string& password) { | 267 const std::string& password) { |
| 260 if (host_connection_->state() != | 268 if (host_connection_->state() != |
| 261 protocol::ConnectionToHost::STATE_CONNECTED) { | 269 protocol::ConnectionToHost::STATE_CONNECTED) { |
| 262 LogDebugInfo("Client not connected or already authenticated."); | 270 logger_->Log(logging::LOG_INFO, |
| 271 "Client not connected or already authenticated."); | |
| 263 return; | 272 return; |
| 264 } | 273 } |
| 265 | 274 |
| 266 protocol::LocalLoginCredentials* credentials = | 275 protocol::LocalLoginCredentials* credentials = |
| 267 new protocol::LocalLoginCredentials(); | 276 new protocol::LocalLoginCredentials(); |
| 268 credentials->set_type(protocol::PASSWORD); | 277 credentials->set_type(protocol::PASSWORD); |
| 269 credentials->set_username(username); | 278 credentials->set_username(username); |
| 270 credentials->set_credential(password.data(), password.length()); | 279 credentials->set_credential(password.data(), password.length()); |
| 271 | 280 |
| 272 host_connection_->host_stub()->BeginSessionRequest( | 281 host_connection_->host_stub()->BeginSessionRequest( |
| 273 credentials, | 282 credentials, |
| 274 new DeleteTask<protocol::LocalLoginCredentials>(credentials)); | 283 new DeleteTask<protocol::LocalLoginCredentials>(credentials)); |
| 275 } | 284 } |
| 276 | 285 |
| 277 void ChromotingInstance::SetScaleToFit(bool scale_to_fit) { | 286 void ChromotingInstance::SetScaleToFit(bool scale_to_fit) { |
| 278 view_proxy_->SetScaleToFit(scale_to_fit); | 287 view_proxy_->SetScaleToFit(scale_to_fit); |
| 279 } | 288 } |
| 280 | 289 |
| 281 void ChromotingInstance::LogDebugInfo(const std::string& info) { | 290 void ChromotingInstance::Log(int severity, const char* format, ...) { |
| 282 GetScriptableObject()->LogDebugInfo(info); | 291 va_list ap; |
| 292 va_start(ap, format); | |
| 293 logger_->va_Log(severity, format, ap); | |
| 294 va_end(ap); | |
| 295 DCHECK(CurrentlyOnPluginThread()); | |
|
dmac
2011/05/13 23:34:10
do you want to do the thread check at the end or b
garykac
2011/05/14 01:09:16
Oops. That's leftover from when I was debugging th
| |
| 296 } | |
| 297 | |
| 298 void ChromotingInstance::VLog(int verboselevel, const char* format, ...) { | |
| 299 va_list ap; | |
| 300 va_start(ap, format); | |
| 301 logger_->va_VLog(verboselevel, format, ap); | |
| 302 va_end(ap); | |
| 303 DCHECK(CurrentlyOnPluginThread()); | |
|
dmac
2011/05/13 23:34:10
same comment as above
garykac
2011/05/14 01:09:16
Done.
| |
| 283 } | 304 } |
| 284 | 305 |
| 285 pp::Var ChromotingInstance::GetInstanceObject() { | 306 pp::Var ChromotingInstance::GetInstanceObject() { |
| 286 if (instance_object_.is_undefined()) { | 307 if (instance_object_.is_undefined()) { |
| 287 ChromotingScriptableObject* object = new ChromotingScriptableObject(this); | 308 ChromotingScriptableObject* object = new ChromotingScriptableObject(this); |
| 288 object->Init(); | 309 object->Init(); |
| 289 | 310 |
| 290 // The pp::Var takes ownership of object here. | 311 // The pp::Var takes ownership of object here. |
| 291 instance_object_ = pp::Var(this, object); | 312 instance_object_ = pp::Var(this, object); |
| 292 } | 313 } |
| 293 | 314 |
| 294 return instance_object_; | 315 return instance_object_; |
| 295 } | 316 } |
| 296 | 317 |
| 297 ChromotingStats* ChromotingInstance::GetStats() { | 318 ChromotingStats* ChromotingInstance::GetStats() { |
| 298 if (!client_.get()) | 319 if (!client_.get()) |
| 299 return NULL; | 320 return NULL; |
| 300 return client_->GetStats(); | 321 return client_->GetStats(); |
| 301 } | 322 } |
| 302 | 323 |
| 303 } // namespace remoting | 324 } // namespace remoting |
| OLD | NEW |