| 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..79415978a02825a94e445f2d9497288c71f3187a 100644
|
| --- a/chrome/browser/extensions/api/messaging/native_message_process_host.cc
|
| +++ b/chrome/browser/extensions/api/messaging/native_message_process_host.cc
|
| @@ -43,15 +43,18 @@ 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,
|
| + content::BrowserThread::IO,
|
| FROM_HERE,
|
| base::Bind(base::IgnoreResult(&base::KillProcess),
|
| native_process_handle_,
|
| @@ -67,9 +70,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 +84,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 +98,28 @@ void NativeMessageProcessHost::CreateWithLauncher(
|
| return;
|
| }
|
|
|
| + content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
|
| + base::Bind(&NativeMessageProcessHost::CheckPathOnFileThread,
|
| + weak_client_ui,
|
| + native_app_name,
|
| + connection_message,
|
| + destination_port,
|
| + type,
|
| + callback,
|
| + base::Passed(&launcher)));
|
| +}
|
| +
|
| +// static
|
| +void NativeMessageProcessHost::CheckPathOnFileThread(
|
| + 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));
|
| @@ -111,14 +137,37 @@ void NativeMessageProcessHost::CreateWithLauncher(
|
| return;
|
| }
|
|
|
| +
|
| + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&NativeMessageProcessHost::FinalizeCreate,
|
| + weak_client_ui,
|
| + connection_message,
|
| + destination_port,
|
| + type,
|
| + callback,
|
| + base::Passed(&launcher),
|
| + native_host_program));
|
| +}
|
| +
|
| +// static
|
| +void NativeMessageProcessHost::FinalizeCreate(
|
| + base::WeakPtr<Client> weak_client_ui,
|
| + const std::string& connection_message,
|
| + int destination_port,
|
| + MessageType type,
|
| + CreateCallback callback,
|
| + scoped_ptr<NativeProcessLauncher> launcher,
|
| + FilePath native_host_program) {
|
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
|
| + ScopedHost process;
|
| FileHandle read_handle;
|
| 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)));
|
| @@ -138,11 +187,12 @@ void NativeMessageProcessHost::CreateWithLauncher(
|
|
|
| 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_,
|
| @@ -183,31 +233,46 @@ bool NativeMessageProcessHost::ReadMessage(MessageType* type,
|
| return false;
|
| }
|
|
|
| + uint32 message_length;
|
| + if (!VerifyMessageMetaData(message_meta_data, type, &message_length))
|
| + return false;
|
| +
|
| + message->resize(message_length, '\0');
|
| + if (!ReadData(read_file_, &(*message)[0], message_length)) {
|
| + LOG(ERROR) << "Error reading the json data.";
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +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);
|
| - uint32 uint_type;
|
| + uint32 int_type;
|
| uint32 data_length;
|
| - if (!pickle_it.ReadUInt32(&uint_type) ||
|
| - !pickle_it.ReadUInt32(&data_length)) {
|
| + if (!pickle_it.ReadUInt32(&int_type) || !pickle_it.ReadUInt32(&data_length)) {
|
| LOG(ERROR) << "Error getting the message type and length from the pickle.";
|
| return false;
|
| }
|
|
|
| - if (uint_type >= NUM_MESSAGE_TYPES) {
|
| + if (int_type < 0 || int_type >= NUM_MESSAGE_TYPES) {
|
| LOG(ERROR) << type << " is not a valid message type.";
|
| return false;
|
| }
|
|
|
| - if ((is_send_message_ && (uint_type != TYPE_SEND_MESSAGE_RESPONSE)) ||
|
| - (!is_send_message_ && (uint_type != TYPE_CONNECT_MESSAGE))) {
|
| - LOG(ERROR) << "Recieved a message of type " << uint_type << ". "
|
| + if ((is_send_message_ && (int_type != TYPE_SEND_MESSAGE_RESPONSE)) ||
|
| + (!is_send_message_ && (int_type != TYPE_CONNECT_MESSAGE))) {
|
| + LOG(ERROR) << "Recieved a message of type " << int_type << ". "
|
| << "Expecting a message of type "
|
| << (is_send_message_ ? TYPE_SEND_MESSAGE_RESPONSE :
|
| 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 +280,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>(int_type);
|
| + *message_length = data_length;
|
|
|
| return true;
|
| }
|
|
|