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"
9 #include "content/public/browser/browser_thread.h"
10 #include "extensions/browser/extension_system.h"
12 using content::BrowserThread
;
16 const char kScannerNotAvailable
[] = "Scanner not available";
17 const char kUserGestureRequiredError
[] =
18 "User gesture required to perform scan";
22 namespace extensions
{
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());
40 void DocumentScanScanFunction::AsyncWorkStart() {
41 if (!user_gesture()) {
42 error_
= kUserGestureRequiredError
;
47 // Add a reference, which is balanced in OnScannerListReceived to keep the
48 // object around and allow the callback to be invoked.
51 document_scan_interface_
->ListScanners(
52 base::Bind(&DocumentScanScanFunction::OnScannerListReceived
,
53 base::Unretained(this)));
56 void DocumentScanScanFunction::OnScannerListReceived(
57 const std::vector
<DocumentScanInterface::ScannerDescription
>&
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()) {
77 if (scanner_i
== scanner_descriptions
.end()) {
78 error_
= kScannerNotAvailable
;
81 // Balance the AddRef in AsyncWorkStart().
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.
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
);
112 AsyncWorkCompleted();
114 // Balance the AddRef in AsyncWorkStart().
118 bool DocumentScanScanFunction::Respond() {
119 return error_
.empty();
124 } // namespace extensions