Commit 2c2e96ff authored by Kyle Horimoto's avatar Kyle Horimoto Committed by Commit Bot

[CrOS Nearby] Use chrome::nearby::NearbyProcessManager in Nearby Share

This CL updates Nearby Share's NearbyProcessManager class to use the
newly-created chrome::nearby::NearbyProcessManager internally in order
to make connections to the Nearby utility process.

In the long-term, Nearby Share's version should be renamed or
potentially removed altogether, but this is not within the scope of the
bug fix, so I've added a TODO to take care of this.

Bug: 1130069
Change-Id: I0f8eb7e29e83ffbc6ce428eeaacd151a294d5ef1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2459572
Commit-Queue: Kyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarJames Vecore <vecore@google.com>
Cr-Commit-Position: refs/heads/master@{#817688}
parent dcf600bd
...@@ -4338,6 +4338,7 @@ static_library("browser") { ...@@ -4338,6 +4338,7 @@ static_library("browser") {
"//chromeos/services/multidevice_setup", "//chromeos/services/multidevice_setup",
"//chromeos/services/multidevice_setup/public/cpp:first_run_field_trial", "//chromeos/services/multidevice_setup/public/cpp:first_run_field_trial",
"//chromeos/services/multidevice_setup/public/mojom", "//chromeos/services/multidevice_setup/public/mojom",
"//chromeos/services/nearby/public/cpp",
"//chromeos/services/network_config", "//chromeos/services/network_config",
"//chromeos/services/network_config/public/mojom", "//chromeos/services/network_config/public/mojom",
"//chromeos/services/secure_channel/public/mojom", "//chromeos/services/secure_channel/public/mojom",
......
...@@ -15,6 +15,8 @@ namespace chromeos { ...@@ -15,6 +15,8 @@ namespace chromeos {
namespace nearby { namespace nearby {
namespace { namespace {
bool g_bypass_primary_user_check_for_testing = false;
bool IsLoggedInAsPrimaryUser(Profile* profile) { bool IsLoggedInAsPrimaryUser(Profile* profile) {
// Guest/incognito profiles cannot use Phone Hub. // Guest/incognito profiles cannot use Phone Hub.
if (profile->IsOffTheRecord()) if (profile->IsOffTheRecord())
...@@ -42,6 +44,13 @@ NearbyProcessManagerFactory* NearbyProcessManagerFactory::GetInstance() { ...@@ -42,6 +44,13 @@ NearbyProcessManagerFactory* NearbyProcessManagerFactory::GetInstance() {
return base::Singleton<NearbyProcessManagerFactory>::get(); return base::Singleton<NearbyProcessManagerFactory>::get();
} }
// static
void NearbyProcessManagerFactory::SetBypassPrimaryUserCheckForTesting(
bool bypass_primary_user_check_for_testing) {
g_bypass_primary_user_check_for_testing =
bypass_primary_user_check_for_testing;
}
NearbyProcessManagerFactory::NearbyProcessManagerFactory() NearbyProcessManagerFactory::NearbyProcessManagerFactory()
: BrowserContextKeyedServiceFactory( : BrowserContextKeyedServiceFactory(
"NearbyProcessManager", "NearbyProcessManager",
...@@ -58,11 +67,15 @@ KeyedService* NearbyProcessManagerFactory::BuildServiceInstanceFor( ...@@ -58,11 +67,15 @@ KeyedService* NearbyProcessManagerFactory::BuildServiceInstanceFor(
// The service is meant to be a singleton, since multiple simultaneous process // The service is meant to be a singleton, since multiple simultaneous process
// managers could interfere with each other. Provide access only to the // managers could interfere with each other. Provide access only to the
// primary user. // primary user.
if (!IsLoggedInAsPrimaryUser(profile)) if (IsLoggedInAsPrimaryUser(profile) ||
return nullptr; g_bypass_primary_user_check_for_testing) {
return NearbyProcessManagerImpl::Factory::Create(
NearbyConnectionsDependenciesProviderFactory::GetForProfile(
profile))
.release();
}
return new NearbyProcessManagerImpl( return nullptr;
NearbyConnectionsDependenciesProviderFactory::GetForProfile(profile));
} }
bool NearbyProcessManagerFactory::ServiceIsCreatedWithBrowserContext() const { bool NearbyProcessManagerFactory::ServiceIsCreatedWithBrowserContext() const {
......
...@@ -23,6 +23,11 @@ class NearbyProcessManagerFactory : public BrowserContextKeyedServiceFactory { ...@@ -23,6 +23,11 @@ class NearbyProcessManagerFactory : public BrowserContextKeyedServiceFactory {
static NearbyProcessManagerFactory* GetInstance(); static NearbyProcessManagerFactory* GetInstance();
// When true is passed, this factory will create a NearbyProcessManager even
// when it is not the primary profile.
static void SetBypassPrimaryUserCheckForTesting(
bool bypass_primary_user_check_for_testing);
private: private:
friend struct base::DefaultSingletonTraits<NearbyProcessManagerFactory>; friend struct base::DefaultSingletonTraits<NearbyProcessManagerFactory>;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chrome/browser/chromeos/nearby/nearby_process_manager_impl.h" #include "chrome/browser/chromeos/nearby/nearby_process_manager_impl.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider.h" #include "chrome/browser/chromeos/nearby/nearby_connections_dependencies_provider.h"
#include "chrome/browser/nearby_sharing/logging/logging.h" #include "chrome/browser/nearby_sharing/logging/logging.h"
#include "chrome/browser/sharing/webrtc/sharing_mojo_service.h" #include "chrome/browser/sharing/webrtc/sharing_mojo_service.h"
...@@ -12,6 +13,29 @@ ...@@ -12,6 +13,29 @@
namespace chromeos { namespace chromeos {
namespace nearby { namespace nearby {
namespace {
NearbyProcessManagerImpl::Factory* g_test_factory = nullptr;
} // namespace
// static
std::unique_ptr<NearbyProcessManager> NearbyProcessManagerImpl::Factory::Create(
NearbyConnectionsDependenciesProvider*
nearby_connections_dependencies_provider) {
if (g_test_factory) {
return g_test_factory->BuildInstance(
nearby_connections_dependencies_provider);
}
return base::WrapUnique(
new NearbyProcessManagerImpl(nearby_connections_dependencies_provider));
}
// static
void NearbyProcessManagerImpl::Factory::SetFactoryForTesting(Factory* factory) {
g_test_factory = factory;
}
NearbyProcessManagerImpl::NearbyReferenceImpl::NearbyReferenceImpl( NearbyProcessManagerImpl::NearbyReferenceImpl::NearbyReferenceImpl(
const mojo::SharedRemote< const mojo::SharedRemote<
......
...@@ -30,9 +30,20 @@ class NearbyConnectionsDependenciesProvider; ...@@ -30,9 +30,20 @@ class NearbyConnectionsDependenciesProvider;
// is killed as soon as the last client releases its reference. // is killed as soon as the last client releases its reference.
class NearbyProcessManagerImpl : public NearbyProcessManager { class NearbyProcessManagerImpl : public NearbyProcessManager {
public: public:
explicit NearbyProcessManagerImpl( class Factory {
public:
static std::unique_ptr<NearbyProcessManager> Create(
NearbyConnectionsDependenciesProvider* NearbyConnectionsDependenciesProvider*
nearby_connections_dependencies_provider); nearby_connections_dependencies_provider);
static void SetFactoryForTesting(Factory* factory);
virtual ~Factory() = default;
private:
virtual std::unique_ptr<NearbyProcessManager> BuildInstance(
NearbyConnectionsDependenciesProvider*
nearby_connections_dependencies_provider) = 0;
};
~NearbyProcessManagerImpl() override; ~NearbyProcessManagerImpl() override;
private: private:
...@@ -61,6 +72,10 @@ class NearbyProcessManagerImpl : public NearbyProcessManager { ...@@ -61,6 +72,10 @@ class NearbyProcessManagerImpl : public NearbyProcessManager {
base::OnceClosure destructor_callback_; base::OnceClosure destructor_callback_;
}; };
explicit NearbyProcessManagerImpl(
NearbyConnectionsDependenciesProvider*
nearby_connections_dependencies_provider);
// NearbyProcessManagerImpl: // NearbyProcessManagerImpl:
std::unique_ptr<NearbyProcessReference> GetNearbyProcessReference( std::unique_ptr<NearbyProcessReference> GetNearbyProcessReference(
base::OnceClosure on_process_stopped_callback) override; base::OnceClosure on_process_stopped_callback) override;
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/nearby/nearby_process_manager_factory.h"
#include "chrome/browser/chromeos/nearby/nearby_process_manager_impl.h"
#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h"
#include "chrome/browser/nearby_sharing/logging/logging.h" #include "chrome/browser/nearby_sharing/logging/logging.h"
#include "chrome/browser/nearby_sharing/webrtc_signaling_messenger.h" #include "chrome/browser/nearby_sharing/webrtc_signaling_messenger.h"
...@@ -87,33 +89,6 @@ bool IsStoredNearbyProfile(Profile* profile) { ...@@ -87,33 +89,6 @@ bool IsStoredNearbyProfile(Profile* profile) {
return profile && entry->GetPath() == profile->GetPath(); return profile && entry->GetPath() == profile->GetPath();
} }
template <typename T>
struct MojoPipe {
mojo::PendingRemote<T> remote;
mojo::PendingReceiver<T> receiver{remote.InitWithNewPipeAndPassReceiver()};
};
class P2PTrustedSocketManagerClientImpl
: public network::mojom::P2PTrustedSocketManagerClient {
public:
explicit P2PTrustedSocketManagerClientImpl(
mojo::PendingRemote<network::mojom::P2PTrustedSocketManager>
socket_manager)
: socket_manager_(std::move(socket_manager)) {}
~P2PTrustedSocketManagerClientImpl() override = default;
// network::mojom::P2PTrustedSocketManagerClient:
void InvalidSocketPortRangeRequested() override { NOTIMPLEMENTED(); }
void DumpPacket(const std::vector<uint8_t>& packet_header,
uint64_t packet_length,
bool incoming) override {
NOTIMPLEMENTED();
}
private:
mojo::Remote<network::mojom::P2PTrustedSocketManager> socket_manager_;
};
} // namespace } // namespace
// static // static
...@@ -167,12 +142,8 @@ NearbyProcessManager::GetOrStartNearbyConnections(Profile* profile) { ...@@ -167,12 +142,8 @@ NearbyProcessManager::GetOrStartNearbyConnections(Profile* profile) {
if (!IsActiveProfile(profile)) if (!IsActiveProfile(profile))
return nullptr; return nullptr;
active_profile_ = profile; EnsureProcessIsRunning();
// Launch a new Nearby Connections interface if required. return reference_->GetNearbyConnections().get();
if (!connections_.is_bound())
BindNearbyConnections();
return connections_.get();
} }
sharing::mojom::NearbySharingDecoder* sharing::mojom::NearbySharingDecoder*
...@@ -180,28 +151,15 @@ NearbyProcessManager::GetOrStartNearbySharingDecoder(Profile* profile) { ...@@ -180,28 +151,15 @@ NearbyProcessManager::GetOrStartNearbySharingDecoder(Profile* profile) {
if (!IsActiveProfile(profile)) if (!IsActiveProfile(profile))
return nullptr; return nullptr;
active_profile_ = profile; EnsureProcessIsRunning();
// Launch a new Nearby Sharing Decoder interface if required. return reference_->GetNearbySharingDecoder().get();
if (!decoder_.is_bound())
BindNearbySharingDecoder();
return decoder_.get();
} }
void NearbyProcessManager::StopProcess(Profile* profile) { void NearbyProcessManager::StopProcess(Profile* profile) {
if (!IsActiveProfile(profile)) if (!IsActiveProfile(profile))
return; return;
bool was_running = sharing_process_.is_bound(); EnsureNearbyProcessReferenceReleased();
connections_.reset();
decoder_.reset();
sharing_process_.reset();
if (was_running) {
for (auto& observer : observers_)
observer.OnNearbyProcessStopped();
}
} }
void NearbyProcessManager::OnProfileAdded(Profile* profile) { void NearbyProcessManager::OnProfileAdded(Profile* profile) {
...@@ -216,14 +174,6 @@ void NearbyProcessManager::OnProfileMarkedForPermanentDeletion( ...@@ -216,14 +174,6 @@ void NearbyProcessManager::OnProfileMarkedForPermanentDeletion(
SetActiveProfile(nullptr); 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() { NearbyProcessManager::NearbyProcessManager() {
// profile_manager() might be null in tests or during shutdown. // profile_manager() might be null in tests or during shutdown.
if (auto* manager = g_browser_process->profile_manager()) if (auto* manager = g_browser_process->profile_manager())
...@@ -235,194 +185,41 @@ NearbyProcessManager::~NearbyProcessManager() { ...@@ -235,194 +185,41 @@ NearbyProcessManager::~NearbyProcessManager() {
manager->RemoveObserver(this); manager->RemoveObserver(this);
} }
void NearbyProcessManager::LaunchNewProcess() { void NearbyProcessManager::EnsureProcessIsRunning() {
// Stop any running process and mojo pipes. DCHECK(IsAnyProfileActive());
StopProcess(active_profile_);
// Launch a new sandboxed process.
// TODO(crbug.com/1095650): 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();
mojo::PendingReceiver<NearbyConnectionsMojom> pending_receiver =
connections_.BindNewPipeAndPassReceiver();
auto dependencies = location::nearby::connections::mojom::
NearbyConnectionsDependencies::New();
location::nearby::connections::mojom::NearbyConnectionsDependencies*
dependencies_ptr = dependencies.get();
// base::Unretained() is safe as |this| is a singleton.
auto done_closure = base::BarrierClosure(
/*num_closures=*/2,
base::BindOnce(&NearbyProcessManager::OnDependenciesGathered,
base::Unretained(this), std::move(pending_receiver),
std::move(dependencies)));
GetBluetoothAdapter(dependencies_ptr,
base::ScopedClosureRunner(done_closure));
GetWebRtcDependencies(dependencies_ptr,
base::ScopedClosureRunner(done_closure));
// Terminate the process if the Nearby Connections interface disconnects as
// that indicated an incorrect state and we have to restart the process.
// base::Unretained() is safe as |this| is a singleton.
connections_.set_disconnect_handler(base::BindOnce(
&NearbyProcessManager::OnNearbyProcessStopped, base::Unretained(this)));
}
void NearbyProcessManager::GetBluetoothAdapter( // A reference already exists; the process is active.
location::nearby::connections::mojom::NearbyConnectionsDependencies* if (reference_)
dependencies,
base::ScopedClosureRunner done_closure) {
NS_LOG(VERBOSE) << __func__
<< " Request for Bluetooth "
"adapter received on the browser process.";
if (!device::BluetoothAdapterFactory::IsBluetoothSupported()) {
NS_LOG(VERBOSE) << __func__ << " Bluetooth is not supported on this device";
dependencies->bluetooth_adapter = mojo::NullRemote();
return; return;
}
// base::Unretained() is safe as |this| is a singleton. chromeos::nearby::NearbyProcessManager* process_manager =
device::BluetoothAdapterFactory::Get()->GetAdapter(base::BindOnce( chromeos::nearby::NearbyProcessManagerFactory::GetForProfile(
&NearbyProcessManager::OnGetBluetoothAdapter, base::Unretained(this), active_profile_);
dependencies, std::move(done_closure))); DCHECK(process_manager);
}
void NearbyProcessManager::OnGetBluetoothAdapter( NS_LOG(INFO) << "Initializing Nearby Share process reference.";
location::nearby::connections::mojom::NearbyConnectionsDependencies*
dependencies,
base::ScopedClosureRunner done_closure,
scoped_refptr<device::BluetoothAdapter> adapter) {
if (!adapter->IsPresent()) {
NS_LOG(VERBOSE) << __func__ << " Bluetooth adapter is not present";
dependencies->bluetooth_adapter = mojo::NullRemote();
return;
}
mojo::PendingRemote<bluetooth::mojom::Adapter> pending_adapter; // Note: base::Unretained(this) is used because this is a singleton.
mojo::MakeSelfOwnedReceiver(std::make_unique<bluetooth::Adapter>(adapter), reference_ = process_manager->GetNearbyProcessReference(base::BindOnce(
pending_adapter.InitWithNewPipeAndPassReceiver()); &NearbyProcessManager::OnNearbyProcessStopped, base::Unretained(this)));
DCHECK(reference_);
NS_LOG(VERBOSE) << __func__ << " Got bluetooth adapter";
dependencies->bluetooth_adapter = std::move(pending_adapter);
}
void NearbyProcessManager::GetWebRtcDependencies(
location::nearby::connections::mojom::NearbyConnectionsDependencies*
dependencies,
base::ScopedClosureRunner done_closure) {
DCHECK(active_profile_);
auto* network_context =
content::BrowserContext::GetDefaultStoragePartition(active_profile_)
->GetNetworkContext();
auto url_loader_factory = active_profile_->GetURLLoaderFactory();
signin::IdentityManager* identity_manager =
IdentityManagerFactory::GetForProfile(active_profile_);
MojoPipe<network::mojom::P2PTrustedSocketManagerClient> socket_manager_client;
MojoPipe<network::mojom::P2PTrustedSocketManager> trusted_socket_manager;
MojoPipe<network::mojom::P2PSocketManager> socket_manager;
MojoPipe<network::mojom::MdnsResponder> mdns_responder;
mojo::MakeSelfOwnedReceiver(
std::make_unique<P2PTrustedSocketManagerClientImpl>(
std::move(trusted_socket_manager.remote)),
std::move(socket_manager_client.receiver));
// Create socket manager.
network_context->CreateP2PSocketManager(
net::NetworkIsolationKey::CreateTransient(),
std::move(socket_manager_client.remote),
std::move(trusted_socket_manager.receiver),
std::move(socket_manager.receiver));
// Create mdns responder.
network_context->CreateMdnsResponder(std::move(mdns_responder.receiver));
// Create ice config fetcher.
MojoPipe<sharing::mojom::IceConfigFetcher> ice_config_fetcher;
mojo::MakeSelfOwnedReceiver(
std::make_unique<IceConfigFetcher>(url_loader_factory),
std::move(ice_config_fetcher.receiver));
MojoPipe<sharing::mojom::WebRtcSignalingMessenger> messenger;
mojo::MakeSelfOwnedReceiver(std::make_unique<WebRtcSignalingMessenger>(
identity_manager, url_loader_factory),
std::move(messenger.receiver));
dependencies->webrtc_dependencies =
location::nearby::connections::mojom::WebRtcDependencies::New(
std::move(socket_manager.remote), std::move(mdns_responder.remote),
std::move(ice_config_fetcher.remote), std::move(messenger.remote));
}
void NearbyProcessManager::OnDependenciesGathered(
mojo::PendingReceiver<NearbyConnectionsMojom> receiver,
location::nearby::connections::mojom::NearbyConnectionsDependenciesPtr
dependencies) {
if (!sharing_process_.is_bound())
return;
// Create the Nearby Connections stack in the sandboxed process.
// base::Unretained() calls below are safe as |this| is a singleton.
sharing_process_->CreateNearbyConnections(
std::move(dependencies),
base::BindOnce(&NearbyProcessManager::OnNearbyConnections,
base::Unretained(this), std::move(receiver)));
}
void NearbyProcessManager::OnNearbyConnections(
mojo::PendingReceiver<NearbyConnectionsMojom> receiver,
mojo::PendingRemote<NearbyConnectionsMojom> remote) {
if (!mojo::FusePipes(std::move(receiver), std::move(remote))) {
NS_LOG(WARNING) << "Failed to initialize Nearby Connections process";
StopProcess(active_profile_);
return;
}
for (auto& observer : observers_) for (auto& observer : observers_)
observer.OnNearbyProcessStarted(); observer.OnNearbyProcessStarted();
} }
void NearbyProcessManager::OnNearbyProcessStopped() { void NearbyProcessManager::OnNearbyProcessStopped() {
StopProcess(active_profile_); NS_LOG(INFO) << "Nearby process has stopped.";
} EnsureNearbyProcessReferenceReleased();
void NearbyProcessManager::BindNearbySharingDecoder() {
// Start a new process if there is none running yet.
if (!sharing_process_.is_bound())
LaunchNewProcess();
// Create the Nearby Sharing Decoder stack in the sandboxed process.
// base::Unretained() calls below are safe as |this| is a singleton.
sharing_process_->CreateNearbySharingDecoder(base::BindOnce(
&NearbyProcessManager::OnNearbySharingDecoder, base::Unretained(this),
decoder_.BindNewPipeAndPassReceiver()));
// Terminate the process if the Nearby Sharing Decoder interface disconnects
// as that indicated an incorrect state and we have to restart the process.
decoder_.set_disconnect_handler(base::BindOnce(
&NearbyProcessManager::OnNearbyProcessStopped, base::Unretained(this)));
} }
void NearbyProcessManager::OnNearbySharingDecoder( void NearbyProcessManager::EnsureNearbyProcessReferenceReleased() {
mojo::PendingReceiver<NearbySharingDecoderMojom> receiver, if (!reference_)
mojo::PendingRemote<NearbySharingDecoderMojom> remote) {
if (!mojo::FusePipes(std::move(receiver), std::move(remote))) {
NS_LOG(WARNING) << "Failed to initialize Nearby Sharing Decoder process";
StopProcess(active_profile_);
return; return;
}
NS_LOG(INFO) << "Releasing Nearby Share process reference.";
reference_.reset();
for (auto& observer : observers_) for (auto& observer : observers_)
observer.OnNearbyProcessStarted(); observer.OnNearbyProcessStopped();
} }
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/observer_list_types.h" #include "base/observer_list_types.h"
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
#include "chrome/browser/profiles/profile_manager_observer.h" #include "chrome/browser/profiles/profile_manager_observer.h"
#include "chromeos/services/nearby/public/cpp/nearby_process_manager.h"
#include "chromeos/services/nearby/public/mojom/nearby_connections.mojom.h" #include "chromeos/services/nearby/public/mojom/nearby_connections.mojom.h"
#include "chromeos/services/nearby/public/mojom/nearby_decoder.mojom.h" #include "chromeos/services/nearby/public/mojom/nearby_decoder.mojom.h"
#include "chromeos/services/nearby/public/mojom/sharing.mojom.h" #include "chromeos/services/nearby/public/mojom/sharing.mojom.h"
...@@ -24,9 +25,10 @@ ...@@ -24,9 +25,10 @@
class Profile; class Profile;
class ProfileAttributesEntry; class ProfileAttributesEntry;
// Manages the lifetime of the Nearby process. It runs the Nearby Connections // Interfaces with the Nearby utility process.
// library and Nearby Sharing data decoding. Only one instance of the process is // TODO(https://crbug.com/1137664): This class should be renamed or deleted
// supported at a time. // altogether. It was written before chromeos::nearby::NerabyProcessManager was
// created.
class NearbyProcessManager : public ProfileManagerObserver { class NearbyProcessManager : public ProfileManagerObserver {
public: public:
using NearbyConnectionsMojom = using NearbyConnectionsMojom =
...@@ -107,10 +109,6 @@ class NearbyProcessManager : public ProfileManagerObserver { ...@@ -107,10 +109,6 @@ class NearbyProcessManager : public ProfileManagerObserver {
void OnProfileAdded(Profile* profile) override; void OnProfileAdded(Profile* profile) override;
void OnProfileMarkedForPermanentDeletion(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: private:
FRIEND_TEST_ALL_PREFIXES(NearbyProcessManagerTest, AddRemoveObserver); FRIEND_TEST_ALL_PREFIXES(NearbyProcessManagerTest, AddRemoveObserver);
FRIEND_TEST_ALL_PREFIXES(NearbySharingServiceImplTest, FRIEND_TEST_ALL_PREFIXES(NearbySharingServiceImplTest,
...@@ -124,65 +122,15 @@ class NearbyProcessManager : public ProfileManagerObserver { ...@@ -124,65 +122,15 @@ class NearbyProcessManager : public ProfileManagerObserver {
NearbyProcessManager(); NearbyProcessManager();
~NearbyProcessManager() override; ~NearbyProcessManager() override;
// Launches a new sandboxed process and stops any currently running one. This void EnsureProcessIsRunning();
// 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();
// Gather dependencies for NearbyConnections:
void GetBluetoothAdapter(
location::nearby::connections::mojom::NearbyConnectionsDependencies*
dependencies,
base::ScopedClosureRunner done_closure);
void OnGetBluetoothAdapter(
location::nearby::connections::mojom::NearbyConnectionsDependencies*
dependencies,
base::ScopedClosureRunner done_closure,
scoped_refptr<device::BluetoothAdapter> adapter);
void GetWebRtcDependencies(
location::nearby::connections::mojom::NearbyConnectionsDependencies*
dependencies,
base::ScopedClosureRunner done_closure);
// Called when all dependencies are gathered.
void OnDependenciesGathered(
mojo::PendingReceiver<NearbyConnectionsMojom> receiver,
location::nearby::connections::mojom::NearbyConnectionsDependenciesPtr
dependencies);
// 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(); void OnNearbyProcessStopped();
void EnsureNearbyProcessReferenceReleased();
// Binds a new pipe to the Nearby Sharing Decoder. May start a new process // Reference to the Nearby utility process; if null, no reference is currently
// if there is none running yet. // held.
void BindNearbySharingDecoder(); std::unique_ptr<
chromeos::nearby::NearbyProcessManager::NearbyProcessReference>
// Called by the sandboxed process after initializing the Nearby Sharing reference_;
// Decoder.
void OnNearbySharingDecoder(
mojo::PendingReceiver<NearbySharingDecoderMojom> receiver,
mojo::PendingRemote<NearbySharingDecoderMojom> remote);
// 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_;
// The bound remote to the Nearby Decoder interface inside the sandbox.
mojo::Remote<NearbySharingDecoderMojom> decoder_;
// All registered observers, typically one per loaded profile. // All registered observers, typically one per loaded profile.
base::ObserverList<Observer> observers_; base::ObserverList<Observer> observers_;
......
...@@ -15,12 +15,16 @@ ...@@ -15,12 +15,16 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h" #include "base/test/bind_test_util.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/nearby/nearby_process_manager_factory.h"
#include "chrome/browser/chromeos/nearby/nearby_process_manager_impl.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h"
#include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h" #include "chrome/test/base/testing_profile_manager.h"
#include "chromeos/services/nearby/public/cpp/fake_nearby_process_manager.h"
#include "chromeos/services/nearby/public/cpp/mock_nearby_connections.h" #include "chromeos/services/nearby/public/cpp/mock_nearby_connections.h"
#include "chromeos/services/nearby/public/cpp/mock_nearby_sharing_decoder.h" #include "chromeos/services/nearby/public/cpp/mock_nearby_sharing_decoder.h"
#include "chromeos/services/nearby/public/mojom/nearby_connections.mojom.h" #include "chromeos/services/nearby/public/mojom/nearby_connections.mojom.h"
...@@ -46,53 +50,26 @@ using NearbySharingDecoderMojom = sharing::mojom::NearbySharingDecoder; ...@@ -46,53 +50,26 @@ using NearbySharingDecoderMojom = sharing::mojom::NearbySharingDecoder;
namespace { namespace {
class FakeSharingMojoService : public sharing::mojom::Sharing { class FakeNearbyProcessManagerFactory
: public chromeos::nearby::NearbyProcessManagerImpl::Factory {
public: public:
FakeSharingMojoService() = default; FakeNearbyProcessManagerFactory() = default;
~FakeSharingMojoService() override = default; ~FakeNearbyProcessManagerFactory() override = default;
// sharing::mojom::Sharing:
void CreateNearbyConnections(
NearbyConnectionsDependenciesPtr dependencies,
CreateNearbyConnectionsCallback callback) override {
dependencies_ = std::move(dependencies);
mojo::PendingRemote<NearbyConnectionsMojom> remote;
mojo::MakeSelfOwnedReceiver(
std::make_unique<chromeos::nearby::MockNearbyConnections>(),
remote.InitWithNewPipeAndPassReceiver());
std::move(callback).Run(std::move(remote));
run_loop_connections.Quit();
}
void CreateNearbySharingDecoder(
CreateNearbySharingDecoderCallback callback) override {
mojo::PendingRemote<NearbySharingDecoderMojom> remote;
mojo::MakeSelfOwnedReceiver(
std::make_unique<chromeos::nearby::MockNearbySharingDecoder>(),
remote.InitWithNewPipeAndPassReceiver());
std::move(callback).Run(std::move(remote));
run_loop_decoder.Quit(); chromeos::nearby::FakeNearbyProcessManager* instance() { return instance_; }
}
mojo::PendingRemote<sharing::mojom::Sharing> BindSharingService() { private:
return receiver.BindNewPipeAndPassRemote(); // chromeos::nearby::NearbyProcessManagerImpl::Factory:
std::unique_ptr<chromeos::nearby::NearbyProcessManager> BuildInstance(
chromeos::nearby::NearbyConnectionsDependenciesProvider*
nearby_connections_dependencies_provider) override {
auto instance =
std::make_unique<chromeos::nearby::FakeNearbyProcessManager>();
instance_ = instance.get();
return instance;
} }
void WaitForConnections() { run_loop_connections.Run(); } chromeos::nearby::FakeNearbyProcessManager* instance_ = nullptr;
void WaitForDecoder() { run_loop_decoder.Run(); }
void Reset() { receiver.reset(); }
NearbyConnectionsDependencies* dependencies() { return dependencies_.get(); }
private:
base::RunLoop run_loop_connections;
base::RunLoop run_loop_decoder;
mojo::Receiver<sharing::mojom::Sharing> receiver{this};
NearbyConnectionsDependenciesPtr dependencies_;
}; };
class MockNearbyProcessManagerObserver : public NearbyProcessManager::Observer { class MockNearbyProcessManagerObserver : public NearbyProcessManager::Observer {
...@@ -108,6 +85,8 @@ class NearbyProcessManagerTest : public testing::Test { ...@@ -108,6 +85,8 @@ class NearbyProcessManagerTest : public testing::Test {
~NearbyProcessManagerTest() override = default; ~NearbyProcessManagerTest() override = default;
void SetUp() override { void SetUp() override {
chromeos::nearby::NearbyProcessManagerImpl::Factory::SetFactoryForTesting(
&fake_nearby_process_manager_factory_);
ASSERT_TRUE(testing_profile_manager_.SetUp()); ASSERT_TRUE(testing_profile_manager_.SetUp());
NearbyProcessManager::GetInstance().ClearActiveProfile(); NearbyProcessManager::GetInstance().ClearActiveProfile();
} }
...@@ -115,10 +94,22 @@ class NearbyProcessManagerTest : public testing::Test { ...@@ -115,10 +94,22 @@ class NearbyProcessManagerTest : public testing::Test {
void TearDown() override { void TearDown() override {
NearbyProcessManager::GetInstance().ClearActiveProfile(); NearbyProcessManager::GetInstance().ClearActiveProfile();
DeleteAllProfiles(); DeleteAllProfiles();
chromeos::nearby::NearbyProcessManagerImpl::Factory::SetFactoryForTesting(
nullptr);
} }
Profile* CreateProfile(const std::string& name) { Profile* CreateProfile(const std::string& name,
bool is_primary_profile = false) {
// NearbyProcessManager is only created for the primary user. Because it is
// created when the Profile is created but it is not possible to set the
// primary user before the Proflile is created, use
// SetBypassPrimaryUserCheckForTesting() to bypass this.
chromeos::nearby::NearbyProcessManagerFactory::
SetBypassPrimaryUserCheckForTesting(is_primary_profile);
Profile* profile = testing_profile_manager_.CreateTestingProfile(name); Profile* profile = testing_profile_manager_.CreateTestingProfile(name);
chromeos::nearby::NearbyProcessManagerFactory::
SetBypassPrimaryUserCheckForTesting(false);
profiles_.insert(profile); profiles_.insert(profile);
return profile; return profile;
} }
...@@ -147,6 +138,10 @@ class NearbyProcessManagerTest : public testing::Test { ...@@ -147,6 +138,10 @@ class NearbyProcessManagerTest : public testing::Test {
profiles_.clear(); profiles_.clear();
} }
chromeos::nearby::FakeNearbyProcessManager* fake_process_manager() {
return fake_nearby_process_manager_factory_.instance();
}
private: private:
void DoDeleteProfile(Profile* profile) { void DoDeleteProfile(Profile* profile) {
NearbyProcessManager::GetInstance().OnProfileMarkedForPermanentDeletion( NearbyProcessManager::GetInstance().OnProfileMarkedForPermanentDeletion(
...@@ -161,6 +156,7 @@ class NearbyProcessManagerTest : public testing::Test { ...@@ -161,6 +156,7 @@ class NearbyProcessManagerTest : public testing::Test {
TestingProfileManager testing_profile_manager_{ TestingProfileManager testing_profile_manager_{
TestingBrowserProcess::GetGlobal()}; TestingBrowserProcess::GetGlobal()};
std::set<Profile*> profiles_; std::set<Profile*> profiles_;
FakeNearbyProcessManagerFactory fake_nearby_process_manager_factory_;
}; };
} // namespace } // namespace
...@@ -263,19 +259,11 @@ TEST_F(NearbyProcessManagerTest, OnProfileDeleted_InactiveProfile) { ...@@ -263,19 +259,11 @@ TEST_F(NearbyProcessManagerTest, OnProfileDeleted_InactiveProfile) {
EXPECT_FALSE(manager.IsActiveProfile(profile_2)); EXPECT_FALSE(manager.IsActiveProfile(profile_2));
} }
TEST_F(NearbyProcessManagerTest, StartStopProcessWithNearbyConnections) { TEST_F(NearbyProcessManagerTest, NearbyConnections) {
auto& manager = NearbyProcessManager::GetInstance(); auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name"); Profile* profile = CreateProfile("name", /*is_primary_profile=*/true);
manager.SetActiveProfile(profile); manager.SetActiveProfile(profile);
// Inject fake Nearby process mojo connection.
FakeSharingMojoService fake_sharing_service;
manager.BindSharingProcess(fake_sharing_service.BindSharingService());
auto adapter = base::MakeRefCounted<device::MockBluetoothAdapter>();
EXPECT_CALL(*adapter, IsPresent()).WillOnce(testing::Return(true));
device::BluetoothAdapterFactory::SetAdapterForTesting(adapter);
MockNearbyProcessManagerObserver observer; MockNearbyProcessManagerObserver observer;
base::RunLoop run_loop_started; base::RunLoop run_loop_started;
base::RunLoop run_loop_stopped; base::RunLoop run_loop_stopped;
...@@ -285,98 +273,104 @@ TEST_F(NearbyProcessManagerTest, StartStopProcessWithNearbyConnections) { ...@@ -285,98 +273,104 @@ TEST_F(NearbyProcessManagerTest, StartStopProcessWithNearbyConnections) {
.WillOnce(testing::Invoke(&run_loop_stopped, &base::RunLoop::Quit)); .WillOnce(testing::Invoke(&run_loop_stopped, &base::RunLoop::Quit));
manager.AddObserver(&observer); manager.AddObserver(&observer);
// Start up a new process and wait for it to launch. NearbyProcessManager::NearbyConnectionsMojom* nearby_connections =
EXPECT_NE(nullptr, manager.GetOrStartNearbyConnections(profile)); manager.GetOrStartNearbyConnections(profile);
run_loop_started.Run(); run_loop_started.Run();
EXPECT_EQ(
nearby_connections,
fake_process_manager()->active_connections()->shared_remote().get());
EXPECT_EQ(1u, fake_process_manager()->GetNumActiveReferences());
// Stop the process and wait for it to finish. // Stop the process and wait for it to finish.
manager.StopProcess(profile); manager.StopProcess(profile);
run_loop_stopped.Run(); run_loop_stopped.Run();
EXPECT_EQ(0u, fake_process_manager()->GetNumActiveReferences());
// Active profile should still be active. // Active profile should still be active.
EXPECT_TRUE(manager.IsActiveProfile(profile)); EXPECT_TRUE(manager.IsActiveProfile(profile));
manager.RemoveObserver(&observer); manager.RemoveObserver(&observer);
} }
TEST_F(NearbyProcessManagerTest, GetOrStartNearbyConnections) { TEST_F(NearbyProcessManagerTest, NearbySharingDecoder) {
auto& manager = NearbyProcessManager::GetInstance(); auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name"); Profile* profile = CreateProfile("name", /*is_primary_profile=*/true);
manager.SetActiveProfile(profile); manager.SetActiveProfile(profile);
// Inject fake Nearby process mojo connection. MockNearbyProcessManagerObserver observer;
FakeSharingMojoService fake_sharing_service; base::RunLoop run_loop_started;
manager.BindSharingProcess(fake_sharing_service.BindSharingService()); base::RunLoop run_loop_stopped;
EXPECT_CALL(observer, OnNearbyProcessStarted())
auto adapter = base::MakeRefCounted<device::MockBluetoothAdapter>(); .WillOnce(testing::Invoke(&run_loop_started, &base::RunLoop::Quit));
EXPECT_CALL(*adapter, IsPresent()).WillOnce(testing::Return(true)); EXPECT_CALL(observer, OnNearbyProcessStopped())
device::BluetoothAdapterFactory::SetAdapterForTesting(adapter); .WillOnce(testing::Invoke(&run_loop_stopped, &base::RunLoop::Quit));
manager.AddObserver(&observer);
// 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.WaitForConnections();
EXPECT_TRUE(fake_sharing_service.dependencies()->bluetooth_adapter);
EXPECT_TRUE(fake_sharing_service.dependencies()->webrtc_dependencies);
}
TEST_F(NearbyProcessManagerTest,
GetOrStartNearbyConnections_BluetoothNotPresent) {
auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name");
manager.SetActiveProfile(profile);
// Inject fake Nearby process mojo connection. sharing::mojom::NearbySharingDecoder* decoder =
FakeSharingMojoService fake_sharing_service; manager.GetOrStartNearbySharingDecoder(profile);
manager.BindSharingProcess(fake_sharing_service.BindSharingService()); run_loop_started.Run();
EXPECT_EQ(decoder,
fake_process_manager()->active_decoder()->shared_remote().get());
EXPECT_EQ(1u, fake_process_manager()->GetNumActiveReferences());
auto adapter = base::MakeRefCounted<device::MockBluetoothAdapter>(); // Stop the process and wait for it to finish.
EXPECT_CALL(*adapter, IsPresent()).WillOnce(testing::Return(false)); manager.StopProcess(profile);
device::BluetoothAdapterFactory::SetAdapterForTesting(adapter); run_loop_stopped.Run();
// Request a new Nearby Connections interface. EXPECT_EQ(0u, fake_process_manager()->GetNumActiveReferences());
EXPECT_NE(nullptr, manager.GetOrStartNearbyConnections(profile));
// Expect the manager to bind a new Nearby Connections pipe.
fake_sharing_service.WaitForConnections();
EXPECT_FALSE(fake_sharing_service.dependencies()->bluetooth_adapter); // Active profile should still be active.
EXPECT_TRUE(fake_sharing_service.dependencies()->webrtc_dependencies); EXPECT_TRUE(manager.IsActiveProfile(profile));
manager.RemoveObserver(&observer);
} }
TEST_F(NearbyProcessManagerTest, ResetNearbyProcess) { TEST_F(NearbyProcessManagerTest, NearbyConnectionsAndDecoder) {
auto& manager = NearbyProcessManager::GetInstance(); auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name"); Profile* profile = CreateProfile("name", /*is_primary_profile=*/true);
manager.SetActiveProfile(profile); manager.SetActiveProfile(profile);
// Inject fake Nearby process mojo connection.
FakeSharingMojoService fake_sharing_service;
manager.BindSharingProcess(fake_sharing_service.BindSharingService());
MockNearbyProcessManagerObserver observer; MockNearbyProcessManagerObserver observer;
base::RunLoop run_loop; 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()) EXPECT_CALL(observer, OnNearbyProcessStopped())
.WillOnce(testing::Invoke(&run_loop, &base::RunLoop::Quit)); .WillOnce(testing::Invoke(&run_loop_stopped, &base::RunLoop::Quit));
manager.AddObserver(&observer); manager.AddObserver(&observer);
// Simulate a dropped mojo connection to the Nearby process. NearbyProcessManager::NearbyConnectionsMojom* nearby_connections =
fake_sharing_service.Reset(); manager.GetOrStartNearbyConnections(profile);
run_loop_started.Run();
EXPECT_EQ(
nearby_connections,
fake_process_manager()->active_connections()->shared_remote().get());
EXPECT_EQ(1u, fake_process_manager()->GetNumActiveReferences());
// Expect the OnNearbyProcessStopped() callback to run. sharing::mojom::NearbySharingDecoder* decoder =
run_loop.Run(); manager.GetOrStartNearbySharingDecoder(profile);
EXPECT_EQ(decoder,
fake_process_manager()->active_decoder()->shared_remote().get());
// Only one reference should have been created to serve both Nearby
// Connections and the Nearby Share decoder.
EXPECT_EQ(1u, fake_process_manager()->GetNumActiveReferences());
// Stop the process and wait for it to finish.
manager.StopProcess(profile);
run_loop_stopped.Run();
EXPECT_EQ(0u, fake_process_manager()->GetNumActiveReferences());
// Active profile should still be active.
EXPECT_TRUE(manager.IsActiveProfile(profile));
manager.RemoveObserver(&observer); manager.RemoveObserver(&observer);
} }
TEST_F(NearbyProcessManagerTest, StartStopProcessWithNearbySharingDecoder) { TEST_F(NearbyProcessManagerTest, SharedReferences) {
auto& manager = NearbyProcessManager::GetInstance(); auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name"); Profile* profile = CreateProfile("name", /*is_primary_profile=*/true);
manager.SetActiveProfile(profile); manager.SetActiveProfile(profile);
// Inject fake Nearby process mojo connection.
FakeSharingMojoService fake_sharing_service;
manager.BindSharingProcess(fake_sharing_service.BindSharingService());
MockNearbyProcessManagerObserver observer; MockNearbyProcessManagerObserver observer;
base::RunLoop run_loop_started; base::RunLoop run_loop_started;
base::RunLoop run_loop_stopped; base::RunLoop run_loop_stopped;
...@@ -386,48 +380,39 @@ TEST_F(NearbyProcessManagerTest, StartStopProcessWithNearbySharingDecoder) { ...@@ -386,48 +380,39 @@ TEST_F(NearbyProcessManagerTest, StartStopProcessWithNearbySharingDecoder) {
.WillOnce(testing::Invoke(&run_loop_stopped, &base::RunLoop::Quit)); .WillOnce(testing::Invoke(&run_loop_stopped, &base::RunLoop::Quit));
manager.AddObserver(&observer); manager.AddObserver(&observer);
// Start up a new process and wait for it to launch. // Create a reference without using the class; this simulates another feature
EXPECT_NE(nullptr, manager.GetOrStartNearbySharingDecoder(profile)); // (e.g., Phone Hub) using Nearby Connections.
auto reference =
fake_process_manager()->GetNearbyProcessReference(base::DoNothing());
EXPECT_EQ(1u, fake_process_manager()->GetNumActiveReferences());
NearbyProcessManager::NearbyConnectionsMojom* nearby_connections =
manager.GetOrStartNearbyConnections(profile);
run_loop_started.Run(); run_loop_started.Run();
EXPECT_EQ(
nearby_connections,
fake_process_manager()->active_connections()->shared_remote().get());
EXPECT_EQ(2u, fake_process_manager()->GetNumActiveReferences());
// Stop the process and wait for it to finish. // Stop the process; there should still be an active reference.
manager.StopProcess(profile); manager.StopProcess(profile);
EXPECT_EQ(1u, fake_process_manager()->GetNumActiveReferences());
// Delete the reference and verify the process is stopped.
reference.reset();
run_loop_stopped.Run(); run_loop_stopped.Run();
EXPECT_EQ(0u, fake_process_manager()->GetNumActiveReferences());
// Active profile should still be active. // Active profile should still be active.
EXPECT_TRUE(manager.IsActiveProfile(profile)); EXPECT_TRUE(manager.IsActiveProfile(profile));
manager.RemoveObserver(&observer); manager.RemoveObserver(&observer);
} }
TEST_F(NearbyProcessManagerTest, GetOrStartNearbySharingDecoder) { TEST_F(NearbyProcessManagerTest, NearbyProcessStopsOnItsOwn) {
auto& manager = NearbyProcessManager::GetInstance(); auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name"); Profile* profile = CreateProfile("name", /*is_primary_profile=*/true);
manager.SetActiveProfile(profile); manager.SetActiveProfile(profile);
// Inject fake Nearby process mojo connection.
FakeSharingMojoService fake_sharing_service;
manager.BindSharingProcess(fake_sharing_service.BindSharingService());
// Request a new Nearby Sharing Decoder interface.
EXPECT_NE(nullptr, manager.GetOrStartNearbySharingDecoder(profile));
// Expect the manager to bind a new Nearby Sharing Decoder pipe.
fake_sharing_service.WaitForDecoder();
}
TEST_F(NearbyProcessManagerTest, GetOrStartNearbySharingDecoderAndConnections) {
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());
auto adapter = base::MakeRefCounted<device::MockBluetoothAdapter>();
EXPECT_CALL(*adapter, IsPresent()).WillOnce(testing::Return(true));
device::BluetoothAdapterFactory::SetAdapterForTesting(adapter);
MockNearbyProcessManagerObserver observer; MockNearbyProcessManagerObserver observer;
base::RunLoop run_loop_started; base::RunLoop run_loop_started;
base::RunLoop run_loop_stopped; base::RunLoop run_loop_stopped;
...@@ -437,21 +422,25 @@ TEST_F(NearbyProcessManagerTest, GetOrStartNearbySharingDecoderAndConnections) { ...@@ -437,21 +422,25 @@ TEST_F(NearbyProcessManagerTest, GetOrStartNearbySharingDecoderAndConnections) {
.WillOnce(testing::Invoke(&run_loop_stopped, &base::RunLoop::Quit)); .WillOnce(testing::Invoke(&run_loop_stopped, &base::RunLoop::Quit));
manager.AddObserver(&observer); manager.AddObserver(&observer);
// Request a new Nearby Sharing Decoder interface. NearbyProcessManager::NearbyConnectionsMojom* nearby_connections =
EXPECT_NE(nullptr, manager.GetOrStartNearbySharingDecoder(profile)); manager.GetOrStartNearbyConnections(profile);
fake_sharing_service.WaitForDecoder();
run_loop_started.Run(); run_loop_started.Run();
EXPECT_EQ(
nearby_connections,
fake_process_manager()->active_connections()->shared_remote().get());
EXPECT_EQ(1u, fake_process_manager()->GetNumActiveReferences());
// Then request a new Nearby Connections interface. // Simulate the process stopping on its own, like what would happen if it
EXPECT_NE(nullptr, manager.GetOrStartNearbyConnections(profile)); // crashed.
fake_sharing_service.WaitForConnections(); fake_process_manager()->SimulateProcessStopped();
// Stop the process and wait for it to finish. // Verify that the observer was notified.
manager.StopProcess(profile);
run_loop_stopped.Run(); run_loop_stopped.Run();
// NearbyProcessManager is expected to have dropped its active reference.
EXPECT_EQ(0u, fake_process_manager()->GetNumActiveReferences());
// Active profile should still be active. // Active profile should still be active.
EXPECT_TRUE(manager.IsActiveProfile(profile)); EXPECT_TRUE(manager.IsActiveProfile(profile));
manager.RemoveObserver(&observer); manager.RemoveObserver(&observer);
} }
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/browser_features.h" #include "chrome/browser/browser_features.h"
#include "chrome/browser/chromeos/nearby/nearby_process_manager_factory.h"
#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h"
#include "chrome/browser/nearby_sharing/logging/logging.h" #include "chrome/browser/nearby_sharing/logging/logging.h"
#include "chrome/browser/nearby_sharing/nearby_connections_manager.h" #include "chrome/browser/nearby_sharing/nearby_connections_manager.h"
...@@ -55,6 +56,7 @@ NearbySharingServiceFactory::NearbySharingServiceFactory() ...@@ -55,6 +56,7 @@ NearbySharingServiceFactory::NearbySharingServiceFactory()
kServiceName, kServiceName,
BrowserContextDependencyManager::GetInstance()) { BrowserContextDependencyManager::GetInstance()) {
DependsOn(IdentityManagerFactory::GetInstance()); DependsOn(IdentityManagerFactory::GetInstance());
DependsOn(chromeos::nearby::NearbyProcessManagerFactory::GetInstance());
DependsOn(NotificationDisplayServiceFactory::GetInstance()); DependsOn(NotificationDisplayServiceFactory::GetInstance());
} }
......
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