blob: 3baa809832cde1192c330e6e889aac2fe6ad97f1 [file] [log] [blame]
// 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 "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
#include "base/test/null_task_runner.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/interfaces/bindings/tests/sample_service.mojom-blink.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/context_lifecycle_notifier.h"
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap_observer_set.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
#include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h"
#include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h"
namespace blink {
namespace {
class ServiceImpl : public sample::blink::Service {
public:
mojo::AssociatedReceiver<sample::blink::Service>& associated_receiver() {
return associated_receiver_;
}
private:
// sample::blink::Service implementation
void Frobinate(sample::blink::FooPtr foo,
sample::blink::Service::BazOptions options,
mojo::PendingRemote<sample::blink::Port> port,
sample::blink::Service::FrobinateCallback callback) override {}
void GetPort(mojo::PendingReceiver<sample::blink::Port> port) override {}
mojo::AssociatedReceiver<sample::blink::Service> associated_receiver_{this};
};
template <HeapMojoWrapperMode Mode>
class AssociatedRemoteOwner
: public GarbageCollected<AssociatedRemoteOwner<Mode>> {
public:
explicit AssociatedRemoteOwner(MockContextLifecycleNotifier* context)
: associated_remote_(context) {}
explicit AssociatedRemoteOwner(
HeapMojoAssociatedRemote<sample::blink::Service, Mode> associated_remote)
: associated_remote_(std::move(associated_remote)) {}
HeapMojoAssociatedRemote<sample::blink::Service, Mode>& associated_remote() {
return associated_remote_;
}
void Trace(Visitor* visitor) const { visitor->Trace(associated_remote_); }
HeapMojoAssociatedRemote<sample::blink::Service, Mode> associated_remote_;
};
template <HeapMojoWrapperMode Mode>
class HeapMojoAssociatedRemoteDestroyContextBaseTest : public TestSupportingGC {
protected:
void SetUp() override {
context_ = MakeGarbageCollected<MockContextLifecycleNotifier>();
owner_ = MakeGarbageCollected<AssociatedRemoteOwner<Mode>>(context_);
scoped_refptr<base::NullTaskRunner> null_task_runner =
base::MakeRefCounted<base::NullTaskRunner>();
impl_.associated_receiver().Bind(
owner_->associated_remote().BindNewEndpointAndPassReceiver(
null_task_runner));
}
ServiceImpl impl_;
Persistent<MockContextLifecycleNotifier> context_;
Persistent<AssociatedRemoteOwner<Mode>> owner_;
};
template <HeapMojoWrapperMode Mode>
class HeapMojoAssociatedRemoteDisconnectWithReasonHandlerBaseTest
: public TestSupportingGC {
public:
base::RunLoop& run_loop() { return run_loop_; }
bool& disconnected_with_reason() { return disconnected_with_reason_; }
protected:
void SetUp() override {
CHECK(!disconnected_with_reason_);
context_ = MakeGarbageCollected<MockContextLifecycleNotifier>();
owner_ = MakeGarbageCollected<AssociatedRemoteOwner<Mode>>(context_);
scoped_refptr<base::NullTaskRunner> null_task_runner =
base::MakeRefCounted<base::NullTaskRunner>();
impl_.associated_receiver().Bind(
owner_->associated_remote().BindNewEndpointAndPassReceiver(
null_task_runner));
impl_.associated_receiver().set_disconnect_with_reason_handler(WTF::Bind(
[](HeapMojoAssociatedRemoteDisconnectWithReasonHandlerBaseTest*
associated_remote_test,
const uint32_t custom_reason, const std::string& description) {
associated_remote_test->run_loop().Quit();
associated_remote_test->disconnected_with_reason() = true;
},
WTF::Unretained(this)));
}
ServiceImpl impl_;
Persistent<MockContextLifecycleNotifier> context_;
Persistent<AssociatedRemoteOwner<Mode>> owner_;
base::RunLoop run_loop_;
bool disconnected_with_reason_ = false;
};
template <HeapMojoWrapperMode Mode>
class HeapMojoAssociatedRemoteMoveBaseTest : public TestSupportingGC {
protected:
void SetUp() override {
context_ = MakeGarbageCollected<MockContextLifecycleNotifier>();
HeapMojoAssociatedRemote<sample::blink::Service, Mode> associated_remote(
context_);
owner_ = MakeGarbageCollected<AssociatedRemoteOwner<Mode>>(
std::move(associated_remote));
scoped_refptr<base::NullTaskRunner> null_task_runner =
base::MakeRefCounted<base::NullTaskRunner>();
impl_.associated_receiver().Bind(
owner_->associated_remote().BindNewEndpointAndPassReceiver(
null_task_runner));
}
ServiceImpl impl_;
Persistent<MockContextLifecycleNotifier> context_;
Persistent<AssociatedRemoteOwner<Mode>> owner_;
};
} // namespace
class HeapMojoAssociatedRemoteDestroyContextWithContextObserverTest
: public HeapMojoAssociatedRemoteDestroyContextBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoAssociatedRemoteDestroyContextWithoutContextObserverTest
: public HeapMojoAssociatedRemoteDestroyContextBaseTest<
HeapMojoWrapperMode::kForceWithoutContextObserver> {};
class HeapMojoAssociatedRemoteDisconnectWithReasonHandlerWithContextObserverTest
: public HeapMojoAssociatedRemoteDisconnectWithReasonHandlerBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class
HeapMojoAssociatedRemoteDisconnectWithReasonHandlerWithoutContextObserverTest
: public HeapMojoAssociatedRemoteDisconnectWithReasonHandlerBaseTest<
HeapMojoWrapperMode::kForceWithoutContextObserver> {};
class HeapMojoAssociatedRemoteMoveWithContextObserverTest
: public HeapMojoAssociatedRemoteMoveBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoAssociatedRemoteMoveWithoutContextObserverTest
: public HeapMojoAssociatedRemoteMoveBaseTest<
HeapMojoWrapperMode::kForceWithoutContextObserver> {};
// Destroy the context with context observer and check that the connection is
// disconnected.
TEST_F(HeapMojoAssociatedRemoteDestroyContextWithContextObserverTest,
ResetsOnContextDestroyed) {
EXPECT_TRUE(owner_->associated_remote().is_bound());
context_->NotifyContextDestroyed();
EXPECT_FALSE(owner_->associated_remote().is_bound());
}
// Destroy the context without context observer and check that the connection is
// still connected.
TEST_F(HeapMojoAssociatedRemoteDestroyContextWithoutContextObserverTest,
ResetsOnContextDestroyed) {
EXPECT_TRUE(owner_->associated_remote().is_bound());
context_->NotifyContextDestroyed();
EXPECT_TRUE(owner_->associated_remote().is_bound());
}
// Reset the AssociatedRemote with custom reason and check that the specified
// handler is fired.
TEST_F(
HeapMojoAssociatedRemoteDisconnectWithReasonHandlerWithContextObserverTest,
ResetWithReason) {
EXPECT_FALSE(disconnected_with_reason());
const std::string message = "test message";
const uint32_t reason = 0;
owner_->associated_remote().ResetWithReason(reason, message);
run_loop().Run();
EXPECT_TRUE(disconnected_with_reason());
}
// Reset the AssociatedRemote with custom reason and check that the specified
// handler is fired.
TEST_F(
HeapMojoAssociatedRemoteDisconnectWithReasonHandlerWithoutContextObserverTest,
ResetWithReason) {
EXPECT_FALSE(disconnected_with_reason());
const std::string message = "test message";
const uint32_t reason = 0;
owner_->associated_remote().ResetWithReason(reason, message);
run_loop().Run();
EXPECT_TRUE(disconnected_with_reason());
}
// Move the AssociatedRemote from the outside of Owner class.
TEST_F(HeapMojoAssociatedRemoteMoveWithContextObserverTest, MoveSemantics) {
EXPECT_TRUE(owner_->associated_remote().is_bound());
context_->NotifyContextDestroyed();
EXPECT_FALSE(owner_->associated_remote().is_bound());
}
// Move the AssociatedRemote from the outside of Owner class.
TEST_F(HeapMojoAssociatedRemoteMoveWithoutContextObserverTest, MoveSemantics) {
EXPECT_TRUE(owner_->associated_remote().is_bound());
context_->NotifyContextDestroyed();
EXPECT_TRUE(owner_->associated_remote().is_bound());
}
} // namespace blink