Commit 4e2f70a7 authored by Sam Goto's avatar Sam Goto Committed by Commit Bot

[sms] Handle incoming remote requests with SmsFetcher

Design-Doc: https://docs.google.com/document/d/1da8CjO71DlFbBzDcSosFRXTvDsKII_XMCohpZLQ_QbM/edit#
Bug: 1015645
Change-Id: I81d0d8971b313bed6829614de431b2943173a0e4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1895319
Commit-Queue: Sam Goto <goto@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarAlex Chau <alexchau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#713221}
parent 8483978f
...@@ -1584,6 +1584,8 @@ jumbo_static_library("browser") { ...@@ -1584,6 +1584,8 @@ jumbo_static_library("browser") {
"sharing/sharing_sync_preference.h", "sharing/sharing_sync_preference.h",
"sharing/sharing_utils.cc", "sharing/sharing_utils.cc",
"sharing/sharing_utils.h", "sharing/sharing_utils.h",
"sharing/sms/sms_fetch_request_handler.cc",
"sharing/sms/sms_fetch_request_handler.h",
"sharing/sms/sms_flags.cc", "sharing/sms/sms_flags.cc",
"sharing/sms/sms_flags.h", "sharing/sms/sms_flags.h",
"sharing/sms/sms_remote_fetcher.cc", "sharing/sms/sms_remote_fetcher.cc",
...@@ -2865,8 +2867,6 @@ jumbo_static_library("browser") { ...@@ -2865,8 +2867,6 @@ jumbo_static_library("browser") {
"search_engines/template_url_service_factory_android.h", "search_engines/template_url_service_factory_android.h",
"sharing/shared_clipboard/shared_clipboard_message_handler_android.cc", "sharing/shared_clipboard/shared_clipboard_message_handler_android.cc",
"sharing/shared_clipboard/shared_clipboard_message_handler_android.h", "sharing/shared_clipboard/shared_clipboard_message_handler_android.h",
"sharing/sms/sms_fetch_request_handler.cc",
"sharing/sms/sms_fetch_request_handler.h",
"signin/identity_services_provider_android.cc", "signin/identity_services_provider_android.cc",
"signin/signin_manager_android_factory.cc", "signin/signin_manager_android_factory.cc",
"signin/signin_manager_android_factory.h", "signin/signin_manager_android_factory.h",
......
...@@ -97,7 +97,8 @@ class ClickToCallUtilsTest : public testing::Test { ...@@ -97,7 +97,8 @@ class ClickToCallUtilsTest : public testing::Test {
/* gcm_driver= */ nullptr, /* gcm_driver= */ nullptr,
/* device_info_tracker= */ nullptr, /* device_info_tracker= */ nullptr,
/* local_device_info_provider= */ nullptr, /* local_device_info_provider= */ nullptr,
/* sync_service */ nullptr); /* sync_service */ nullptr,
/* sms_fetcher= */ nullptr);
} }
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
......
...@@ -27,6 +27,7 @@ MockSharingService::MockSharingService() ...@@ -27,6 +27,7 @@ MockSharingService::MockSharingService()
/*gcm_driver=*/nullptr, /*gcm_driver=*/nullptr,
/*device_info_tracker=*/nullptr, /*device_info_tracker=*/nullptr,
/*local_device_info_provider=*/nullptr, /*local_device_info_provider=*/nullptr,
/*sync_service*/ nullptr) {} /*sync_service*/ nullptr,
/*sms_fetcher=*/nullptr) {}
MockSharingService::~MockSharingService() = default; MockSharingService::~MockSharingService() = default;
...@@ -81,7 +81,8 @@ class SharedClipboardUtilsTest : public testing::Test { ...@@ -81,7 +81,8 @@ class SharedClipboardUtilsTest : public testing::Test {
/* gcm_driver= */ nullptr, /* gcm_driver= */ nullptr,
/* device_info_tracker= */ nullptr, /* device_info_tracker= */ nullptr,
/* local_device_info_provider= */ nullptr, /* local_device_info_provider= */ nullptr,
/* sync_service */ nullptr); /* sync_service */ nullptr,
/* sms_fetcher= */ nullptr);
} }
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
......
...@@ -60,7 +60,8 @@ SharingService::SharingService( ...@@ -60,7 +60,8 @@ SharingService::SharingService(
gcm::GCMDriver* gcm_driver, gcm::GCMDriver* gcm_driver,
syncer::DeviceInfoTracker* device_info_tracker, syncer::DeviceInfoTracker* device_info_tracker,
syncer::LocalDeviceInfoProvider* local_device_info_provider, syncer::LocalDeviceInfoProvider* local_device_info_provider,
syncer::SyncService* sync_service) syncer::SyncService* sync_service,
content::SmsFetcher* sms_fetcher)
: sync_prefs_(std::move(sync_prefs)), : sync_prefs_(std::move(sync_prefs)),
vapid_key_manager_(std::move(vapid_key_manager)), vapid_key_manager_(std::move(vapid_key_manager)),
sharing_device_registration_(std::move(sharing_device_registration)), sharing_device_registration_(std::move(sharing_device_registration)),
...@@ -105,7 +106,8 @@ SharingService::SharingService( ...@@ -105,7 +106,8 @@ SharingService::SharingService(
} }
if (sharing_device_registration_->IsSmsFetcherSupported()) { if (sharing_device_registration_->IsSmsFetcherSupported()) {
sms_fetch_request_handler_ = std::make_unique<SmsFetchRequestHandler>(); sms_fetch_request_handler_ =
std::make_unique<SmsFetchRequestHandler>(sms_fetcher);
fcm_handler_->AddSharingHandler( fcm_handler_->AddSharingHandler(
chrome_browser_sharing::SharingMessage::kSmsFetchRequest, chrome_browser_sharing::SharingMessage::kSmsFetchRequest,
sms_fetch_request_handler_.get()); sms_fetch_request_handler_.get());
......
...@@ -34,6 +34,10 @@ ...@@ -34,6 +34,10 @@
#include "chrome/browser/sharing/sharing_service_proxy_android.h" #include "chrome/browser/sharing/sharing_service_proxy_android.h"
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID)
namespace content {
class SmsFetcher;
}
namespace gcm { namespace gcm {
class GCMDriver; class GCMDriver;
} // namespace gcm } // namespace gcm
...@@ -83,7 +87,8 @@ class SharingService : public KeyedService, ...@@ -83,7 +87,8 @@ class SharingService : public KeyedService,
gcm::GCMDriver* gcm_driver, gcm::GCMDriver* gcm_driver,
syncer::DeviceInfoTracker* device_info_tracker, syncer::DeviceInfoTracker* device_info_tracker,
syncer::LocalDeviceInfoProvider* local_device_info_provider, syncer::LocalDeviceInfoProvider* local_device_info_provider,
syncer::SyncService* sync_service); syncer::SyncService* sync_service,
content::SmsFetcher* sms_fetcher);
~SharingService() override; ~SharingService() override;
// Returns the device matching |guid|, or nullptr if no match was found. // Returns the device matching |guid|, or nullptr if no match was found.
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "components/sync_device_info/device_info_sync_service.h" #include "components/sync_device_info/device_info_sync_service.h"
#include "components/sync_device_info/local_device_info_provider.h" #include "components/sync_device_info/local_device_info_provider.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/sms_fetcher.h"
namespace { namespace {
constexpr char kServiceName[] = "SharingService"; constexpr char kServiceName[] = "SharingService";
...@@ -98,11 +99,14 @@ KeyedService* SharingServiceFactory::BuildServiceInstanceFor( ...@@ -98,11 +99,14 @@ KeyedService* SharingServiceFactory::BuildServiceInstanceFor(
std::make_unique<SharingMessageSender>(fcm_sender.get(), sync_prefs.get(), std::make_unique<SharingMessageSender>(fcm_sender.get(), sync_prefs.get(),
local_device_info_provider); local_device_info_provider);
content::SmsFetcher* sms_fetcher = content::SmsFetcher::Get(context);
return new SharingService( return new SharingService(
profile, std::move(sync_prefs), std::move(vapid_key_manager), profile, std::move(sync_prefs), std::move(vapid_key_manager),
std::move(sharing_device_registration), std::move(fcm_sender), std::move(sharing_device_registration), std::move(fcm_sender),
std::move(fcm_handler), std::move(sharing_message_sender), gcm_driver, std::move(fcm_handler), std::move(sharing_message_sender), gcm_driver,
device_info_tracker, local_device_info_provider, sync_service); device_info_tracker, local_device_info_provider, sync_service,
sms_fetcher);
} }
content::BrowserContext* SharingServiceFactory::GetBrowserContextToUse( content::BrowserContext* SharingServiceFactory::GetBrowserContextToUse(
......
...@@ -223,7 +223,8 @@ class SharingServiceTest : public testing::Test { ...@@ -223,7 +223,8 @@ class SharingServiceTest : public testing::Test {
base::WrapUnique(sharing_message_sender_), nullptr, base::WrapUnique(sharing_message_sender_), nullptr,
fake_device_info_sync_service.GetDeviceInfoTracker(), fake_device_info_sync_service.GetDeviceInfoTracker(),
fake_device_info_sync_service.GetLocalDeviceInfoProvider(), fake_device_info_sync_service.GetLocalDeviceInfoProvider(),
&test_sync_service_); &test_sync_service_,
/* sms_fetcher= */ nullptr);
} }
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
return sharing_service_.get(); return sharing_service_.get();
......
...@@ -6,8 +6,12 @@ ...@@ -6,8 +6,12 @@
#include "base/logging.h" #include "base/logging.h"
#include "components/sync/protocol/sharing_sms_fetch_message.pb.h" #include "components/sync/protocol/sharing_sms_fetch_message.pb.h"
#include "content/public/browser/sms_fetcher.h"
#include "url/gurl.h"
#include "url/origin.h"
SmsFetchRequestHandler::SmsFetchRequestHandler() = default; SmsFetchRequestHandler::SmsFetchRequestHandler(content::SmsFetcher* fetcher)
: fetcher_(fetcher) {}
SmsFetchRequestHandler::~SmsFetchRequestHandler() = default; SmsFetchRequestHandler::~SmsFetchRequestHandler() = default;
...@@ -15,6 +19,41 @@ void SmsFetchRequestHandler::OnMessage( ...@@ -15,6 +19,41 @@ void SmsFetchRequestHandler::OnMessage(
chrome_browser_sharing::SharingMessage message, chrome_browser_sharing::SharingMessage message,
SharingMessageHandler::DoneCallback done_callback) { SharingMessageHandler::DoneCallback done_callback) {
DCHECK(message.has_sms_fetch_request()); DCHECK(message.has_sms_fetch_request());
// TODO(crbug.com/1015645): implementation left pending deliberately.
NOTIMPLEMENTED(); auto origin = url::Origin::Create(GURL(message.sms_fetch_request().origin()));
auto request = std::make_unique<Request>(this, fetcher_, origin,
std::move(done_callback));
requests_.insert(std::move(request));
}
void SmsFetchRequestHandler::RemoveRequest(Request* request) {
requests_.erase(request);
}
SmsFetchRequestHandler::Request::Request(
SmsFetchRequestHandler* handler,
content::SmsFetcher* fetcher,
const url::Origin& origin,
SharingMessageHandler::DoneCallback respond_callback)
: handler_(handler),
fetcher_(fetcher),
origin_(origin),
respond_callback_(std::move(respond_callback)) {
fetcher_->Subscribe(origin_, this);
}
SmsFetchRequestHandler::Request::~Request() {
fetcher_->Unsubscribe(origin_, this);
}
void SmsFetchRequestHandler::Request::OnReceive(
const std::string& one_time_code,
const std::string& sms) {
auto response = std::make_unique<chrome_browser_sharing::ResponseMessage>();
response->mutable_sms_fetch_response()->set_sms(sms);
response->mutable_sms_fetch_response()->set_one_time_code(one_time_code);
std::move(respond_callback_).Run(std::move(response));
handler_->RemoveRequest(this);
} }
...@@ -5,14 +5,23 @@ ...@@ -5,14 +5,23 @@
#ifndef CHROME_BROWSER_SHARING_SMS_SMS_FETCH_REQUEST_HANDLER_H_ #ifndef CHROME_BROWSER_SHARING_SMS_SMS_FETCH_REQUEST_HANDLER_H_
#define CHROME_BROWSER_SHARING_SMS_SMS_FETCH_REQUEST_HANDLER_H_ #define CHROME_BROWSER_SHARING_SMS_SMS_FETCH_REQUEST_HANDLER_H_
#include "base/bind.h"
#include "base/containers/flat_set.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/sharing/sharing_message_handler.h" #include "chrome/browser/sharing/sharing_message_handler.h"
#include "components/sync/protocol/sharing_message.pb.h" #include "components/sync/protocol/sharing_message.pb.h"
#include "content/public/browser/sms_fetcher.h"
#include "url/origin.h"
namespace content {
class SmsFetcher;
}
// Handles incoming messages for the sms fetcher feature. // Handles incoming messages for the sms fetcher feature.
class SmsFetchRequestHandler : public SharingMessageHandler { class SmsFetchRequestHandler : public SharingMessageHandler {
public: public:
SmsFetchRequestHandler(); explicit SmsFetchRequestHandler(content::SmsFetcher* fetcher);
~SmsFetchRequestHandler() override; ~SmsFetchRequestHandler() override;
// SharingMessageHandler // SharingMessageHandler
...@@ -20,6 +29,39 @@ class SmsFetchRequestHandler : public SharingMessageHandler { ...@@ -20,6 +29,39 @@ class SmsFetchRequestHandler : public SharingMessageHandler {
SharingMessageHandler::DoneCallback done_callback) override; SharingMessageHandler::DoneCallback done_callback) override;
private: private:
// Request represents an incoming request from a remote SmsService.
// It manages subscribing and unsubscribing for SMSes in SmsFetcher and
// responding to the callback.
// It also lets SmsFetchRequestHandler know when the request is fulfilled
// to allow its memory to be freed.
class Request : public content::SmsFetcher::Subscriber {
public:
Request(SmsFetchRequestHandler* handler,
content::SmsFetcher* fetcher,
const url::Origin& origin,
SharingMessageHandler::DoneCallback respond_callback);
~Request() override;
void OnReceive(const std::string& one_time_code,
const std::string& sms) override;
private:
SmsFetchRequestHandler* handler_;
content::SmsFetcher* fetcher_;
const url::Origin& origin_;
SharingMessageHandler::DoneCallback respond_callback_;
DISALLOW_COPY_AND_ASSIGN(Request);
};
void RemoveRequest(Request* Request);
// |fetcher_| is safe because it is owned by BrowserContext, which also
// owns (transitively, via SharingService) this class.
content::SmsFetcher* fetcher_;
base::flat_set<std::unique_ptr<Request>, base::UniquePtrComparator> requests_;
base::WeakPtrFactory<SmsFetchRequestHandler> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(SmsFetchRequestHandler); DISALLOW_COPY_AND_ASSIGN(SmsFetchRequestHandler);
}; };
......
// Copyright 2019 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/sharing/sms/sms_fetch_request_handler.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "chrome/browser/sharing/sharing_message_handler.h"
#include "components/sync/protocol/sharing_message.pb.h"
#include "content/public/browser/sms_fetcher.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
using base::BindLambdaForTesting;
using chrome_browser_sharing::ResponseMessage;
using chrome_browser_sharing::SharingMessage;
using ::testing::_;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::StrictMock;
namespace {
class MockSmsFetcher : public content::SmsFetcher {
public:
MockSmsFetcher() = default;
~MockSmsFetcher() = default;
MOCK_METHOD2(Subscribe,
void(const url::Origin& origin, Subscriber* subscriber));
MOCK_METHOD2(Unsubscribe,
void(const url::Origin& origin, Subscriber* subscriber));
MOCK_METHOD0(HasSubscribers, bool());
private:
DISALLOW_COPY_AND_ASSIGN(MockSmsFetcher);
};
SharingMessage CreateRequest(const std::string& origin) {
SharingMessage message;
message.mutable_sms_fetch_request()->set_origin(origin);
return message;
}
} // namespace
TEST(SmsFetchRequestHandlerTest, Basic) {
base::test::SingleThreadTaskEnvironment task_environment;
StrictMock<MockSmsFetcher> fetcher;
SmsFetchRequestHandler handler(&fetcher);
SharingMessage message = CreateRequest("https://a.com");
base::RunLoop loop;
content::SmsFetcher::Subscriber* subscriber;
EXPECT_CALL(fetcher, Subscribe(_, _)).WillOnce(SaveArg<1>(&subscriber));
EXPECT_CALL(fetcher, Unsubscribe(_, _));
handler.OnMessage(
message,
BindLambdaForTesting([&loop](std::unique_ptr<ResponseMessage> response) {
EXPECT_TRUE(response->has_sms_fetch_response());
EXPECT_EQ("123", response->sms_fetch_response().one_time_code());
EXPECT_EQ("hello", response->sms_fetch_response().sms());
loop.Quit();
}));
subscriber->OnReceive("123", "hello");
loop.Run();
}
TEST(SmsFetchRequestHandlerTest, OutOfOrder) {
base::test::SingleThreadTaskEnvironment task_environment;
StrictMock<MockSmsFetcher> fetcher;
SmsFetchRequestHandler handler(&fetcher);
SharingMessage message = CreateRequest("https://a.com");
base::RunLoop loop1;
content::SmsFetcher::Subscriber* request1;
EXPECT_CALL(fetcher, Subscribe(_, _)).WillOnce(SaveArg<1>(&request1));
EXPECT_CALL(fetcher, Unsubscribe(_, _)).Times(2);
handler.OnMessage(
message,
BindLambdaForTesting([&loop1](std::unique_ptr<ResponseMessage> response) {
EXPECT_TRUE(response->has_sms_fetch_response());
EXPECT_EQ("first", response->sms_fetch_response().sms());
loop1.Quit();
}));
base::RunLoop loop2;
content::SmsFetcher::Subscriber* request2;
EXPECT_CALL(fetcher, Subscribe(_, _)).WillOnce(SaveArg<1>(&request2));
handler.OnMessage(
message,
BindLambdaForTesting([&loop2](std::unique_ptr<ResponseMessage> response) {
EXPECT_TRUE(response->has_sms_fetch_response());
EXPECT_EQ("second", response->sms_fetch_response().sms());
loop2.Quit();
}));
request2->OnReceive("2", "second");
loop2.Run();
request1->OnReceive("1", "first");
loop1.Run();
}
TEST(SmsFetchRequestHandlerTest, HangingRequestUnsubscribedUponDestruction) {
base::test::SingleThreadTaskEnvironment task_environment;
StrictMock<MockSmsFetcher> fetcher;
SmsFetchRequestHandler handler(&fetcher);
SharingMessage message = CreateRequest("https://a.com");
content::SmsFetcher::Subscriber* subscriber;
EXPECT_CALL(fetcher, Subscribe(_, _)).WillOnce(SaveArg<1>(&subscriber));
// Expects Unsubscribe to be called when SmsFetchRequestHandler goes out of
// scope.
EXPECT_CALL(fetcher, Unsubscribe(_, _));
// Leaves the request deliberately hanging without a response to assert
// that it gets cleaned up.
handler.OnMessage(
message,
BindLambdaForTesting([&](std::unique_ptr<ResponseMessage> response) {}));
}
...@@ -11,12 +11,18 @@ ...@@ -11,12 +11,18 @@
#include "chrome/browser/sharing/sms/sms_flags.h" #include "chrome/browser/sharing/sms/sms_flags.h"
#include "components/sync_device_info/device_info.h" #include "components/sync_device_info/device_info.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "url/origin.h"
namespace {
const uint32_t kDefaultTimeoutSeconds = 60;
} // namespace
void FetchRemoteSms( void FetchRemoteSms(
content::BrowserContext* context, content::BrowserContext* context,
const url::Origin& origin, const url::Origin& origin,
base::OnceCallback<void(base::Optional<std::string>)> callback) { base::OnceCallback<void(base::Optional<std::string>)> callback) {
if (!base::FeatureList::IsEnabled(kSmsFetchRequestHandler)) { if (!base::FeatureList::IsEnabled(kSmsFetchRequestHandler)) {
std::move(callback).Run(base::nullopt);
return; return;
} }
...@@ -25,21 +31,39 @@ void FetchRemoteSms( ...@@ -25,21 +31,39 @@ void FetchRemoteSms(
SharingService::SharingDeviceList devices = SharingService::SharingDeviceList devices =
sharing_service->GetDeviceCandidates( sharing_service->GetDeviceCandidates(
sync_pb::SharingSpecificFields::SMS_FETCHER); sync_pb::SharingSpecificFields::SMS_FETCHER);
for (const std::unique_ptr<syncer::DeviceInfo>& info : devices) {
chrome_browser_sharing::SharingMessage sharing_message; if (devices.empty()) {
// No devices available to call.
sharing_service->SendMessageToDevice( std::move(callback).Run(base::nullopt);
info->guid(), kSendMessageTimeout, std::move(sharing_message), return;
base::BindOnce(
[](SharingSendMessageResult result,
std::unique_ptr<chrome_browser_sharing::ResponseMessage>
response) {
// TODO(crbug.com/1015645): implementation pending.
NOTIMPLEMENTED();
}));
// Sends to the first device that has the capability enabled.
// TODO(crbug.com/1015645): figure out the routing strategy.
break;
} }
// Sends to the first device that has the capability enabled.
// TODO(crbug.com/1015645): figure out the routing strategy, possibly
// requiring UX to allow the users to specify the device.
const std::unique_ptr<syncer::DeviceInfo>& device = devices.front();
chrome_browser_sharing::SharingMessage request;
request.mutable_sms_fetch_request()->set_origin(origin.Serialize());
sharing_service->SendMessageToDevice(
device->guid(), base::TimeDelta::FromSeconds(kDefaultTimeoutSeconds),
std::move(request),
base::BindOnce(
[](base::OnceCallback<void(base::Optional<std::string>)> callback,
SharingSendMessageResult result,
std::unique_ptr<chrome_browser_sharing::ResponseMessage>
response) {
if (result != SharingSendMessageResult::kSuccessful) {
std::move(callback).Run(base::nullopt);
return;
}
DCHECK(response);
DCHECK(response->has_sms_fetch_response());
std::move(callback).Run(response->sms_fetch_response().sms());
},
std::move(callback)));
} }
// Copyright 2019 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/sharing/sms/sms_remote_fetcher.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/sharing/mock_sharing_service.h"
#include "chrome/browser/sharing/sharing_service.h"
#include "chrome/browser/sharing/sharing_service_factory.h"
#include "chrome/browser/sharing/sms/sms_flags.h"
#include "chrome/test/base/testing_profile.h"
#include "components/sync/protocol/sharing_message.pb.h"
#include "content/public/browser/sms_fetcher.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
using base::BindLambdaForTesting;
using chrome_browser_sharing::ResponseMessage;
using chrome_browser_sharing::SharingMessage;
using ::testing::_;
using ::testing::ByMove;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::SaveArg;
MockSharingService* CreateSharingService(content::BrowserContext* context) {
return static_cast<MockSharingService*>(
SharingServiceFactory::GetInstance()->SetTestingFactoryAndUse(
context, base::BindRepeating([](content::BrowserContext* context) {
return static_cast<std::unique_ptr<KeyedService>>(
std::make_unique<MockSharingService>());
})));
}
url::Origin GetOriginForURL(const std::string url) {
return url::Origin::Create(GURL(url));
}
std::unique_ptr<syncer::DeviceInfo> CreateDevice() {
return std::make_unique<syncer::DeviceInfo>(
"guid1", "name", "chrome_version", "user_agent",
sync_pb::SyncEnums_DeviceType_TYPE_PHONE, "device_id",
base::SysInfo::HardwareInfo(),
/*last_updated_timestamp=*/base::Time::Now(),
/*send_tab_to_self_receiving_enabled=*/false,
/*sharing_info=*/base::nullopt);
}
TEST(SmsRemoteFetcherTest, DisabledByDefault) {
content::BrowserTaskEnvironment task_environment;
TestingProfile profile;
base::RunLoop loop;
FetchRemoteSms(
&profile, GetOriginForURL("a.com"),
BindLambdaForTesting([&loop](base::Optional<std::string> result) {
ASSERT_FALSE(result);
loop.Quit();
}));
loop.Run();
}
TEST(SmsRemoteFetcherTest, NoDevicesAvailable) {
base::test::ScopedFeatureList flags;
content::BrowserTaskEnvironment task_environment;
TestingProfile profile;
flags.InitAndEnableFeature(kSmsFetchRequestHandler);
MockSharingService* service = CreateSharingService(&profile);
std::vector<std::unique_ptr<syncer::DeviceInfo>> devices;
EXPECT_CALL(*service, GetDeviceCandidates(_))
.WillOnce(Return(ByMove(std::move(devices))));
base::RunLoop loop;
FetchRemoteSms(
&profile, GetOriginForURL("a.com"),
BindLambdaForTesting([&loop](base::Optional<std::string> result) {
ASSERT_FALSE(result);
loop.Quit();
}));
loop.Run();
}
TEST(SmsRemoteFetcherTest, OneDevice) {
base::test::ScopedFeatureList flags;
content::BrowserTaskEnvironment task_environment;
TestingProfile profile;
flags.InitAndEnableFeature(kSmsFetchRequestHandler);
MockSharingService* service = CreateSharingService(&profile);
std::vector<std::unique_ptr<syncer::DeviceInfo>> devices;
devices.push_back(CreateDevice());
EXPECT_CALL(*service, GetDeviceCandidates(_))
.WillOnce(Return(ByMove(std::move(devices))));
base::RunLoop loop;
EXPECT_CALL(*service, SendMessageToDevice(_, _, _, _))
.WillOnce(Invoke([&](const std::string& device_guid,
base::TimeDelta response_timeout,
chrome_browser_sharing::SharingMessage message,
SharingMessageSender::ResponseCallback callback) {
auto response = std::make_unique<ResponseMessage>();
response->mutable_sms_fetch_response()->set_sms("hello");
std::move(callback).Run(SharingSendMessageResult::kSuccessful,
std::move(response));
}));
FetchRemoteSms(
&profile, GetOriginForURL("a.com"),
BindLambdaForTesting([&loop](base::Optional<std::string> result) {
ASSERT_TRUE(result);
ASSERT_EQ("hello", result);
loop.Quit();
}));
loop.Run();
}
TEST(SmsRemoteFetcherTest, OneDeviceTimesOut) {
base::test::ScopedFeatureList flags;
content::BrowserTaskEnvironment task_environment;
TestingProfile profile;
flags.InitAndEnableFeature(kSmsFetchRequestHandler);
MockSharingService* service = CreateSharingService(&profile);
std::vector<std::unique_ptr<syncer::DeviceInfo>> devices;
devices.push_back(CreateDevice());
EXPECT_CALL(*service, GetDeviceCandidates(_))
.WillOnce(Return(ByMove(std::move(devices))));
base::RunLoop loop;
EXPECT_CALL(*service, SendMessageToDevice(_, _, _, _))
.WillOnce(Invoke([&](const std::string& device_guid,
base::TimeDelta response_timeout,
chrome_browser_sharing::SharingMessage message,
SharingMessageSender::ResponseCallback callback) {
std::move(callback).Run(SharingSendMessageResult::kAckTimeout,
std::make_unique<ResponseMessage>());
}));
FetchRemoteSms(
&profile, GetOriginForURL("a.com"),
BindLambdaForTesting([&loop](base::Optional<std::string> result) {
ASSERT_FALSE(result);
loop.Quit();
}));
loop.Run();
}
...@@ -4017,6 +4017,8 @@ test("unit_tests") { ...@@ -4017,6 +4017,8 @@ test("unit_tests") {
"../browser/sharing/shared_clipboard/shared_clipboard_test_base.h", "../browser/sharing/shared_clipboard/shared_clipboard_test_base.h",
"../browser/sharing/shared_clipboard/shared_clipboard_ui_controller_unittest.cc", "../browser/sharing/shared_clipboard/shared_clipboard_ui_controller_unittest.cc",
"../browser/sharing/shared_clipboard/shared_clipboard_utils_unittest.cc", "../browser/sharing/shared_clipboard/shared_clipboard_utils_unittest.cc",
"../browser/sharing/sms/sms_fetch_request_handler_unittest.cc",
"../browser/sharing/sms/sms_remote_fetcher_unittest.cc",
"../browser/ui/autofill/payments/local_card_migration_bubble_controller_impl_unittest.cc", "../browser/ui/autofill/payments/local_card_migration_bubble_controller_impl_unittest.cc",
"../browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc", "../browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc",
"../browser/ui/bluetooth/bluetooth_chooser_controller_unittest.cc", "../browser/ui/bluetooth/bluetooth_chooser_controller_unittest.cc",
......
...@@ -10,7 +10,19 @@ package chrome_browser_sharing; ...@@ -10,7 +10,19 @@ package chrome_browser_sharing;
option optimize_for = LITE_RUNTIME; option optimize_for = LITE_RUNTIME;
// Request message to fetch a SMS from a remote device. // Request message to fetch a SMS from a remote device.
message SmsFetchRequest {} message SmsFetchRequest {
// The origin that is requesting the SMS. Remote devices use it to match
// against the metadata contained in the received SMS.
// required
string origin = 1;
}
// Response message to fetch a SMS from a remote device. // Response message to fetch a SMS from a remote device.
message SmsFetchResponse {} message SmsFetchResponse {
// The full contents of the received SMS.
// required
string sms = 1;
// The parsed one time code of the received SMS.
// required
string one_time_code = 2;
}
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