| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/renderer_host/pepper/pepper_talk_host.h" |
| |
| #include "base/bind.h" |
| #include "content/public/browser/browser_ppapi_host.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/render_view_host.h" |
| #include "grit/generated_resources.h" |
| #include "ppapi/c/pp_errors.h" |
| #include "ppapi/host/dispatch_host_message.h" |
| #include "ppapi/host/host_message_context.h" |
| #include "ppapi/host/ppapi_host.h" |
| #include "ppapi/proxy/ppapi_messages.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| #if defined(USE_ASH) |
| #include "ash/shell.h" |
| #include "ash/shell_window_ids.h" |
| #include "ash/system/tray/system_tray_notifier.h" |
| #include "chrome/browser/ui/simple_message_box.h" |
| #include "ui/aura/window.h" |
| #endif |
| |
| namespace chrome { |
| |
| namespace { |
| |
| ppapi::host::ReplyMessageContext GetPermissionOnUIThread( |
| PP_TalkPermission permission, |
| int render_process_id, |
| int render_view_id, |
| ppapi::host::ReplyMessageContext reply) { |
| DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| reply.params.set_result(0); |
| |
| content::RenderViewHost* render_view_host = |
| content::RenderViewHost::FromID(render_process_id, render_view_id); |
| if (!render_view_host) |
| return reply; // RVH destroyed while task was pending. |
| |
| #if defined(USE_ASH) |
| string16 title; |
| string16 message; |
| |
| switch (permission) { |
| case PP_TALKPERMISSION_SCREENCAST: |
| title = l10n_util::GetStringUTF16(IDS_GTALK_SCREEN_SHARE_DIALOG_TITLE); |
| message = l10n_util::GetStringUTF16( |
| IDS_GTALK_SCREEN_SHARE_DIALOG_MESSAGE); |
| break; |
| case PP_TALKPERMISSION_REMOTING: |
| title = l10n_util::GetStringUTF16(IDS_GTALK_REMOTING_DIALOG_TITLE); |
| message = l10n_util::GetStringUTF16( |
| IDS_GTALK_REMOTING_DIALOG_MESSAGE); |
| break; |
| case PP_TALKPERMISSION_REMOTING_CONTINUE: |
| title = l10n_util::GetStringUTF16(IDS_GTALK_REMOTING_DIALOG_TITLE); |
| message = l10n_util::GetStringUTF16( |
| IDS_GTALK_REMOTING_CONTINUE_DIALOG_MESSAGE); |
| break; |
| default: |
| NOTREACHED(); |
| return reply; |
| } |
| |
| // TODO(brettw). We should not be grabbing the active toplevel window, we |
| // should use the toplevel window associated with the render view. |
| aura::Window* parent = ash::Shell::GetContainer( |
| ash::Shell::GetTargetRootWindow(), |
| ash::internal::kShellWindowId_SystemModalContainer); |
| reply.params.set_result(static_cast<int32_t>( |
| chrome::ShowMessageBox(parent, title, message, |
| chrome::MESSAGE_BOX_TYPE_QUESTION) == |
| chrome::MESSAGE_BOX_RESULT_YES)); |
| #else |
| NOTIMPLEMENTED(); |
| #endif |
| return reply; |
| } |
| |
| void OnTerminateRemotingEventOnUIThread(const base::Closure& stop_callback) { |
| content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, |
| stop_callback); |
| } |
| |
| ppapi::host::ReplyMessageContext StartRemotingOnUIThread( |
| const base::Closure& stop_callback, |
| int render_process_id, |
| int render_view_id, |
| ppapi::host::ReplyMessageContext reply) { |
| DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| content::RenderViewHost* render_view_host = |
| content::RenderViewHost::FromID(render_process_id, render_view_id); |
| if (!render_view_host) { |
| reply.params.set_result(PP_ERROR_FAILED); |
| return reply; // RVH destroyed while task was pending. |
| } |
| |
| #if defined(USE_ASH) && defined(OS_CHROMEOS) |
| base::Closure stop_callback_ui_thread = base::Bind( |
| &OnTerminateRemotingEventOnUIThread, |
| stop_callback); |
| |
| ash::Shell::GetInstance()->system_tray_notifier()->NotifyScreenShareStart( |
| stop_callback_ui_thread, base::string16()); |
| reply.params.set_result(PP_OK); |
| #else |
| NOTIMPLEMENTED(); |
| reply.params.set_result(PP_ERROR_NOTSUPPORTED); |
| #endif |
| return reply; |
| } |
| |
| void StopRemotingOnUIThread() { |
| DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| #if defined(USE_ASH) && defined(OS_CHROMEOS) |
| if (ash::Shell::GetInstance()) { |
| ash::Shell::GetInstance()->system_tray_notifier()->NotifyScreenShareStop(); |
| } |
| #else |
| NOTIMPLEMENTED(); |
| #endif |
| } |
| |
| ppapi::host::ReplyMessageContext StopRemotingOnUIThreadWithResult( |
| ppapi::host::ReplyMessageContext reply) { |
| reply.params.set_result(PP_OK); |
| StopRemotingOnUIThread(); |
| return reply; |
| } |
| |
| } // namespace |
| |
| PepperTalkHost::PepperTalkHost(content::BrowserPpapiHost* host, |
| PP_Instance instance, |
| PP_Resource resource) |
| : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource), |
| browser_ppapi_host_(host), |
| remoting_started_(false), |
| weak_factory_(this) { |
| } |
| |
| PepperTalkHost::~PepperTalkHost() { |
| if (remoting_started_) { |
| content::BrowserThread::PostTask( |
| content::BrowserThread::UI, FROM_HERE, |
| base::Bind(&StopRemotingOnUIThread)); |
| } |
| } |
| |
| int32_t PepperTalkHost::OnResourceMessageReceived( |
| const IPC::Message& msg, |
| ppapi::host::HostMessageContext* context) { |
| IPC_BEGIN_MESSAGE_MAP(PepperTalkHost, msg) |
| PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Talk_RequestPermission, |
| OnRequestPermission) |
| PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Talk_StartRemoting, |
| OnStartRemoting) |
| PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Talk_StopRemoting, |
| OnStopRemoting) |
| IPC_END_MESSAGE_MAP() |
| return PP_ERROR_FAILED; |
| } |
| |
| int32_t PepperTalkHost::OnRequestPermission( |
| ppapi::host::HostMessageContext* context, |
| PP_TalkPermission permission) { |
| if (permission < PP_TALKPERMISSION_SCREENCAST || |
| permission >= PP_TALKPERMISSION_NUM_PERMISSIONS) |
| return PP_ERROR_BADARGUMENT; |
| |
| int render_process_id = 0; |
| int render_view_id = 0; |
| browser_ppapi_host_->GetRenderViewIDsForInstance( |
| pp_instance(), &render_process_id, &render_view_id); |
| |
| content::BrowserThread::PostTaskAndReplyWithResult( |
| content::BrowserThread::UI, FROM_HERE, |
| base::Bind(&GetPermissionOnUIThread, permission, render_process_id, |
| render_view_id, context->MakeReplyMessageContext()), |
| base::Bind(&PepperTalkHost::OnRequestPermissionCompleted, |
| weak_factory_.GetWeakPtr())); |
| return PP_OK_COMPLETIONPENDING; |
| } |
| |
| int32_t PepperTalkHost::OnStartRemoting( |
| ppapi::host::HostMessageContext* context) { |
| int render_process_id = 0; |
| int render_view_id = 0; |
| browser_ppapi_host_->GetRenderViewIDsForInstance( |
| pp_instance(), &render_process_id, &render_view_id); |
| |
| base::Closure remoting_stop_callback = base::Bind( |
| &PepperTalkHost::OnRemotingStopEvent, |
| weak_factory_.GetWeakPtr()); |
| |
| content::BrowserThread::PostTaskAndReplyWithResult( |
| content::BrowserThread::UI, FROM_HERE, |
| base::Bind(&StartRemotingOnUIThread, remoting_stop_callback, |
| render_process_id, render_view_id, |
| context->MakeReplyMessageContext()), |
| base::Bind(&PepperTalkHost::OnStartRemotingCompleted, |
| weak_factory_.GetWeakPtr())); |
| return PP_OK_COMPLETIONPENDING; |
| } |
| |
| int32_t PepperTalkHost::OnStopRemoting( |
| ppapi::host::HostMessageContext* context) { |
| content::BrowserThread::PostTaskAndReplyWithResult( |
| content::BrowserThread::UI, FROM_HERE, |
| base::Bind(&StopRemotingOnUIThreadWithResult, |
| context->MakeReplyMessageContext()), |
| base::Bind(&PepperTalkHost::OnStopRemotingCompleted, |
| weak_factory_.GetWeakPtr())); |
| return PP_OK_COMPLETIONPENDING; |
| } |
| |
| void PepperTalkHost::OnRemotingStopEvent() { |
| DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| remoting_started_ = false; |
| host()->SendUnsolicitedReply( |
| pp_resource(), PpapiPluginMsg_Talk_NotifyEvent(PP_TALKEVENT_TERMINATE)); |
| } |
| |
| void PepperTalkHost::OnRequestPermissionCompleted( |
| ppapi::host::ReplyMessageContext reply) { |
| DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| host()->SendReply(reply, PpapiPluginMsg_Talk_RequestPermissionReply()); |
| } |
| |
| void PepperTalkHost::OnStartRemotingCompleted( |
| ppapi::host::ReplyMessageContext reply) { |
| DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| // Remember to hide remoting UI when resource is deleted. |
| if (reply.params.result() == PP_OK) |
| remoting_started_ = true; |
| |
| host()->SendReply(reply, PpapiPluginMsg_Talk_StartRemotingReply()); |
| } |
| |
| void PepperTalkHost::OnStopRemotingCompleted( |
| ppapi::host::ReplyMessageContext reply) { |
| DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| remoting_started_ = false; |
| host()->SendReply(reply, PpapiPluginMsg_Talk_StopRemotingReply()); |
| } |
| |
| } // namespace chrome |