Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: chrome/browser/extensions/api/messaging/native_message_process_host.cc

Issue 11968028: Remove connect message from Native Messaging API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/messaging/native_message_process_host.h" 5 #include "chrome/browser/extensions/api/messaging/native_message_process_host.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/file_path.h" 8 #include "base/file_path.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
(...skipping 15 matching lines...) Expand all
26 26
27 } // namespace 27 } // namespace
28 28
29 namespace extensions { 29 namespace extensions {
30 30
31 NativeMessageProcessHost::NativeMessageProcessHost( 31 NativeMessageProcessHost::NativeMessageProcessHost(
32 base::WeakPtr<Client> weak_client_ui, 32 base::WeakPtr<Client> weak_client_ui,
33 int destination_port, 33 int destination_port,
34 base::ProcessHandle native_process_handle, 34 base::ProcessHandle native_process_handle,
35 FileHandle read_file, 35 FileHandle read_file,
36 FileHandle write_file, 36 FileHandle write_file)
37 bool is_send_message)
38 : weak_client_ui_(weak_client_ui), 37 : weak_client_ui_(weak_client_ui),
39 destination_port_(destination_port), 38 destination_port_(destination_port),
40 native_process_handle_(native_process_handle), 39 native_process_handle_(native_process_handle),
41 read_file_(read_file), 40 read_file_(read_file),
42 write_file_(write_file), 41 write_file_(write_file),
43 scoped_read_file_(&read_file_), 42 scoped_read_file_(&read_file_),
44 scoped_write_file_(&write_file_), 43 scoped_write_file_(&write_file_) {
45 is_send_message_(is_send_message) {
46 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 44 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
47 InitIO(); 45 InitIO();
48 } 46 }
49 47
50 NativeMessageProcessHost::~NativeMessageProcessHost() { 48 NativeMessageProcessHost::~NativeMessageProcessHost() {
51 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 49 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
52 // Give the process some time to shutdown, then try and kill it. 50 // Give the process some time to shutdown, then try and kill it.
53 content::BrowserThread::PostDelayedTask( 51 content::BrowserThread::PostDelayedTask(
54 content::BrowserThread::FILE, 52 content::BrowserThread::FILE,
55 FROM_HERE, 53 FROM_HERE,
56 base::Bind(base::IgnoreResult(&base::KillProcess), 54 base::Bind(base::IgnoreResult(&base::KillProcess),
57 native_process_handle_, 55 native_process_handle_,
58 content::RESULT_CODE_NORMAL_EXIT, 56 content::RESULT_CODE_NORMAL_EXIT,
59 false /* don't wait for exit */), 57 false /* don't wait for exit */),
60 base::TimeDelta::FromMilliseconds(kExitTimeoutMS)); 58 base::TimeDelta::FromMilliseconds(kExitTimeoutMS));
61 } 59 }
62 60
63 // static 61 // static
64 void NativeMessageProcessHost::Create(base::WeakPtr<Client> weak_client_ui, 62 void NativeMessageProcessHost::Create(base::WeakPtr<Client> weak_client_ui,
65 const std::string& native_app_name, 63 const std::string& native_app_name,
66 const std::string& connection_message,
67 int destination_port, 64 int destination_port,
68 MessageType type,
69 CreateCallback callback) { 65 CreateCallback callback) {
70 NativeProcessLauncher launcher; 66 NativeProcessLauncher launcher;
71 CreateWithLauncher(weak_client_ui, native_app_name, connection_message, 67 CreateWithLauncher(weak_client_ui, native_app_name, destination_port,
72 destination_port, type, callback, launcher); 68 callback, launcher);
73 } 69 }
74 70
75 // static 71 // static
76 void NativeMessageProcessHost::CreateWithLauncher( 72 void NativeMessageProcessHost::CreateWithLauncher(
77 base::WeakPtr<Client> weak_client_ui, 73 base::WeakPtr<Client> weak_client_ui,
78 const std::string& native_app_name, 74 const std::string& native_app_name,
79 const std::string& connection_message,
80 int destination_port, 75 int destination_port,
81 MessageType type,
82 CreateCallback callback, 76 CreateCallback callback,
83 const NativeProcessLauncher& launcher) { 77 const NativeProcessLauncher& launcher) {
84 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 78 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
85 DCHECK(type == TYPE_SEND_MESSAGE_REQUEST || type == TYPE_CONNECT);
86 79
87 ScopedHost process; 80 ScopedHost process;
88 if (Feature::GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV || 81 if (Feature::GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV ||
89 !CommandLine::ForCurrentProcess()->HasSwitch( 82 !CommandLine::ForCurrentProcess()->HasSwitch(
90 switches::kEnableNativeMessaging)) { 83 switches::kEnableNativeMessaging)) {
91 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 84 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
92 base::Bind(callback, 85 base::Bind(callback,
93 base::Passed(&process))); 86 base::Passed(&process)));
94 return; 87 return;
95 } 88 }
(...skipping 24 matching lines...) Expand all
120 &read_handle, 113 &read_handle,
121 &write_handle)) { 114 &write_handle)) {
122 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 115 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
123 base::Bind(callback, 116 base::Bind(callback,
124 base::Passed(&process))); 117 base::Passed(&process)));
125 return; 118 return;
126 } 119 }
127 120
128 process.reset(new NativeMessageProcessHost( 121 process.reset(new NativeMessageProcessHost(
129 weak_client_ui, destination_port, native_process_handle, read_handle, 122 weak_client_ui, destination_port, native_process_handle, read_handle,
130 write_handle, type == TYPE_SEND_MESSAGE_REQUEST)); 123 write_handle));
131
132 process->SendImpl(type, connection_message);
133 124
134 content::BrowserThread::PostTask( 125 content::BrowserThread::PostTask(
135 content::BrowserThread::UI, FROM_HERE, 126 content::BrowserThread::UI, FROM_HERE,
136 base::Bind(callback, base::Passed(&process))); 127 base::Bind(callback, base::Passed(&process)));
137 } 128 }
138 129
139 void NativeMessageProcessHost::SendImpl(MessageType type, 130 void NativeMessageProcessHost::Send(const std::string& json) {
140 const std::string& json) {
141 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 131 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
142 132
143 // Make sure that the process has not died. 133 // Make sure that the process has not died.
144 if (base::GetTerminationStatus(native_process_handle_, NULL) != 134 if (base::GetTerminationStatus(native_process_handle_, NULL) !=
145 base::TERMINATION_STATUS_STILL_RUNNING) { 135 base::TERMINATION_STATUS_STILL_RUNNING) {
146 // Notify the message service that the channel should close. 136 // Notify the message service that the channel should close.
147 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 137 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
148 base::Bind(&Client::CloseChannel, weak_client_ui_, 138 base::Bind(&Client::CloseChannel, weak_client_ui_,
149 destination_port_, true)); 139 destination_port_, true));
150 } 140 }
151 141
152 WriteMessage(type, json); 142 WriteMessage(json);
153 } 143 }
154 144
155 bool NativeMessageProcessHost::WriteMessage(MessageType type, 145 bool NativeMessageProcessHost::WriteMessage(const std::string& message) {
156 const std::string& message) {
157 Pickle pickle; 146 Pickle pickle;
158 147
159 // Pickles will always pad bytes to 32-bit alignment, so just use a unit32.
160 pickle.WriteUInt32(type);
161
162 // Pickles write the length of a string before it as a uint32. 148 // Pickles write the length of a string before it as a uint32.
163 pickle.WriteString(message); 149 pickle.WriteString(message);
164 150
165 // Make sure that the pickle doesn't do any unexpected padding. 151 // Make sure that the pickle doesn't do any unexpected padding.
166 CHECK(8 + message.length() == pickle.payload_size()); 152 CHECK_EQ(4 + message.length(), pickle.payload_size());
167 153
168 if (!WriteData(write_file_, const_cast<const Pickle*>(&pickle)->payload(), 154 if (!WriteData(write_file_, const_cast<const Pickle*>(&pickle)->payload(),
169 pickle.payload_size())) { 155 pickle.payload_size())) {
170 LOG(ERROR) << "Error writing message to the native client."; 156 LOG(ERROR) << "Error writing message to the native client.";
171 return false; 157 return false;
172 } 158 }
173 159
174 return true; 160 return true;
175 } 161 }
176 162
177 bool NativeMessageProcessHost::ReadMessage(MessageType* type, 163 bool NativeMessageProcessHost::ReadMessage(std::string* message) {
178 std::string* message) { 164 // Read the length (uint32).
179 // Read the type (uint32) and length (uint32). 165 char message_meta_data[4];
180 char message_meta_data[8]; 166 if (!ReadData(read_file_, message_meta_data, sizeof(message_meta_data))) {
181 if (!ReadData(read_file_, message_meta_data, 8)) { 167 LOG(ERROR) << "Error reading the message length.";
182 LOG(ERROR) << "Error reading the message type and length.";
183 return false; 168 return false;
184 } 169 }
185 170
186 Pickle pickle; 171 Pickle pickle;
187 pickle.WriteBytes(message_meta_data, 8); 172 pickle.WriteBytes(message_meta_data, 8);
188 PickleIterator pickle_it(pickle); 173 PickleIterator pickle_it(pickle);
189 uint32 uint_type;
190 uint32 data_length; 174 uint32 data_length;
191 if (!pickle_it.ReadUInt32(&uint_type) || 175 if (!pickle_it.ReadUInt32(&data_length)) {
192 !pickle_it.ReadUInt32(&data_length)) { 176 LOG(ERROR) << "Error getting the message length from the pickle.";
193 LOG(ERROR) << "Error getting the message type and length from the pickle.";
194 return false; 177 return false;
195 } 178 }
196 179
197 if (uint_type >= NUM_MESSAGE_TYPES) {
198 LOG(ERROR) << type << " is not a valid message type.";
199 return false;
200 }
201
202 if ((is_send_message_ && (uint_type != TYPE_SEND_MESSAGE_RESPONSE)) ||
203 (!is_send_message_ && (uint_type != TYPE_CONNECT_MESSAGE))) {
204 LOG(ERROR) << "Recieved a message of type " << uint_type << ". "
205 << "Expecting a message of type "
206 << (is_send_message_ ? TYPE_SEND_MESSAGE_RESPONSE :
207 TYPE_CONNECT_MESSAGE);
208 return false;
209 }
210 *type = static_cast<MessageType>(uint_type);
211
212 if (data_length > kMaxMessageDataLength) { 180 if (data_length > kMaxMessageDataLength) {
213 LOG(ERROR) << data_length << " is too large for the length of a message. " 181 LOG(ERROR) << data_length << " is too large for the length of a message. "
214 << "Max message size is " << kMaxMessageDataLength; 182 << "Max message size is " << kMaxMessageDataLength;
215 return false; 183 return false;
216 } 184 }
217 185
218 message->resize(data_length, '\0'); 186 message->resize(data_length, '\0');
219 if (!ReadData(read_file_, &(*message)[0], data_length)) { 187 if (!ReadData(read_file_, &(*message)[0], data_length)) {
220 LOG(ERROR) << "Error reading the json data."; 188 LOG(ERROR) << "Error reading the json data.";
221 return false; 189 return false;
222 } 190 }
223 191
224 return true; 192 return true;
225 } 193 }
226 194
227 } // namespace extensions 195 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698