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 |