| Index: services/ui/ws/embedded_surface_tracker_unittest.cc
|
| diff --git a/services/ui/ws/embedded_surface_tracker_unittest.cc b/services/ui/ws/embedded_surface_tracker_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ba3d842f6815663ace2e23c881492b02fe09f17e
|
| --- /dev/null
|
| +++ b/services/ui/ws/embedded_surface_tracker_unittest.cc
|
| @@ -0,0 +1,239 @@
|
| +// Copyright 2017 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 "services/ui/ws/embedded_surface_tracker.h"
|
| +
|
| +#include <memory>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/macros.h"
|
| +#include "cc/ipc/mojo_compositor_frame_sink.mojom.h"
|
| +#include "cc/surfaces/frame_sink_id.h"
|
| +#include "cc/surfaces/surface_id.h"
|
| +#include "cc/surfaces/surface_reference.h"
|
| +#include "mojo/public/cpp/bindings/binding.h"
|
| +#include "mojo/public/cpp/bindings/interface_request.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using testing::ElementsAre;
|
| +using testing::IsEmpty;
|
| +
|
| +namespace ui {
|
| +namespace test {
|
| +namespace {
|
| +
|
| +constexpr cc::FrameSinkId kParentFrameSink(2, 1);
|
| +constexpr cc::FrameSinkId kEmbeddedFrameSink(65563, 1);
|
| +
|
| +cc::SurfaceId MakeSurfaceId(const cc::FrameSinkId& frame_sink_id,
|
| + uint32_t local_id) {
|
| + return cc::SurfaceId(
|
| + frame_sink_id,
|
| + cc::LocalFrameId(local_id, base::UnguessableToken::Deserialize(0, 1u)));
|
| +}
|
| +
|
| +class TestMojoCompositorFrameSink : public cc::mojom::MojoCompositorFrameSink {
|
| + public:
|
| + TestMojoCompositorFrameSink() {}
|
| + ~TestMojoCompositorFrameSink() override {}
|
| +
|
| + const std::vector<cc::SurfaceReference>& added() const { return added_; }
|
| + const std::vector<cc::SurfaceReference>& removed() const { return removed_; }
|
| +
|
| + // Reset |added_| and |removed_|.
|
| + void Reset() {
|
| + added_.clear();
|
| + removed_.clear();
|
| + }
|
| +
|
| + // cc::mojom::MojoCompositorFrameSink:
|
| + void SetNeedsBeginFrame(bool needs_begin_frame) override {}
|
| + void SubmitCompositorFrame(const cc::LocalFrameId& local_frame_id,
|
| + cc::CompositorFrame frame) override {}
|
| + void AddSurfaceReferences(
|
| + const std::vector<cc::SurfaceReference>& references) override {
|
| + added_ = references;
|
| + }
|
| + void RemoveSurfaceReferences(
|
| + const std::vector<cc::SurfaceReference>& references) override {
|
| + removed_ = references;
|
| + }
|
| + void EvictFrame() override {}
|
| + void Require(const cc::LocalFrameId& local_frame_id,
|
| + const cc::SurfaceSequence& sequence) override {}
|
| + void Satisfy(const cc::SurfaceSequence& sequence) override {}
|
| +
|
| + private:
|
| + std::vector<cc::SurfaceReference> added_;
|
| + std::vector<cc::SurfaceReference> removed_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TestMojoCompositorFrameSink);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class EmbeddedSurfaceTrackerTest : public testing::Test {
|
| + public:
|
| + EmbeddedSurfaceTrackerTest() {}
|
| + ~EmbeddedSurfaceTrackerTest() override {}
|
| +
|
| + EmbeddedSurfaceTracker& tracker() { return *tracker_; }
|
| + TestMojoCompositorFrameSink& frame_sink() { return frame_sink_; }
|
| +
|
| + const std::vector<cc::SurfaceReference>& references_to_add() {
|
| + return tracker_->references_to_add_;
|
| + }
|
| +
|
| + const std::vector<cc::SurfaceReference>& references_to_remove() {
|
| + return tracker_->references_to_remove_;
|
| + }
|
| +
|
| + // testing::Test:
|
| + void SetUp() override {
|
| + testing::Test::SetUp();
|
| + tracker_ = base::MakeUnique<EmbeddedSurfaceTracker>();
|
| + }
|
| +
|
| + void TearDown() override {
|
| + frame_sink_.Reset();
|
| + tracker_.reset();
|
| + }
|
| +
|
| + private:
|
| + std::unique_ptr<EmbeddedSurfaceTracker> tracker_;
|
| + TestMojoCompositorFrameSink frame_sink_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(EmbeddedSurfaceTrackerTest);
|
| +};
|
| +
|
| +TEST_F(EmbeddedSurfaceTrackerTest, SetCurrentSurfaceId) {
|
| + const cc::SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
|
| +
|
| + // Initially HasValidSurfaceId() should be false.
|
| + EXPECT_FALSE(tracker().HasValidSurfaceId());
|
| +
|
| + // After setting current SurfaceId then HasValidSurfaceId() should be true.
|
| + tracker().SetCurrentSurfaceId(parent_id);
|
| + EXPECT_TRUE(tracker().HasValidSurfaceId());
|
| + EXPECT_EQ(parent_id, tracker().current_surface_id());
|
| +}
|
| +
|
| +TEST_F(EmbeddedSurfaceTrackerTest, EmbedSurface) {
|
| + const cc::SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
|
| + const cc::SurfaceId embedded_id = MakeSurfaceId(kEmbeddedFrameSink, 1);
|
| + const cc::SurfaceReference reference(parent_id, embedded_id);
|
| +
|
| + // Set parent surface id then embed another surface. The tracker should have a
|
| + // reference to add from parent surface to embedded surface.
|
| + tracker().SetCurrentSurfaceId(parent_id);
|
| + tracker().EmbedSurface(embedded_id);
|
| + EXPECT_THAT(references_to_add(), ElementsAre(reference));
|
| +
|
| + // After adding references the tracker should no longer have any references to
|
| + // add and MojoCompositorFrameSink should have been called with surfaces to
|
| + // add.
|
| + tracker().SendAddSurfaceReferences(&frame_sink());
|
| + EXPECT_THAT(frame_sink().added(), ElementsAre(reference));
|
| + EXPECT_THAT(references_to_add(), IsEmpty());
|
| +}
|
| +
|
| +TEST_F(EmbeddedSurfaceTrackerTest, EmbedNewSurface) {
|
| + const cc::SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
|
| + const cc::SurfaceId embedded_id_first = MakeSurfaceId(kEmbeddedFrameSink, 1);
|
| + const cc::SurfaceId embedded_id_second = MakeSurfaceId(kEmbeddedFrameSink, 2);
|
| + const cc::SurfaceReference reference_first(parent_id, embedded_id_first);
|
| + const cc::SurfaceReference reference_second(parent_id, embedded_id_second);
|
| +
|
| + // Embed a surface and add references.
|
| + tracker().SetCurrentSurfaceId(parent_id);
|
| + tracker().EmbedSurface(embedded_id_first);
|
| + tracker().SendAddSurfaceReferences(&frame_sink());
|
| + EXPECT_THAT(frame_sink().added(), ElementsAre(reference_first));
|
| +
|
| + // Embed a newer surface with the same FrameSinkId as the first embedded
|
| + // surface. The first reference should be in the list to remove and the new
|
| + // reference in the last to add.
|
| + tracker().EmbedSurface(embedded_id_second);
|
| + EXPECT_THAT(references_to_remove(), ElementsAre(reference_first));
|
| + EXPECT_THAT(references_to_add(), ElementsAre(reference_second));
|
| +}
|
| +
|
| +TEST_F(EmbeddedSurfaceTrackerTest, UnembedSurface) {
|
| + const cc::SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
|
| + const cc::SurfaceId embedded_id = MakeSurfaceId(kEmbeddedFrameSink, 1);
|
| + const cc::SurfaceReference reference(parent_id, embedded_id);
|
| +
|
| + tracker().SetCurrentSurfaceId(parent_id);
|
| + tracker().EmbedSurface(embedded_id);
|
| + tracker().SendAddSurfaceReferences(&frame_sink());
|
| + EXPECT_THAT(frame_sink().added(), ElementsAre(reference));
|
| + EXPECT_THAT(references_to_remove(), IsEmpty());
|
| +
|
| + // Unembed the surface. The reference should be in the list to remove.
|
| + tracker().UnembedSurface(embedded_id.frame_sink_id());
|
| + EXPECT_THAT(references_to_remove(), ElementsAre(reference));
|
| +
|
| + // Perform remove, the list to remove should be empty and
|
| + // MojoCompositorFrameSink should have been called with surfaces to remove.
|
| + tracker().SendRemoveSurfaceReferences(&frame_sink());
|
| + EXPECT_THAT(references_to_remove(), IsEmpty());
|
| + EXPECT_THAT(frame_sink().removed(), ElementsAre(reference));
|
| +}
|
| +
|
| +TEST_F(EmbeddedSurfaceTrackerTest, EmbedSurfaceBeforeSetClientSurfaceId) {
|
| + const cc::SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
|
| + const cc::SurfaceId embedded_id = MakeSurfaceId(kEmbeddedFrameSink, 1);
|
| + const cc::SurfaceReference reference(parent_id, embedded_id);
|
| +
|
| + // Embed a surface before the parent id is set. There should be no references
|
| + // to add because we don't know the parent id yet.
|
| + tracker().EmbedSurface(embedded_id);
|
| + EXPECT_THAT(references_to_add(), IsEmpty());
|
| +
|
| + // Set the parent id, this should add a reference to add to the embedded
|
| + // surface.
|
| + tracker().SetCurrentSurfaceId(parent_id);
|
| + EXPECT_THAT(references_to_add(), ElementsAre(reference));
|
| +}
|
| +
|
| +TEST_F(EmbeddedSurfaceTrackerTest, UpdateCurrentSurfaceId) {
|
| + const cc::SurfaceId parent_id_first = MakeSurfaceId(kParentFrameSink, 1);
|
| + const cc::SurfaceId parent_id_second = MakeSurfaceId(kParentFrameSink, 1);
|
| + const cc::SurfaceId embedded_id = MakeSurfaceId(kEmbeddedFrameSink, 1);
|
| + const cc::SurfaceReference reference(parent_id_second, embedded_id);
|
| +
|
| + // Set parent id and embed a surface.
|
| + tracker().SetCurrentSurfaceId(parent_id_first);
|
| + tracker().EmbedSurface(embedded_id);
|
| + tracker().SendAddSurfaceReferences(&frame_sink());
|
| +
|
| + // Update the current parent id. There should be a reference to add from the
|
| + // new parent id to the embedded surface.
|
| + tracker().SetCurrentSurfaceId(parent_id_second);
|
| + EXPECT_THAT(references_to_add(), ElementsAre(reference));
|
| +}
|
| +
|
| +TEST_F(EmbeddedSurfaceTrackerTest, UpdateCurrentSurfaceIdBeforeAdding) {
|
| + const cc::SurfaceId parent_id_first = MakeSurfaceId(kParentFrameSink, 1);
|
| + const cc::SurfaceId parent_id_second = MakeSurfaceId(kParentFrameSink, 1);
|
| + const cc::SurfaceId embedded_id = MakeSurfaceId(kEmbeddedFrameSink, 1);
|
| + const cc::SurfaceReference reference_first(parent_id_first, embedded_id);
|
| + const cc::SurfaceReference reference_second(parent_id_second, embedded_id);
|
| +
|
| + // Set parent id and embed a surface. There should be a reference to add from
|
| + // the parent to embedded surface.
|
| + tracker().SetCurrentSurfaceId(parent_id_first);
|
| + tracker().EmbedSurface(embedded_id);
|
| + EXPECT_THAT(references_to_add(), ElementsAre(reference_first));
|
| +
|
| + // Update the parent id before sending IPC to add references. There should be
|
| + // a reference to add from the new parent id to the embedded surface and the
|
| + // previous reference to add was deleted.
|
| + tracker().SetCurrentSurfaceId(parent_id_second);
|
| + EXPECT_THAT(references_to_add(), ElementsAre(reference_second));
|
| +}
|
| +
|
| +} // namespace test
|
| +} // namespace ui
|
|
|