Skip to content

Commit

Permalink
Wire NearbySharingDecoder to SharingService and NearbyProcessManager
Browse files Browse the repository at this point in the history
Bug: 1084582
Change-Id: If0590968e298e6d32dd139c4e8f0a74aea6131c0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2232918
Reviewed-by: Alex Chau <alexchau@chromium.org>
Reviewed-by: Alex Gough <ajgo@chromium.org>
Reviewed-by: Richard Knoll <knollr@chromium.org>
Commit-Queue: Naomi Musgrave <nmusgrave@chromium.org>
Cr-Commit-Position: refs/heads/master@{#777008}
  • Loading branch information
Naomi Musgrave authored and Commit Bot committed Jun 10, 2020
1 parent 9efa381 commit bea0c82
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 8 deletions.
46 changes: 46 additions & 0 deletions chrome/browser/nearby_sharing/nearby_process_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

#include "chrome/browser/nearby_sharing/nearby_process_manager.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "build/build_config.h"
Expand Down Expand Up @@ -129,6 +132,18 @@ NearbyProcessManager::GetOrStartNearbyConnections(Profile* profile) {
return connections_.get();
}

sharing::mojom::NearbySharingDecoder*
NearbyProcessManager::GetOrStartNearbySharingDecoder(Profile* profile) {
if (!IsActiveProfile(profile))
return nullptr;

// Launch a new Nearby Sharing Decoder interface if required.
if (!decoder_.is_bound())
BindNearbySharingDecoder();

return decoder_.get();
}

void NearbyProcessManager::StopProcess(Profile* profile) {
if (!IsActiveProfile(profile))
return;
Expand All @@ -137,6 +152,7 @@ void NearbyProcessManager::StopProcess(Profile* profile) {

connections_host_.reset();
connections_.reset();
decoder_.reset();
sharing_process_.reset();

if (was_running) {
Expand Down Expand Up @@ -241,6 +257,36 @@ void NearbyProcessManager::OnNearbyProcessStopped() {
StopProcess(active_profile_);
}

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(
mojo::PendingReceiver<NearbySharingDecoderMojom> receiver,
mojo::PendingRemote<NearbySharingDecoderMojom> remote) {
if (!mojo::FusePipes(std::move(receiver), std::move(remote))) {
LOG(WARNING) << "Failed to initialize Nearby Sharing Decoder process";
StopProcess(active_profile_);
return;
}

for (auto& observer : observers_)
observer.OnNearbyProcessStarted();
}

void NearbyProcessManager::OnGetBluetoothAdapter(
location::nearby::connections::mojom::NearbyConnectionsHost::
GetBluetoothAdapterCallback callback,
Expand Down
18 changes: 14 additions & 4 deletions chrome/browser/nearby_sharing/nearby_process_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#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/nearby_decoder.mojom.h"
#include "chrome/services/sharing/public/mojom/sharing.mojom.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
Expand All @@ -33,6 +34,7 @@ class NearbyProcessManager
location::nearby::connections::mojom::NearbyConnections;
using NearbyConnectionsHostMojom =
location::nearby::connections::mojom::NearbyConnectionsHost;
using NearbySharingDecoderMojom = sharing::mojom::NearbySharingDecoder;

// 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.
Expand Down Expand Up @@ -90,12 +92,11 @@ class NearbyProcessManager
// 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);
NearbySharingDecoderMojom* GetOrStartNearbySharingDecoder(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
Expand Down Expand Up @@ -148,6 +149,16 @@ class NearbyProcessManager
// Observer::OnNearbyProcessStopped().
void OnNearbyProcessStopped();

// Binds a new pipe to the Nearby Sharing Decoder. May start a new process
// if there is none running yet.
void BindNearbySharingDecoder();

// Called by the sandboxed process after initializing the Nearby Sharing
// Decoder.
void OnNearbySharingDecoder(
mojo::PendingReceiver<NearbySharingDecoderMojom> receiver,
mojo::PendingRemote<NearbySharingDecoderMojom> remote);

// Called when a bluetooth adapter is acquired and we can finish
// the GetBluetoothAdapter mojo call
void OnGetBluetoothAdapter(GetBluetoothAdapterCallback callback,
Expand All @@ -157,9 +168,8 @@ class NearbyProcessManager
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_;
mojo::Remote<NearbySharingDecoderMojom> decoder_;

// Host interface for the Nearby Connections interface.
mojo::Receiver<NearbyConnectionsHostMojom> connections_host_{this};
Expand Down
129 changes: 125 additions & 4 deletions chrome/browser/nearby_sharing/nearby_process_manager_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/files/file_path.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.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/nearby_decoder.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"
Expand All @@ -31,13 +34,35 @@ using NearbyConnectionsMojom =
location::nearby::connections::mojom::NearbyConnections;
using NearbyConnectionsHostMojom =
location::nearby::connections::mojom::NearbyConnectionsHost;
using NearbySharingDecoderMojom = sharing::mojom::NearbySharingDecoder;

namespace {

class MockNearbyConnections : public NearbyConnectionsMojom {
public:
};

class MockNearbySharingDecoder : public NearbySharingDecoderMojom {
public:
MockNearbySharingDecoder() = default;
explicit MockNearbySharingDecoder(
const sharing::mojom::NearbySharingDecoder&) = delete;
MockNearbySharingDecoder& operator=(
const sharing::mojom::NearbySharingDecoder&) = delete;
~MockNearbySharingDecoder() override = default;

// sharing::mojom::NearbySharingDecoder:
MOCK_METHOD(void,
DecodeAdvertisement,
(const std::vector<uint8_t>& data,
DecodeAdvertisementCallback callback),
(override));
MOCK_METHOD(void,
DecodeFrame,
(const std::vector<uint8_t>& data, DecodeFrameCallback callback),
(override));
};

class FakeSharingMojoService : public sharing::mojom::Sharing {
public:
FakeSharingMojoService() = default;
Expand Down Expand Up @@ -67,16 +92,29 @@ class FakeSharingMojoService : public sharing::mojom::Sharing {
run_loop_connections.Quit();
}

void CreateNearbySharingDecoder(
CreateNearbySharingDecoderCallback callback) override {
mojo::PendingRemote<NearbySharingDecoderMojom> remote;
mojo::MakeSelfOwnedReceiver(std::make_unique<MockNearbySharingDecoder>(),
remote.InitWithNewPipeAndPassReceiver());
std::move(callback).Run(std::move(remote));

run_loop_decoder.Quit();
}

mojo::PendingRemote<sharing::mojom::Sharing> BindSharingService() {
return receiver.BindNewPipeAndPassRemote();
}

void WaitForNearbyConnections() { run_loop_connections.Run(); }
void WaitForConnections() { run_loop_connections.Run(); }

void WaitForDecoder() { run_loop_decoder.Run(); }

void Reset() { receiver.reset(); }

private:
base::RunLoop run_loop_connections;
base::RunLoop run_loop_decoder;
mojo::Receiver<sharing::mojom::Sharing> receiver{this};
mojo::Remote<NearbyConnectionsHostMojom> connections_host;
};
Expand Down Expand Up @@ -128,7 +166,6 @@ class NearbyProcessManagerTest : public testing::Test {
TestingBrowserProcess::GetGlobal()};
std::set<Profile*> profiles_;
};

} // namespace

TEST_F(NearbyProcessManagerTest, AddRemoveObserver) {
Expand Down Expand Up @@ -213,7 +250,7 @@ TEST_F(NearbyProcessManagerTest, OnProfileDeleted_InactiveProfile) {
EXPECT_FALSE(manager.IsActiveProfile(profile_2));
}

TEST_F(NearbyProcessManagerTest, StartStopProcess) {
TEST_F(NearbyProcessManagerTest, StartStopProcessWithNearbyConnections) {
auto& manager = NearbyProcessManager::GetInstance();
Profile* profile = CreateProfile("name");
manager.SetActiveProfile(profile);
Expand Down Expand Up @@ -257,7 +294,7 @@ TEST_F(NearbyProcessManagerTest, GetOrStartNearbyConnections) {
// 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();
fake_sharing_service.WaitForConnections();
}

TEST_F(NearbyProcessManagerTest, ResetNearbyProcess) {
Expand All @@ -284,6 +321,90 @@ TEST_F(NearbyProcessManagerTest, ResetNearbyProcess) {
manager.RemoveObserver(&observer);
}

TEST_F(NearbyProcessManagerTest, StartStopProcessWithNearbySharingDecoder) {
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_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.GetOrStartNearbySharingDecoder(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, GetOrStartNearbySharingDecoder) {
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 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());

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);

// Request a new Nearby Sharing Decoder interface.
EXPECT_NE(nullptr, manager.GetOrStartNearbySharingDecoder(profile));
fake_sharing_service.WaitForDecoder();
run_loop_started.Run();

// Then request a new Nearby Connections interface.
EXPECT_NE(nullptr, manager.GetOrStartNearbyConnections(profile));
fake_sharing_service.WaitForConnections();

// 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, GetBluetoothAdapter) {
auto& manager = NearbyProcessManager::GetInstance();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

#include "chrome/browser/sharing/webrtc/sharing_service_host.h"

#include <memory>
#include <utility>
#include <vector>

#include "base/strings/strcat.h"
#include "base/test/bind_test_util.h"
#include "chrome/browser/sharing/mock_sharing_device_source.h"
Expand Down Expand Up @@ -49,6 +53,10 @@ class FakeSharingMojoService : public sharing::mojom::Sharing,
CreateNearbyConnectionsCallback callback) override {
NOTIMPLEMENTED();
}
void CreateNearbySharingDecoder(
CreateNearbySharingDecoderCallback callback) override {
NOTIMPLEMENTED();
}

void OnOfferReceived(const std::string& offer,
OnOfferReceivedCallback callback) override {
Expand Down
5 changes: 5 additions & 0 deletions chrome/services/sharing/public/mojom/sharing.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
module sharing.mojom;

import "chrome/services/sharing/public/mojom/nearby_connections.mojom";
import "chrome/services/sharing/public/mojom/nearby_decoder.mojom";
import "chrome/services/sharing/public/mojom/webrtc.mojom";
import "services/network/public/mojom/p2p.mojom";
import "services/network/public/mojom/mdns_responder.mojom";
Expand Down Expand Up @@ -41,4 +42,8 @@ interface Sharing {
host)
=> (pending_remote<location.nearby.connections.mojom.NearbyConnections>
connections);

// Creates a new Nearby Sharing Decoder.
CreateNearbySharingDecoder()
=> (pending_remote<sharing.mojom.NearbySharingDecoder> decoder);
};
Loading

0 comments on commit bea0c82

Please sign in to comment.