printer_query.cc revision f2477e01787aa58f445919b809d89e252beef54f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/printing/printer_query.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/printing/print_job_worker.h" 138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/printing/printing_ui_web_contents_observer.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace printing { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrinterQuery::PrinterQuery() 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : io_message_loop_(base::MessageLoop::current()), 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) worker_(new PrintJobWorker(this)), 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_print_dialog_box_shown_(false), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookie_(PrintSettings::NewCookie()), 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_status_(PrintingContext::FAILED) { 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(io_message_loop_->type(), base::MessageLoop::TYPE_IO); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrinterQuery::~PrinterQuery() { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The job should be finished (or at least canceled) when it is destroyed. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_print_dialog_box_shown_); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this fires, it is that this pending printer context has leaked. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!worker_.get()); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrinterQuery::GetSettingsDone(const PrintSettings& new_settings, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintingContext::Result result) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_print_dialog_box_shown_ = false; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_status_ = result; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != PrintingContext::FAILED) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings_ = new_settings; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookie_ = PrintSettings::NewCookie(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Failure. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookie_ = 0; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback_.is_null()) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This may cause reentrancy like to call StopWorker(). 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Reset(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintJobWorker* PrinterQuery::DetachWorker(PrintJobWorkerOwner* new_owner) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(callback_.is_null()); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(worker_.get()); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->SetNewOwner(new_owner); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return worker_.release(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::MessageLoop* PrinterQuery::message_loop() { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return io_message_loop_; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PrintSettings& PrinterQuery::settings() const { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return settings_; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PrinterQuery::cookie() const { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cookie_; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PrinterQuery::GetSettings( 738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetSettingsAskParam ask_user_for_settings, 748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<PrintingUIWebContentsObserver> web_contents_observer, 758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int expected_page_count, 768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool has_selection, 778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MarginType margin_type, 788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const base::Closure& callback) { 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(io_message_loop_, base::MessageLoop::current()); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_print_dialog_box_shown_); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartWorker(callback); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Real work is done in PrintJobWorker::GetSettings(). 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_print_dialog_box_shown_ = ask_user_for_settings == ASK_USER; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->message_loop()->PostTask( 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PrintJobWorker::GetSettings, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(worker_.get()), 908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) is_print_dialog_box_shown_, 918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Passed(&web_contents_observer), 928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) expected_page_count, 938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) has_selection, 948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) margin_type)); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrinterQuery::SetSettings(const DictionaryValue& new_settings, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartWorker(callback); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->message_loop()->PostTask( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PrintJobWorker::SetSettings, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(worker_.get()), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_settings.DeepCopy())); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrinterQuery::SetWorkerDestination( 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintDestinationInterface* destination) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->SetPrintDestination(destination); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrinterQuery::StartWorker(const base::Closure& callback) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(callback_.is_null()); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(worker_.get()); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Lazily create the worker thread. There is one worker thread per print job. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!worker_->message_loop()) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->Start(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_ = callback; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrinterQuery::StopWorker() { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (worker_.get()) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/66082: We're blocking on the PrinterQuery's worker 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread. It's not clear to me if this may result in blocking the current 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread for an unacceptable time. We should probably fix it. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->Stop(); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_.reset(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrinterQuery::is_callback_pending() const { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !callback_.is_null(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrinterQuery::is_valid() const { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return worker_.get() != NULL; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace printing 144