Commit 5e10a0f6 authored by Richard Knoll's avatar Richard Knoll Committed by Commit Bot

[Nearby] Define NearbyProcessManager singleton

This class manages the lifetime and profile affinity of the sandbox
process that runs Nearby Connections. Only one instance of the process
will run at a time and it will be associated with one profile only. A
profile can be set as the active profile (usually via an explicit user
action) after which it gets access to the mojo interfaces running in the
sandboxed process.

Bug: 1084576
Change-Id: I50c8c61e1b7b85a078f4fdea96e0ecda1ac57123
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2196486Reviewed-by: default avatarDominic Battré <battre@chromium.org>
Reviewed-by: default avatarAlex Chau <alexchau@chromium.org>
Commit-Queue: Richard Knoll <knollr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#772209}
parent 213a1bb3
...@@ -3411,6 +3411,8 @@ static_library("browser") { ...@@ -3411,6 +3411,8 @@ static_library("browser") {
"nearby_sharing/nearby_connection.h", "nearby_sharing/nearby_connection.h",
"nearby_sharing/nearby_connections_manager.h", "nearby_sharing/nearby_connections_manager.h",
"nearby_sharing/nearby_constants.h", "nearby_sharing/nearby_constants.h",
"nearby_sharing/nearby_process_manager.cc",
"nearby_sharing/nearby_process_manager.h",
"nearby_sharing/nearby_sharing_prefs.cc", "nearby_sharing/nearby_sharing_prefs.cc",
"nearby_sharing/nearby_sharing_prefs.h", "nearby_sharing/nearby_sharing_prefs.h",
"nearby_sharing/nearby_sharing_service.h", "nearby_sharing/nearby_sharing_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/nearby_sharing/nearby_process_manager.h"
#include "base/files/file_path.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/nearby_sharing/nearby_sharing_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/sharing/webrtc/sharing_mojo_service.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/service_process_host.h"
namespace {
ProfileAttributesEntry* GetStoredNearbyProfile() {
PrefService* local_state = g_browser_process->local_state();
if (!local_state)
return nullptr;
base::FilePath advertising_profile_path =
local_state->GetFilePath(kNearbySharingActiveProfilePrefName);
if (advertising_profile_path.empty())
return nullptr;
ProfileManager* profile_manager = g_browser_process->profile_manager();
if (!profile_manager)
return nullptr;
ProfileAttributesStorage& storage =
profile_manager->GetProfileAttributesStorage();
ProfileAttributesEntry* entry;
if (!storage.GetProfileAttributesWithPath(advertising_profile_path, &entry)) {
// Stored profile path is invalid so remove it.
local_state->ClearPref(kNearbySharingActiveProfilePrefName);
return nullptr;
}
return entry;
}
void SetStoredNearbyProfile(Profile* profile) {
PrefService* local_state = g_browser_process->local_state();
if (!local_state)
return;
if (profile) {
local_state->SetFilePath(kNearbySharingActiveProfilePrefName,
profile->GetPath());
} else {
local_state->ClearPref(kNearbySharingActiveProfilePrefName);
}
}
bool IsStoredNearbyProfile(Profile* profile) {
ProfileAttributesEntry* entry = GetStoredNearbyProfile();
if (!entry)
return profile == nullptr;
return profile && entry->GetPath() == profile->GetPath();
}
} // namespace
// static
NearbyProcessManager& NearbyProcessManager::GetInstance() {
static base::NoDestructor<NearbyProcessManager> instance;
return *instance;
}
void NearbyProcessManager::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void NearbyProcessManager::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
ProfileAttributesEntry* NearbyProcessManager::GetActiveProfile() const {
return GetStoredNearbyProfile();
}
bool NearbyProcessManager::IsActiveProfile(Profile* profile) const {
// If the active profile is not loaded yet, try looking in prefs.
// TODO(knollr): Add a test for this.
if (!active_profile_)
return IsStoredNearbyProfile(profile);
return active_profile_ == profile;
}
bool NearbyProcessManager::IsAnyProfileActive() const {
return !IsActiveProfile(/*profile=*/nullptr);
}
void NearbyProcessManager::SetActiveProfile(Profile* profile) {
if (IsActiveProfile(profile))
return;
active_profile_ = profile;
SetStoredNearbyProfile(active_profile_);
StopProcess(active_profile_);
for (auto& observer : observers_)
observer.OnNearbyProfileChanged(profile);
}
void NearbyProcessManager::ClearActiveProfile() {
SetActiveProfile(/*profile=*/nullptr);
}
location::nearby::connections::mojom::NearbyConnections*
NearbyProcessManager::GetOrStartNearbyConnections(Profile* profile) {
if (!IsActiveProfile(profile))
return nullptr;
// Launch a new Nearby Connections interface if required.
if (!connections_.is_bound())
BindNearbyConnections();
return connections_.get();
}
void NearbyProcessManager::StopProcess(Profile* profile) {
if (!IsActiveProfile(profile))
return;
bool was_running = sharing_process_.is_bound();
connections_host_.reset();
connections_.reset();
sharing_process_.reset();
if (was_running) {
for (auto& observer : observers_)
observer.OnNearbyProcessStopped();
}
}
void NearbyProcessManager::OnProfileAdded(Profile* profile) {
// Cache active |profile| once it loads so we don't have to check prefs.
if (IsActiveProfile(profile))
active_profile_ = profile;
}
void NearbyProcessManager::OnProfileMarkedForPermanentDeletion(
Profile* profile) {
if (IsActiveProfile(profile))
SetActiveProfile(nullptr);
}
void NearbyProcessManager::BindSharingProcess(
mojo::PendingRemote<sharing::mojom::Sharing> sharing) {
sharing_process_.Bind(std::move(sharing));
// base::Unretained() is safe as |this| is a singleton.
sharing_process_.set_disconnect_handler(base::BindOnce(
&NearbyProcessManager::OnNearbyProcessStopped, base::Unretained(this)));
}
NearbyProcessManager::NearbyProcessManager() {
// profile_manager() might be null in tests or during shutdown.
if (auto* manager = g_browser_process->profile_manager())
manager->AddObserver(this);
}
NearbyProcessManager::~NearbyProcessManager() {
if (auto* manager = g_browser_process->profile_manager())
manager->RemoveObserver(this);
}
void NearbyProcessManager::LaunchNewProcess() {
// Stop any running process and mojo pipes.
StopProcess(active_profile_);
// Launch a new sandboxed process.
// TODO(knollr): Set process name to "Nearby Sharing".
BindSharingProcess(sharing::LaunchSharing());
}
void NearbyProcessManager::BindNearbyConnections() {
// Start a new process if there is none running yet.
if (!sharing_process_.is_bound())
LaunchNewProcess();
// Create the Nearby Connections stack in the sandboxed process.
// base::Unretained() calls below are safe as |this| is a singleton.
sharing_process_->CreateNearbyConnections(
connections_host_.BindNewPipeAndPassRemote(),
base::BindOnce(&NearbyProcessManager::OnNearbyConnections,
base::Unretained(this),
connections_.BindNewPipeAndPassReceiver()));
// Terminate the process if the Nearby Connections interface disconnects as
// that indicated an incorrect state and we have to restart the process.
connections_host_.set_disconnect_handler(base::BindOnce(
&NearbyProcessManager::OnNearbyProcessStopped, base::Unretained(this)));
connections_.set_disconnect_handler(base::BindOnce(
&NearbyProcessManager::OnNearbyProcessStopped, base::Unretained(this)));
}
void NearbyProcessManager::OnNearbyConnections(
mojo::PendingReceiver<NearbyConnectionsMojom> receiver,
mojo::PendingRemote<NearbyConnectionsMojom> remote) {
if (!mojo::FusePipes(std::move(receiver), std::move(remote))) {
LOG(WARNING) << "Failed to initialize Nearby Connectins process";
StopProcess(active_profile_);
return;
}
for (auto& observer : observers_)
observer.OnNearbyProcessStarted();
}
void NearbyProcessManager::OnNearbyProcessStopped() {
StopProcess(active_profile_);
}
// 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_NEARBY_SHARING_NEARBY_PROCESS_MANAGER_H_
#define CHROME_BROWSER_NEARBY_SHARING_NEARBY_PROCESS_MANAGER_H_
#include "base/gtest_prod_util.h"
#include "base/no_destructor.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/scoped_observer.h"
#include "chrome/browser/profiles/profile_manager_observer.h"
#include "chrome/services/sharing/public/mojom/nearby_connections.mojom.h"
#include "chrome/services/sharing/public/mojom/sharing.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
class Profile;
class ProfileAttributesEntry;
// Manages the lifetime of the Nearby process. It runs the Nearby Connections
// library and Nearby Sharing data decoding. Only one instance of the process is
// supported at a time.
class NearbyProcessManager
: public ProfileManagerObserver,
public location::nearby::connections::mojom::NearbyConnectionsHost {
public:
using NearbyConnectionsMojom =
location::nearby::connections::mojom::NearbyConnections;
using NearbyConnectionsHostMojom =
location::nearby::connections::mojom::NearbyConnectionsHost;
// Returns an instance to the singleton of this class. This is used from
// multiple BCKS and only allows the first one to launch a process.
static NearbyProcessManager& GetInstance();
// Observes the global state of the NearbyProcessManager.
class Observer : public base::CheckedObserver {
public:
// Called when the |profile| got set as the active profile.
virtual void OnNearbyProfileChanged(Profile* profile) = 0;
// Called when the Nearby process has started. This happens after a profile
// called one of the GetOrStart*() methods.
virtual void OnNearbyProcessStarted() = 0;
// Called when the Nearby process has stopped. This can happen when the
// process gets stopped to switch to a different profile or when the process
// gets killed by the system.
virtual void OnNearbyProcessStopped() = 0;
};
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Gets the entry for the currently active profile or nullptr if no profile is
// set. We return a ProfileAttributesEntry instead of a Profile as the active
// profile might not be loaded yet and we do not want to load it here.
ProfileAttributesEntry* GetActiveProfile() const;
// Returns whether the |profile| is the active profile to use the Nearby
// process. Convenience method to calling GetActiveProfile() and manually
// comparing if they match.
bool IsActiveProfile(Profile* profile) const;
// Returns if any profile is currently set as the active profile. Note that
// the active profile might not be loaded yet.
bool IsAnyProfileActive() const;
// Starts an exclusive usage of the Nearby process for the given |profile|.
// This will stop the process if it is currently running for a different
// profile. After calling this the client may call any of the GetOrStart*()
// methods below to start up a new sandboxed process.
void SetActiveProfile(Profile* profile);
// Removes any stored active profile. This will stop the process if it is
// currently running for that profile.
void ClearActiveProfile();
// Gets a pointer to the Nearby Connections interface. If there is currently
// no process running this will start a new sandboxed process. This will
// only work if the |profile| is currently set as the active profile.
// Returns a mojo interface to the Nearby Connections library inside the
// sandbox if this |profile| is allowed to access it and nullptr otherwise.
// Don't store this pointer as it might get invalid if the process gets
// stopped (via the OS or StopProcess()). That event can be observed via
// Observer::OnNearbyProcessStopped() and a client can decide to restart the
// process (e.g. via backoff timer) if it is still the active profile.
NearbyConnectionsMojom* GetOrStartNearbyConnections(Profile* profile);
// TODO(knollr): Add once the mojo interface for the decoder is submitted.
// Gets a pointer to the Nearby Decoder interface. Starts a new process if
// there is none running already or reuses an existing one. The same
// limitations around profiles and lifetime in GetOrStartNearbyConnections()
// apply here as well.
// NearbySharingDecoderMojom* GetOrStartNearbyDecoder(Profile* profile);
// Stops the Nearby process if the |profile| is the active profile. This may
// be used to save resources or to force stop any communication of the
// Nearby Connections library if it should not be used right now. This will
// not change the active profile and can be used to temporarily stop the
// process (e.g. on screen lock) while keeping the active profile.
void StopProcess(Profile* profile);
// ProfileManagerObserver:
void OnProfileAdded(Profile* profile) override;
void OnProfileMarkedForPermanentDeletion(Profile* profile) override;
// Binds the given |sharing| remote to be used as the interface to the Sharing
// process running in a sandbox.
void BindSharingProcess(mojo::PendingRemote<sharing::mojom::Sharing> sharing);
private:
FRIEND_TEST_ALL_PREFIXES(NearbyProcessManagerTest, AddRemoveObserver);
friend class base::NoDestructor<NearbyProcessManager>;
// This class is a singleton.
NearbyProcessManager();
~NearbyProcessManager() override;
// Launches a new sandboxed process and stops any currently running one. This
// process is then used to run the Nearby Connections library. The process
// will use the current profile to initialize Nearby Connections as returned
// by UsedProfile().
void LaunchNewProcess();
// Binds a new pipe to the Nearby Connections library. May start a new process
// if there is none running yet.
void BindNearbyConnections();
// Called by the sandboxed process after initializing the Nearby Connections
// library.
void OnNearbyConnections(
mojo::PendingReceiver<NearbyConnectionsMojom> receiver,
mojo::PendingRemote<NearbyConnectionsMojom> remote);
// Called if any of the mojo interfaces to the sandboxed process disconnects.
// If that happens we stop the process and notify all observers via
// Observer::OnNearbyProcessStopped().
void OnNearbyProcessStopped();
// The bound remote to a sandboxed process.
mojo::Remote<sharing::mojom::Sharing> sharing_process_;
// The bound remote to the Nearby Connections library inside the sandbox.
mojo::Remote<NearbyConnectionsMojom> connections_;
// TODO(knollr): Add once the mojo interface for the decoder is submitted.
// The bound remote to the Nearby Decoder interface inside the sandbox.
// mojo::Remote<NearbySharingDecoderMojom> decoder_;
// Host interface for the Nearby Connections interface.
mojo::Receiver<NearbyConnectionsHostMojom> connections_host_{this};
// All registered observers, typically one per loaded profile.
base::ObserverList<Observer> observers_;
// Profile using the Nearby process. This might be nullptr if the active
// profile has not been loaded yet.
Profile* active_profile_ = nullptr;
};
#endif // CHROME_BROWSER_NEARBY_SHARING_NEARBY_PROCESS_MANAGER_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/nearby_sharing/nearby_process_manager.h"
#include <memory>
#include <set>
#include <string>
#include "base/files/file_path.h"
#include "base/run_loop.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/services/sharing/public/mojom/nearby_connections.mojom.h"
#include "chrome/services/sharing/public/mojom/nearby_connections_types.mojom.h"
#include "chrome/services/sharing/public/mojom/sharing.mojom.h"
#include "chrome/services/sharing/public/mojom/webrtc.mojom.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_utils.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using NearbyConnectionsMojom =
location::nearby::connections::mojom::NearbyConnections;
using NearbyConnectionsHostMojom =
location::nearby::connections::mojom::NearbyConnectionsHost;
namespace {
class MockNearbyConnections : public NearbyConnectionsMojom {
public:
};
class FakeSharingMojoService : public sharing::mojom::Sharing {
public:
FakeSharingMojoService() = default;
~FakeSharingMojoService() override = default;
// sharing::mojom::Sharing:
void CreateSharingWebRtcConnection(
mojo::PendingRemote<sharing::mojom::SignallingSender>,
mojo::PendingReceiver<sharing::mojom::SignallingReceiver>,
mojo::PendingRemote<sharing::mojom::SharingWebRtcConnectionDelegate>,
mojo::PendingReceiver<sharing::mojom::SharingWebRtcConnection>,
mojo::PendingRemote<network::mojom::P2PSocketManager>,
mojo::PendingRemote<network::mojom::MdnsResponder>,
std::vector<sharing::mojom::IceServerPtr>) override {
NOTIMPLEMENTED();
}
void CreateNearbyConnections(
mojo::PendingRemote<NearbyConnectionsHostMojom> host,
CreateNearbyConnectionsCallback callback) override {
connections_host.Bind(std::move(host));
mojo::PendingRemote<NearbyConnectionsMojom> remote;
mojo::MakeSelfOwnedReceiver(std::make_unique<MockNearbyConnections>(),
remote.InitWithNewPipeAndPassReceiver());
std::move(callback).Run(std::move(remote));
run_loop_connections.Quit();
}
mojo::PendingRemote<sharing::mojom::Sharing> BindSharingService() {
return receiver.BindNewPipeAndPassRemote();
}
void WaitForNearbyConnections() { run_loop_connections.Run(); }
void Reset() { receiver.reset(); }
private:
base::RunLoop run_loop_connections;
mojo::Receiver<sharing::mojom::Sharing> receiver{this};
mojo::Remote<NearbyConnectionsHostMojom> connections_host;
};
class MockNearbyProcessManagerObserver : public NearbyProcessManager::Observer {
public:
MOCK_METHOD1(OnNearbyProfileChanged, void(Profile* profile));
MOCK_METHOD0(OnNearbyProcessStarted, void());
MOCK_METHOD0(OnNearbyProcessStopped, void());
};
class NearbyProcessManagerTest : public testing::Test {
public:
NearbyProcessManagerTest() = default;
~NearbyProcessManagerTest() override = default;
void SetUp() override { ASSERT_TRUE(testing_profile_manager_.SetUp()); }
void TearDown() override { DeleteAllProfiles(); }
Profile* CreateProfile(const std::string& name) {
Profile* profile = testing_profile_manager_.CreateTestingProfile(name);
profiles_.insert(profile);
return profile;
}
void DeleteProfile(Profile* profile) {
DoDeleteProfile(profile);
profiles_.erase(profile);
}
void DeleteAllProfiles() {
for (Profile* profile : profiles_)
DoDeleteProfile(profile);
profiles_.clear();
}
private:
void DoDeleteProfile(Profile* profile) {
NearbyProcessManager::GetInstance().OnProfileMarkedForPermanentDeletion(
profile);
testing_profile_manager_.DeleteTestingProfile(
profile->GetProfileUserName());
}
content::BrowserTaskEnvironment task_environment_;
content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
TestingProfileManager testing_profile_manager_{
TestingBrowserProcess::GetGlobal()};
std::set<Profile*> profiles_;
};
} // namespace
TEST_F(NearbyProcessManagerTest, AddRemoveObserver) {
MockNearbyProcessManagerObserver observer;
auto& manager = NearbyProcessManager::GetInstance();
manager.AddObserver(&observer);
EXPECT_TRUE(manager.observers_.HasObserver(&observer));
manager.RemoveObserver(&observer);
EXPECT_FALSE(manager.observers_.HasObserver(&observer));
}
TEST_F(NearbyProcessManagerTest, SetGetActiveProfile) {
auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name");
EXPECT_EQ(nullptr, manager.GetActiveProfile());
manager.SetActiveProfile(profile);
ASSERT_NE(nullptr, manager.GetActiveProfile());
EXPECT_EQ(profile->GetPath(), manager.GetActiveProfile()->GetPath());
}
TEST_F(NearbyProcessManagerTest, IsActiveProfile) {
auto& manager = NearbyProcessManager::GetInstance();
Profile* profile_1 = CreateProfile("name 1");
Profile* profile_2 = CreateProfile("name 2");
EXPECT_FALSE(manager.IsActiveProfile(profile_1));
EXPECT_FALSE(manager.IsActiveProfile(profile_2));
manager.SetActiveProfile(profile_1);
EXPECT_TRUE(manager.IsActiveProfile(profile_1));
EXPECT_FALSE(manager.IsActiveProfile(profile_2));
manager.SetActiveProfile(profile_2);
EXPECT_FALSE(manager.IsActiveProfile(profile_1));
EXPECT_TRUE(manager.IsActiveProfile(profile_2));
manager.ClearActiveProfile();
EXPECT_FALSE(manager.IsActiveProfile(profile_1));
EXPECT_FALSE(manager.IsActiveProfile(profile_2));
}
TEST_F(NearbyProcessManagerTest, IsAnyProfileActive) {
auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name");
EXPECT_FALSE(manager.IsAnyProfileActive());
manager.SetActiveProfile(profile);
EXPECT_TRUE(manager.IsAnyProfileActive());
manager.ClearActiveProfile();
EXPECT_FALSE(manager.IsAnyProfileActive());
}
TEST_F(NearbyProcessManagerTest, OnProfileDeleted_ActiveProfile) {
auto& manager = NearbyProcessManager::GetInstance();
Profile* profile_1 = CreateProfile("name 1");
Profile* profile_2 = CreateProfile("name 2");
// Set active profile and delete it.
manager.SetActiveProfile(profile_1);
manager.OnProfileMarkedForPermanentDeletion(profile_1);
// No profile should be active now.
EXPECT_FALSE(manager.IsActiveProfile(profile_1));
EXPECT_FALSE(manager.IsActiveProfile(profile_2));
}
TEST_F(NearbyProcessManagerTest, OnProfileDeleted_InactiveProfile) {
auto& manager = NearbyProcessManager::GetInstance();
Profile* profile_1 = CreateProfile("name 1");
Profile* profile_2 = CreateProfile("name 2");
// Set active profile and delete inactive one.
manager.SetActiveProfile(profile_1);
manager.OnProfileMarkedForPermanentDeletion(profile_2);
// Active profile should still be active.
EXPECT_TRUE(manager.IsActiveProfile(profile_1));
EXPECT_FALSE(manager.IsActiveProfile(profile_2));
}
TEST_F(NearbyProcessManagerTest, StartStopProcess) {
auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name");
manager.SetActiveProfile(profile);
MockNearbyProcessManagerObserver observer;
base::RunLoop run_loop_started;
base::RunLoop run_loop_stopped;
EXPECT_CALL(observer, OnNearbyProcessStarted())
.WillOnce(testing::Invoke(&run_loop_started, &base::RunLoop::Quit));
EXPECT_CALL(observer, OnNearbyProcessStopped())
.WillOnce(testing::Invoke(&run_loop_stopped, &base::RunLoop::Quit));
manager.AddObserver(&observer);
// Start up a new process and wait for it to launch.
EXPECT_NE(nullptr, manager.GetOrStartNearbyConnections(profile));
run_loop_started.Run();
// Stop the process and wait for it to finish.
manager.StopProcess(profile);
run_loop_stopped.Run();
// Active profile should still be active.
EXPECT_TRUE(manager.IsActiveProfile(profile));
manager.RemoveObserver(&observer);
}
TEST_F(NearbyProcessManagerTest, GetOrStartNearbyConnections) {
auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name");
manager.SetActiveProfile(profile);
// Inject fake Nearby process mojo connection.
FakeSharingMojoService fake_sharing_service;
manager.BindSharingProcess(fake_sharing_service.BindSharingService());
// Request a new Nearby Connections interface.
EXPECT_NE(nullptr, manager.GetOrStartNearbyConnections(profile));
// Expect the manager to bind a new Nearby Connections pipe.
fake_sharing_service.WaitForNearbyConnections();
}
TEST_F(NearbyProcessManagerTest, ResetNearbyProcess) {
auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name");
manager.SetActiveProfile(profile);
// Inject fake Nearby process mojo connection.
FakeSharingMojoService fake_sharing_service;
manager.BindSharingProcess(fake_sharing_service.BindSharingService());
MockNearbyProcessManagerObserver observer;
base::RunLoop run_loop;
EXPECT_CALL(observer, OnNearbyProcessStopped())
.WillOnce(testing::Invoke(&run_loop, &base::RunLoop::Quit));
manager.AddObserver(&observer);
// Simulate a dropped mojo connection to the Nearby process.
fake_sharing_service.Reset();
// Expect the OnNearbyProcessStopped() callback to run.
run_loop.Run();
manager.RemoveObserver(&observer);
}
...@@ -4,10 +4,16 @@ ...@@ -4,10 +4,16 @@
#include "chrome/browser/nearby_sharing/nearby_sharing_prefs.h" #include "chrome/browser/nearby_sharing/nearby_sharing_prefs.h"
#include <string>
#include "base/files/file_path.h"
#include "components/pref_registry/pref_registry_syncable.h" #include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_registry.h" #include "components/prefs/pref_registry.h"
#include "components/prefs/pref_registry_simple.h"
const char kNearbySharingEnabledPrefName[] = "nearby_sharing.enabled"; const char kNearbySharingEnabledPrefName[] = "nearby_sharing.enabled";
const char kNearbySharingActiveProfilePrefName[] =
"nearby_sharing.active_profile";
void RegisterNearbySharingPrefs(user_prefs::PrefRegistrySyncable* registry) { void RegisterNearbySharingPrefs(user_prefs::PrefRegistrySyncable* registry) {
// This pref is not synced. // This pref is not synced.
...@@ -17,3 +23,8 @@ void RegisterNearbySharingPrefs(user_prefs::PrefRegistrySyncable* registry) { ...@@ -17,3 +23,8 @@ void RegisterNearbySharingPrefs(user_prefs::PrefRegistrySyncable* registry) {
kNearbySharingEnabledPrefName, true /* default_value */, kNearbySharingEnabledPrefName, true /* default_value */,
PrefRegistry::PrefRegistrationFlags::NO_REGISTRATION_FLAGS /* flags */); PrefRegistry::PrefRegistrationFlags::NO_REGISTRATION_FLAGS /* flags */);
} }
void RegisterNearbySharingLocalPrefs(PrefRegistrySimple* local_state) {
local_state->RegisterFilePathPref(kNearbySharingActiveProfilePrefName,
base::FilePath() /* default_value */);
}
...@@ -9,8 +9,13 @@ namespace user_prefs { ...@@ -9,8 +9,13 @@ namespace user_prefs {
class PrefRegistrySyncable; class PrefRegistrySyncable;
} // namespace user_prefs } // namespace user_prefs
class PrefRegistrySimple;
extern const char kNearbySharingEnabledPrefName[]; extern const char kNearbySharingEnabledPrefName[];
extern const char kNearbySharingActiveProfilePrefName[];
void RegisterNearbySharingPrefs(user_prefs::PrefRegistrySyncable* registry); void RegisterNearbySharingPrefs(user_prefs::PrefRegistrySyncable* registry);
void RegisterNearbySharingLocalPrefs(PrefRegistrySimple* local_state);
#endif // CHROME_BROWSER_NEARBY_SHARING_NEARBY_SHARING_PREFS_H_ #endif // CHROME_BROWSER_NEARBY_SHARING_NEARBY_SHARING_PREFS_H_
...@@ -241,6 +241,7 @@ ...@@ -241,6 +241,7 @@
#include "chrome/browser/gcm/gcm_product_util.h" #include "chrome/browser/gcm/gcm_product_util.h"
#include "chrome/browser/media/unified_autoplay_config.h" #include "chrome/browser/media/unified_autoplay_config.h"
#include "chrome/browser/metrics/tab_stats_tracker.h" #include "chrome/browser/metrics/tab_stats_tracker.h"
#include "chrome/browser/nearby_sharing/nearby_sharing_prefs.h"
#include "chrome/browser/search/instant_service.h" #include "chrome/browser/search/instant_service.h"
#include "chrome/browser/search/promos/promo_service.h" #include "chrome/browser/search/promos/promo_service.h"
#include "chrome/browser/search/search_suggest/search_suggest_service.h" #include "chrome/browser/search/search_suggest/search_suggest_service.h"
...@@ -704,6 +705,7 @@ void RegisterLocalState(PrefRegistrySimple* registry) { ...@@ -704,6 +705,7 @@ void RegisterLocalState(PrefRegistrySimple* registry) {
media_router::RegisterLocalStatePrefs(registry); media_router::RegisterLocalStatePrefs(registry);
metrics::TabStatsTracker::RegisterPrefs(registry); metrics::TabStatsTracker::RegisterPrefs(registry);
RegisterBrowserPrefs(registry); RegisterBrowserPrefs(registry);
RegisterNearbySharingLocalPrefs(registry);
StartupBrowserCreator::RegisterLocalStatePrefs(registry); StartupBrowserCreator::RegisterLocalStatePrefs(registry);
task_manager::TaskManagerInterface::RegisterPrefs(registry); task_manager::TaskManagerInterface::RegisterPrefs(registry);
UpgradeDetector::RegisterPrefs(registry); UpgradeDetector::RegisterPrefs(registry);
......
...@@ -3560,6 +3560,7 @@ test("unit_tests") { ...@@ -3560,6 +3560,7 @@ test("unit_tests") {
"../browser/content_settings/generated_cookie_prefs_unittest.cc", "../browser/content_settings/generated_cookie_prefs_unittest.cc",
"../browser/device_identity/device_oauth2_token_service_unittest.cc", "../browser/device_identity/device_oauth2_token_service_unittest.cc",
"../browser/nearby_sharing/fast_initiation_manager_unittest.cc", "../browser/nearby_sharing/fast_initiation_manager_unittest.cc",
"../browser/nearby_sharing/nearby_process_manager_unittest.cc",
"../browser/profiles/profile_avatar_icon_util_unittest.cc", "../browser/profiles/profile_avatar_icon_util_unittest.cc",
"../browser/sharing/webrtc/sharing_service_host_unittest.cc", "../browser/sharing/webrtc/sharing_service_host_unittest.cc",
"../browser/sharing/webrtc/sharing_webrtc_connection_host_unittest.cc", "../browser/sharing/webrtc/sharing_webrtc_connection_host_unittest.cc",
......
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