printer_query.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/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" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace printing { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrinterQuery::PrinterQuery() 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : io_message_loop_(base::MessageLoop::current()), 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) worker_(new PrintJobWorker(this)), 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_print_dialog_box_shown_(false), 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookie_(PrintSettings::NewCookie()), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_status_(PrintingContext::FAILED) { 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(io_message_loop_->type(), base::MessageLoop::TYPE_IO); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrinterQuery::~PrinterQuery() { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The job should be finished (or at least canceled) when it is destroyed. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_print_dialog_box_shown_); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this fires, it is that this pending printer context has leaked. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!worker_.get()); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrinterQuery::GetSettingsDone(const PrintSettings& new_settings, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintingContext::Result result) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_print_dialog_box_shown_ = false; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_status_ = result; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != PrintingContext::FAILED) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings_ = new_settings; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookie_ = PrintSettings::NewCookie(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Failure. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookie_ = 0; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback_.is_null()) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This may cause reentrancy like to call StopWorker(). 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Reset(); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintJobWorker* PrinterQuery::DetachWorker(PrintJobWorkerOwner* new_owner) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(callback_.is_null()); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(worker_.get()); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->SetNewOwner(new_owner); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return worker_.release(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::MessageLoop* PrinterQuery::message_loop() { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return io_message_loop_; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PrintSettings& PrinterQuery::settings() const { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return settings_; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PrinterQuery::cookie() const { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cookie_; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrinterQuery::GetSettings(GetSettingsAskParam ask_user_for_settings, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeView parent_view, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int expected_page_count, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_selection, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarginType margin_type, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback) { 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(io_message_loop_, base::MessageLoop::current()); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_print_dialog_box_shown_); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartWorker(callback); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Real work is done in PrintJobWorker::Init(). 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_print_dialog_box_shown_ = ask_user_for_settings == ASK_USER; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->message_loop()->PostTask( 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PrintJobWorker::GetSettings, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(worker_.get()), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_print_dialog_box_shown_, parent_view, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_page_count, has_selection, margin_type)); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrinterQuery::SetSettings(const DictionaryValue& new_settings, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartWorker(callback); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->message_loop()->PostTask( 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PrintJobWorker::SetSettings, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(worker_.get()), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_settings.DeepCopy())); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrinterQuery::SetWorkerDestination( 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintDestinationInterface* destination) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->SetPrintDestination(destination); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrinterQuery::StartWorker(const base::Closure& callback) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(callback_.is_null()); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(worker_.get()); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Lazily create the worker thread. There is one worker thread per print job. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!worker_->message_loop()) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->Start(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_ = callback; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrinterQuery::StopWorker() { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (worker_.get()) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/66082: We're blocking on the PrinterQuery's worker 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread. It's not clear to me if this may result in blocking the current 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread for an unacceptable time. We should probably fix it. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->Stop(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_.reset(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrinterQuery::is_callback_pending() const { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !callback_.is_null(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrinterQuery::is_valid() const { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return worker_.get() != NULL; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace printing 139