| Index: chrome/browser/extensions/api/messaging/native_message_process_host.cc
|
| diff --git a/chrome/browser/extensions/api/messaging/native_message_process_host.cc b/chrome/browser/extensions/api/messaging/native_message_process_host.cc
|
| index 98afbc56e66c2c3f874d1f07b2879c43a8723290..b8ed087b0d9331738c8b6afdd6c2bf0a8e3f532c 100644
|
| --- a/chrome/browser/extensions/api/messaging/native_message_process_host.cc
|
| +++ b/chrome/browser/extensions/api/messaging/native_message_process_host.cc
|
| @@ -20,14 +20,16 @@
|
|
|
| namespace {
|
|
|
| -const int kExitTimeoutMS = 5000;
|
| -const uint32 kMaxMessageDataLength = 10 * 1024 * 1024;
|
| const char kNativeHostsDirectoryName[] = "Native Hosts";
|
|
|
| } // namespace
|
|
|
| namespace extensions {
|
|
|
| +// static
|
| +const int NativeMessageProcessHost::kExitTimeoutMS = 5000;
|
| +const uint32 NativeMessageProcessHost::kMaxMessageDataLength = 10 * 1024 * 1024;
|
| +
|
| NativeMessageProcessHost::NativeMessageProcessHost(
|
| base::WeakPtr<Client> weak_client_ui,
|
| int destination_port,
|
| @@ -43,21 +45,28 @@ NativeMessageProcessHost::NativeMessageProcessHost(
|
| scoped_read_file_(&read_file_),
|
| scoped_write_file_(&write_file_),
|
| is_send_message_(is_send_message) {
|
| - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
|
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
|
| InitIO();
|
| }
|
|
|
| NativeMessageProcessHost::~NativeMessageProcessHost() {
|
| - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
|
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
|
| +
|
| + StopIO();
|
| +
|
| // Give the process some time to shutdown, then try and kill it.
|
| - content::BrowserThread::PostDelayedTask(
|
| - content::BrowserThread::FILE,
|
| - FROM_HERE,
|
| - base::Bind(base::IgnoreResult(&base::KillProcess),
|
| - native_process_handle_,
|
| - content::RESULT_CODE_NORMAL_EXIT,
|
| - false /* don't wait for exit */),
|
| - base::TimeDelta::FromMilliseconds(kExitTimeoutMS));
|
| + if (native_process_handle_ != base::kNullProcessHandle &&
|
| + base::GetTerminationStatus(native_process_handle_, NULL) ==
|
| + base::TERMINATION_STATUS_STILL_RUNNING) {
|
| + content::BrowserThread::PostDelayedTask(
|
| + content::BrowserThread::IO,
|
| + FROM_HERE,
|
| + base::Bind(base::IgnoreResult(&base::KillProcess),
|
| + native_process_handle_,
|
| + content::RESULT_CODE_NORMAL_EXIT,
|
| + true /* wait for exit */),
|
| + base::TimeDelta::FromMilliseconds(kExitTimeoutMS));
|
| + }
|
| }
|
|
|
| // static
|
| @@ -67,9 +76,10 @@ void NativeMessageProcessHost::Create(base::WeakPtr<Client> weak_client_ui,
|
| int destination_port,
|
| MessageType type,
|
| CreateCallback callback) {
|
| - NativeProcessLauncher launcher;
|
| CreateWithLauncher(weak_client_ui, native_app_name, connection_message,
|
| - destination_port, type, callback, launcher);
|
| + destination_port, type, callback,
|
| + scoped_ptr<NativeProcessLauncher>(
|
| + new NativeProcessLauncher()));
|
| }
|
|
|
| // static
|
| @@ -80,8 +90,8 @@ void NativeMessageProcessHost::CreateWithLauncher(
|
| int destination_port,
|
| MessageType type,
|
| CreateCallback callback,
|
| - const NativeProcessLauncher& launcher) {
|
| - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
|
| + scoped_ptr<NativeProcessLauncher> launcher) {
|
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
|
| DCHECK(type == TYPE_SEND_MESSAGE_REQUEST || type == TYPE_CONNECT);
|
|
|
| ScopedHost process;
|
| @@ -94,6 +104,28 @@ void NativeMessageProcessHost::CreateWithLauncher(
|
| return;
|
| }
|
|
|
| + content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
|
| + base::Bind(&NativeMessageProcessHost::LaunchProcessOnFileThread,
|
| + weak_client_ui,
|
| + native_app_name,
|
| + connection_message,
|
| + destination_port,
|
| + type,
|
| + callback,
|
| + base::Passed(&launcher)));
|
| +}
|
| +
|
| +// static
|
| +void NativeMessageProcessHost::LaunchProcessOnFileThread(
|
| + base::WeakPtr<Client> weak_client_ui,
|
| + const std::string& native_app_name,
|
| + const std::string& connection_message,
|
| + int destination_port,
|
| + MessageType type,
|
| + CreateCallback callback,
|
| + scoped_ptr<NativeProcessLauncher> launcher) {
|
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
|
| + ScopedHost process;
|
| FilePath native_host_program;
|
| FilePath native_host_registry;
|
| CHECK(PathService::Get(chrome::DIR_USER_DATA, &native_host_registry));
|
| @@ -115,34 +147,57 @@ void NativeMessageProcessHost::CreateWithLauncher(
|
| FileHandle write_handle;
|
| base::ProcessHandle native_process_handle;
|
|
|
| - if (!launcher.LaunchNativeProcess(native_host_program,
|
| - &native_process_handle,
|
| - &read_handle,
|
| - &write_handle)) {
|
| + if (!launcher->LaunchNativeProcess(native_host_program,
|
| + &native_process_handle,
|
| + &read_handle,
|
| + &write_handle)) {
|
| content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
| base::Bind(callback,
|
| base::Passed(&process)));
|
| return;
|
| }
|
|
|
| + NativeProcessHostCreationInformation creation_info(weak_client_ui,
|
| + connection_message,
|
| + destination_port,
|
| + type,
|
| + callback,
|
| + read_handle,
|
| + write_handle,
|
| + native_process_handle);
|
| +
|
| + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&NativeMessageProcessHost::FinalizeCreate,
|
| + creation_info));
|
| +}
|
| +
|
| +// static
|
| +void NativeMessageProcessHost::FinalizeCreate(
|
| + NativeProcessHostCreationInformation creation_info) {
|
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
|
| + ScopedHost process;
|
| +
|
| process.reset(new NativeMessageProcessHost(
|
| - weak_client_ui, destination_port, native_process_handle, read_handle,
|
| - write_handle, type == TYPE_SEND_MESSAGE_REQUEST));
|
| + creation_info.weak_client_ui, creation_info.destination_port,
|
| + creation_info.native_process_handle, creation_info.read_handle,
|
| + creation_info.write_handle,
|
| + creation_info.type == TYPE_SEND_MESSAGE_REQUEST));
|
|
|
| - process->SendImpl(type, connection_message);
|
| + process->SendImpl(creation_info.type, creation_info.connection_message);
|
|
|
| content::BrowserThread::PostTask(
|
| content::BrowserThread::UI, FROM_HERE,
|
| - base::Bind(callback, base::Passed(&process)));
|
| + base::Bind(creation_info.callback, base::Passed(&process)));
|
| }
|
|
|
| void NativeMessageProcessHost::SendImpl(MessageType type,
|
| const std::string& json) {
|
| - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
|
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
|
|
|
| // Make sure that the process has not died.
|
| - if (base::GetTerminationStatus(native_process_handle_, NULL) !=
|
| - base::TERMINATION_STATUS_STILL_RUNNING) {
|
| + if (native_process_handle_ != base::kNullProcessHandle &&
|
| + base::GetTerminationStatus(native_process_handle_, NULL) !=
|
| + base::TERMINATION_STATUS_STILL_RUNNING) {
|
| // Notify the message service that the channel should close.
|
| content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
| base::Bind(&Client::CloseChannel, weak_client_ui_,
|
| @@ -174,15 +229,10 @@ bool NativeMessageProcessHost::WriteMessage(MessageType type,
|
| return true;
|
| }
|
|
|
| -bool NativeMessageProcessHost::ReadMessage(MessageType* type,
|
| - std::string* message) {
|
| - // Read the type (uint32) and length (uint32).
|
| - char message_meta_data[8];
|
| - if (!ReadData(read_file_, message_meta_data, 8)) {
|
| - LOG(ERROR) << "Error reading the message type and length.";
|
| - return false;
|
| - }
|
| -
|
| +bool NativeMessageProcessHost::VerifyMessageMetaData(
|
| + const char* message_meta_data,
|
| + MessageType* type,
|
| + uint32* message_length) {
|
| Pickle pickle;
|
| pickle.WriteBytes(message_meta_data, 8);
|
| PickleIterator pickle_it(pickle);
|
| @@ -207,7 +257,6 @@ bool NativeMessageProcessHost::ReadMessage(MessageType* type,
|
| TYPE_CONNECT_MESSAGE);
|
| return false;
|
| }
|
| - *type = static_cast<MessageType>(uint_type);
|
|
|
| if (data_length > kMaxMessageDataLength) {
|
| LOG(ERROR) << data_length << " is too large for the length of a message. "
|
| @@ -215,11 +264,8 @@ bool NativeMessageProcessHost::ReadMessage(MessageType* type,
|
| return false;
|
| }
|
|
|
| - message->resize(data_length, '\0');
|
| - if (!ReadData(read_file_, &(*message)[0], data_length)) {
|
| - LOG(ERROR) << "Error reading the json data.";
|
| - return false;
|
| - }
|
| + *type = static_cast<MessageType>(uint_type);
|
| + *message_length = data_length;
|
|
|
| return true;
|
| }
|
|
|