Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: cloud_print/gcp20/prototype/print_job_handler.cc

Issue 23271004: GCP2.0 Device: Adding advanced printing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@local-printing
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cloud_print/gcp20/prototype/print_job_handler.h ('k') | cloud_print/gcp20/prototype/printer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cloud_print/gcp20/prototype/print_job_handler.cc
diff --git a/cloud_print/gcp20/prototype/print_job_handler.cc b/cloud_print/gcp20/prototype/print_job_handler.cc
index 7c285607faafa4389f6152d7bc742c063126892b..7bbc1af701e83ced8dc6703df0ae59418dd19408 100644
--- a/cloud_print/gcp20/prototype/print_job_handler.cc
+++ b/cloud_print/gcp20/prototype/print_job_handler.cc
@@ -4,22 +4,66 @@
#include "cloud_print/gcp20/prototype/print_job_handler.h"
+#include "base/bind.h"
+#include "base/command_line.h"
#include "base/file_util.h"
#include "base/format_macros.h"
#include "base/guid.h"
#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "base/rand_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
namespace {
-const int kLocalPrintJobInitExpiration = 5*60; // in seconds
+const int kDraftExpirationSec = 10;
+const int kLocalPrintJobExpirationSec = 20;
+const int kErrorTimeoutSec = 30;
+
+// Errors simulation constants:
+const double kPaperJamProbability = 0.2;
+const int kTooManyDraftsTimeout = 10;
+const int kMaxDrafts = 5;
const base::FilePath::CharType kJobsPath[] = FILE_PATH_LITERAL("printjobs");
+bool ValidateTicket(const std::string& ticket) {
+ return true;
+}
+
+std::string GenerateId() {
+ return StringToLowerASCII(base::GenerateGUID());
+}
+
} // namespace
+struct PrintJobHandler::LocalPrintJobExtended {
+ LocalPrintJobExtended(const LocalPrintJob& job, const std::string& ticket)
+ : data(job),
+ ticket(ticket),
+ state(LocalPrintJob::STATE_DRAFT) {}
+ LocalPrintJobExtended() : state(LocalPrintJob::STATE_DRAFT) {}
+ ~LocalPrintJobExtended() {}
+
+ LocalPrintJob data;
+ std::string ticket;
+ LocalPrintJob::State state;
+ base::Time expiration;
+};
+
+struct PrintJobHandler::LocalPrintJobDraft {
+ LocalPrintJobDraft() {}
+ LocalPrintJobDraft(const std::string& ticket, const base::Time& expiration)
+ : ticket(ticket),
+ expiration(expiration) {}
+ ~LocalPrintJobDraft() {}
+
+ std::string ticket;
+ base::Time expiration;
+};
+
using base::StringPrintf;
PrintJobHandler::PrintJobHandler() {
@@ -28,11 +72,87 @@ PrintJobHandler::PrintJobHandler() {
PrintJobHandler::~PrintJobHandler() {
}
+LocalPrintJob::CreateResult PrintJobHandler::CreatePrintJob(
+ const std::string& ticket,
+ std::string* job_id_out,
+ // TODO(maksymb): Use base::TimeDelta for timeout values
+ int* expires_in_out,
+ // TODO(maksymb): Use base::TimeDelta for timeout values
+ int* error_timeout_out,
+ std::string* error_description) {
+ if (!ValidateTicket(ticket))
+ return LocalPrintJob::CREATE_INVALID_TICKET;
+
+ // Let's simulate at least some errors just for testing.
+ if (CommandLine::ForCurrentProcess()->HasSwitch("simulate-printing-errors")) {
+ if (base::RandDouble() <= kPaperJamProbability) {
+ *error_description = "Paper jam, try again";
+ return LocalPrintJob::CREATE_PRINTER_ERROR;
+ }
+
+ if (drafts.size() > kMaxDrafts) { // Another simulation of error: business
+ *error_timeout_out = kTooManyDraftsTimeout;
+ return LocalPrintJob::CREATE_PRINTER_BUSY;
+ }
+ }
+
+ std::string id = GenerateId();
+ drafts[id] = LocalPrintJobDraft(
+ ticket,
+ base::Time::Now() + base::TimeDelta::FromSeconds(kDraftExpirationSec));
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&PrintJobHandler::ForgetDraft, AsWeakPtr(), id),
+ base::TimeDelta::FromSeconds(kDraftExpirationSec));
+
+ *job_id_out = id;
+ *expires_in_out = kDraftExpirationSec;
+ return LocalPrintJob::CREATE_SUCCESS;
+}
+
LocalPrintJob::SaveResult PrintJobHandler::SaveLocalPrintJob(
const LocalPrintJob& job,
- std::string* job_id,
- std::string* error_description,
- int* timeout) {
+ std::string* job_id_out,
+ int* expires_in_out,
+ std::string* error_description_out,
+ int* timeout_out) {
+ std::string id;
+ int expires_in;
+
+ switch (CreatePrintJob(std::string(), &id, &expires_in,
+ timeout_out, error_description_out)) {
+ case LocalPrintJob::CREATE_INVALID_TICKET:
+ NOTREACHED();
+ return LocalPrintJob::SAVE_SUCCESS;
+
+ case LocalPrintJob::CREATE_PRINTER_BUSY:
+ return LocalPrintJob::SAVE_PRINTER_BUSY;
+
+ case LocalPrintJob::CREATE_PRINTER_ERROR:
+ return LocalPrintJob::SAVE_PRINTER_ERROR;
+
+ case LocalPrintJob::CREATE_SUCCESS:
+ *job_id_out = id;
+ return CompleteLocalPrintJob(job, id, expires_in_out,
+ error_description_out, timeout_out);
+
+ default:
+ NOTREACHED();
+ return LocalPrintJob::SAVE_SUCCESS;
+ }
+}
+
+LocalPrintJob::SaveResult PrintJobHandler::CompleteLocalPrintJob(
+ const LocalPrintJob& job,
+ const std::string& job_id,
+ int* expires_in_out,
+ std::string* error_description_out,
+ int* timeout_out) {
+ if (!drafts.count(job_id)) {
+ *timeout_out = kErrorTimeoutSec;
+ return LocalPrintJob::SAVE_INVALID_PRINT_JOB;
+ }
+
std::string suffix = StringPrintf("%s:%s",
job.user_name.c_str(),
job.client_name.c_str());
@@ -46,23 +166,50 @@ LocalPrintJob::SaveResult PrintJobHandler::SaveLocalPrintJob(
} else if (job.content_type == "image/jpeg") {
file_extension = "jpg";
} else {
- error_description->clear();
+ error_description_out->clear();
return LocalPrintJob::SAVE_INVALID_DOCUMENT_TYPE;
}
+ CompleteDraft(job_id, job);
+ std::map<std::string, LocalPrintJobExtended>::iterator current_job =
+ jobs.find(job_id);
- std::string id = StringToLowerASCII(base::GenerateGUID());
- if (!SavePrintJob(job.content, std::string(),
- base::Time::Now(),
- StringPrintf("%s", id.c_str()),
- suffix, job.job_name, file_extension)) {
- *error_description = "IO error";
+ if (!SavePrintJob(current_job->second.data.content,
+ current_job->second.ticket,
+ base::Time::Now(),
+ StringPrintf("%s", job_id.c_str()),
+ suffix,
+ current_job->second.data.job_name, file_extension)) {
+ SetJobState(job_id, LocalPrintJob::STATE_ABORTED);
+ *error_description_out = "IO error";
return LocalPrintJob::SAVE_PRINTER_ERROR;
}
- *job_id = id;
+ SetJobState(job_id, LocalPrintJob::STATE_DONE);
+ *expires_in_out = static_cast<int>(GetJobExpiration(job_id).InSeconds());
return LocalPrintJob::SAVE_SUCCESS;
}
+bool PrintJobHandler::GetJobState(const std::string& id,
+ LocalPrintJob::Info* info_out) {
+ using base::Time;
+
+ std::map<std::string, LocalPrintJobDraft>::iterator draft = drafts.find(id);
+ if (draft != drafts.end()) {
+ info_out->state = LocalPrintJob::STATE_DRAFT;
+ info_out->expires_in =
+ static_cast<int>((draft->second.expiration - Time::Now()).InSeconds());
+ return true;
+ }
+
+ std::map<std::string, LocalPrintJobExtended>::iterator job = jobs.find(id);
+ if (job != jobs.end()) {
+ info_out->state = job->second.state;
+ info_out->expires_in = static_cast<int>(GetJobExpiration(id).InSeconds());
+ return true;
+ }
+ return false;
+}
+
bool PrintJobHandler::SavePrintJob(const std::string& content,
const std::string& ticket,
const base::Time& create_time,
@@ -123,3 +270,55 @@ bool PrintJobHandler::SavePrintJob(const std::string& content,
return true;
}
+void PrintJobHandler::SetJobState(const std::string& id,
+ LocalPrintJob::State state) {
+ DCHECK(!drafts.count(id)) << "Draft should be completed at first";
+
+ std::map<std::string, LocalPrintJobExtended>::iterator job = jobs.find(id);
+ DCHECK(job != jobs.end());
+ job->second.state = state;
+ switch (state) {
+ case LocalPrintJob::STATE_DRAFT:
+ NOTREACHED();
+ break;
+ case LocalPrintJob::STATE_ABORTED:
+ case LocalPrintJob::STATE_DONE:
+ job->second.expiration =
+ base::Time::Now() +
+ base::TimeDelta::FromSeconds(kLocalPrintJobExpirationSec);
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&PrintJobHandler::ForgetLocalJob, AsWeakPtr(), id),
+ base::TimeDelta::FromSeconds(kLocalPrintJobExpirationSec));
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void PrintJobHandler::CompleteDraft(const std::string& id,
+ const LocalPrintJob& job) {
+ std::map<std::string, LocalPrintJobDraft>::iterator draft = drafts.find(id);
+ if (draft != drafts.end()) {
+ jobs[id] = LocalPrintJobExtended(job, draft->second.ticket);
+ drafts.erase(draft);
+ }
+}
+
+// TODO(maksymb): Use base::Time for expiration
+base::TimeDelta PrintJobHandler::GetJobExpiration(const std::string& id) const {
+ DCHECK(jobs.count(id));
+ base::Time expiration = jobs.at(id).expiration;
+ if (expiration.is_null())
+ return base::TimeDelta::FromSeconds(kLocalPrintJobExpirationSec);
+ return expiration - base::Time::Now();
+}
+
+void PrintJobHandler::ForgetDraft(const std::string& id) {
+ drafts.erase(id);
+}
+
+void PrintJobHandler::ForgetLocalJob(const std::string& id) {
+ jobs.erase(id);
+}
+
« no previous file with comments | « cloud_print/gcp20/prototype/print_job_handler.h ('k') | cloud_print/gcp20/prototype/printer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698