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" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/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" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "cloud_print/gcp20/prototype/gcp20_switches.h" 19558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 20558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace { 21558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kDraftExpirationSec = 10; 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kLocalPrintJobExpirationSec = 20; 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kErrorTimeoutSec = 30; 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Errors simulation constants: 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const double kPaperJamProbability = 1.0; 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kTooManyDraftsTimeout = 10; 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const size_t kMaxDrafts = 5; 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochconst base::FilePath::CharType kJobsPath[] = FILE_PATH_LITERAL("printjobs"); 32558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ValidateTicket(const std::string& ticket) { 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::string GenerateId() { 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return base::StringToLowerASCII(base::GenerateGUID()); 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 41558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} // namespace 42558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct PrintJobHandler::LocalPrintJobExtended { 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJobExtended(const LocalPrintJob& job, const std::string& ticket) 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : data(job), 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ticket(ticket), 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) state(LocalPrintJob::STATE_DRAFT) {} 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJobExtended() : state(LocalPrintJob::STATE_DRAFT) {} 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ~LocalPrintJobExtended() {} 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob data; 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string ticket; 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob::State state; 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time expiration; 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct PrintJobHandler::LocalPrintJobDraft { 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJobDraft() {} 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJobDraft(const std::string& ticket, const base::Time& expiration) 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : ticket(ticket), 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) expiration(expiration) {} 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ~LocalPrintJobDraft() {} 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string ticket; 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time expiration; 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using base::StringPrintf; 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 70558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPrintJobHandler::PrintJobHandler() { 71558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 72558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 73558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPrintJobHandler::~PrintJobHandler() { 74558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 75558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)LocalPrintJob::CreateResult PrintJobHandler::CreatePrintJob( 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& ticket, 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* job_id_out, 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(maksymb): Use base::TimeDelta for timeout values 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* expires_in_out, 813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(maksymb): Use base::TimeDelta for timeout values 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* error_timeout_out, 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* error_description) { 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ValidateTicket(ticket)) 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::CREATE_INVALID_TICKET; 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Let's simulate at least some errors just for testing. 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (CommandLine::ForCurrentProcess()->HasSwitch( 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switches::kSimulatePrintingErrors)) { 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (base::RandDouble() <= kPaperJamProbability) { 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *error_description = "Paper jam, try again"; 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::CREATE_PRINTER_ERROR; 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (drafts.size() > kMaxDrafts) { // Another simulation of error: business 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *error_timeout_out = kTooManyDraftsTimeout; 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::CREATE_PRINTER_BUSY; 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string id = GenerateId(); 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) drafts[id] = LocalPrintJobDraft( 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ticket, 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time::Now() + base::TimeDelta::FromSeconds(kDraftExpirationSec)); 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FROM_HERE, 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&PrintJobHandler::ForgetDraft, AsWeakPtr(), id), 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TimeDelta::FromSeconds(kDraftExpirationSec)); 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *job_id_out = id; 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *expires_in_out = kDraftExpirationSec; 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::CREATE_SUCCESS; 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)LocalPrintJob::SaveResult PrintJobHandler::SaveLocalPrintJob( 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const LocalPrintJob& job, 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* job_id_out, 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* expires_in_out, 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* error_description_out, 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* timeout_out) { 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string id; 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int expires_in; 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (CreatePrintJob(std::string(), &id, &expires_in, 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) timeout_out, error_description_out)) { 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_INVALID_TICKET: 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_SUCCESS; 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_PRINTER_BUSY: 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_PRINTER_BUSY; 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_PRINTER_ERROR: 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_PRINTER_ERROR; 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_SUCCESS: 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *job_id_out = id; 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CompleteLocalPrintJob(job, id, expires_in_out, 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) error_description_out, timeout_out); 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_SUCCESS; 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)LocalPrintJob::SaveResult PrintJobHandler::CompleteLocalPrintJob( 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const LocalPrintJob& job, 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& job_id, 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* expires_in_out, 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* error_description_out, 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int* timeout_out) { 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!drafts.count(job_id)) { 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *timeout_out = kErrorTimeoutSec; 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_INVALID_PRINT_JOB; 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string file_extension; 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(maksymb): Gather together this type checking with Printer 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // supported types in kCdd. 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (job.content_type == "application/pdf") { 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) file_extension = "pdf"; 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (job.content_type == "image/pwg-raster") { 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) file_extension = "pwg"; 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (job.content_type == "image/jpeg") { 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) file_extension = "jpg"; 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) error_description_out->clear(); 1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_INVALID_DOCUMENT_TYPE; 1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CompleteDraft(job_id, job); 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::map<std::string, LocalPrintJobExtended>::iterator current_job = 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) jobs.find(job_id); 1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!SavePrintJob(current_job->second.data.content, 1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) current_job->second.ticket, 1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time::Now(), 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringPrintf("%s", job_id.c_str()), 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) current_job->second.data.job_name, file_extension)) { 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetJobState(job_id, LocalPrintJob::STATE_ABORTED); 1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *error_description_out = "IO error"; 1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_PRINTER_ERROR; 1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetJobState(job_id, LocalPrintJob::STATE_DONE); 1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *expires_in_out = static_cast<int>(GetJobExpiration(job_id).InSeconds()); 1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocalPrintJob::SAVE_SUCCESS; 1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool PrintJobHandler::GetJobState(const std::string& id, 1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob::Info* info_out) { 1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) using base::Time; 1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::map<std::string, LocalPrintJobDraft>::iterator draft = drafts.find(id); 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (draft != drafts.end()) { 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) info_out->state = LocalPrintJob::STATE_DRAFT; 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) info_out->expires_in = 1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static_cast<int>((draft->second.expiration - Time::Now()).InSeconds()); 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::map<std::string, LocalPrintJobExtended>::iterator job = jobs.find(id); 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (job != jobs.end()) { 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) info_out->state = job->second.state; 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) info_out->expires_in = static_cast<int>(GetJobExpiration(id).InSeconds()); 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool PrintJobHandler::SavePrintJob(const std::string& content, 212558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const std::string& ticket, 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::Time& create_time, 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& id, 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& title, 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& file_extension) { 217558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch VLOG(1) << "Printing printjob: \"" + title + "\""; 218558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::FilePath directory(kJobsPath); 219558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!base::DirectoryExists(directory) && 221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !base::CreateDirectory(directory)) { 222558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 223558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 224558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time::Exploded create_time_exploded; 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) create_time.UTCExplode(&create_time_exploded); 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::FilePath::StringType job_prefix = 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StringPrintf(FILE_PATH_LITERAL("%.4d%.2d%.2d-%.2d%.2d%.2d_"), 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.year, 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.month, 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.day_of_month, 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.hour, 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.minute, 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) create_time_exploded.second); 235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!base::CreateTemporaryDirInDir(directory, job_prefix, &directory)) { 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(WARNING) << "Cannot create directory for " << job_prefix; 237558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 238558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 239558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int written = base::WriteFile(directory.AppendASCII("ticket.xml"), 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ticket.data(), 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<int>(ticket.size())); 243558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (static_cast<size_t>(written) != ticket.size()) { 244558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch LOG(WARNING) << "Cannot save ticket."; 245558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 246558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 247558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) written = base::WriteFile( 2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) directory.AppendASCII("data." + file_extension), 2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content.data(), static_cast<int>(content.size())); 2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (static_cast<size_t>(written) != content.size()) { 252558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch LOG(WARNING) << "Cannot save data."; 253558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 254558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 255558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) VLOG(0) << "Job saved at " << directory.value(); 257558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return true; 258558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 259558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void PrintJobHandler::SetJobState(const std::string& id, 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob::State state) { 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!drafts.count(id)) << "Draft should be completed at first"; 2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::map<std::string, LocalPrintJobExtended>::iterator job = jobs.find(id); 2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(job != jobs.end()); 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) job->second.state = state; 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (state) { 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::STATE_DRAFT: 2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::STATE_ABORTED: 2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::STATE_DONE: 2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) job->second.expiration = 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time::Now() + 2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TimeDelta::FromSeconds(kLocalPrintJobExpirationSec); 2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FROM_HERE, 2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&PrintJobHandler::ForgetLocalJob, AsWeakPtr(), id), 2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TimeDelta::FromSeconds(kLocalPrintJobExpirationSec)); 2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void PrintJobHandler::CompleteDraft(const std::string& id, 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const LocalPrintJob& job) { 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::map<std::string, LocalPrintJobDraft>::iterator draft = drafts.find(id); 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (draft != drafts.end()) { 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) jobs[id] = LocalPrintJobExtended(job, draft->second.ticket); 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) drafts.erase(draft); 2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// TODO(maksymb): Use base::Time for expiration 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::TimeDelta PrintJobHandler::GetJobExpiration(const std::string& id) const { 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(jobs.count(id)); 2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Time expiration = jobs.at(id).expiration; 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (expiration.is_null()) 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return base::TimeDelta::FromSeconds(kLocalPrintJobExpirationSec); 3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return expiration - base::Time::Now(); 3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void PrintJobHandler::ForgetDraft(const std::string& id) { 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) drafts.erase(id); 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void PrintJobHandler::ForgetLocalJob(const std::string& id) { 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) jobs.erase(id); 3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 311