Commit 092528e4 authored by Jesse Schettler's avatar Jesse Schettler Committed by Commit Bot

scanning: Create ScanService Mojo interface

Create and begin implementing a ScanService Mojo interface. The
interface will be used by the Scan SWA to get connected scanners, obtain
scanner capabilities, and perform scans. For now, only GetScanners() is
defined and implemented.

Subsequent CLs will add more methods and update the Scan SWA to use the
interface.

Bug: 1059779
Change-Id: Ia2511d586ea775bc35ed7549e7da63aa2a29bd10
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2368175
Commit-Queue: Jesse Schettler <jschettler@chromium.org>
Reviewed-by: default avatarJimmy Gong <jimmyxgong@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#801412}
parent c190cc30
......@@ -122,6 +122,7 @@ source_set("chromeos") {
"//chromeos/components/quick_answers/public/cpp:prefs",
"//chromeos/components/remote_apps/mojom",
"//chromeos/components/scanning",
"//chromeos/components/scanning/mojom",
"//chromeos/components/smbfs",
"//chromeos/components/smbfs/mojom",
"//chromeos/components/string_matching",
......@@ -2440,6 +2441,10 @@ source_set("chromeos") {
"scanning/lorgnette_scanner_manager_factory.h",
"scanning/lorgnette_scanner_manager_util.cc",
"scanning/lorgnette_scanner_manager_util.h",
"scanning/scan_service.cc",
"scanning/scan_service.h",
"scanning/scan_service_factory.cc",
"scanning/scan_service_factory.h",
"scanning/scanner_detector.h",
"scanning/zeroconf_scanner_detector.cc",
"scanning/zeroconf_scanner_detector.h",
......@@ -3498,6 +3503,7 @@ source_set("unit_tests") {
"scanning/fake_lorgnette_scanner_manager.h",
"scanning/lorgnette_scanner_manager_unittest.cc",
"scanning/lorgnette_scanner_manager_util_unittest.cc",
"scanning/scan_service_unittest.cc",
"scanning/zeroconf_scanner_detector_unittest.cc",
"scheduler_configuration_manager_unittest.cc",
"session_length_limiter_unittest.cc",
......
// Copyright 2020 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/chromeos/scanning/scan_service.h"
#include <utility>
#include "base/bind.h"
#include "base/check.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/scanning/lorgnette_scanner_manager.h"
namespace chromeos {
namespace {
namespace mojo_ipc = scanning::mojom;
} // namespace
ScanService::ScanService(LorgnetteScannerManager* lorgnette_scanner_manager)
: lorgnette_scanner_manager_(lorgnette_scanner_manager) {
DCHECK(lorgnette_scanner_manager_);
}
ScanService::~ScanService() = default;
void ScanService::GetScanners(GetScannersCallback callback) {
lorgnette_scanner_manager_->GetScannerNames(
base::BindOnce(&ScanService::OnScannerNamesReceived,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void ScanService::BindInterface(
mojo::PendingReceiver<mojo_ipc::ScanService> pending_receiver) {
receiver_.Bind(std::move(pending_receiver));
}
void ScanService::Shutdown() {
lorgnette_scanner_manager_ = nullptr;
receiver_.reset();
weak_ptr_factory_.InvalidateWeakPtrs();
}
void ScanService::OnScannerNamesReceived(
GetScannersCallback callback,
std::vector<std::string> scanner_names) {
std::vector<mojo_ipc::ScannerPtr> scanners;
scanners.reserve(scanner_names.size());
for (const auto& name : scanner_names) {
base::UnguessableToken id = base::UnguessableToken::Create();
scanners.push_back(mojo_ipc::Scanner::New(id, base::UTF8ToUTF16(name)));
}
std::move(callback).Run(std::move(scanners));
}
} // namespace chromeos
// Copyright 2020 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.
#ifndef CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_H_
#define CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_H_
#include <string>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "base/unguessable_token.h"
#include "chromeos/components/scanning/mojom/scanning.mojom.h"
#include "components/keyed_service/core/keyed_service.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
namespace chromeos {
class LorgnetteScannerManager;
// Implementation of the chromeos::scanning::mojom::ScanService interface. Used
// by the scanning WebUI (chrome://scanning) to get connected scanners, obtain
// scanner capabilities, and perform scans.
class ScanService : public scanning::mojom::ScanService, public KeyedService {
public:
explicit ScanService(LorgnetteScannerManager* lorgnette_scanner_manager);
~ScanService() override;
ScanService(const ScanService&) = delete;
ScanService& operator=(const ScanService&) = delete;
// scanning::mojom::ScanService:
void GetScanners(GetScannersCallback callback) override;
// Binds receiver_ by consuming |pending_receiver|.
void BindInterface(
mojo::PendingReceiver<scanning::mojom::ScanService> pending_receiver);
private:
// KeyedService:
void Shutdown() override;
// Processes the result of calling LorgnetteScannerManager::GetScannerNames().
void OnScannerNamesReceived(GetScannersCallback callback,
std::vector<std::string> scanner_names);
// Receives and dispatches method calls to this implementation of the
// chromeos::scanning::mojom::ScanService interface.
mojo::Receiver<scanning::mojom::ScanService> receiver_{this};
// Unowned. Used to get scanner information and perform scans.
LorgnetteScannerManager* lorgnette_scanner_manager_;
base::WeakPtrFactory<ScanService> weak_ptr_factory_{this};
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_H_
// Copyright 2020 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/chromeos/scanning/scan_service_factory.h"
#include "base/memory/singleton.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/scanning/lorgnette_scanner_manager_factory.h"
#include "chrome/browser/chromeos/scanning/scan_service.h"
#include "chrome/browser/profiles/profile.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/browser/browser_context.h"
namespace chromeos {
// static
ScanService* ScanServiceFactory::GetForBrowserContext(
content::BrowserContext* context) {
return static_cast<ScanService*>(
ScanServiceFactory::GetInstance()->GetServiceForBrowserContext(
context, /*create=*/true));
}
// static
ScanServiceFactory* ScanServiceFactory::GetInstance() {
return base::Singleton<ScanServiceFactory>::get();
}
ScanServiceFactory::ScanServiceFactory()
: BrowserContextKeyedServiceFactory(
"ScanService",
BrowserContextDependencyManager::GetInstance()) {
DependsOn(LorgnetteScannerManagerFactory::GetInstance());
}
ScanServiceFactory::~ScanServiceFactory() = default;
KeyedService* ScanServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
// Prevent an instance of ScanService from being created on the lock screen.
Profile* profile = Profile::FromBrowserContext(context);
if (ProfileHelper::IsLockScreenAppProfile(profile) ||
ProfileHelper::IsSigninProfile(profile)) {
return nullptr;
}
return new ScanService(
LorgnetteScannerManagerFactory::GetForBrowserContext(context));
}
bool ScanServiceFactory::ServiceIsCreatedWithBrowserContext() const {
return true;
}
bool ScanServiceFactory::ServiceIsNULLWhileTesting() const {
return true;
}
} // namespace chromeos
// Copyright 2020 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.
#ifndef CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_FACTORY_H_
#define CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_FACTORY_H_
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
namespace base {
template <typename T>
struct DefaultSingletonTraits;
} // namespace base
namespace content {
class BrowserContext;
} // namespace content
namespace chromeos {
class ScanService;
// Factory for ScanService.
class ScanServiceFactory : public BrowserContextKeyedServiceFactory {
public:
static ScanService* GetForBrowserContext(content::BrowserContext* context);
static ScanServiceFactory* GetInstance();
private:
friend struct base::DefaultSingletonTraits<ScanServiceFactory>;
ScanServiceFactory();
~ScanServiceFactory() override;
ScanServiceFactory(const ScanServiceFactory&) = delete;
ScanServiceFactory& operator=(const ScanServiceFactory&) = delete;
// BrowserContextKeyedServiceFactory:
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override;
bool ServiceIsCreatedWithBrowserContext() const override;
bool ServiceIsNULLWhileTesting() const override;
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_SCANNING_SCAN_SERVICE_FACTORY_H_
// Copyright 2020 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/chromeos/scanning/scan_service.h"
#include <vector>
#include "base/strings/utf_string_conversions.h"
#include "base/test/task_environment.h"
#include "chrome/browser/chromeos/scanning/fake_lorgnette_scanner_manager.h"
#include "chromeos/components/scanning/mojom/scanning.mojom-test-utils.h"
#include "chromeos/components/scanning/mojom/scanning.mojom.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace {
namespace mojo_ipc = scanning::mojom;
// Scanner names used for tests.
constexpr char kFirstTestScannerName[] = "Test Scanner 1";
constexpr char kSecondTestScannerName[] = "Test Scanner 2";
} // namespace
class ScanServiceTest : public testing::Test {
public:
ScanServiceTest() = default;
void SetUp() override {
scan_service_.BindInterface(
scan_service_remote_.BindNewPipeAndPassReceiver());
}
// Gets scanners by calling ScanService::GetScanners() via the mojo::Remote.
std::vector<mojo_ipc::ScannerPtr> GetScanners() {
std::vector<mojo_ipc::ScannerPtr> scanners;
mojo_ipc::ScanServiceAsyncWaiter(scan_service_remote_.get())
.GetScanners(&scanners);
return scanners;
}
protected:
FakeLorgnetteScannerManager fake_lorgnette_scanner_manager_;
private:
base::test::TaskEnvironment task_environment_;
ScanService scan_service_{&fake_lorgnette_scanner_manager_};
mojo::Remote<mojo_ipc::ScanService> scan_service_remote_;
};
// Test that no scanners are returned when there are no scanner names.
TEST_F(ScanServiceTest, NoScannerNames) {
fake_lorgnette_scanner_manager_.SetGetScannerNamesResponse({});
auto scanners = GetScanners();
EXPECT_TRUE(scanners.empty());
}
// Test that a scanner is returned with the correct display name.
TEST_F(ScanServiceTest, GetScanners) {
fake_lorgnette_scanner_manager_.SetGetScannerNamesResponse(
{kFirstTestScannerName});
auto scanners = GetScanners();
ASSERT_EQ(scanners.size(), 1u);
EXPECT_EQ(scanners[0]->display_name,
base::UTF8ToUTF16(kFirstTestScannerName));
}
// Test that two returned scanners have unique IDs.
TEST_F(ScanServiceTest, UniqueScannerIds) {
fake_lorgnette_scanner_manager_.SetGetScannerNamesResponse(
{kFirstTestScannerName, kSecondTestScannerName});
auto scanners = GetScanners();
ASSERT_EQ(scanners.size(), 2u);
EXPECT_EQ(scanners[0]->display_name,
base::UTF8ToUTF16(kFirstTestScannerName));
EXPECT_EQ(scanners[1]->display_name,
base::UTF8ToUTF16(kSecondTestScannerName));
EXPECT_NE(scanners[0]->id, scanners[1]->id);
}
} // namespace chromeos
# Copyright 2020 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.
import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") {
sources = [ "scanning.mojom" ]
public_deps = [ "//mojo/public/mojom/base" ]
}
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
// Copyright 2020 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.
module chromeos.scanning.mojom;
import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
// Represents a connected scanner.
struct Scanner {
// The scanner's unique identifier.
mojo_base.mojom.UnguessableToken id;
// The scanner's display name.
mojo_base.mojom.String16 display_name;
};
// Interface used to obtain information about and interact with connected
// scanners. It is implemented in the browser and exposed to the Scan app
// (chrome://scanning).
interface ScanService {
// Returns the connected scanners. Obtaining a scanner's capabilities is
// implemented in a separate method to minimize the amount of time clients
// must wait before receiving the scanners and displaying their display names.
GetScanners() => (array<Scanner> scanners);
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment