print_job_handler.cc revision f2477e01787aa58f445919b809d89e252beef54f
1558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// found in the LICENSE file. 4558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "cloud_print/gcp20/prototype/print_job_handler.h" 6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/bind.h" 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/command_line.h" 9558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/file_util.h" 103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/format_macros.h" 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/guid.h" 12558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/logging.h" 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/message_loop/message_loop.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/rand_util.h" 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/strings/string_util.h" 16558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/strings/stringprintf.h" 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/time/time.h" 18558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 19558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace { 20558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kDraftExpirationSec = 10; 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kLocalPrintJobExpirationSec = 20; 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kErrorTimeoutSec = 30; 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Errors simulation constants: 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const double kPaperJamProbability = 1.0; 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kTooManyDraftsTimeout = 10; 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const size_t kMaxDrafts = 5; 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 30558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochconst base::FilePath::CharType kJobsPath[] = FILE_PATH_LITERAL("printjobs"); 31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ValidateTicket(const std::string& ticket) { 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::string GenerateId() { 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return StringToLowerASCII(base::GenerateGUID()); 383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 40558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} // namespace 41558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct PrintJobHandler::LocalPrintJobExtended { 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJobExtended(const LocalPrintJob& job, const std::string& ticket) 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : data(job), 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ticket(ticket), 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) state(LocalPrintJob::STATE_DRAFT) {} 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJobExtended() : state(LocalPrintJob::STATE_DRAFT) {} 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ~LocalPrintJobExtended() {} 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob data; 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string ticket; 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob::State state; 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time expiration; 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct PrintJobHandler::LocalPrintJobDraft { 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJobDraft() {} 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJobDraft(const std::string& ticket, const base::Time& expiration) 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : ticket(ticket), 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) expiration(expiration) {} 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ~LocalPrintJobDraft() {} 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string ticket; 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time expiration; 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using base::StringPrintf; 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 69558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPrintJobHandler::PrintJobHandler() { 70558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 71558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 72558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPrintJobHandler::~PrintJobHandler() { 73558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 74558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)LocalPrintJob::CreateResult PrintJobHandler::CreatePrintJob( 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& ticket, 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* job_id_out, 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(maksymb): Use base::TimeDelta for timeout values 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* expires_in_out, 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(maksymb): Use base::TimeDelta for timeout values 813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* error_timeout_out, 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* error_description) { 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ValidateTicket(ticket)) 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::CREATE_INVALID_TICKET; 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Let's simulate at least some errors just for testing. 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch("simulate-printing-errors")) { 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (base::RandDouble() <= kPaperJamProbability) { 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *error_description = "Paper jam, try again"; 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::CREATE_PRINTER_ERROR; 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (drafts.size() > kMaxDrafts) { // Another simulation of error: business 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *error_timeout_out = kTooManyDraftsTimeout; 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::CREATE_PRINTER_BUSY; 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string id = GenerateId(); 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) drafts[id] = LocalPrintJobDraft( 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ticket, 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time::Now() + base::TimeDelta::FromSeconds(kDraftExpirationSec)); 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FROM_HERE, 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&PrintJobHandler::ForgetDraft, AsWeakPtr(), id), 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TimeDelta::FromSeconds(kDraftExpirationSec)); 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *job_id_out = id; 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *expires_in_out = kDraftExpirationSec; 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::CREATE_SUCCESS; 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)LocalPrintJob::SaveResult PrintJobHandler::SaveLocalPrintJob( 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const LocalPrintJob& job, 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* job_id_out, 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* expires_in_out, 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* error_description_out, 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* timeout_out) { 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string id; 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int expires_in; 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (CreatePrintJob(std::string(), &id, &expires_in, 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) timeout_out, error_description_out)) { 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_INVALID_TICKET: 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_SUCCESS; 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_PRINTER_BUSY: 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_PRINTER_BUSY; 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_PRINTER_ERROR: 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_PRINTER_ERROR; 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_SUCCESS: 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *job_id_out = id; 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CompleteLocalPrintJob(job, id, expires_in_out, 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) error_description_out, timeout_out); 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_SUCCESS; 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)LocalPrintJob::SaveResult PrintJobHandler::CompleteLocalPrintJob( 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const LocalPrintJob& job, 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& job_id, 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* expires_in_out, 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* error_description_out, 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* timeout_out) { 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!drafts.count(job_id)) { 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *timeout_out = kErrorTimeoutSec; 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_INVALID_PRINT_JOB; 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string file_extension; 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(maksymb): Gather together this type checking with Printer 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // supported types in kCdd. 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (job.content_type == "application/pdf") { 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) file_extension = "pdf"; 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (job.content_type == "image/pwg-raster") { 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) file_extension = "pwg"; 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (job.content_type == "image/jpeg") { 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) file_extension = "jpg"; 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) error_description_out->clear(); 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_INVALID_DOCUMENT_TYPE; 1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CompleteDraft(job_id, job); 1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::map<std::string, LocalPrintJobExtended>::iterator current_job = 1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) jobs.find(job_id); 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!SavePrintJob(current_job->second.data.content, 1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) current_job->second.ticket, 1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time::Now(), 1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringPrintf("%s", job_id.c_str()), 1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) current_job->second.data.job_name, file_extension)) { 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetJobState(job_id, LocalPrintJob::STATE_ABORTED); 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *error_description_out = "IO error"; 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_PRINTER_ERROR; 1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetJobState(job_id, LocalPrintJob::STATE_DONE); 1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *expires_in_out = static_cast<int>(GetJobExpiration(job_id).InSeconds()); 1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_SUCCESS; 1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool PrintJobHandler::GetJobState(const std::string& id, 1893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob::Info* info_out) { 1903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) using base::Time; 1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::map<std::string, LocalPrintJobDraft>::iterator draft = drafts.find(id); 1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (draft != drafts.end()) { 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) info_out->state = LocalPrintJob::STATE_DRAFT; 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) info_out->expires_in = 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static_cast<int>((draft->second.expiration - Time::Now()).InSeconds()); 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::map<std::string, LocalPrintJobExtended>::iterator job = jobs.find(id); 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (job != jobs.end()) { 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) info_out->state = job->second.state; 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) info_out->expires_in = static_cast<int>(GetJobExpiration(id).InSeconds()); 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool PrintJobHandler::SavePrintJob(const std::string& content, 210558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const std::string& ticket, 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::Time& create_time, 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& id, 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& title, 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& file_extension) { 215558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch VLOG(1) << "Printing printjob: \"" + title + "\""; 216558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::FilePath directory(kJobsPath); 217558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!base::DirectoryExists(directory) && 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !file_util::CreateDirectory(directory)) { 220558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 221558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 222558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time::Exploded create_time_exploded; 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) create_time.UTCExplode(&create_time_exploded); 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::FilePath::StringType job_prefix = 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StringPrintf(FILE_PATH_LITERAL("%.4d%.2d%.2d-%.2d%.2d%.2d_"), 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.year, 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.month, 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.day_of_month, 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.hour, 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.minute, 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.second); 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!file_util::CreateTemporaryDirInDir(directory, job_prefix, &directory)) { 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(WARNING) << "Cannot create directory for " << job_prefix; 235558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 236558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 237558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 238558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch int written = file_util::WriteFile(directory.AppendASCII("ticket.xml"), 239558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ticket.data(), 240558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch static_cast<int>(ticket.size())); 241558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (static_cast<size_t>(written) != ticket.size()) { 242558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch LOG(WARNING) << "Cannot save ticket."; 243558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 244558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 245558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) written = file_util::WriteFile( 2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) directory.AppendASCII("data." + file_extension), 2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content.data(), static_cast<int>(content.size())); 2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (static_cast<size_t>(written) != content.size()) { 250558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch LOG(WARNING) << "Cannot save data."; 251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 252558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 253558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(INFO) << "Job saved at " << directory.value(); 255558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return true; 256558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 257558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void PrintJobHandler::SetJobState(const std::string& id, 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob::State state) { 2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!drafts.count(id)) << "Draft should be completed at first"; 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::map<std::string, LocalPrintJobExtended>::iterator job = jobs.find(id); 2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(job != jobs.end()); 2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) job->second.state = state; 2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (state) { 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::STATE_DRAFT: 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::STATE_ABORTED: 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::STATE_DONE: 2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) job->second.expiration = 2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time::Now() + 2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TimeDelta::FromSeconds(kLocalPrintJobExpirationSec); 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FROM_HERE, 2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&PrintJobHandler::ForgetLocalJob, AsWeakPtr(), id), 2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TimeDelta::FromSeconds(kLocalPrintJobExpirationSec)); 2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void PrintJobHandler::CompleteDraft(const std::string& id, 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const LocalPrintJob& job) { 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::map<std::string, LocalPrintJobDraft>::iterator draft = drafts.find(id); 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (draft != drafts.end()) { 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) jobs[id] = LocalPrintJobExtended(job, draft->second.ticket); 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) drafts.erase(draft); 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// TODO(maksymb): Use base::Time for expiration 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::TimeDelta PrintJobHandler::GetJobExpiration(const std::string& id) const { 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(jobs.count(id)); 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time expiration = jobs.at(id).expiration; 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (expiration.is_null()) 2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return base::TimeDelta::FromSeconds(kLocalPrintJobExpirationSec); 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return expiration - base::Time::Now(); 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void PrintJobHandler::ForgetDraft(const std::string& id) { 3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) drafts.erase(id); 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void PrintJobHandler::ForgetLocalJob(const std::string& id) { 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) jobs.erase(id); 3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 309