Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / renderer_host / pepper / pepper_talk_host.cc
blob0b61c0c6c1ba53145af8e688899da3d7d291f32d
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"
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"
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
27 namespace chrome {
29 namespace {
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);
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)
46 base::string16 title;
47 base::string16 message;
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;
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;
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,
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.
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);
111 #else
112 NOTIMPLEMENTED();
113 reply.params.set_result(PP_ERROR_NOTSUPPORTED);
114 #endif
115 return reply;
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();
124 #else
125 NOTIMPLEMENTED();
126 #endif
129 ppapi::host::ReplyMessageContext StopRemotingOnUIThreadWithResult(
130 ppapi::host::ReplyMessageContext reply) {
131 reply.params.set_result(PP_OK);
132 StopRemotingOnUIThread();
133 return reply;
136 } // namespace
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,
149 FROM_HERE,
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,
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;
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,
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;
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,
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;
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;
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