Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / renderer_host / pepper / pepper_talk_host.cc
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.
4
5 #include "chrome/browser/renderer_host/pepper/pepper_talk_host.h"
6
7 #include "base/bind.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"
18
19 #if defined(USE_ASH)
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"
25 #endif
26
27 namespace chrome {
28
29 namespace {
30
31 ppapi::host::ReplyMessageContext GetPermissionOnUIThread(
32     PP_TalkPermission permission,
33     int render_process_id,
34     int render_frame_id,
35     ppapi::host::ReplyMessageContext reply) {
36   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
37   reply.params.set_result(0);
38
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.
43
44   // crbug.com/381398, crbug.com/413906 for !USE_ATHENA
45 #if defined(USE_ASH) && !defined(USE_ATHENA)
46   base::string16 title;
47   base::string16 message;
48
49   switch (permission) {
50     case PP_TALKPERMISSION_SCREENCAST:
51       title = l10n_util::GetStringUTF16(IDS_GTALK_SCREEN_SHARE_DIALOG_TITLE);
52       message =
53           l10n_util::GetStringUTF16(IDS_GTALK_SCREEN_SHARE_DIALOG_MESSAGE);
54       break;
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);
58       break;
59     case PP_TALKPERMISSION_REMOTING_CONTINUE:
60       title = l10n_util::GetStringUTF16(IDS_GTALK_REMOTING_DIALOG_TITLE);
61       message =
62           l10n_util::GetStringUTF16(IDS_GTALK_REMOTING_CONTINUE_DIALOG_MESSAGE);
63       break;
64     default:
65       NOTREACHED();
66       return reply;
67   }
68
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));
78 #else
79   NOTIMPLEMENTED();
80 #endif
81   return reply;
82 }
83
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);
88 }
89 #endif  // defined(USE_ASH) && defined(OS_CHROMEOS)
90
91 ppapi::host::ReplyMessageContext StartRemotingOnUIThread(
92     const base::Closure& stop_callback,
93     int render_process_id,
94     int render_frame_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.
102   }
103
104 #if defined(USE_ASH) && defined(OS_CHROMEOS) && !defined(USE_ATHENA)
105   base::Closure stop_callback_ui_thread =
106       base::Bind(&OnTerminateRemotingEventOnUIThread, stop_callback);
107
108   ash::Shell::GetInstance()->system_tray_notifier()->NotifyScreenShareStart(
109       stop_callback_ui_thread, base::string16());
110   reply.params.set_result(PP_OK);
111 #else
112   NOTIMPLEMENTED();
113   reply.params.set_result(PP_ERROR_NOTSUPPORTED);
114 #endif
115   return reply;
116 }
117
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();
123   }
124 #else
125   NOTIMPLEMENTED();
126 #endif
127 }
128
129 ppapi::host::ReplyMessageContext StopRemotingOnUIThreadWithResult(
130     ppapi::host::ReplyMessageContext reply) {
131   reply.params.set_result(PP_OK);
132   StopRemotingOnUIThread();
133   return reply;
134 }
135
136 }  // namespace
137
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) {}
145
146 PepperTalkHost::~PepperTalkHost() {
147   if (remoting_started_) {
148     content::BrowserThread::PostTask(content::BrowserThread::UI,
149                                      FROM_HERE,
150                                      base::Bind(&StopRemotingOnUIThread));
151   }
152 }
153
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,
159                                       OnRequestPermission)
160     PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Talk_StartRemoting,
161                                         OnStartRemoting)
162     PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Talk_StopRemoting,
163                                         OnStopRemoting)
164   PPAPI_END_MESSAGE_MAP()
165   return PP_ERROR_FAILED;
166 }
167
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;
174
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);
179
180   content::BrowserThread::PostTaskAndReplyWithResult(
181       content::BrowserThread::UI,
182       FROM_HERE,
183       base::Bind(&GetPermissionOnUIThread,
184                  permission,
185                  render_process_id,
186                  render_frame_id,
187                  context->MakeReplyMessageContext()),
188       base::Bind(&PepperTalkHost::OnRequestPermissionCompleted,
189                  weak_factory_.GetWeakPtr()));
190   return PP_OK_COMPLETIONPENDING;
191 }
192
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);
199
200   base::Closure remoting_stop_callback = base::Bind(
201       &PepperTalkHost::OnRemotingStopEvent, weak_factory_.GetWeakPtr());
202
203   content::BrowserThread::PostTaskAndReplyWithResult(
204       content::BrowserThread::UI,
205       FROM_HERE,
206       base::Bind(&StartRemotingOnUIThread,
207                  remoting_stop_callback,
208                  render_process_id,
209                  render_frame_id,
210                  context->MakeReplyMessageContext()),
211       base::Bind(&PepperTalkHost::OnStartRemotingCompleted,
212                  weak_factory_.GetWeakPtr()));
213   return PP_OK_COMPLETIONPENDING;
214 }
215
216 int32_t PepperTalkHost::OnStopRemoting(
217     ppapi::host::HostMessageContext* context) {
218   content::BrowserThread::PostTaskAndReplyWithResult(
219       content::BrowserThread::UI,
220       FROM_HERE,
221       base::Bind(&StopRemotingOnUIThreadWithResult,
222                  context->MakeReplyMessageContext()),
223       base::Bind(&PepperTalkHost::OnStopRemotingCompleted,
224                  weak_factory_.GetWeakPtr()));
225   return PP_OK_COMPLETIONPENDING;
226 }
227
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));
233 }
234
235 void PepperTalkHost::OnRequestPermissionCompleted(
236     ppapi::host::ReplyMessageContext reply) {
237   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
238   host()->SendReply(reply, PpapiPluginMsg_Talk_RequestPermissionReply());
239 }
240
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;
247
248   host()->SendReply(reply, PpapiPluginMsg_Talk_StartRemotingReply());
249 }
250
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());
256 }
257
258 }  // namespace chrome