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