Commit e6e98eb9 authored by James Vecore's avatar James Vecore Committed by Commit Bot

[Nearby] Add ContactsManager mojo

Adds a mojo interface on top of the existing contacts manager and makes
it available for binding in both chrome://nearby and
chrome://os-settings.

Bug: b:166503584
Change-Id: I67b8588fae5c838f4f0a57bffd2078d99c9c83fe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2402758
Commit-Queue: James Vecore <vecore@google.com>
Reviewed-by: default avatarAlex Gough <ajgo@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarJosh Nohle <nohle@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807058}
parent 8f89bbdb
...@@ -709,6 +709,10 @@ void PopulateChromeWebUIFrameBinders( ...@@ -709,6 +709,10 @@ void PopulateChromeWebUIFrameBinders(
nearby_share::mojom::NearbyShareSettings, nearby_share::mojom::NearbyShareSettings,
chromeos::settings::OSSettingsUI, nearby_share::NearbyShareDialogUI>( chromeos::settings::OSSettingsUI, nearby_share::NearbyShareDialogUI>(
map); map);
RegisterWebUIControllerInterfaceBinder<nearby_share::mojom::ContactManager,
chromeos::settings::OSSettingsUI,
nearby_share::NearbyShareDialogUI>(
map);
RegisterWebUIControllerInterfaceBinder< RegisterWebUIControllerInterfaceBinder<
nearby_share::mojom::DiscoveryManager, nearby_share::mojom::DiscoveryManager,
nearby_share::NearbyShareDialogUI>(map); nearby_share::NearbyShareDialogUI>(map);
......
...@@ -22,6 +22,7 @@ source_set("contacts") { ...@@ -22,6 +22,7 @@ source_set("contacts") {
"//chrome/browser/nearby_sharing/logging", "//chrome/browser/nearby_sharing/logging",
"//chrome/browser/nearby_sharing/proto", "//chrome/browser/nearby_sharing/proto",
"//chrome/browser/nearby_sharing/scheduling", "//chrome/browser/nearby_sharing/scheduling",
"//chrome/browser/ui/webui/nearby_share/public/mojom",
"//components/prefs", "//components/prefs",
] ]
} }
...@@ -63,7 +64,9 @@ source_set("unit_tests") { ...@@ -63,7 +64,9 @@ source_set("unit_tests") {
"//chrome/browser/nearby_sharing/proto", "//chrome/browser/nearby_sharing/proto",
"//chrome/browser/nearby_sharing/scheduling", "//chrome/browser/nearby_sharing/scheduling",
"//chrome/browser/nearby_sharing/scheduling:test_support", "//chrome/browser/nearby_sharing/scheduling:test_support",
"//chrome/browser/ui/webui/nearby_share/public/mojom",
"//components/sync_preferences:test_support", "//components/sync_preferences:test_support",
"//content/test:test_support",
"//testing/gtest", "//testing/gtest",
] ]
} }
...@@ -40,3 +40,12 @@ void FakeNearbyShareContactManager::SetAllowedContacts( ...@@ -40,3 +40,12 @@ void FakeNearbyShareContactManager::SetAllowedContacts(
void FakeNearbyShareContactManager::OnStart() {} void FakeNearbyShareContactManager::OnStart() {}
void FakeNearbyShareContactManager::OnStop() {} void FakeNearbyShareContactManager::OnStop() {}
void FakeNearbyShareContactManager::Bind(
mojo::PendingReceiver<nearby_share::mojom::ContactManager> receiver) {}
void FakeNearbyShareContactManager::AddDownloadContactsObserver(
::mojo::PendingRemote<nearby_share::mojom::DownloadContactsObserver>
observer) {}
void FakeNearbyShareContactManager::DownloadContacts() {}
...@@ -91,6 +91,14 @@ class FakeNearbyShareContactManager : public NearbyShareContactManager { ...@@ -91,6 +91,14 @@ class FakeNearbyShareContactManager : public NearbyShareContactManager {
const std::set<std::string>& allowed_contact_ids) override; const std::set<std::string>& allowed_contact_ids) override;
void OnStart() override; void OnStart() override;
void OnStop() override; void OnStop() override;
void Bind(mojo::PendingReceiver<nearby_share::mojom::ContactManager> receiver)
override;
// nearby_share::mojom::ContactsManager:
void AddDownloadContactsObserver(
::mojo::PendingRemote<nearby_share::mojom::DownloadContactsObserver>
observer) override;
void DownloadContacts() override;
std::vector<bool> download_contacts_calls_; std::vector<bool> download_contacts_calls_;
std::vector<std::set<std::string>> set_allowed_contacts_calls_; std::vector<std::set<std::string>> set_allowed_contacts_calls_;
......
...@@ -32,6 +32,14 @@ void NearbyShareContactManager::Stop() { ...@@ -32,6 +32,14 @@ void NearbyShareContactManager::Stop() {
OnStop(); OnStop();
} }
void NearbyShareContactManager::SetAllowedContacts(
const std::vector<std::string>& allowed_contacts) {
// This is mojo version of the call, but mojo doesn't support sets, so we
// have to convert the vector to set.
std::set<std::string> set(allowed_contacts.begin(), allowed_contacts.end());
SetAllowedContacts(set);
}
void NearbyShareContactManager::NotifyAllowlistChanged( void NearbyShareContactManager::NotifyAllowlistChanged(
bool were_contacts_added_to_allowlist, bool were_contacts_added_to_allowlist,
bool were_contacts_removed_from_allowlist) { bool were_contacts_removed_from_allowlist) {
......
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
#include "base/observer_list_types.h" #include "base/observer_list_types.h"
#include "base/optional.h" #include "base/optional.h"
#include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h" #include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
#include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
// The Nearby Share contacts manager interfaces with the Nearby server in the // The Nearby Share contacts manager interfaces with the Nearby server in the
// following ways: // following ways:
...@@ -29,7 +32,7 @@ ...@@ -29,7 +32,7 @@
// //
// All contact data and update notifications are conveyed via observer methods; // All contact data and update notifications are conveyed via observer methods;
// the manager does not return data directly from function calls. // the manager does not return data directly from function calls.
class NearbyShareContactManager { class NearbyShareContactManager : public nearby_share::mojom::ContactManager {
public: public:
class Observer : public base::CheckedObserver { class Observer : public base::CheckedObserver {
public: public:
...@@ -44,7 +47,7 @@ class NearbyShareContactManager { ...@@ -44,7 +47,7 @@ class NearbyShareContactManager {
}; };
NearbyShareContactManager(); NearbyShareContactManager();
virtual ~NearbyShareContactManager(); ~NearbyShareContactManager() override;
void AddObserver(Observer* observer); void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer); void RemoveObserver(Observer* observer);
...@@ -71,6 +74,15 @@ class NearbyShareContactManager { ...@@ -71,6 +74,15 @@ class NearbyShareContactManager {
virtual void SetAllowedContacts( virtual void SetAllowedContacts(
const std::set<std::string>& allowed_contact_ids) = 0; const std::set<std::string>& allowed_contact_ids) = 0;
virtual void Bind(
mojo::PendingReceiver<nearby_share::mojom::ContactManager> receiver) = 0;
// nearby_share::mojom::ContactManager:
void SetAllowedContacts(
const std::vector<std::string>& allowed_contacts) override;
// This prevents the mojo version of DownloadContacts from being hidden.
using nearby_share::mojom::ContactManager::DownloadContacts;
protected: protected:
virtual void OnStart() = 0; virtual void OnStart() = 0;
virtual void OnStop() = 0; virtual void OnStop() = 0;
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h" #include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
#include "chrome/browser/nearby_sharing/scheduling/nearby_share_scheduler.h" #include "chrome/browser/nearby_sharing/scheduling/nearby_share_scheduler.h"
#include "chrome/browser/nearby_sharing/scheduling/nearby_share_scheduler_factory.h" #include "chrome/browser/nearby_sharing/scheduling/nearby_share_scheduler_factory.h"
#include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom-shared.h"
#include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
namespace { namespace {
...@@ -57,6 +59,52 @@ std::vector<nearbyshare::proto::Contact> ContactRecordsToContacts( ...@@ -57,6 +59,52 @@ std::vector<nearbyshare::proto::Contact> ContactRecordsToContacts(
return contacts; return contacts;
} }
nearby_share::mojom::ContactIdentifierPtr ProtoToMojo(
const nearbyshare::proto::Contact_Identifier& identifier) {
nearby_share::mojom::ContactIdentifierPtr identifier_ptr =
nearby_share::mojom::ContactIdentifier::New();
switch (identifier.identifier_case()) {
case nearbyshare::proto::Contact_Identifier::IdentifierCase::kAccountName:
identifier_ptr->set_account_name(identifier.account_name());
break;
case nearbyshare::proto::Contact_Identifier::IdentifierCase::
kObfuscatedGaia:
identifier_ptr->set_obfuscated_gaia(identifier.obfuscated_gaia());
break;
case nearbyshare::proto::Contact_Identifier::IdentifierCase::kPhoneNumber:
identifier_ptr->set_phone_number(identifier.phone_number());
break;
case nearbyshare::proto::Contact_Identifier::IdentifierCase::
IDENTIFIER_NOT_SET:
NOTREACHED();
break;
}
return identifier_ptr;
}
nearby_share::mojom::ContactRecordPtr ProtoToMojo(
const nearbyshare::proto::ContactRecord& contact_record) {
nearby_share::mojom::ContactRecordPtr contact_record_ptr =
nearby_share::mojom::ContactRecord::New();
contact_record_ptr->id = contact_record.id();
contact_record_ptr->person_name = contact_record.person_name();
contact_record_ptr->image_url = GURL(contact_record.image_url());
for (const auto& identifier : contact_record.identifiers()) {
contact_record_ptr->identifiers.push_back(ProtoToMojo(identifier));
}
return contact_record_ptr;
}
std::vector<nearby_share::mojom::ContactRecordPtr> ProtoToMojo(
const std::vector<nearbyshare::proto::ContactRecord>& contacts) {
std::vector<nearby_share::mojom::ContactRecordPtr> mojo_contacts;
mojo_contacts.reserve(contacts.size());
for (const auto& contact_record : contacts) {
mojo_contacts.push_back(ProtoToMojo(contact_record));
}
return mojo_contacts;
}
} // namespace } // namespace
// static // static
...@@ -140,6 +188,21 @@ void NearbyShareContactManagerImpl::OnStop() { ...@@ -140,6 +188,21 @@ void NearbyShareContactManagerImpl::OnStop() {
contact_upload_scheduler_->Stop(); contact_upload_scheduler_->Stop();
} }
void NearbyShareContactManagerImpl::Bind(
mojo::PendingReceiver<nearby_share::mojom::ContactManager> receiver) {
receiver_set_.Add(this, std::move(receiver));
}
void NearbyShareContactManagerImpl::AddDownloadContactsObserver(
::mojo::PendingRemote<nearby_share::mojom::DownloadContactsObserver>
observer) {
observers_set_.Add(std::move(observer));
}
void NearbyShareContactManagerImpl::DownloadContacts() {
DownloadContacts(/*only_download_if_changed=*/false);
}
std::set<std::string> NearbyShareContactManagerImpl::GetAllowedContacts() std::set<std::string> NearbyShareContactManagerImpl::GetAllowedContacts()
const { const {
std::set<std::string> allowlist; std::set<std::string> allowlist;
...@@ -189,7 +252,9 @@ void NearbyShareContactManagerImpl::OnContactsDownloadSuccess( ...@@ -189,7 +252,9 @@ void NearbyShareContactManagerImpl::OnContactsDownloadSuccess(
GetAllowedContacts(), *contacts)); GetAllowedContacts(), *contacts));
// Notify observers that the contact list was downloaded. // Notify observers that the contact list was downloaded.
NotifyContactsDownloaded(GetAllowedContacts(), *contacts); std::set<std::string> allowed_contact_ids = GetAllowedContacts();
NotifyContactsDownloaded(allowed_contact_ids, *contacts);
NotifyMojoObserverContactsDownloaded(allowed_contact_ids, *contacts);
// Request a contacts upload if needed, or process an existing upload // Request a contacts upload if needed, or process an existing upload
// request now that we have the access to the full contacts list. // request now that we have the access to the full contacts list.
...@@ -221,6 +286,11 @@ void NearbyShareContactManagerImpl::OnContactsDownloadSuccess( ...@@ -221,6 +286,11 @@ void NearbyShareContactManagerImpl::OnContactsDownloadSuccess(
} }
void NearbyShareContactManagerImpl::OnContactsDownloadFailure() { void NearbyShareContactManagerImpl::OnContactsDownloadFailure() {
// Notify mojo remotes.
for (auto& remote : observers_set_) {
remote->OnContactsDownloadFailed();
}
contact_download_scheduler_->HandleResult(/*success=*/false); contact_download_scheduler_->HandleResult(/*success=*/false);
} }
...@@ -289,3 +359,21 @@ bool NearbyShareContactManagerImpl::SetAllowlist( ...@@ -289,3 +359,21 @@ bool NearbyShareContactManagerImpl::SetAllowlist(
return true; return true;
} }
void NearbyShareContactManagerImpl::NotifyMojoObserverContactsDownloaded(
const std::set<std::string>& allowed_contact_ids,
const std::vector<nearbyshare::proto::ContactRecord>& contacts) {
if (observers_set_.empty()) {
return;
}
// Mojo doesn't have sets, so we have to copy to an array.
std::vector<std::string> allowed_contact_ids_vector(
allowed_contact_ids.begin(), allowed_contact_ids.end());
// Notify mojo remotes.
for (auto& remote : observers_set_) {
remote->OnContactsDownloaded(allowed_contact_ids_vector,
ProtoToMojo(contacts));
}
}
...@@ -13,6 +13,10 @@ ...@@ -13,6 +13,10 @@
#include "base/optional.h" #include "base/optional.h"
#include "chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager.h" #include "chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager.h"
#include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h" #include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote_set.h"
class NearbyShareClientFactory; class NearbyShareClientFactory;
class NearbyShareContactDownloader; class NearbyShareContactDownloader;
...@@ -74,6 +78,18 @@ class NearbyShareContactManagerImpl : public NearbyShareContactManager { ...@@ -74,6 +78,18 @@ class NearbyShareContactManagerImpl : public NearbyShareContactManager {
const std::set<std::string>& allowed_contact_ids) override; const std::set<std::string>& allowed_contact_ids) override;
void OnStart() override; void OnStart() override;
void OnStop() override; void OnStop() override;
void Bind(mojo::PendingReceiver<nearby_share::mojom::ContactManager> receiver)
override;
void NotifyMojoObserverContactsDownloaded(
const std::set<std::string>& allowed_contact_ids,
const std::vector<nearbyshare::proto::ContactRecord>& contacts);
// nearby_share::mojom::ContactsManager:
void AddDownloadContactsObserver(
::mojo::PendingRemote<nearby_share::mojom::DownloadContactsObserver>
observer) override;
void DownloadContacts() override;
std::set<std::string> GetAllowedContacts() const; std::set<std::string> GetAllowedContacts() const;
void OnContactsDownloadRequested(); void OnContactsDownloadRequested();
...@@ -101,6 +117,8 @@ class NearbyShareContactManagerImpl : public NearbyShareContactManager { ...@@ -101,6 +117,8 @@ class NearbyShareContactManagerImpl : public NearbyShareContactManager {
std::unique_ptr<NearbyShareScheduler> contact_download_scheduler_; std::unique_ptr<NearbyShareScheduler> contact_download_scheduler_;
std::unique_ptr<NearbyShareScheduler> contact_upload_scheduler_; std::unique_ptr<NearbyShareScheduler> contact_upload_scheduler_;
std::unique_ptr<NearbyShareContactDownloader> contact_downloader_; std::unique_ptr<NearbyShareContactDownloader> contact_downloader_;
mojo::RemoteSet<nearby_share::mojom::DownloadContactsObserver> observers_set_;
mojo::ReceiverSet<nearby_share::mojom::ContactManager> receiver_set_;
base::WeakPtrFactory<NearbyShareContactManagerImpl> weak_ptr_factory_{this}; base::WeakPtrFactory<NearbyShareContactManagerImpl> weak_ptr_factory_{this};
}; };
......
...@@ -22,7 +22,10 @@ ...@@ -22,7 +22,10 @@
#include "chrome/browser/nearby_sharing/scheduling/fake_nearby_share_scheduler.h" #include "chrome/browser/nearby_sharing/scheduling/fake_nearby_share_scheduler.h"
#include "chrome/browser/nearby_sharing/scheduling/fake_nearby_share_scheduler_factory.h" #include "chrome/browser/nearby_sharing/scheduling/fake_nearby_share_scheduler_factory.h"
#include "chrome/browser/nearby_sharing/scheduling/nearby_share_scheduler_factory.h" #include "chrome/browser/nearby_sharing/scheduling/nearby_share_scheduler_factory.h"
#include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom-test-utils.h"
#include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h"
#include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace { namespace {
...@@ -65,8 +68,20 @@ std::vector<nearbyshare::proto::ContactRecord> TestContactRecordList( ...@@ -65,8 +68,20 @@ std::vector<nearbyshare::proto::ContactRecord> TestContactRecordList(
for (size_t i = 0; i < num_contacts; ++i) { for (size_t i = 0; i < num_contacts; ++i) {
nearbyshare::proto::ContactRecord contact; nearbyshare::proto::ContactRecord contact;
contact.set_id(GetTestContactId(i)); contact.set_id(GetTestContactId(i));
contact.add_identifiers()->set_account_name(GetTestContactEmail(i)); contact.set_image_url("https://google.com");
contact.add_identifiers()->set_phone_number(GetTestContactPhone(i)); contact.set_person_name("John Doe");
// only one of these fields should be set...
switch ((i % 3)) {
case 0:
contact.add_identifiers()->set_account_name(GetTestContactEmail(i));
break;
case 1:
contact.add_identifiers()->set_phone_number(GetTestContactPhone(i));
break;
case 2:
contact.add_identifiers()->set_obfuscated_gaia("4938tyah");
break;
}
contact_list.push_back(contact); contact_list.push_back(contact);
} }
return contact_list; return contact_list;
...@@ -90,6 +105,28 @@ std::vector<nearbyshare::proto::Contact> ContactRecordsToContacts( ...@@ -90,6 +105,28 @@ std::vector<nearbyshare::proto::Contact> ContactRecordsToContacts(
return contacts; return contacts;
} }
class TestDownloadContactsObserver
: public nearby_share::mojom::DownloadContactsObserver {
public:
void OnContactsDownloaded(
const std::vector<std::string>& allowed_contacts,
std::vector<nearby_share::mojom::ContactRecordPtr> contacts) override {
allowed_contacts_ = allowed_contacts;
contacts_ = std::move(contacts);
on_contacts_downloaded_called_ = true;
}
void OnContactsDownloadFailed() override {
on_contacts_download_failed_called_ = true;
}
std::vector<std::string> allowed_contacts_;
std::vector<nearby_share::mojom::ContactRecordPtr> contacts_;
bool on_contacts_downloaded_called_ = false;
bool on_contacts_download_failed_called_ = false;
mojo::Receiver<nearby_share::mojom::DownloadContactsObserver> receiver_{this};
};
} // namespace } // namespace
class NearbyShareContactManagerImplTest class NearbyShareContactManagerImplTest
...@@ -119,12 +156,18 @@ class NearbyShareContactManagerImplTest ...@@ -119,12 +156,18 @@ class NearbyShareContactManagerImplTest
manager_ = NearbyShareContactManagerImpl::Factory::Create( manager_ = NearbyShareContactManagerImpl::Factory::Create(
&pref_service_, &http_client_factory_, &local_device_data_manager_); &pref_service_, &http_client_factory_, &local_device_data_manager_);
manager_awaiter_ =
std::make_unique<nearby_share::mojom::ContactManagerAsyncWaiter>(
manager_.get());
VerifySchedulerInitialization(); VerifySchedulerInitialization();
manager_->AddObserver(this); manager_->AddObserver(this);
manager_->AddDownloadContactsObserver(
mojo_observer_.receiver_.BindNewPipeAndPassRemote());
manager_->Start(); manager_->Start();
} }
void TearDown() override { void TearDown() override {
manager_awaiter_.reset();
manager_->RemoveObserver(this); manager_->RemoveObserver(this);
manager_.reset(); manager_.reset();
NearbyShareSchedulerFactory::SetFactoryForTesting(nullptr); NearbyShareSchedulerFactory::SetFactoryForTesting(nullptr);
...@@ -132,6 +175,10 @@ class NearbyShareContactManagerImplTest ...@@ -132,6 +175,10 @@ class NearbyShareContactManagerImplTest
} }
void DownloadContacts(bool only_download_if_changed) { void DownloadContacts(bool only_download_if_changed) {
// Manually reset these before each download.
mojo_observer_.on_contacts_downloaded_called_ = false;
mojo_observer_.on_contacts_download_failed_called_ = false;
// Verify that the download scheduler is sent request. // Verify that the download scheduler is sent request.
size_t num_requests = download_scheduler()->num_immediate_requests(); size_t num_requests = download_scheduler()->num_immediate_requests();
manager_->DownloadContacts(only_download_if_changed); manager_->DownloadContacts(only_download_if_changed);
...@@ -194,6 +241,15 @@ class NearbyShareContactManagerImplTest ...@@ -194,6 +241,15 @@ class NearbyShareContactManagerImplTest
EXPECT_EQ(num_handled_results + 1, EXPECT_EQ(num_handled_results + 1,
download_scheduler()->handled_results().size()); download_scheduler()->handled_results().size());
EXPECT_TRUE(download_scheduler()->handled_results().back()); EXPECT_TRUE(download_scheduler()->handled_results().back());
// Verify the mojo observer was called if we had contacts.
mojo_observer_.receiver_.FlushForTesting();
EXPECT_EQ(contacts.has_value(),
mojo_observer_.on_contacts_downloaded_called_);
EXPECT_FALSE(mojo_observer_.on_contacts_download_failed_called_);
if (contacts) {
VerifyMojoContacts(contacts.value(), mojo_observer_.contacts_);
}
} }
void FailDownload(bool expected_only_download_if_changed) { void FailDownload(bool expected_only_download_if_changed) {
...@@ -205,6 +261,11 @@ class NearbyShareContactManagerImplTest ...@@ -205,6 +261,11 @@ class NearbyShareContactManagerImplTest
EXPECT_EQ(num_handled_results + 1, EXPECT_EQ(num_handled_results + 1,
download_scheduler()->handled_results().size()); download_scheduler()->handled_results().size());
EXPECT_FALSE(download_scheduler()->handled_results().back()); EXPECT_FALSE(download_scheduler()->handled_results().back());
// Verify the mojo observer was called as well.
mojo_observer_.receiver_.FlushForTesting();
EXPECT_FALSE(mojo_observer_.on_contacts_downloaded_called_);
EXPECT_TRUE(mojo_observer_.on_contacts_download_failed_called_);
} }
void TriggerUploadFromScheduler() { void TriggerUploadFromScheduler() {
...@@ -397,6 +458,47 @@ class NearbyShareContactManagerImplTest ...@@ -397,6 +458,47 @@ class NearbyShareContactManagerImplTest
} }
} }
void VerifyMojoContacts(
const std::vector<nearbyshare::proto::ContactRecord>& proto_list,
const std::vector<nearby_share::mojom::ContactRecordPtr>& mojo_list) {
ASSERT_EQ(proto_list.size(), mojo_list.size());
int i = 0;
for (auto& proto_contact : proto_list) {
auto& mojo_contact = mojo_list.at(i++);
EXPECT_EQ(proto_contact.id(), mojo_contact->id);
EXPECT_EQ(proto_contact.person_name(), mojo_contact->person_name);
EXPECT_EQ(GURL(proto_contact.image_url()), mojo_contact->image_url);
ASSERT_EQ((size_t)proto_contact.identifiers().size(),
mojo_contact->identifiers.size());
int j = 0;
for (auto& proto_identifier : proto_contact.identifiers()) {
auto& mojo_identifier = mojo_contact->identifiers.at(j++);
switch (proto_identifier.identifier_case()) {
case nearbyshare::proto::Contact_Identifier::IdentifierCase::
kAccountName:
EXPECT_EQ(proto_identifier.account_name(),
mojo_identifier->get_account_name());
break;
case nearbyshare::proto::Contact_Identifier::IdentifierCase::
kObfuscatedGaia:
EXPECT_EQ(proto_identifier.obfuscated_gaia(),
mojo_identifier->get_obfuscated_gaia());
break;
case nearbyshare::proto::Contact_Identifier::IdentifierCase::
kPhoneNumber:
EXPECT_EQ(proto_identifier.phone_number(),
mojo_identifier->get_phone_number());
break;
case nearbyshare::proto::Contact_Identifier::IdentifierCase::
IDENTIFIER_NOT_SET:
NOTREACHED();
break;
}
}
}
}
TestDownloadContactsObserver mojo_observer_;
std::vector<AllowlistChangedNotification> allowlist_changed_notifications_; std::vector<AllowlistChangedNotification> allowlist_changed_notifications_;
std::vector<ContactsDownloadedNotification> std::vector<ContactsDownloadedNotification>
contacts_downloaded_notifications_; contacts_downloaded_notifications_;
...@@ -407,6 +509,9 @@ class NearbyShareContactManagerImplTest ...@@ -407,6 +509,9 @@ class NearbyShareContactManagerImplTest
FakeNearbyShareSchedulerFactory scheduler_factory_; FakeNearbyShareSchedulerFactory scheduler_factory_;
FakeNearbyShareContactDownloader::Factory downloader_factory_; FakeNearbyShareContactDownloader::Factory downloader_factory_;
std::unique_ptr<NearbyShareContactManager> manager_; std::unique_ptr<NearbyShareContactManager> manager_;
std::unique_ptr<nearby_share::mojom::ContactManagerAsyncWaiter>
manager_awaiter_;
content::BrowserTaskEnvironment task_environment_;
}; };
TEST_F(NearbyShareContactManagerImplTest, SetAllowlist) { TEST_F(NearbyShareContactManagerImplTest, SetAllowlist) {
......
...@@ -50,6 +50,7 @@ js_library("nearby_share_settings") { ...@@ -50,6 +50,7 @@ js_library("nearby_share_settings") {
deps = [ deps = [
"//chrome/browser/ui/webui/nearby_share/public/mojom:mojom_js_library_for_compile", "//chrome/browser/ui/webui/nearby_share/public/mojom:mojom_js_library_for_compile",
"//ui/webui/resources/js:cr", "//ui/webui/resources/js:cr",
"//url/mojom:url_mojom_gurl_js_library_for_compile",
] ]
} }
...@@ -141,6 +142,7 @@ js_library("nearby_share_settings.m") { ...@@ -141,6 +142,7 @@ js_library("nearby_share_settings.m") {
deps = [ deps = [
"//chrome/browser/ui/webui/nearby_share/public/mojom:mojom_js_library_for_compile", "//chrome/browser/ui/webui/nearby_share/public/mojom:mojom_js_library_for_compile",
"//ui/webui/resources/js:cr.m", "//ui/webui/resources/js:cr.m",
"//url/mojom:url_mojom_gurl_js_library_for_compile",
] ]
extra_deps = [ ":modulize" ] extra_deps = [ ":modulize" ]
} }
......
<link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html"> <link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
<script src="chrome://resources/mojo/url/mojom/url.mojom-lite.js"></script>
<script src="/mojo/nearby_share_settings.mojom-lite.js"></script> <script src="/mojo/nearby_share_settings.mojom-lite.js"></script>
<script src="nearby_share_settings.js"></script> <script src="nearby_share_settings.js"></script>
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
// clang-format off // clang-format off
// #import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; // #import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
// #import 'chrome://resources/mojo/url/mojom/url.mojom-lite.js'
// #import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; // #import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
// #import '/mojo/nearby_share_settings.mojom-lite.js'; // #import '/mojo/nearby_share_settings.mojom-lite.js';
// clang-format on // clang-format on
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
// clang-format off // clang-format off
// #import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; // #import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
// #import 'chrome://resources/mojo/url/mojom/url.mojom-lite.js'
// #import 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js'; // #import 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js';
// #import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; // #import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
// #import '/mojo/nearby_share_target_types.mojom-lite.js'; // #import '/mojo/nearby_share_target_types.mojom-lite.js';
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <string> #include <string>
#include "chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager.h"
#include "chrome/browser/nearby_sharing/nearby_per_session_discovery_manager.h" #include "chrome/browser/nearby_sharing/nearby_per_session_discovery_manager.h"
#include "chrome/browser/nearby_sharing/nearby_share_settings.h" #include "chrome/browser/nearby_sharing/nearby_share_settings.h"
#include "chrome/browser/nearby_sharing/nearby_sharing_service.h" #include "chrome/browser/nearby_sharing/nearby_sharing_service.h"
...@@ -93,6 +94,14 @@ void NearbyShareDialogUI::BindInterface( ...@@ -93,6 +94,14 @@ void NearbyShareDialogUI::BindInterface(
nearby_sharing_service->GetSettings()->Bind(std::move(receiver)); nearby_sharing_service->GetSettings()->Bind(std::move(receiver));
} }
void NearbyShareDialogUI::BindInterface(
mojo::PendingReceiver<nearby_share::mojom::ContactManager> receiver) {
NearbySharingService* nearby_sharing_service =
NearbySharingServiceFactory::GetForBrowserContext(
Profile::FromWebUI(web_ui()));
nearby_sharing_service->GetContactManager()->Bind(std::move(receiver));
}
void NearbyShareDialogUI::HandleClose(const base::ListValue* args) { void NearbyShareDialogUI::HandleClose(const base::ListValue* args) {
for (auto& observer : observers_) { for (auto& observer : observers_) {
observer.OnClose(); observer.OnClose();
......
...@@ -43,6 +43,10 @@ class NearbyShareDialogUI : public ui::MojoWebUIController { ...@@ -43,6 +43,10 @@ class NearbyShareDialogUI : public ui::MojoWebUIController {
// ui::MojoWebUIController // ui::MojoWebUIController
void BindInterface( void BindInterface(
mojo::PendingReceiver<mojom::NearbyShareSettings> receiver); mojo::PendingReceiver<mojom::NearbyShareSettings> receiver);
// Binds to the existing contacts manager instance owned by the nearby share
// keyed service.
void BindInterface(
mojo::PendingReceiver<nearby_share::mojom::ContactManager> receiver);
private: private:
void HandleClose(const base::ListValue* args); void HandleClose(const base::ListValue* args);
......
...@@ -7,5 +7,8 @@ import("//mojo/public/tools/bindings/mojom.gni") ...@@ -7,5 +7,8 @@ import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") { mojom("mojom") {
sources = [ "nearby_share_settings.mojom" ] sources = [ "nearby_share_settings.mojom" ]
public_deps = [ "//mojo/public/mojom/base" ] public_deps = [
"//mojo/public/mojom/base",
"//url/mojom:url_mojom_gurl",
]
} }
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
// found in the LICENSE file. // found in the LICENSE file.
module nearby_share.mojom; module nearby_share.mojom;
import "url/mojom/url.mojom";
// TODO(crbug.com/1110098): Remove kUnknown. // TODO(crbug.com/1110098): Remove kUnknown.
// Represents the data usage preference when sharing. // Represents the data usage preference when sharing.
enum DataUsage { enum DataUsage {
...@@ -72,6 +74,9 @@ interface NearbyShareSettings { ...@@ -72,6 +74,9 @@ interface NearbyShareSettings {
// Set the visibility of this device with respect to the user's contacts. // Set the visibility of this device with respect to the user's contacts.
SetVisibility(Visibility visibility); SetVisibility(Visibility visibility);
// TODO(crbug.com/1128110): This functionality has been moved to
// ContactManger and will be removed in a follow up CL.
//
// Get all contact ids that this device should be visible to when visibility // Get all contact ids that this device should be visible to when visibility
// is |kSelectedContacts|. // is |kSelectedContacts|.
GetAllowedContacts() => (array<string> allowed_contacts); GetAllowedContacts() => (array<string> allowed_contacts);
...@@ -79,3 +84,82 @@ interface NearbyShareSettings { ...@@ -79,3 +84,82 @@ interface NearbyShareSettings {
// is |kSelectedContacts|. // is |kSelectedContacts|.
SetAllowedContacts(array<string> allowed_contacts); SetAllowedContacts(array<string> allowed_contacts);
}; };
// Translated from the proto file (Contact.Identifier):
// https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/nearby_sharing/proto/rpc_resources.proto
// A single contact identifier.
union ContactIdentifier {
string obfuscated_gaia;
string phone_number;
string account_name;
};
// Translated from the proto file (ContactRecord):
// https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/nearby_sharing/proto/rpc_resources.proto
// A contact record from People backend.
struct ContactRecord {
// The stable id of this contact record.
string id;
// The contact record's name.
string person_name;
// The URL of an image displayed to the user when selecting a share
// target.
url.mojom.Url image_url;
array<ContactIdentifier> identifiers;
};
// Allows a client of |ContactManager| to observe contacts downloading results.
// These events can be in response to direct requests or due to periodic
// updates.
//
// This interface is implemented in a shared Polymer component that is used in
// two WebUIs: chrome://nearby and chrome://os-settings.
interface DownloadContactsObserver {
// Notifies the observer that contacts have been downloaded successfully and
// gives the most recent allowed contact ids at the same time.
//
// |allowed_contacts| is a set of contacts ids used when visibility is
// |Visibility::kSelectedContacts|. This can be set explicitly with
// SetAllowedContacts() on |ContactManager|. This array may be empty if the
// user has not selected any contacts yet.
// |contacts| is a full set of a user's GAIA contacts from the the people
// api. The list is pre-sorted by person_name server side. Any ids present
// in allowed_contacts will have a corresponding contact record here. This
// array may be empty if the user has no contacts (in which case
// |allowed_contacts| will also be empty).
OnContactsDownloaded(array<string> allowed_contacts,
array<ContactRecord> contacts);
// Notifies the observer that contacts have failed to download.
// NOTE: At the moment we don't provide a specific reason as to why this
// failed, it is just a signal for the UI to show a generic error/retry page.
OnContactsDownloadFailed();
};
// The contacts manager allows clients to observe contacts downloading status
// and results. Contact downloads can happen periodically or on demand with
// DownloadContacts(). The results are not returned directly on DownloadContacts
// because multiple queued download requests may result in only a single
// response and a client is likely interested in getting any contacts download
// even if they did not explicitly request it (i.e. periodic update).
//
// Implemented in the browser process and owned by a keyed service.
interface ContactManager {
// Adds an observer which can listen for the success or failure of contact
// downloading.
AddDownloadContactsObserver(pending_remote<DownloadContactsObserver>
observer);
// Request a download of contacts from the server. This will queue the call
// with the scheduler which may or may not execute right away depending on the
// online state of the device.
DownloadContacts();
// Set all contact ids that this device should be visible to when visibility
// is |Visibility::kSelectedContacts|. Once set, this will update the device's
// private certificates. The latest value of this will be sent on the next
// OnContactsDownloaded event on the observer interface, but it will not
// trigger an immediate OnContactsDownloaded() event.
SetAllowedContacts(array<string> allowed_contacts);
};
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "ash/public/cpp/network_config_service.h" #include "ash/public/cpp/network_config_service.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
#include "chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager.h"
#include "chrome/browser/nearby_sharing/nearby_receive_manager.h" #include "chrome/browser/nearby_sharing/nearby_receive_manager.h"
#include "chrome/browser/nearby_sharing/nearby_share_settings.h" #include "chrome/browser/nearby_sharing/nearby_share_settings.h"
#include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h" #include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h"
...@@ -179,6 +180,14 @@ void OSSettingsUI::BindInterface( ...@@ -179,6 +180,14 @@ void OSSettingsUI::BindInterface(
std::move(receiver)); std::move(receiver));
} }
void OSSettingsUI::BindInterface(
mojo::PendingReceiver<nearby_share::mojom::ContactManager> receiver) {
NearbySharingService* service =
NearbySharingServiceFactory::GetForBrowserContext(
Profile::FromWebUI(web_ui()));
service->GetContactManager()->Bind(std::move(receiver));
}
WEB_UI_CONTROLLER_TYPE_IMPL(OSSettingsUI) WEB_UI_CONTROLLER_TYPE_IMPL(OSSettingsUI)
} // namespace settings } // namespace settings
......
...@@ -73,6 +73,11 @@ class OSSettingsUI : public ui::MojoWebUIController { ...@@ -73,6 +73,11 @@ class OSSettingsUI : public ui::MojoWebUIController {
void BindInterface( void BindInterface(
mojo::PendingReceiver<nearby_share::mojom::ReceiveManager> receiver); mojo::PendingReceiver<nearby_share::mojom::ReceiveManager> receiver);
// Binds to the existing contacts manager instance owned by the nearby share
// keyed service.
void BindInterface(
mojo::PendingReceiver<nearby_share::mojom::ContactManager> receiver);
private: private:
base::TimeTicks time_when_opened_; base::TimeTicks time_when_opened_;
......
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