| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_plugin.h" | 5 #include "remoting/client/plugin/chromoting_plugin.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/message_loop.h" |
| 10 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 11 #include "base/thread.h" | 12 #include "base/thread.h" |
| 12 #include "remoting/client/chromoting_client.h" | 13 #include "remoting/client/chromoting_client.h" |
| 13 #include "remoting/client/host_connection.h" | 14 #include "remoting/client/host_connection.h" |
| 14 #include "remoting/client/jingle_host_connection.h" | 15 #include "remoting/client/jingle_host_connection.h" |
| 15 #include "remoting/client/plugin/pepper_view.h" | 16 #include "remoting/client/plugin/pepper_view.h" |
| 16 #include "remoting/jingle_glue/jingle_thread.h" | 17 #include "remoting/jingle_glue/jingle_thread.h" |
| 17 #include "third_party/ppapi/c/pp_event.h" | 18 #include "third_party/ppapi/c/pp_event.h" |
| 18 #include "third_party/ppapi/c/pp_rect.h" | 19 #include "third_party/ppapi/c/pp_rect.h" |
| 19 #include "third_party/ppapi/cpp/completion_callback.h" | 20 #include "third_party/ppapi/cpp/completion_callback.h" |
| 20 #include "third_party/ppapi/cpp/image_data.h" | |
| 21 | 21 |
| 22 using std::string; | 22 using std::string; |
| 23 using std::vector; | 23 using std::vector; |
| 24 | 24 |
| 25 namespace remoting { | 25 namespace remoting { |
| 26 | 26 |
| 27 const char* ChromotingPlugin::kMimeType = "pepper-application/x-chromoting"; | 27 const char* ChromotingPlugin::kMimeType = "pepper-application/x-chromoting"; |
| 28 | 28 |
| 29 ChromotingPlugin::ChromotingPlugin(PP_Instance pp_instance, | 29 ChromotingPlugin::ChromotingPlugin(PP_Instance pp_instance) |
| 30 const PPB_Instance* ppb_instance_funcs) | 30 : pp::Instance(pp_instance), |
| 31 : width_(0), | 31 pepper_main_loop_dont_post_to_me_(NULL) { |
| 32 height_(0), | |
| 33 drawing_context_(NULL), | |
| 34 pp_instance_(pp_instance), | |
| 35 ppb_instance_funcs_(ppb_instance_funcs) { | |
| 36 } | 32 } |
| 37 | 33 |
| 38 ChromotingPlugin::~ChromotingPlugin() { | 34 ChromotingPlugin::~ChromotingPlugin() { |
| 39 if (host_connection_.get()) | 35 if (host_connection_.get()) |
| 40 host_connection_->Disconnect(); | 36 host_connection_->Disconnect(); |
| 41 | 37 |
| 42 // TODO(ajwong): We need to ensure all objects have actually stopped posting | 38 // TODO(ajwong): We need to ensure all objects have actually stopped posting |
| 43 // to the message loop before this point. Right now, we don't have a well | 39 // to the message loop before this point. Right now, we don't have a well |
| 44 // defined stop for the plugin process, and the thread shutdown is likely a | 40 // defined stop for the plugin process, and the thread shutdown is likely a |
| 45 // race condition. | 41 // race condition. |
| 46 if (network_thread_.get()) | 42 if (network_thread_.get()) |
| 47 network_thread_->Stop(); | 43 network_thread_->Stop(); |
| 48 | 44 |
| 49 if (main_thread_.get()) | 45 if (main_thread_.get()) |
| 50 main_thread_->Stop(); | 46 main_thread_->Stop(); |
| 51 } | 47 } |
| 52 | 48 |
| 53 bool ChromotingPlugin::Init(uint32_t argc, | 49 bool ChromotingPlugin::Init(uint32_t argc, |
| 54 const char* argn[], | 50 const char* argn[], |
| 55 const char* argv[]) { | 51 const char* argv[]) { |
| 52 CHECK(pepper_main_loop_dont_post_to_me_ == NULL); |
| 53 |
| 54 // Record the current thread. This function should only be invoked by the |
| 55 // plugin thread, so we capture the current message loop and assume it is |
| 56 // indeed the plugin thread. |
| 57 // |
| 58 // We're abusing the pepper API slightly here. We know we're running as an |
| 59 // internal plugin, and thus we are on the pepper main thread that uses a |
| 60 // message loop. |
| 61 // |
| 62 // TODO(ajwong): See if there is a method for querying what thread we're on |
| 63 // from inside the pepper API. |
| 64 pepper_main_loop_dont_post_to_me_ = MessageLoop::current(); |
| 56 LOG(INFO) << "Started ChromotingPlugin::Init"; | 65 LOG(INFO) << "Started ChromotingPlugin::Init"; |
| 57 | 66 |
| 58 // Extract the URL from the arguments. | 67 // Extract the URL from the arguments. |
| 59 const char* url = NULL; | 68 const char* url = NULL; |
| 60 for (uint32_t i = 0; i < argc; ++i) { | 69 for (uint32_t i = 0; i < argc; ++i) { |
| 61 if (strcmp(argn[i], "src") == 0) { | 70 if (strcmp(argn[i], "src") == 0) { |
| 62 url = argv[i]; | 71 url = argv[i]; |
| 63 break; | 72 break; |
| 64 } | 73 } |
| 65 } | 74 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 80 main_thread_.reset(new base::Thread("ChromoClientMain")); | 89 main_thread_.reset(new base::Thread("ChromoClientMain")); |
| 81 if (!main_thread_->Start()) { | 90 if (!main_thread_->Start()) { |
| 82 LOG(ERROR) << "Main thread failed to start."; | 91 LOG(ERROR) << "Main thread failed to start."; |
| 83 return false; | 92 return false; |
| 84 } | 93 } |
| 85 network_thread_.reset(new JingleThread()); | 94 network_thread_.reset(new JingleThread()); |
| 86 network_thread_->Start(); | 95 network_thread_->Start(); |
| 87 | 96 |
| 88 // Create the chromting objects. | 97 // Create the chromting objects. |
| 89 host_connection_.reset(new JingleHostConnection(network_thread_.get())); | 98 host_connection_.reset(new JingleHostConnection(network_thread_.get())); |
| 90 /* | 99 view_.reset(new PepperView(this)); |
| 91 view_.reset(new PepperView(main_thread_->message_loop(), device_, | 100 client_.reset(new ChromotingClient(main_thread_->message_loop(), |
| 92 instance())); | 101 host_connection_.get(), view_.get())); |
| 93 */ | 102 |
| 94 //client_.reset(new ChromotingClient(main_thread_->message_loop(), | 103 // Default to a medium grey. |
| 95 // host_connection_.get(), view_.get())); | 104 view_->SetSolidFill(0xFFCDCDCD); |
| 96 | 105 |
| 97 // Kick off the connection. | 106 // Kick off the connection. |
| 98 //host_connection_->Connect(user_id, auth_token, host_jid, client_.get()); | 107 host_connection_->Connect(user_id, auth_token, host_jid, client_.get()); |
| 99 | 108 |
| 100 return true; | 109 return true; |
| 101 } | 110 } |
| 102 | 111 |
| 103 void ChromotingPlugin::ViewChanged(const PP_Rect& position, | 112 void ChromotingPlugin::ViewChanged(const PP_Rect& position, |
| 104 const PP_Rect& clip) { | 113 const PP_Rect& clip) { |
| 114 DCHECK(CurrentlyOnPluginThread()); |
| 115 |
| 105 // TODO(ajwong): This is going to be a race condition when the view changes | 116 // TODO(ajwong): This is going to be a race condition when the view changes |
| 106 // and we're in the middle of a Paint(). | 117 // and we're in the middle of a Paint(). |
| 107 LOG(INFO) << "ViewChanged " | 118 LOG(INFO) << "ViewChanged " |
| 108 << position.point.x << "," | 119 << position.point.x << "," |
| 109 << position.point.y << "," | 120 << position.point.y << "," |
| 110 << position.size.width << "," | 121 << position.size.width << "," |
| 111 << position.size.height; | 122 << position.size.height; |
| 112 | 123 |
| 113 // TODO(ajwong): Do we care about the position? Probably not... | 124 view_->SetViewport(position.point.x, position.point.y, |
| 114 if (position.size.width == width_ || position.size.height == height_) | 125 position.size.width, position.size.height); |
| 115 return; | 126 view_->Paint(); |
| 127 } |
| 116 | 128 |
| 117 width_ = position.size.width; | 129 bool ChromotingPlugin::CurrentlyOnPluginThread() const { |
| 118 height_ = position.size.height; | 130 return pepper_main_loop_dont_post_to_me_ == MessageLoop::current(); |
| 119 | |
| 120 /* | |
| 121 * TODO(ajwong): Reenable this code once we fingure out how we want to | |
| 122 * abstract away the C-api for DeviceContext2D. | |
| 123 device_context_ = pp::DeviceContext2D(width_, height_, false); | |
| 124 if (!ppb_instance_funcs_->BindGraphicsDeviceContext( | |
| 125 pp_instance_, | |
| 126 device_context_.pp_resource())) { | |
| 127 LOG(ERROR) << "Couldn't bind the device context."; | |
| 128 return; | |
| 129 } | |
| 130 | |
| 131 pp::ImageData image(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width_, height_, false); | |
| 132 if (!image.is_null()) { | |
| 133 for (int y = 0; y < image.height(); y++) { | |
| 134 for (int x = 0; x < image.width(); x++) { | |
| 135 *image.GetAddr32(x, y) = 0xccff00cc; | |
| 136 } | |
| 137 } | |
| 138 device_context_.ReplaceContents(&image); | |
| 139 device_context_.Flush(pp::CompletionCallback(NULL, this)); | |
| 140 } else { | |
| 141 LOG(ERROR) << "Unable to allocate image."; | |
| 142 } | |
| 143 */ | |
| 144 | |
| 145 //client_->SetViewport(0, 0, width_, height_); | |
| 146 //client_->Repaint(); | |
| 147 } | 131 } |
| 148 | 132 |
| 149 bool ChromotingPlugin::HandleEvent(const PP_Event& event) { | 133 bool ChromotingPlugin::HandleEvent(const PP_Event& event) { |
| 134 DCHECK(CurrentlyOnPluginThread()); |
| 135 |
| 150 switch (event.type) { | 136 switch (event.type) { |
| 151 case PP_EVENT_TYPE_MOUSEDOWN: | 137 case PP_EVENT_TYPE_MOUSEDOWN: |
| 152 case PP_EVENT_TYPE_MOUSEUP: | 138 case PP_EVENT_TYPE_MOUSEUP: |
| 153 case PP_EVENT_TYPE_MOUSEMOVE: | 139 case PP_EVENT_TYPE_MOUSEMOVE: |
| 154 case PP_EVENT_TYPE_MOUSEENTER: | 140 case PP_EVENT_TYPE_MOUSEENTER: |
| 155 case PP_EVENT_TYPE_MOUSELEAVE: | 141 case PP_EVENT_TYPE_MOUSELEAVE: |
| 156 //client_->handle_mouse_event(npevent); | 142 //client_->handle_mouse_event(npevent); |
| 157 break; | 143 break; |
| 158 | 144 |
| 159 case PP_EVENT_TYPE_CHAR: | 145 case PP_EVENT_TYPE_CHAR: |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 pos = parts[2].rfind('='); | 184 pos = parts[2].rfind('='); |
| 199 if (pos == string::npos && (pos + 1) != string::npos) { | 185 if (pos == string::npos && (pos + 1) != string::npos) { |
| 200 return false; | 186 return false; |
| 201 } | 187 } |
| 202 host_jid->assign(parts[2].substr(pos + 1)); | 188 host_jid->assign(parts[2].substr(pos + 1)); |
| 203 | 189 |
| 204 return true; | 190 return true; |
| 205 } | 191 } |
| 206 | 192 |
| 207 } // namespace remoting | 193 } // namespace remoting |
| OLD | NEW |