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
3 // found in the LICENSE file.
5 #include "chrome/browser/renderer_host/pepper/pepper_talk_host.h"
8 #include "chrome/grit/generated_resources.h"
9 #include "content/public/browser/browser_ppapi_host.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/render_frame_host.h"
12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/host/dispatch_host_message.h"
14 #include "ppapi/host/host_message_context.h"
15 #include "ppapi/host/ppapi_host.h"
16 #include "ppapi/proxy/ppapi_messages.h"
17 #include "ui/base/l10n/l10n_util.h"
20 #include "ash/shell.h"
21 #include "ash/shell_window_ids.h"
22 #include "ash/system/tray/system_tray_notifier.h"
23 #include "chrome/browser/ui/simple_message_box.h"
24 #include "ui/aura/window.h"
31 ppapi::host::ReplyMessageContext
GetPermissionOnUIThread(
32 PP_TalkPermission permission
,
33 int render_process_id
,
35 ppapi::host::ReplyMessageContext reply
) {
36 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
37 reply
.params
.set_result(0);
39 content::RenderFrameHost
* render_frame_host
=
40 content::RenderFrameHost::FromID(render_process_id
, render_frame_id
);
41 if (!render_frame_host
)
42 return reply
; // RFH destroyed while task was pending.
44 // crbug.com/381398, crbug.com/413906 for !USE_ATHENA
45 #if defined(USE_ASH) && !defined(USE_ATHENA)
47 base::string16 message
;
50 case PP_TALKPERMISSION_SCREENCAST
:
51 title
= l10n_util::GetStringUTF16(IDS_GTALK_SCREEN_SHARE_DIALOG_TITLE
);
53 l10n_util::GetStringUTF16(IDS_GTALK_SCREEN_SHARE_DIALOG_MESSAGE
);
55 case PP_TALKPERMISSION_REMOTING
:
56 title
= l10n_util::GetStringUTF16(IDS_GTALK_REMOTING_DIALOG_TITLE
);
57 message
= l10n_util::GetStringUTF16(IDS_GTALK_REMOTING_DIALOG_MESSAGE
);
59 case PP_TALKPERMISSION_REMOTING_CONTINUE
:
60 title
= l10n_util::GetStringUTF16(IDS_GTALK_REMOTING_DIALOG_TITLE
);
62 l10n_util::GetStringUTF16(IDS_GTALK_REMOTING_CONTINUE_DIALOG_MESSAGE
);
69 // TODO(brettw). We should not be grabbing the active toplevel window, we
70 // should use the toplevel window associated with the render view.
71 aura::Window
* parent
=
72 ash::Shell::GetContainer(ash::Shell::GetTargetRootWindow(),
73 ash::kShellWindowId_SystemModalContainer
);
74 reply
.params
.set_result(static_cast<int32_t>(
75 chrome::ShowMessageBox(
76 parent
, title
, message
, chrome::MESSAGE_BOX_TYPE_QUESTION
) ==
77 chrome::MESSAGE_BOX_RESULT_YES
));
84 #if defined(USE_ASH) && defined(OS_CHROMEOS) && !defined(USE_ATHENA)
85 void OnTerminateRemotingEventOnUIThread(const base::Closure
& stop_callback
) {
86 content::BrowserThread::PostTask(
87 content::BrowserThread::IO
, FROM_HERE
, stop_callback
);
89 #endif // defined(USE_ASH) && defined(OS_CHROMEOS)
91 ppapi::host::ReplyMessageContext
StartRemotingOnUIThread(
92 const base::Closure
& stop_callback
,
93 int render_process_id
,
95 ppapi::host::ReplyMessageContext reply
) {
96 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
97 content::RenderFrameHost
* render_frame_host
=
98 content::RenderFrameHost::FromID(render_process_id
, render_frame_id
);
99 if (!render_frame_host
) {
100 reply
.params
.set_result(PP_ERROR_FAILED
);
101 return reply
; // RFH destroyed while task was pending.
104 #if defined(USE_ASH) && defined(OS_CHROMEOS) && !defined(USE_ATHENA)
105 base::Closure stop_callback_ui_thread
=
106 base::Bind(&OnTerminateRemotingEventOnUIThread
, stop_callback
);
108 ash::Shell::GetInstance()->system_tray_notifier()->NotifyScreenShareStart(
109 stop_callback_ui_thread
, base::string16());
110 reply
.params
.set_result(PP_OK
);
113 reply
.params
.set_result(PP_ERROR_NOTSUPPORTED
);
118 void StopRemotingOnUIThread() {
119 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
120 #if defined(USE_ASH) && defined(OS_CHROMEOS) && !defined(USE_ATHENA)
121 if (ash::Shell::GetInstance()) {
122 ash::Shell::GetInstance()->system_tray_notifier()->NotifyScreenShareStop();
129 ppapi::host::ReplyMessageContext
StopRemotingOnUIThreadWithResult(
130 ppapi::host::ReplyMessageContext reply
) {
131 reply
.params
.set_result(PP_OK
);
132 StopRemotingOnUIThread();
138 PepperTalkHost::PepperTalkHost(content::BrowserPpapiHost
* host
,
139 PP_Instance instance
,
140 PP_Resource resource
)
141 : ppapi::host::ResourceHost(host
->GetPpapiHost(), instance
, resource
),
142 browser_ppapi_host_(host
),
143 remoting_started_(false),
144 weak_factory_(this) {}
146 PepperTalkHost::~PepperTalkHost() {
147 if (remoting_started_
) {
148 content::BrowserThread::PostTask(content::BrowserThread::UI
,
150 base::Bind(&StopRemotingOnUIThread
));
154 int32_t PepperTalkHost::OnResourceMessageReceived(
155 const IPC::Message
& msg
,
156 ppapi::host::HostMessageContext
* context
) {
157 PPAPI_BEGIN_MESSAGE_MAP(PepperTalkHost
, msg
)
158 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Talk_RequestPermission
,
160 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Talk_StartRemoting
,
162 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Talk_StopRemoting
,
164 PPAPI_END_MESSAGE_MAP()
165 return PP_ERROR_FAILED
;
168 int32_t PepperTalkHost::OnRequestPermission(
169 ppapi::host::HostMessageContext
* context
,
170 PP_TalkPermission permission
) {
171 if (permission
< PP_TALKPERMISSION_SCREENCAST
||
172 permission
>= PP_TALKPERMISSION_NUM_PERMISSIONS
)
173 return PP_ERROR_BADARGUMENT
;
175 int render_process_id
= 0;
176 int render_frame_id
= 0;
177 browser_ppapi_host_
->GetRenderFrameIDsForInstance(
178 pp_instance(), &render_process_id
, &render_frame_id
);
180 content::BrowserThread::PostTaskAndReplyWithResult(
181 content::BrowserThread::UI
,
183 base::Bind(&GetPermissionOnUIThread
,
187 context
->MakeReplyMessageContext()),
188 base::Bind(&PepperTalkHost::OnRequestPermissionCompleted
,
189 weak_factory_
.GetWeakPtr()));
190 return PP_OK_COMPLETIONPENDING
;
193 int32_t PepperTalkHost::OnStartRemoting(
194 ppapi::host::HostMessageContext
* context
) {
195 int render_process_id
= 0;
196 int render_frame_id
= 0;
197 browser_ppapi_host_
->GetRenderFrameIDsForInstance(
198 pp_instance(), &render_process_id
, &render_frame_id
);
200 base::Closure remoting_stop_callback
= base::Bind(
201 &PepperTalkHost::OnRemotingStopEvent
, weak_factory_
.GetWeakPtr());
203 content::BrowserThread::PostTaskAndReplyWithResult(
204 content::BrowserThread::UI
,
206 base::Bind(&StartRemotingOnUIThread
,
207 remoting_stop_callback
,
210 context
->MakeReplyMessageContext()),
211 base::Bind(&PepperTalkHost::OnStartRemotingCompleted
,
212 weak_factory_
.GetWeakPtr()));
213 return PP_OK_COMPLETIONPENDING
;
216 int32_t PepperTalkHost::OnStopRemoting(
217 ppapi::host::HostMessageContext
* context
) {
218 content::BrowserThread::PostTaskAndReplyWithResult(
219 content::BrowserThread::UI
,
221 base::Bind(&StopRemotingOnUIThreadWithResult
,
222 context
->MakeReplyMessageContext()),
223 base::Bind(&PepperTalkHost::OnStopRemotingCompleted
,
224 weak_factory_
.GetWeakPtr()));
225 return PP_OK_COMPLETIONPENDING
;
228 void PepperTalkHost::OnRemotingStopEvent() {
229 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
));
230 remoting_started_
= false;
231 host()->SendUnsolicitedReply(
232 pp_resource(), PpapiPluginMsg_Talk_NotifyEvent(PP_TALKEVENT_TERMINATE
));
235 void PepperTalkHost::OnRequestPermissionCompleted(
236 ppapi::host::ReplyMessageContext reply
) {
237 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
));
238 host()->SendReply(reply
, PpapiPluginMsg_Talk_RequestPermissionReply());
241 void PepperTalkHost::OnStartRemotingCompleted(
242 ppapi::host::ReplyMessageContext reply
) {
243 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
));
244 // Remember to hide remoting UI when resource is deleted.
245 if (reply
.params
.result() == PP_OK
)
246 remoting_started_
= true;
248 host()->SendReply(reply
, PpapiPluginMsg_Talk_StartRemotingReply());
251 void PepperTalkHost::OnStopRemotingCompleted(
252 ppapi::host::ReplyMessageContext reply
) {
253 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
));
254 remoting_started_
= false;
255 host()->SendReply(reply
, PpapiPluginMsg_Talk_StopRemotingReply());
258 } // namespace chrome