[M87] scanning: Add page number to page callback

Add the page number to the page callback so that ScanService can include
it in filenames when saving scanned images.

(cherry picked from commit 8db6ec01cc43c20c8df8b9e6c4ef6fd6f86e5c44)

Tbr: [email protected]
Bug: 1059779
Change-Id: I3085b6e180d0d60e8afc85be071d6370a08c2573
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2445670
Commit-Queue: Jesse Schettler <[email protected]>
Reviewed-by: Steven Bennetts <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#813825}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2459511
Reviewed-by: Jesse Schettler <[email protected]>
Cr-Commit-Position: refs/branch-heads/4280@{#125}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/chrome/browser/chromeos/extensions/document_scan/document_scan_api.cc b/chrome/browser/chromeos/extensions/document_scan/document_scan_api.cc
index 0927d22..c7e5ff3 100644
--- a/chrome/browser/chromeos/extensions/document_scan/document_scan_api.cc
+++ b/chrome/browser/chromeos/extensions/document_scan/document_scan_api.cc
@@ -85,7 +85,8 @@
           base::BindOnce(&DocumentScanScanFunction::OnScanCompleted, this));
 }
 
-void DocumentScanScanFunction::OnPageReceived(std::string scanned_image) {
+void DocumentScanScanFunction::OnPageReceived(std::string scanned_image,
+                                              uint32_t /*page_number*/) {
   // Take only the first page of the scan.
   if (!scan_data_.has_value()) {
     scan_data_ = std::move(scanned_image);
diff --git a/chrome/browser/chromeos/extensions/document_scan/document_scan_api.h b/chrome/browser/chromeos/extensions/document_scan/document_scan_api.h
index f423596..c6e1b11b 100644
--- a/chrome/browser/chromeos/extensions/document_scan/document_scan_api.h
+++ b/chrome/browser/chromeos/extensions/document_scan/document_scan_api.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_DOCUMENT_SCAN_DOCUMENT_SCAN_API_H_
 #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_DOCUMENT_SCAN_DOCUMENT_SCAN_API_H_
 
+#include <cstdint>
 #include <memory>
 #include <string>
 #include <vector>
@@ -34,7 +35,7 @@
   friend class DocumentScanScanFunctionTest;
 
   void OnNamesReceived(std::vector<std::string> scanner_names);
-  void OnPageReceived(std::string scanned_image);
+  void OnPageReceived(std::string scanned_image, uint32_t /*page_number*/);
   void OnScanCompleted(bool success);
 
   base::Optional<std::string> scan_data_;
diff --git a/chrome/browser/chromeos/scanning/fake_lorgnette_scanner_manager.cc b/chrome/browser/chromeos/scanning/fake_lorgnette_scanner_manager.cc
index 2939cf3..39018988 100644
--- a/chrome/browser/chromeos/scanning/fake_lorgnette_scanner_manager.cc
+++ b/chrome/browser/chromeos/scanning/fake_lorgnette_scanner_manager.cc
@@ -36,7 +36,8 @@
                                        ScanCallback callback) {
   if (scan_data_.has_value()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(page_callback, scan_data_.value()));
+        FROM_HERE,
+        base::BindOnce(page_callback, scan_data_.value(), /*page_number=*/0));
   }
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
diff --git a/chrome/browser/chromeos/scanning/lorgnette_scanner_manager.h b/chrome/browser/chromeos/scanning/lorgnette_scanner_manager.h
index c152484c..6d0dd94c 100644
--- a/chrome/browser/chromeos/scanning/lorgnette_scanner_manager.h
+++ b/chrome/browser/chromeos/scanning/lorgnette_scanner_manager.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_CHROMEOS_SCANNING_LORGNETTE_SCANNER_MANAGER_H_
 #define CHROME_BROWSER_CHROMEOS_SCANNING_LORGNETTE_SCANNER_MANAGER_H_
 
+#include <cstdint>
 #include <memory>
 #include <string>
 #include <vector>
@@ -27,7 +28,8 @@
       base::OnceCallback<void(std::vector<std::string> scanner_names)>;
   using GetScannerCapabilitiesCallback = base::OnceCallback<void(
       const base::Optional<lorgnette::ScannerCapabilities>& capabilities)>;
-  using PageCallback = base::RepeatingCallback<void(std::string scan_data)>;
+  using PageCallback = base::RepeatingCallback<void(std::string scan_data,
+                                                    uint32_t page_number)>;
   using ScanCallback = base::OnceCallback<void(bool success)>;
 
   ~LorgnetteScannerManager() override = default;
diff --git a/chrome/browser/chromeos/scanning/lorgnette_scanner_manager_unittest.cc b/chrome/browser/chromeos/scanning/lorgnette_scanner_manager_unittest.cc
index c975077..e6e1d8e 100644
--- a/chrome/browser/chromeos/scanning/lorgnette_scanner_manager_unittest.cc
+++ b/chrome/browser/chromeos/scanning/lorgnette_scanner_manager_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/chromeos/scanning/lorgnette_scanner_manager.h"
 
+#include <cstdint>
 #include <memory>
 #include <string>
 #include <utility>
@@ -209,7 +210,9 @@
   }
 
   // Handles receiving a page from LorgnetteScannerManager::Scan().
-  void PageCallback(std::string page_data) { scan_data_.push_back(page_data); }
+  void PageCallback(std::string page_data, uint32_t /*page_number*/) {
+    scan_data_.push_back(page_data);
+  }
 
   // Handles completion of LorgnetteScannerManager::Scan().
   void ScanCallback(bool success) {
diff --git a/chrome/browser/chromeos/scanning/scan_service.cc b/chrome/browser/chromeos/scanning/scan_service.cc
index 3b2b641..d1d01bb 100644
--- a/chrome/browser/chromeos/scanning/scan_service.cc
+++ b/chrome/browser/chromeos/scanning/scan_service.cc
@@ -59,6 +59,7 @@
   if (scanner_name.empty())
     std::move(callback).Run(false);
 
+  base::Time::Now().UTCExplode(&start_time_);
   save_failed_ = false;
 
   // TODO(jschettler): Create a TypeConverter to convert from
@@ -118,13 +119,13 @@
       mojo::ConvertTo<mojo_ipc::ScannerCapabilitiesPtr>(capabilities.value()));
 }
 
-void ScanService::OnPageReceived(std::string scanned_image) {
-  // TODO(jschettler): Add page number to filename.
-  base::Time::Exploded time;
-  base::Time::Now().UTCExplode(&time);
+void ScanService::OnPageReceived(std::string scanned_image,
+                                 uint32_t page_number) {
+  // The |page_number| is 0-indexed.
   const std::string filename = base::StringPrintf(
-      "scan_%02d%02d%02d-%02d%02d%02d.png", time.year, time.month,
-      time.day_of_month, time.hour, time.minute, time.second);
+      "scan_%02d%02d%02d-%02d%02d%02d_page_%d.png", start_time_.year,
+      start_time_.month, start_time_.day_of_month, start_time_.hour,
+      start_time_.minute, start_time_.second, page_number + 1);
   const auto file_path = root_dir_.Append(kMyFilesPath).Append(filename);
   if (!base::WriteFile(file_path, scanned_image)) {
     LOG(ERROR) << "Failed to save scanned image: " << file_path.value().c_str();
diff --git a/chrome/browser/chromeos/scanning/scan_service.h b/chrome/browser/chromeos/scanning/scan_service.h
index 30f0acb..1fdd2bf7 100644
--- a/chrome/browser/chromeos/scanning/scan_service.h
+++ b/chrome/browser/chromeos/scanning/scan_service.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_H_
 #define CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_H_
 
+#include <cstdint>
 #include <string>
 #include <vector>
 
@@ -12,6 +13,7 @@
 #include "base/files/file_path.h"
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
+#include "base/time/time.h"
 #include "base/unguessable_token.h"
 #include "chromeos/components/scanning/mojom/scanning.mojom.h"
 #include "chromeos/dbus/lorgnette/lorgnette_service.pb.h"
@@ -65,7 +67,7 @@
 
   // Processes each |scanned_image| received after calling
   // LorgnetteScannerManager::Scan().
-  void OnPageReceived(std::string scanned_image);
+  void OnPageReceived(std::string scanned_image, uint32_t page_number);
 
   // Processes the final result of calling LorgnetteScannerManager::Scan().
   void OnScanCompleted(ScanCallback callback, bool success);
@@ -92,6 +94,9 @@
   // Indicates whether there was a failure to save scanned images.
   bool save_failed_;
 
+  // The time a scan was started. Used in filenames when saving scanned images.
+  base::Time::Exploded start_time_;
+
   base::WeakPtrFactory<ScanService> weak_ptr_factory_{this};
 };
 
diff --git a/chromeos/dbus/fake_lorgnette_manager_client.cc b/chromeos/dbus/fake_lorgnette_manager_client.cc
index 52dcd811..af1b968 100644
--- a/chromeos/dbus/fake_lorgnette_manager_client.cc
+++ b/chromeos/dbus/fake_lorgnette_manager_client.cc
@@ -37,9 +37,10 @@
     const std::string& device_name,
     const lorgnette::ScanSettings& settings,
     VoidDBusMethodCallback completion_callback,
-    base::RepeatingCallback<void(std::string)> page_callback,
+    base::RepeatingCallback<void(std::string, uint32_t)> page_callback,
     base::RepeatingCallback<void(int)> progress_callback) {
   if (scan_response_.has_value()) {
+    uint32_t page_number = 0;
     for (const std::string& page_data : scan_response_.value()) {
       // Simulate progress reporting for the scan job.
       if (progress_callback) {
@@ -50,7 +51,7 @@
       }
 
       base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::BindOnce(page_callback, page_data));
+          FROM_HERE, base::BindOnce(page_callback, page_data, ++page_number));
     }
   }
 
diff --git a/chromeos/dbus/fake_lorgnette_manager_client.h b/chromeos/dbus/fake_lorgnette_manager_client.h
index 5977a8a0..c074597 100644
--- a/chromeos/dbus/fake_lorgnette_manager_client.h
+++ b/chromeos/dbus/fake_lorgnette_manager_client.h
@@ -5,6 +5,7 @@
 #ifndef CHROMEOS_DBUS_FAKE_LORGNETTE_MANAGER_CLIENT_H_
 #define CHROMEOS_DBUS_FAKE_LORGNETTE_MANAGER_CLIENT_H_
 
+#include <cstdint>
 #include <string>
 #include <vector>
 
@@ -30,11 +31,12 @@
   void GetScannerCapabilities(
       const std::string& device_name,
       DBusMethodCallback<lorgnette::ScannerCapabilities> callback) override;
-  void StartScan(const std::string& device_name,
-                 const lorgnette::ScanSettings& settings,
-                 VoidDBusMethodCallback completion_callback,
-                 base::RepeatingCallback<void(std::string)> page_callback,
-                 base::RepeatingCallback<void(int)> progress_callback) override;
+  void StartScan(
+      const std::string& device_name,
+      const lorgnette::ScanSettings& settings,
+      VoidDBusMethodCallback completion_callback,
+      base::RepeatingCallback<void(std::string, uint32_t)> page_callback,
+      base::RepeatingCallback<void(int)> progress_callback) override;
 
   // Sets the response returned by ListScanners().
   void SetListScannersResponse(
diff --git a/chromeos/dbus/lorgnette_manager_client.cc b/chromeos/dbus/lorgnette_manager_client.cc
index f49a3fe..e8fdca06 100644
--- a/chromeos/dbus/lorgnette_manager_client.cc
+++ b/chromeos/dbus/lorgnette_manager_client.cc
@@ -70,7 +70,7 @@
       const std::string& device_name,
       const lorgnette::ScanSettings& settings,
       VoidDBusMethodCallback completion_callback,
-      base::RepeatingCallback<void(std::string)> page_callback,
+      base::RepeatingCallback<void(std::string, uint32_t)> page_callback,
       base::RepeatingCallback<void(int)> progress_callback) override {
     lorgnette::StartScanRequest request;
     request.set_device_name(device_name);
@@ -185,7 +185,7 @@
   struct ScanJobState {
     VoidDBusMethodCallback completion_callback;
     base::RepeatingCallback<void(int)> progress_callback;
-    base::RepeatingCallback<void(std::string)> page_callback;
+    base::RepeatingCallback<void(std::string, uint32_t)> page_callback;
     std::unique_ptr<ScanDataReader> scan_data_reader;
   };
 
@@ -267,6 +267,7 @@
 
   // Called when scan data read is completed.
   void OnScanDataCompleted(const std::string& uuid,
+                           uint32_t page_number,
                            bool more_pages,
                            base::Optional<std::string> data) {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -284,7 +285,7 @@
       return;
     }
 
-    state.page_callback.Run(std::move(data.value()));
+    state.page_callback.Run(std::move(data.value()), page_number);
 
     if (more_pages) {
       GetNextImage(uuid);
@@ -375,10 +376,10 @@
       VLOG(1) << "Scan job " << signal_proto.scan_uuid() << " page "
               << signal_proto.page() << " completed successfully";
       ScanDataReader* reader = state.scan_data_reader.get();
-      reader->Wait(
-          base::BindOnce(&LorgnetteManagerClientImpl::OnScanDataCompleted,
-                         weak_ptr_factory_.GetWeakPtr(),
-                         signal_proto.scan_uuid(), signal_proto.more_pages()));
+      reader->Wait(base::BindOnce(
+          &LorgnetteManagerClientImpl::OnScanDataCompleted,
+          weak_ptr_factory_.GetWeakPtr(), signal_proto.scan_uuid(),
+          signal_proto.page(), signal_proto.more_pages()));
     } else if (signal_proto.state() == lorgnette::SCAN_STATE_COMPLETED) {
       VLOG(1) << "Scan job " << signal_proto.scan_uuid()
               << " completed successfully";
diff --git a/chromeos/dbus/lorgnette_manager_client.h b/chromeos/dbus/lorgnette_manager_client.h
index 3e6fc2ae..6d78917 100644
--- a/chromeos/dbus/lorgnette_manager_client.h
+++ b/chromeos/dbus/lorgnette_manager_client.h
@@ -5,6 +5,7 @@
 #ifndef CHROMEOS_DBUS_LORGNETTE_MANAGER_CLIENT_H_
 #define CHROMEOS_DBUS_LORGNETTE_MANAGER_CLIENT_H_
 
+#include <cstdint>
 #include <map>
 #include <memory>
 #include <string>
@@ -43,9 +44,9 @@
       DBusMethodCallback<lorgnette::ScannerCapabilities> callback) = 0;
 
   // Request a scanned image using lorgnette's StartScan API. As each page is
-  // completed, calls |page_callback| with a string containing the image data.
-  // Calls |completion_callback| when the scan has completed. Image data will
-  // be stored in the .png format.
+  // completed, calls |page_callback| with the page number and a string
+  // containing the image data. Calls |completion_callback| when the scan has
+  // completed. Image data will be stored in the .png format.
   //
   // If |progress_callback| is provided, it will be called as scan progress
   // increases. The progress will be passed as a value from 0-100.
@@ -53,7 +54,7 @@
       const std::string& device_name,
       const lorgnette::ScanSettings& settings,
       VoidDBusMethodCallback completion_callback,
-      base::RepeatingCallback<void(std::string)> page_callback,
+      base::RepeatingCallback<void(std::string, uint32_t)> page_callback,
       base::RepeatingCallback<void(int)> progress_callback) = 0;
 
   // Factory function, creates a new instance and returns ownership.