OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/renderer_host/pepper/pepper_talk_host.h" | 5 #include "chrome/browser/renderer_host/pepper/pepper_talk_host.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "content/public/browser/browser_ppapi_host.h" | 8 #include "content/public/browser/browser_ppapi_host.h" |
9 #include "content/public/browser/browser_thread.h" | 9 #include "content/public/browser/browser_thread.h" |
10 #include "content/public/browser/render_view_host.h" | 10 #include "content/public/browser/render_view_host.h" |
11 #include "grit/generated_resources.h" | 11 #include "grit/generated_resources.h" |
12 #include "ppapi/c/pp_errors.h" | 12 #include "ppapi/c/pp_errors.h" |
13 #include "ppapi/host/dispatch_host_message.h" | 13 #include "ppapi/host/dispatch_host_message.h" |
14 #include "ppapi/host/host_message_context.h" | 14 #include "ppapi/host/host_message_context.h" |
15 #include "ppapi/host/ppapi_host.h" | 15 #include "ppapi/host/ppapi_host.h" |
16 #include "ppapi/proxy/ppapi_messages.h" | 16 #include "ppapi/proxy/ppapi_messages.h" |
17 #include "ui/base/l10n/l10n_util.h" | 17 #include "ui/base/l10n/l10n_util.h" |
18 | 18 |
19 #if defined(USE_ASH) | 19 #if defined(USE_ASH) |
20 #include "ash/shell.h" | 20 #include "ash/shell.h" |
21 #include "ash/shell_window_ids.h" | 21 #include "ash/shell_window_ids.h" |
22 #include "ash/system/tray/system_tray_notifier.h" | |
22 #include "chrome/browser/ui/simple_message_box.h" | 23 #include "chrome/browser/ui/simple_message_box.h" |
23 #include "ui/aura/window.h" | 24 #include "ui/aura/window.h" |
24 #endif | 25 #endif |
25 | 26 |
26 namespace chrome { | 27 namespace chrome { |
27 | 28 |
28 namespace { | 29 namespace { |
29 | 30 |
30 ppapi::host::ReplyMessageContext GetPermissionOnUIThread( | 31 ppapi::host::ReplyMessageContext GetPermissionOnUIThread( |
32 PP_TalkPermission permission, | |
31 int render_process_id, | 33 int render_process_id, |
32 int render_view_id, | 34 int render_view_id, |
33 ppapi::host::ReplyMessageContext reply) { | 35 ppapi::host::ReplyMessageContext reply) { |
34 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 36 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
35 reply.params.set_result(0); | 37 reply.params.set_result(0); |
36 | 38 |
37 content::RenderViewHost* render_view_host = | 39 content::RenderViewHost* render_view_host = |
38 content::RenderViewHost::FromID(render_process_id, render_view_id); | 40 content::RenderViewHost::FromID(render_process_id, render_view_id); |
39 if (!render_view_host) | 41 if (!render_view_host) |
40 return reply; // RVH destroyed while task was pending. | 42 return reply; // RVH destroyed while task was pending. |
41 | 43 |
42 #if defined(USE_ASH) | 44 #if defined(USE_ASH) |
45 string16 title; | |
46 string16 message; | |
47 | |
48 switch (permission) { | |
49 case PP_TALKPERMISSION_SCREENCAST: | |
50 title = l10n_util::GetStringUTF16(IDS_GTALK_SCREEN_SHARE_DIALOG_TITLE); | |
51 message = l10n_util::GetStringUTF16( | |
52 IDS_GTALK_SCREEN_SHARE_DIALOG_MESSAGE); | |
53 break; | |
54 case PP_TALKPERMISSION_REMOTING: | |
55 title = l10n_util::GetStringUTF16(IDS_GTALK_REMOTING_DIALOG_TITLE); | |
56 message = l10n_util::GetStringUTF16( | |
57 IDS_GTALK_REMOTING_DIALOG_MESSAGE); | |
58 break; | |
59 case PP_TALKPERMISSION_REMOTING_CONTINUE: | |
60 title = l10n_util::GetStringUTF16(IDS_GTALK_REMOTING_DIALOG_TITLE); | |
61 message = l10n_util::GetStringUTF16( | |
62 IDS_GTALK_REMOTING_CONTINUE_DIALOG_MESSAGE); | |
63 break; | |
64 default: | |
65 NOTREACHED(); | |
66 return reply; | |
67 } | |
68 | |
43 // TODO(brettw). We should not be grabbing the active toplevel window, we | 69 // TODO(brettw). We should not be grabbing the active toplevel window, we |
44 // should use the toplevel window associated with the render view. | 70 // should use the toplevel window associated with the render view. |
45 const string16 title = l10n_util::GetStringUTF16( | |
46 IDS_GTALK_SCREEN_SHARE_DIALOG_TITLE); | |
47 const string16 message = l10n_util::GetStringUTF16( | |
48 IDS_GTALK_SCREEN_SHARE_DIALOG_MESSAGE); | |
49 | |
50 aura::Window* parent = ash::Shell::GetContainer( | 71 aura::Window* parent = ash::Shell::GetContainer( |
51 ash::Shell::GetActiveRootWindow(), | 72 ash::Shell::GetActiveRootWindow(), |
52 ash::internal::kShellWindowId_SystemModalContainer); | 73 ash::internal::kShellWindowId_SystemModalContainer); |
53 reply.params.set_result(static_cast<int32_t>( | 74 reply.params.set_result(static_cast<int32_t>( |
54 chrome::ShowMessageBox(parent, title, message, | 75 chrome::ShowMessageBox(parent, title, message, |
55 chrome::MESSAGE_BOX_TYPE_QUESTION) == | 76 chrome::MESSAGE_BOX_TYPE_QUESTION) == |
56 chrome::MESSAGE_BOX_RESULT_YES)); | 77 chrome::MESSAGE_BOX_RESULT_YES)); |
57 #else | 78 #else |
58 NOTIMPLEMENTED(); | 79 NOTIMPLEMENTED(); |
59 #endif | 80 #endif |
60 return reply; | 81 return reply; |
61 } | 82 } |
62 | 83 |
84 void OnTerminateRemotingEventOnUIThread(const base::Closure& stop_callback) { | |
85 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, | |
86 stop_callback); | |
87 } | |
88 | |
89 ppapi::host::ReplyMessageContext StartRemotingOnUIThread( | |
90 const base::Closure& stop_callback, | |
91 int render_process_id, | |
92 int render_view_id, | |
93 ppapi::host::ReplyMessageContext reply) { | |
94 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
95 content::RenderViewHost* render_view_host = | |
96 content::RenderViewHost::FromID(render_process_id, render_view_id); | |
97 if (!render_view_host) { | |
98 reply.params.set_result(PP_ERROR_FAILED); | |
99 return reply; // RVH destroyed while task was pending. | |
100 } | |
101 | |
102 #if defined(USE_ASH) | |
103 base::Closure stop_callback_ui_thread = base::Bind( | |
104 &OnTerminateRemotingEventOnUIThread, | |
105 stop_callback); | |
106 | |
107 ash::Shell::GetInstance()->system_tray_notifier()->NotifyScreenShareStart( | |
108 stop_callback_ui_thread, base::string16()); | |
109 reply.params.set_result(PP_OK); | |
110 #else | |
111 NOTIMPLEMENTED(); | |
112 reply.params.set_result(PP_ERROR_NOTSUPPORTED); | |
113 #endif | |
114 return reply; | |
115 } | |
116 | |
117 void StopRemotingOnUIThread() { | |
118 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
119 #if defined(USE_ASH) | |
120 if (ash::Shell::GetInstance()) { | |
121 ash::Shell::GetInstance()->system_tray_notifier()->NotifyScreenShareStop(); | |
122 } | |
123 #else | |
124 NOTIMPLEMENTED(); | |
125 #endif | |
126 } | |
127 | |
128 ppapi::host::ReplyMessageContext StopRemotingOnUIThreadWithResult( | |
129 ppapi::host::ReplyMessageContext reply) { | |
130 reply.params.set_result(PP_OK); | |
131 StopRemotingOnUIThread(); | |
132 return reply; | |
133 } | |
134 | |
63 } // namespace | 135 } // namespace |
64 | 136 |
65 PepperTalkHost::PepperTalkHost(content::BrowserPpapiHost* host, | 137 PepperTalkHost::PepperTalkHost(content::BrowserPpapiHost* host, |
66 PP_Instance instance, | 138 PP_Instance instance, |
67 PP_Resource resource) | 139 PP_Resource resource) |
68 : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource), | 140 : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource), |
69 weak_factory_(this), | 141 weak_factory_(this), |
70 browser_ppapi_host_(host) { | 142 browser_ppapi_host_(host), |
143 remoting_started_(false) { | |
71 } | 144 } |
72 | 145 |
73 PepperTalkHost::~PepperTalkHost() { | 146 PepperTalkHost::~PepperTalkHost() { |
147 if (remoting_started_) { | |
148 content::BrowserThread::PostTask( | |
149 content::BrowserThread::UI, FROM_HERE, | |
150 base::Bind(&StopRemotingOnUIThread)); | |
151 } | |
74 } | 152 } |
75 | 153 |
76 int32_t PepperTalkHost::OnResourceMessageReceived( | 154 int32_t PepperTalkHost::OnResourceMessageReceived( |
77 const IPC::Message& msg, | 155 const IPC::Message& msg, |
78 ppapi::host::HostMessageContext* context) { | 156 ppapi::host::HostMessageContext* context) { |
79 IPC_BEGIN_MESSAGE_MAP(PepperTalkHost, msg) | 157 IPC_BEGIN_MESSAGE_MAP(PepperTalkHost, msg) |
80 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Talk_RequestPermission, | 158 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Talk_RequestPermission, |
81 OnRequestPermission) | 159 OnRequestPermission) |
82 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Talk_StartRemoting, | 160 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Talk_StartRemoting, |
83 OnStartRemoting) | 161 OnStartRemoting) |
84 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Talk_StopRemoting, | 162 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Talk_StopRemoting, |
85 OnStopRemoting) | 163 OnStopRemoting) |
86 IPC_END_MESSAGE_MAP() | 164 IPC_END_MESSAGE_MAP() |
87 return PP_ERROR_FAILED; | 165 return PP_ERROR_FAILED; |
88 } | 166 } |
89 | 167 |
90 int32_t PepperTalkHost::OnRequestPermission( | 168 int32_t PepperTalkHost::OnRequestPermission( |
91 ppapi::host::HostMessageContext* context, | 169 ppapi::host::HostMessageContext* context, |
92 PP_TalkPermission permission) { | 170 PP_TalkPermission permission) { |
93 // TODO(dcaiafa): Implement support for other permission types. | 171 if (permission < PP_TALKPERMISSION_SCREENCAST || |
94 if (permission != PP_TALKPERMISSION_SCREENCAST) | 172 permission >= PP_TALKPERMISSION_NUM_PERMISSIONS) |
95 return PP_ERROR_BADARGUMENT; | 173 return PP_ERROR_BADARGUMENT; |
96 | 174 |
97 int render_process_id = 0; | 175 int render_process_id = 0; |
98 int render_view_id = 0; | 176 int render_view_id = 0; |
99 browser_ppapi_host_->GetRenderViewIDsForInstance( | 177 browser_ppapi_host_->GetRenderViewIDsForInstance( |
100 pp_instance(), &render_process_id, &render_view_id); | 178 pp_instance(), &render_process_id, &render_view_id); |
101 | 179 |
102 content::BrowserThread::PostTaskAndReplyWithResult( | 180 content::BrowserThread::PostTaskAndReplyWithResult( |
103 content::BrowserThread::UI, FROM_HERE, | 181 content::BrowserThread::UI, FROM_HERE, |
104 base::Bind(&GetPermissionOnUIThread, render_process_id, render_view_id, | 182 base::Bind(&GetPermissionOnUIThread, permission, render_process_id, |
105 context->MakeReplyMessageContext()), | 183 render_view_id, context->MakeReplyMessageContext()), |
106 base::Bind(&PepperTalkHost::GotTalkPermission, | 184 base::Bind(&PepperTalkHost::OnRequestPermissionCompleted, |
107 weak_factory_.GetWeakPtr())); | 185 weak_factory_.GetWeakPtr())); |
108 return PP_OK_COMPLETIONPENDING; | 186 return PP_OK_COMPLETIONPENDING; |
109 } | 187 } |
110 | 188 |
111 void PepperTalkHost::GotTalkPermission( | 189 void PepperTalkHost::OnRequestPermissionCompleted( |
raymes
2013/06/18 19:44:50
nit: The order of functions in the implementation
| |
112 ppapi::host::ReplyMessageContext reply) { | 190 ppapi::host::ReplyMessageContext reply) { |
113 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 191 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
114 host()->SendReply(reply, PpapiPluginMsg_Talk_RequestPermissionReply()); | 192 host()->SendReply(reply, PpapiPluginMsg_Talk_RequestPermissionReply()); |
115 } | 193 } |
116 | 194 |
117 int32_t PepperTalkHost::OnStartRemoting( | 195 int32_t PepperTalkHost::OnStartRemoting( |
118 ppapi::host::HostMessageContext* context) { | 196 ppapi::host::HostMessageContext* context) { |
119 // TODO(dcaiafa): Request IPC audit when this is implemented | 197 if (remoting_started_) { |
120 NOTIMPLEMENTED(); | 198 return PP_ERROR_INPROGRESS; |
121 return PP_ERROR_FAILED; | 199 } |
200 // Remember to hide remoting UI when resource is deleted. | |
201 remoting_started_ = true; | |
202 | |
203 int render_process_id = 0; | |
204 int render_view_id = 0; | |
205 browser_ppapi_host_->GetRenderViewIDsForInstance( | |
206 pp_instance(), &render_process_id, &render_view_id); | |
207 | |
208 base::Closure remoting_stop_callback = base::Bind( | |
209 &PepperTalkHost::OnRemotingStopEvent, | |
210 weak_factory_.GetWeakPtr()); | |
211 | |
212 content::BrowserThread::PostTaskAndReplyWithResult( | |
213 content::BrowserThread::UI, FROM_HERE, | |
214 base::Bind(&StartRemotingOnUIThread, remoting_stop_callback, | |
215 render_process_id, render_view_id, | |
216 context->MakeReplyMessageContext()), | |
217 base::Bind(&PepperTalkHost::OnStartRemotingCompleted, | |
218 weak_factory_.GetWeakPtr())); | |
219 return PP_OK_COMPLETIONPENDING; | |
220 } | |
221 | |
222 void PepperTalkHost::OnStartRemotingCompleted( | |
223 ppapi::host::ReplyMessageContext reply) { | |
224 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
225 if (reply.params.result() != PP_OK) { | |
raymes
2013/06/18 19:44:50
nit: no need for { for single-line if
| |
226 remoting_started_ = false; | |
227 } | |
228 host()->SendReply(reply, PpapiPluginMsg_Talk_StartRemotingReply()); | |
122 } | 229 } |
123 | 230 |
124 int32_t PepperTalkHost::OnStopRemoting( | 231 int32_t PepperTalkHost::OnStopRemoting( |
125 ppapi::host::HostMessageContext* context) { | 232 ppapi::host::HostMessageContext* context) { |
126 // TODO(dcaiafa): Request IPC audit when this is implemented | 233 content::BrowserThread::PostTaskAndReplyWithResult( |
127 NOTIMPLEMENTED(); | 234 content::BrowserThread::UI, FROM_HERE, |
128 return PP_ERROR_FAILED; | 235 base::Bind(&StopRemotingOnUIThreadWithResult, |
236 context->MakeReplyMessageContext()), | |
237 base::Bind(&PepperTalkHost::OnStopRemotingCompleted, | |
238 weak_factory_.GetWeakPtr())); | |
239 return PP_OK_COMPLETIONPENDING; | |
240 } | |
241 | |
242 void PepperTalkHost::OnStopRemotingCompleted( | |
243 ppapi::host::ReplyMessageContext reply) { | |
244 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
245 remoting_started_ = false; | |
246 host()->SendReply(reply, PpapiPluginMsg_Talk_StopRemotingReply()); | |
247 } | |
248 | |
249 void PepperTalkHost::OnRemotingStopEvent() { | |
250 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
251 remoting_started_ = false; | |
252 host()->SendUnsolicitedReply( | |
253 pp_resource(), PpapiPluginMsg_Talk_NotifyEvent(PP_TALKEVENT_TERMINATE)); | |
129 } | 254 } |
130 | 255 |
131 } // namespace chrome | 256 } // namespace chrome |
OLD | NEW |