1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/document_scan/document_scan_api.h"
#include <algorithm>
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/extension_system.h"
using content::BrowserThread;
namespace {
const char kScannerNotAvailable[] = "Scanner not available";
const char kUserGestureRequiredError[] =
"User gesture required to perform scan";
} // namespace
namespace extensions {
namespace api {
DocumentScanScanFunction::DocumentScanScanFunction()
: document_scan_interface_(DocumentScanInterface::CreateInstance()) {}
DocumentScanScanFunction::~DocumentScanScanFunction() {}
bool DocumentScanScanFunction::Prepare() {
set_work_thread_id(BrowserThread::FILE);
params_ = document_scan::Scan::Params::Create(*args_);
EXTENSION_FUNCTION_VALIDATE(params_.get());
return true;
}
void DocumentScanScanFunction::AsyncWorkStart() {
if (!user_gesture()) {
error_ = kUserGestureRequiredError;
AsyncWorkCompleted();
return;
}
// Add a reference, which is balanced in OnScannerListReceived to keep the
// object around and allow the callback to be invoked.
AddRef();
document_scan_interface_->ListScanners(
base::Bind(&DocumentScanScanFunction::OnScannerListReceived,
base::Unretained(this)));
}
void DocumentScanScanFunction::OnScannerListReceived(
const std::vector<DocumentScanInterface::ScannerDescription>&
scanner_descriptions,
const std::string& error) {
std::vector<DocumentScanInterface::ScannerDescription>::const_iterator
scanner_i = scanner_descriptions.begin();
// If no |scanner_descriptions| is empty, this is an error. If no
// MIME types are specified, the first scanner is chosen. If MIME
// types are specified, the first scanner that supports one of these
// MIME types is selected.
if (params_->options.mime_types) {
std::vector<std::string>& mime_types = *params_->options.mime_types.get();
for (; scanner_i != scanner_descriptions.end(); ++scanner_i) {
if (std::find(mime_types.begin(), mime_types.end(),
scanner_i->image_mime_type) != mime_types.end()) {
break;
}
}
}
if (scanner_i == scanner_descriptions.end()) {
error_ = kScannerNotAvailable;
AsyncWorkCompleted();
// Balance the AddRef in AsyncWorkStart().
Release();
return;
}
// TODO(pstew): Call a delegate method here to select a scanner and options.
document_scan_interface_->Scan(
scanner_i->name,
DocumentScanInterface::kScanModeColor,
0,
base::Bind(&DocumentScanScanFunction::OnResultsReceived,
base::Unretained(this)));
}
void DocumentScanScanFunction::OnResultsReceived(
const std::string& scanned_image,
const std::string& mime_type,
const std::string& error) {
// TODO(pstew): Enlist a delegate to display received scan in the UI
// and confirm that this scan should be sent to the caller. If this
// is a multi-page scan, provide a means for adding additional scanned
// images up to the requested limit.
if (error.empty()) {
document_scan::ScanResults scan_results;
if (!scanned_image.empty()) {
scan_results.data_urls.push_back(scanned_image);
}
scan_results.mime_type = mime_type;
results_ = document_scan::Scan::Results::Create(scan_results);
}
error_ = error;
AsyncWorkCompleted();
// Balance the AddRef in AsyncWorkStart().
Release();
}
bool DocumentScanScanFunction::Respond() {
return error_.empty();
}
} // namespace api
} // namespace extensions
|