1 // Copyright 2014 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 "components/nacl/renderer/manifest_service_channel.h" 6 7 #include "base/bind.h" 8 #include "base/callback.h" 9 #include "base/callback_helpers.h" 10 #include "content/public/common/sandbox_init.h" 11 #include "content/public/renderer/render_thread.h" 12 #include "ipc/ipc_channel.h" 13 #include "ipc/ipc_sync_channel.h" 14 #include "ppapi/c/pp_errors.h" 15 #include "ppapi/c/ppb_file_io.h" 16 #include "ppapi/proxy/ppapi_messages.h" 17 18 namespace nacl { 19 20 ManifestServiceChannel::ManifestServiceChannel( 21 const IPC::ChannelHandle& handle, 22 const base::Callback<void(int32_t)>& connected_callback, 23 scoped_ptr<Delegate> delegate, 24 base::WaitableEvent* waitable_event) 25 : connected_callback_(connected_callback), 26 delegate_(delegate.Pass()), 27 channel_(IPC::SyncChannel::Create( 28 handle, 29 IPC::Channel::MODE_CLIENT, 30 this, 31 content::RenderThread::Get()->GetIOMessageLoopProxy(), 32 true, 33 waitable_event)), 34 peer_pid_(base::kNullProcessId), 35 weak_ptr_factory_(this) { 36 } 37 38 ManifestServiceChannel::~ManifestServiceChannel() { 39 if (!connected_callback_.is_null()) 40 base::ResetAndReturn(&connected_callback_).Run(PP_ERROR_FAILED); 41 } 42 43 void ManifestServiceChannel::Send(IPC::Message* message) { 44 channel_->Send(message); 45 } 46 47 bool ManifestServiceChannel::OnMessageReceived(const IPC::Message& message) { 48 bool handled = true; 49 IPC_BEGIN_MESSAGE_MAP(ManifestServiceChannel, message) 50 IPC_MESSAGE_HANDLER(PpapiHostMsg_StartupInitializationComplete, 51 OnStartupInitializationComplete) 52 IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiHostMsg_OpenResource, 53 OnOpenResource) 54 IPC_MESSAGE_UNHANDLED(handled = false) 55 IPC_END_MESSAGE_MAP() 56 return handled; 57 } 58 59 void ManifestServiceChannel::OnChannelConnected(int32 peer_pid) { 60 peer_pid_ = peer_pid; 61 if (!connected_callback_.is_null()) 62 base::ResetAndReturn(&connected_callback_).Run(PP_OK); 63 } 64 65 void ManifestServiceChannel::OnChannelError() { 66 if (!connected_callback_.is_null()) 67 base::ResetAndReturn(&connected_callback_).Run(PP_ERROR_FAILED); 68 } 69 70 void ManifestServiceChannel::OnStartupInitializationComplete() { 71 delegate_->StartupInitializationComplete(); 72 } 73 74 void ManifestServiceChannel::OnOpenResource( 75 const std::string& key, IPC::Message* reply) { 76 delegate_->OpenResource( 77 key, 78 base::Bind(&ManifestServiceChannel::DidOpenResource, 79 weak_ptr_factory_.GetWeakPtr(), reply)); 80 } 81 82 void ManifestServiceChannel::DidOpenResource(IPC::Message* reply, 83 base::File file, 84 uint64_t token_lo, 85 uint64_t token_hi) { 86 ppapi::proxy::SerializedHandle handle; 87 if (file.IsValid()) { 88 IPC::PlatformFileForTransit file_for_transit; 89 #if defined(OS_WIN) 90 bool ok = content::BrokerDuplicateHandle( 91 file.TakePlatformFile(), 92 peer_pid_, 93 &file_for_transit, 94 0, // desired_access is 0 since we're using DUPLICATE_SAME_ACCESS. 95 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); 96 if (ok) 97 handle.set_file_handle(file_for_transit, PP_FILEOPENFLAG_READ, 0); 98 #else 99 file_for_transit = base::FileDescriptor(file.Pass()); 100 handle.set_file_handle(file_for_transit, PP_FILEOPENFLAG_READ, 0); 101 #endif 102 } 103 PpapiHostMsg_OpenResource::WriteReplyParams(reply, 104 handle, 105 token_lo, 106 token_hi); 107 Send(reply); 108 } 109 110 } // namespace nacl 111