| OLD | NEW |
| 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/service/service_utility_process_host.h" | 5 #include "chrome/service/service_utility_process_host.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/files/file.h" | 11 #include "base/files/file.h" |
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
| 14 #include "base/files/scoped_temp_dir.h" | 14 #include "base/files/scoped_temp_dir.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/message_loop/message_loop_proxy.h" | |
| 17 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
| 18 #include "base/process/launch.h" | 17 #include "base/process/launch.h" |
| 19 #include "base/task_runner_util.h" | 18 #include "base/task_runner_util.h" |
| 19 #include "base/thread_task_runner_handle.h" |
| 20 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
| 21 #include "chrome/common/chrome_utility_printing_messages.h" | 21 #include "chrome/common/chrome_utility_printing_messages.h" |
| 22 #include "content/public/common/child_process_host.h" | 22 #include "content/public/common/child_process_host.h" |
| 23 #include "content/public/common/result_codes.h" | 23 #include "content/public/common/result_codes.h" |
| 24 #include "content/public/common/sandbox_init.h" | 24 #include "content/public/common/sandbox_init.h" |
| 25 #include "content/public/common/sandboxed_process_launcher_delegate.h" | 25 #include "content/public/common/sandboxed_process_launcher_delegate.h" |
| 26 #include "ipc/ipc_switches.h" | 26 #include "ipc/ipc_switches.h" |
| 27 #include "printing/emf_win.h" | 27 #include "printing/emf_win.h" |
| 28 #include "sandbox/win/src/sandbox_policy_base.h" | 28 #include "sandbox/win/src/sandbox_policy_base.h" |
| 29 #include "ui/base/ui_base_switches.h" | 29 #include "ui/base/ui_base_switches.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 base::ScopedTempDir temp_dir_; | 143 base::ScopedTempDir temp_dir_; |
| 144 ServiceUtilityProcessHost* host_; | 144 ServiceUtilityProcessHost* host_; |
| 145 std::queue<base::File> emf_files_; | 145 std::queue<base::File> emf_files_; |
| 146 int page_count_; | 146 int page_count_; |
| 147 int current_page_; | 147 int current_page_; |
| 148 int pages_in_progress_; | 148 int pages_in_progress_; |
| 149 }; | 149 }; |
| 150 | 150 |
| 151 ServiceUtilityProcessHost::ServiceUtilityProcessHost( | 151 ServiceUtilityProcessHost::ServiceUtilityProcessHost( |
| 152 Client* client, | 152 Client* client, |
| 153 base::MessageLoopProxy* client_message_loop_proxy) | 153 base::SingleThreadTaskRunner* client_task_runner) |
| 154 : client_(client), | 154 : client_(client), |
| 155 client_message_loop_proxy_(client_message_loop_proxy), | 155 client_task_runner_(client_task_runner), |
| 156 waiting_for_reply_(false), | 156 waiting_for_reply_(false), |
| 157 weak_ptr_factory_(this) { | 157 weak_ptr_factory_(this) { |
| 158 child_process_host_.reset(ChildProcessHost::Create(this)); | 158 child_process_host_.reset(ChildProcessHost::Create(this)); |
| 159 } | 159 } |
| 160 | 160 |
| 161 ServiceUtilityProcessHost::~ServiceUtilityProcessHost() { | 161 ServiceUtilityProcessHost::~ServiceUtilityProcessHost() { |
| 162 // We need to kill the child process when the host dies. | 162 // We need to kill the child process when the host dies. |
| 163 process_.Terminate(content::RESULT_CODE_NORMAL_EXIT, false); | 163 process_.Terminate(content::RESULT_CODE_NORMAL_EXIT, false); |
| 164 } | 164 } |
| 165 | 165 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 #else | 251 #else |
| 252 int flags = ChildProcessHost::CHILD_NORMAL; | 252 int flags = ChildProcessHost::CHILD_NORMAL; |
| 253 #endif | 253 #endif |
| 254 return ChildProcessHost::GetChildPath(flags); | 254 return ChildProcessHost::GetChildPath(flags); |
| 255 } | 255 } |
| 256 | 256 |
| 257 void ServiceUtilityProcessHost::OnChildDisconnected() { | 257 void ServiceUtilityProcessHost::OnChildDisconnected() { |
| 258 if (waiting_for_reply_) { | 258 if (waiting_for_reply_) { |
| 259 // If we are yet to receive a reply then notify the client that the | 259 // If we are yet to receive a reply then notify the client that the |
| 260 // child died. | 260 // child died. |
| 261 client_message_loop_proxy_->PostTask( | 261 client_task_runner_->PostTask( |
| 262 FROM_HERE, base::Bind(&Client::OnChildDied, client_.get())); | 262 FROM_HERE, base::Bind(&Client::OnChildDied, client_.get())); |
| 263 ReportUmaEvent(SERVICE_UTILITY_DISCONNECTED); | 263 ReportUmaEvent(SERVICE_UTILITY_DISCONNECTED); |
| 264 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityDisconnectTime", | 264 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityDisconnectTime", |
| 265 base::Time::Now() - start_time_); | 265 base::Time::Now() - start_time_); |
| 266 } | 266 } |
| 267 delete this; | 267 delete this; |
| 268 } | 268 } |
| 269 | 269 |
| 270 bool ServiceUtilityProcessHost::OnMessageReceived(const IPC::Message& message) { | 270 bool ServiceUtilityProcessHost::OnMessageReceived(const IPC::Message& message) { |
| 271 bool handled = true; | 271 bool handled = true; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 } | 312 } |
| 313 | 313 |
| 314 void ServiceUtilityProcessHost::OnRenderPDFPagesToMetafilesPageDone( | 314 void ServiceUtilityProcessHost::OnRenderPDFPagesToMetafilesPageDone( |
| 315 bool success, | 315 bool success, |
| 316 float scale_factor) { | 316 float scale_factor) { |
| 317 DCHECK(waiting_for_reply_); | 317 DCHECK(waiting_for_reply_); |
| 318 if (!pdf_to_emf_state_ || !success) | 318 if (!pdf_to_emf_state_ || !success) |
| 319 return OnPDFToEmfFinished(false); | 319 return OnPDFToEmfFinished(false); |
| 320 base::File emf_file = pdf_to_emf_state_->TakeNextFile(); | 320 base::File emf_file = pdf_to_emf_state_->TakeNextFile(); |
| 321 base::PostTaskAndReplyWithResult( | 321 base::PostTaskAndReplyWithResult( |
| 322 client_message_loop_proxy_.get(), FROM_HERE, | 322 client_task_runner_.get(), FROM_HERE, |
| 323 base::Bind(&Client::MetafileAvailable, client_.get(), scale_factor, | 323 base::Bind(&Client::MetafileAvailable, client_.get(), scale_factor, |
| 324 base::Passed(&emf_file)), | 324 base::Passed(&emf_file)), |
| 325 base::Bind(&ServiceUtilityProcessHost::OnMetafileSpooled, | 325 base::Bind(&ServiceUtilityProcessHost::OnMetafileSpooled, |
| 326 weak_ptr_factory_.GetWeakPtr())); | 326 weak_ptr_factory_.GetWeakPtr())); |
| 327 } | 327 } |
| 328 | 328 |
| 329 void ServiceUtilityProcessHost::OnPDFToEmfFinished(bool success) { | 329 void ServiceUtilityProcessHost::OnPDFToEmfFinished(bool success) { |
| 330 if (!waiting_for_reply_) | 330 if (!waiting_for_reply_) |
| 331 return; | 331 return; |
| 332 waiting_for_reply_ = false; | 332 waiting_for_reply_ = false; |
| 333 if (success) { | 333 if (success) { |
| 334 ReportUmaEvent(SERVICE_UTILITY_METAFILE_SUCCEEDED); | 334 ReportUmaEvent(SERVICE_UTILITY_METAFILE_SUCCEEDED); |
| 335 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityMetafileTime", | 335 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityMetafileTime", |
| 336 base::Time::Now() - start_time_); | 336 base::Time::Now() - start_time_); |
| 337 } else { | 337 } else { |
| 338 ReportUmaEvent(SERVICE_UTILITY_METAFILE_FAILED); | 338 ReportUmaEvent(SERVICE_UTILITY_METAFILE_FAILED); |
| 339 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityMetafileFailTime", | 339 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityMetafileFailTime", |
| 340 base::Time::Now() - start_time_); | 340 base::Time::Now() - start_time_); |
| 341 } | 341 } |
| 342 client_message_loop_proxy_->PostTask( | 342 client_task_runner_->PostTask( |
| 343 FROM_HERE, | 343 FROM_HERE, base::Bind(&Client::OnRenderPDFPagesToMetafileDone, |
| 344 base::Bind( | 344 client_.get(), success)); |
| 345 &Client::OnRenderPDFPagesToMetafileDone, client_.get(), success)); | |
| 346 pdf_to_emf_state_.reset(); | 345 pdf_to_emf_state_.reset(); |
| 347 } | 346 } |
| 348 | 347 |
| 349 void ServiceUtilityProcessHost::OnGetPrinterCapsAndDefaultsSucceeded( | 348 void ServiceUtilityProcessHost::OnGetPrinterCapsAndDefaultsSucceeded( |
| 350 const std::string& printer_name, | 349 const std::string& printer_name, |
| 351 const printing::PrinterCapsAndDefaults& caps_and_defaults) { | 350 const printing::PrinterCapsAndDefaults& caps_and_defaults) { |
| 352 DCHECK(waiting_for_reply_); | 351 DCHECK(waiting_for_reply_); |
| 353 ReportUmaEvent(SERVICE_UTILITY_CAPS_SUCCEEDED); | 352 ReportUmaEvent(SERVICE_UTILITY_CAPS_SUCCEEDED); |
| 354 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityCapsTime", | 353 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityCapsTime", |
| 355 base::Time::Now() - start_time_); | 354 base::Time::Now() - start_time_); |
| 356 waiting_for_reply_ = false; | 355 waiting_for_reply_ = false; |
| 357 client_message_loop_proxy_->PostTask( | 356 client_task_runner_->PostTask( |
| 358 FROM_HERE, | 357 FROM_HERE, base::Bind(&Client::OnGetPrinterCapsAndDefaults, client_.get(), |
| 359 base::Bind(&Client::OnGetPrinterCapsAndDefaults, client_.get(), true, | 358 true, printer_name, caps_and_defaults)); |
| 360 printer_name, caps_and_defaults)); | |
| 361 } | 359 } |
| 362 | 360 |
| 363 void ServiceUtilityProcessHost::OnGetPrinterSemanticCapsAndDefaultsSucceeded( | 361 void ServiceUtilityProcessHost::OnGetPrinterSemanticCapsAndDefaultsSucceeded( |
| 364 const std::string& printer_name, | 362 const std::string& printer_name, |
| 365 const printing::PrinterSemanticCapsAndDefaults& caps_and_defaults) { | 363 const printing::PrinterSemanticCapsAndDefaults& caps_and_defaults) { |
| 366 DCHECK(waiting_for_reply_); | 364 DCHECK(waiting_for_reply_); |
| 367 ReportUmaEvent(SERVICE_UTILITY_SEMANTIC_CAPS_SUCCEEDED); | 365 ReportUmaEvent(SERVICE_UTILITY_SEMANTIC_CAPS_SUCCEEDED); |
| 368 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilitySemanticCapsTime", | 366 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilitySemanticCapsTime", |
| 369 base::Time::Now() - start_time_); | 367 base::Time::Now() - start_time_); |
| 370 waiting_for_reply_ = false; | 368 waiting_for_reply_ = false; |
| 371 client_message_loop_proxy_->PostTask( | 369 client_task_runner_->PostTask( |
| 372 FROM_HERE, | 370 FROM_HERE, |
| 373 base::Bind(&Client::OnGetPrinterSemanticCapsAndDefaults, client_.get(), | 371 base::Bind(&Client::OnGetPrinterSemanticCapsAndDefaults, client_.get(), |
| 374 true, printer_name, caps_and_defaults)); | 372 true, printer_name, caps_and_defaults)); |
| 375 } | 373 } |
| 376 | 374 |
| 377 void ServiceUtilityProcessHost::OnGetPrinterCapsAndDefaultsFailed( | 375 void ServiceUtilityProcessHost::OnGetPrinterCapsAndDefaultsFailed( |
| 378 const std::string& printer_name) { | 376 const std::string& printer_name) { |
| 379 DCHECK(waiting_for_reply_); | 377 DCHECK(waiting_for_reply_); |
| 380 ReportUmaEvent(SERVICE_UTILITY_CAPS_FAILED); | 378 ReportUmaEvent(SERVICE_UTILITY_CAPS_FAILED); |
| 381 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityCapsFailTime", | 379 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityCapsFailTime", |
| 382 base::Time::Now() - start_time_); | 380 base::Time::Now() - start_time_); |
| 383 waiting_for_reply_ = false; | 381 waiting_for_reply_ = false; |
| 384 client_message_loop_proxy_->PostTask( | 382 client_task_runner_->PostTask( |
| 385 FROM_HERE, | 383 FROM_HERE, |
| 386 base::Bind(&Client::OnGetPrinterCapsAndDefaults, client_.get(), false, | 384 base::Bind(&Client::OnGetPrinterCapsAndDefaults, client_.get(), false, |
| 387 printer_name, printing::PrinterCapsAndDefaults())); | 385 printer_name, printing::PrinterCapsAndDefaults())); |
| 388 } | 386 } |
| 389 | 387 |
| 390 void ServiceUtilityProcessHost::OnGetPrinterSemanticCapsAndDefaultsFailed( | 388 void ServiceUtilityProcessHost::OnGetPrinterSemanticCapsAndDefaultsFailed( |
| 391 const std::string& printer_name) { | 389 const std::string& printer_name) { |
| 392 DCHECK(waiting_for_reply_); | 390 DCHECK(waiting_for_reply_); |
| 393 ReportUmaEvent(SERVICE_UTILITY_SEMANTIC_CAPS_FAILED); | 391 ReportUmaEvent(SERVICE_UTILITY_SEMANTIC_CAPS_FAILED); |
| 394 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilitySemanticCapsFailTime", | 392 UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilitySemanticCapsFailTime", |
| 395 base::Time::Now() - start_time_); | 393 base::Time::Now() - start_time_); |
| 396 waiting_for_reply_ = false; | 394 waiting_for_reply_ = false; |
| 397 client_message_loop_proxy_->PostTask( | 395 client_task_runner_->PostTask( |
| 398 FROM_HERE, | 396 FROM_HERE, base::Bind(&Client::OnGetPrinterSemanticCapsAndDefaults, |
| 399 base::Bind(&Client::OnGetPrinterSemanticCapsAndDefaults, | 397 client_.get(), false, printer_name, |
| 400 client_.get(), false, printer_name, | 398 printing::PrinterSemanticCapsAndDefaults())); |
| 401 printing::PrinterSemanticCapsAndDefaults())); | |
| 402 } | 399 } |
| 403 | 400 |
| 404 bool ServiceUtilityProcessHost::Client::MetafileAvailable(float scale_factor, | 401 bool ServiceUtilityProcessHost::Client::MetafileAvailable(float scale_factor, |
| 405 base::File file) { | 402 base::File file) { |
| 406 file.Seek(base::File::FROM_BEGIN, 0); | 403 file.Seek(base::File::FROM_BEGIN, 0); |
| 407 int64 size = file.GetLength(); | 404 int64 size = file.GetLength(); |
| 408 if (size <= 0) { | 405 if (size <= 0) { |
| 409 OnRenderPDFPagesToMetafileDone(false); | 406 OnRenderPDFPagesToMetafileDone(false); |
| 410 return false; | 407 return false; |
| 411 } | 408 } |
| 412 std::vector<char> data(size); | 409 std::vector<char> data(size); |
| 413 if (file.ReadAtCurrentPos(data.data(), data.size()) != size) { | 410 if (file.ReadAtCurrentPos(data.data(), data.size()) != size) { |
| 414 OnRenderPDFPagesToMetafileDone(false); | 411 OnRenderPDFPagesToMetafileDone(false); |
| 415 return false; | 412 return false; |
| 416 } | 413 } |
| 417 printing::Emf emf; | 414 printing::Emf emf; |
| 418 if (!emf.InitFromData(data.data(), data.size())) { | 415 if (!emf.InitFromData(data.data(), data.size())) { |
| 419 OnRenderPDFPagesToMetafileDone(false); | 416 OnRenderPDFPagesToMetafileDone(false); |
| 420 return false; | 417 return false; |
| 421 } | 418 } |
| 422 OnRenderPDFPagesToMetafilePageDone(scale_factor, emf); | 419 OnRenderPDFPagesToMetafilePageDone(scale_factor, emf); |
| 423 return true; | 420 return true; |
| 424 } | 421 } |
| OLD | NEW |