// Copyright 2014 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 <stddef.h>
#include <stdint.h>

#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/service_test.h"
#include "services/ui/common/util.h"
#include "services/ui/public/interfaces/constants.mojom.h"
#include "services/ui/public/interfaces/window_tree.mojom.h"
#include "services/ui/public/interfaces/window_tree_host_factory.mojom.h"
#include "services/ui/ws/ids.h"
#include "services/ui/ws/test_change_tracker.h"
#include "services/ui/ws/window_server_service_test_base.h"
#include "ui/base/cursor/cursor.h"

using mojo::InterfaceRequest;
using service_manager::Service;
using ui::mojom::WindowDataPtr;
using ui::mojom::WindowTree;
using ui::mojom::WindowTreeClient;

namespace ui {
namespace ws {
namespace test {

namespace {

// Creates an id used for transport from the specified parameters.
Id BuildWindowId(ClientSpecificId client_id,
                 ClientSpecificId window_id) {
  const Id tmp = client_id;
  return (tmp << 32) | window_id;
}

// Callback function from WindowTree functions.
// ----------------------------------

void WindowTreeResultCallback(base::RunLoop* run_loop,
                              std::vector<TestWindow>* windows,
                              std::vector<WindowDataPtr> results) {
  WindowDatasToTestWindows(results, windows);
  run_loop->Quit();
}

void EmbedCallbackImpl(base::RunLoop* run_loop,
                       bool* result_cache,
                       bool result) {
  *result_cache = result;
  run_loop->Quit();
}

void ScheduleEmbedCallbackImpl(base::RunLoop* run_loop,
                               base::UnguessableToken* resulting_token,
                               const base::UnguessableToken& token) {
  *resulting_token = token;
  run_loop->Quit();
}

// -----------------------------------------------------------------------------

bool EmbedUrl(service_manager::Connector* connector,
              WindowTree* tree,
              const std::string& url,
              Id root_id) {
  bool result = false;
  base::RunLoop run_loop;
  {
    mojom::WindowTreeClientPtr client;
    connector->BindInterface(url, &client);
    const uint32_t embed_flags = 0;
    tree->Embed(root_id, std::move(client), embed_flags,
                base::Bind(&EmbedCallbackImpl, &run_loop, &result));
  }
  run_loop.Run();
  return result;
}

bool Embed(WindowTree* tree, Id root_id, mojom::WindowTreeClientPtr client) {
  bool result = false;
  base::RunLoop run_loop;
  {
    const uint32_t embed_flags = 0;
    tree->Embed(root_id, std::move(client), embed_flags,
                base::Bind(&EmbedCallbackImpl, &run_loop, &result));
  }
  run_loop.Run();
  return result;
}

bool EmbedUsingToken(WindowTree* tree,
                     Id root_id,
                     const base::UnguessableToken& token) {
  bool result = false;
  base::RunLoop run_loop;
  const uint32_t embed_flags = 0;
  tree->EmbedUsingToken(root_id, token, embed_flags,
                        base::Bind(&EmbedCallbackImpl, &run_loop, &result));
  run_loop.Run();
  return result;
}

void ScheduleEmbed(WindowTree* tree,
                   mojom::WindowTreeClientPtr client,
                   base::UnguessableToken* token) {
  base::RunLoop run_loop;
  tree->ScheduleEmbed(std::move(client),
                      base::Bind(&ScheduleEmbedCallbackImpl, &run_loop, token));
  run_loop.Run();
}

void GetWindowTree(WindowTree* tree,
                   Id window_id,
                   std::vector<TestWindow>* windows) {
  base::RunLoop run_loop;
  tree->GetWindowTree(
      window_id, base::Bind(&WindowTreeResultCallback, &run_loop, windows));
  run_loop.Run();
}

// Utility functions -----------------------------------------------------------

const Id kNullParentId = 0;
std::string IdToString(Id id) {
  return (id == kNullParentId)
             ? "null"
             : base::StringPrintf("%d,%d", ClientIdFromTransportId(id),
                                  ClientWindowIdFromTransportId(id));
}

std::string WindowParentToString(Id window, Id parent) {
  return base::StringPrintf("window=%s parent=%s", IdToString(window).c_str(),
                            IdToString(parent).c_str());
}

// -----------------------------------------------------------------------------

// A WindowTreeClient implementation that logs all changes to a tracker.
class TestWindowTreeClient : public mojom::WindowTreeClient,
                             public TestChangeTracker::Delegate,
                             public mojom::WindowManager {
 public:
  TestWindowTreeClient()
      : binding_(this),
        root_window_id_(0),
        // Start with a random large number so tests can use lower ids if they
        // want.
        next_change_id_(10000),
        waiting_change_id_(0),
        on_change_completed_result_(false),
        track_root_bounds_changes_(false) {
    tracker_.set_delegate(this);
  }

  void Bind(mojo::InterfaceRequest<mojom::WindowTreeClient> request) {
    binding_.Bind(std::move(request));
  }

  mojom::WindowTree* tree() { return tree_.get(); }
  TestChangeTracker* tracker() { return &tracker_; }
  Id root_window_id() const { return root_window_id_; }

  // Sets whether changes to the bounds of the root should be tracked. Normally
  // they are ignored (as during startup we often times get random size
  // changes).
  void set_track_root_bounds_changes(bool value) {
    track_root_bounds_changes_ = value;
  }

  // Runs a nested MessageLoop until |count| changes (calls to
  // WindowTreeClient functions) have been received.
  void WaitForChangeCount(size_t count) {
    if (tracker_.changes()->size() >= count)
      return;

    ASSERT_TRUE(wait_state_.get() == nullptr);
    wait_state_ = std::make_unique<WaitState>();
    wait_state_->change_count = count;
    wait_state_->run_loop.Run();
    wait_state_.reset();
  }

  uint32_t GetAndAdvanceChangeId() { return next_change_id_++; }

  // Runs a nested MessageLoop until OnEmbed() has been encountered.
  void WaitForOnEmbed() {
    if (tree_)
      return;
    embed_run_loop_ = std::make_unique<base::RunLoop>();
    embed_run_loop_->Run();
    embed_run_loop_.reset();
  }

  bool WaitForChangeCompleted(uint32_t id) {
    waiting_change_id_ = id;
    change_completed_run_loop_ = std::make_unique<base::RunLoop>();
    change_completed_run_loop_->Run();
    return on_change_completed_result_;
  }

  bool DeleteWindow(Id id) {
    const uint32_t change_id = GetAndAdvanceChangeId();
    tree()->DeleteWindow(change_id, id);
    return WaitForChangeCompleted(change_id);
  }

  bool AddWindow(Id parent, Id child) {
    const uint32_t change_id = GetAndAdvanceChangeId();
    tree()->AddWindow(change_id, parent, child);
    return WaitForChangeCompleted(change_id);
  }

  bool RemoveWindowFromParent(Id window_id) {
    const uint32_t change_id = GetAndAdvanceChangeId();
    tree()->RemoveWindowFromParent(change_id, window_id);
    return WaitForChangeCompleted(change_id);
  }

  bool ReorderWindow(Id window_id,
                     Id relative_window_id,
                     mojom::OrderDirection direction) {
    const uint32_t change_id = GetAndAdvanceChangeId();
    tree()->ReorderWindow(change_id, window_id, relative_window_id, direction);
    return WaitForChangeCompleted(change_id);
  }

  // Waits for all messages to be received by |ws|. This is done by attempting
  // to set opacity on an embed/invalid window. 1.0f is the default opacity
  // value. When we get the response we know all messages have been processed.
  bool WaitForAllMessages() { return !SetWindowOpacity(0, 1.0f); }

  Id NewWindow(ClientSpecificId window_id) {
    return NewWindowWithCompleteId(window_id);
  }

  // Generally you want NewWindow(), but use this if you need to test given
  // a complete window id (NewWindow() ors with the client id).
  Id NewWindowWithCompleteId(Id id) {
    std::unordered_map<std::string, std::vector<uint8_t>> properties;
    const uint32_t change_id = GetAndAdvanceChangeId();
    tree()->NewWindow(change_id, id, std::move(properties));
    return WaitForChangeCompleted(change_id) ? id : 0;
  }

  bool SetWindowProperty(Id window_id,
                         const std::string& name,
                         const std::vector<uint8_t>* data) {
    base::Optional<std::vector<uint8_t>> mojo_data;
    if (data)
      mojo_data.emplace(*data);
    const uint32_t change_id = GetAndAdvanceChangeId();
    tree()->SetWindowProperty(change_id, window_id, name, mojo_data);
    return WaitForChangeCompleted(change_id);
  }

  bool SetCursor(Id window_id, const ui::CursorData& cursor) {
    const uint32_t change_id = GetAndAdvanceChangeId();
    tree()->SetCursor(change_id, window_id, cursor);
    return WaitForChangeCompleted(change_id);
  }

  bool SetWindowVisibility(Id window_id, bool visible) {
    const uint32_t change_id = GetAndAdvanceChangeId();
    tree()->SetWindowVisibility(change_id, window_id, visible);
    return WaitForChangeCompleted(change_id);
  }

  bool SetWindowOpacity(Id window_id, float opacity) {
    const uint32_t change_id = GetAndAdvanceChangeId();
    tree()->SetWindowOpacity(change_id, window_id, opacity);
    return WaitForChangeCompleted(change_id);
  }

 private:
  // Used when running a nested MessageLoop.
  struct WaitState {
    WaitState() : change_count(0) {}

    // Number of changes waiting for.
    size_t change_count;
    base::RunLoop run_loop;
  };

  // TestChangeTracker::Delegate:
  void OnChangeAdded() override {
    if (wait_state_.get() &&
        tracker_.changes()->size() >= wait_state_->change_count) {
      wait_state_->run_loop.Quit();
    }
  }

  // WindowTreeClient:
  void OnEmbed(
      WindowDataPtr root,
      mojom::WindowTreePtr tree,
      int64_t display_id,
      Id focused_window_id,
      bool drawn,
      const base::Optional<viz::LocalSurfaceId>& local_surface_id) override {
    // TODO(sky): add coverage of |focused_window_id|.
    ASSERT_TRUE(root);
    root_window_id_ = root->window_id;
    tree_ = std::move(tree);
    tracker()->OnEmbed(std::move(root), drawn);
    if (embed_run_loop_)
      embed_run_loop_->Quit();
  }
  void OnEmbeddedAppDisconnected(Id window_id) override {
    tracker()->OnEmbeddedAppDisconnected(window_id);
  }
  void OnUnembed(Id window_id) override { tracker()->OnUnembed(window_id); }
  void OnCaptureChanged(Id new_capture_window_id,
                        Id old_capture_window_id) override {
    tracker()->OnCaptureChanged(new_capture_window_id, old_capture_window_id);
  }
  void OnFrameSinkIdAllocated(Id window_id,
                              const viz::FrameSinkId& frame_sink_id) override {}
  void OnTopLevelCreated(
      uint32_t change_id,
      mojom::WindowDataPtr data,
      int64_t display_id,
      bool drawn,
      const base::Optional<viz::LocalSurfaceId>& local_surface_id) override {
    tracker()->OnTopLevelCreated(change_id, std::move(data), drawn);
  }
  void OnWindowBoundsChanged(
      Id window_id,
      const gfx::Rect& old_bounds,
      const gfx::Rect& new_bounds,
      const base::Optional<viz::LocalSurfaceId>& local_surface_id) override {
    // The bounds of the root may change during startup on Android at random
    // times. As this doesn't matter, and shouldn't impact test exepctations,
    // it is ignored.
    if (window_id == root_window_id_ && !track_root_bounds_changes_)
      return;
    tracker()->OnWindowBoundsChanged(window_id, old_bounds, new_bounds,
                                     local_surface_id);
  }
  void OnWindowTransformChanged(Id window_id,
                                const gfx::Transform& old_transform,
                                const gfx::Transform& new_transform) override {
    tracker()->OnWindowTransformChanged(window_id);
  }
  void OnClientAreaChanged(
      Id window_id,
      const gfx::Insets& new_client_area,
      const std::vector<gfx::Rect>& new_additional_client_areas) override {}
  void OnTransientWindowAdded(Id window_id, Id transient_window_id) override {
    tracker()->OnTransientWindowAdded(window_id, transient_window_id);
  }
  void OnTransientWindowRemoved(Id window_id, Id transient_window_id) override {
    tracker()->OnTransientWindowRemoved(window_id, transient_window_id);
  }
  void OnWindowHierarchyChanged(Id window,
                                Id old_parent,
                                Id new_parent,
                                std::vector<WindowDataPtr> windows) override {
    tracker()->OnWindowHierarchyChanged(window, old_parent, new_parent,
                                        std::move(windows));
  }
  void OnWindowReordered(Id window_id,
                         Id relative_window_id,
                         mojom::OrderDirection direction) override {
    tracker()->OnWindowReordered(window_id, relative_window_id, direction);
  }
  void OnWindowDeleted(Id window) override {
    tracker()->OnWindowDeleted(window);
  }
  void OnWindowVisibilityChanged(Id window, bool visible) override {
    tracker()->OnWindowVisibilityChanged(window, visible);
  }
  void OnWindowOpacityChanged(Id window,
                              float old_opacity,
                              float new_opacity) override {
    tracker()->OnWindowOpacityChanged(window, new_opacity);
  }
  void OnWindowParentDrawnStateChanged(Id window, bool drawn) override {
    tracker()->OnWindowParentDrawnStateChanged(window, drawn);
  }
  void OnWindowInputEvent(
      uint32_t event_id,
      Id window_id,
      int64_t display_id,
      Id display_root_window_id,
      const gfx::PointF& event_location_in_screen_pixel_layout,
      std::unique_ptr<ui::Event> event,
      bool matches_pointer_watcher) override {
    // Ack input events to clear the state on the server. These can be received
    // during test startup. X11Window::DispatchEvent sends a synthetic move
    // event to notify of entry.
    tree()->OnWindowInputEventAck(event_id, mojom::EventResult::HANDLED);
    // Don't log input events as none of the tests care about them and they
    // may come in at random points.
  }
  void OnPointerEventObserved(std::unique_ptr<ui::Event>,
                              Id window_id,
                              int64_t display_id) override {}
  void OnWindowSharedPropertyChanged(
      Id window,
      const std::string& name,
      const base::Optional<std::vector<uint8_t>>& new_data) override {
    tracker_.OnWindowSharedPropertyChanged(window, name, new_data);
  }
  // TODO(sky): add testing coverage.
  void OnWindowFocused(Id focused_window_id) override {}
  void OnWindowCursorChanged(Id window_id, ui::CursorData cursor) override {
    tracker_.OnWindowCursorChanged(window_id, cursor);
  }

  void OnDragDropStart(
      const std::unordered_map<std::string, std::vector<uint8_t>>& drag_data)
      override {
    NOTIMPLEMENTED();
  }

  void OnWindowSurfaceChanged(Id window_id,
                              const viz::SurfaceInfo& surface_info) override {
    tracker_.OnWindowSurfaceChanged(window_id, surface_info);
  }

  void OnDragEnter(Id window,
                   uint32_t key_state,
                   const gfx::Point& position,
                   uint32_t effect_bitmask,
                   OnDragEnterCallback callback) override {
    NOTIMPLEMENTED();
  }
  void OnDragOver(Id window,
                  uint32_t key_state,
                  const gfx::Point& position,
                  uint32_t effect_bitmask,
                  OnDragOverCallback callback) override {
    NOTIMPLEMENTED();
  }
  void OnDragLeave(Id window) override { NOTIMPLEMENTED(); }
  void OnCompleteDrop(Id window,
                      uint32_t key_state,
                      const gfx::Point& position,
                      uint32_t effect_bitmask,
                      OnCompleteDropCallback callback) override {
    NOTIMPLEMENTED();
  }

  void OnPerformDragDropCompleted(uint32_t change_id,
                                  bool success,
                                  uint32_t action_taken) override {
    NOTIMPLEMENTED();
  }

  void OnDragDropDone() override { NOTIMPLEMENTED(); }

  void OnChangeCompleted(uint32_t change_id, bool success) override {
    if (waiting_change_id_ == change_id && change_completed_run_loop_) {
      on_change_completed_result_ = success;
      change_completed_run_loop_->Quit();
    }
  }
  void RequestClose(Id window_id) override {}
  void GetWindowManager(mojo::AssociatedInterfaceRequest<mojom::WindowManager>
                            internal) override {
    window_manager_binding_ =
        std::make_unique<mojo::AssociatedBinding<mojom::WindowManager>>(
            this, std::move(internal));
    tree_->GetWindowManagerClient(MakeRequest(&window_manager_client_));
  }

  // mojom::WindowManager:
  void OnConnect() override {}
  void WmOnAcceleratedWidgetForDisplay(
      int64_t display,
      gpu::SurfaceHandle surface_handle) override {}
  void WmNewDisplayAdded(
      const display::Display& display,
      mojom::WindowDataPtr root_data,
      bool drawn,
      const base::Optional<viz::LocalSurfaceId>& local_surface_id) override {
    NOTIMPLEMENTED();
  }
  void WmDisplayRemoved(int64_t display_id) override { NOTIMPLEMENTED(); }
  void WmDisplayModified(const display::Display& display) override {
    NOTIMPLEMENTED();
  }
  void WmSetBounds(uint32_t change_id,
                   Id window_id,
                   const gfx::Rect& bounds) override {
    window_manager_client_->WmResponse(change_id, false);
  }
  void WmSetProperty(
      uint32_t change_id,
      Id window_id,
      const std::string& name,
      const base::Optional<std::vector<uint8_t>>& value) override {
    window_manager_client_->WmResponse(change_id, false);
  }
  void WmSetModalType(Id window_id, ui::ModalType type) override {}
  void WmSetCanFocus(Id window_id, bool can_focus) override {}
  void WmCreateTopLevelWindow(
      uint32_t change_id,
      const viz::FrameSinkId& frame_sink_id,
      const std::unordered_map<std::string, std::vector<uint8_t>>& properties)
      override {
    NOTIMPLEMENTED();
  }
  void WmClientJankinessChanged(ClientSpecificId client_id,
                                bool janky) override {
    NOTIMPLEMENTED();
  }
  void WmBuildDragImage(const gfx::Point& screen_location,
                        const SkBitmap& drag_image,
                        const gfx::Vector2d& drag_image_offset,
                        ui::mojom::PointerKind source) override {}
  void WmMoveDragImage(const gfx::Point& screen_location,
                       WmMoveDragImageCallback callback) override {
    std::move(callback).Run();
  }
  void WmDestroyDragImage() override {}
  void WmPerformMoveLoop(uint32_t change_id,
                         Id window_id,
                         mojom::MoveLoopSource source,
                         const gfx::Point& cursor_location) override {
    NOTIMPLEMENTED();
  }
  void WmCancelMoveLoop(uint32_t change_id) override { NOTIMPLEMENTED(); }
  void WmDeactivateWindow(Id window_id) override { NOTIMPLEMENTED(); }
  void WmStackAbove(uint32_t change_id, Id above_id, Id below_id) override {
    NOTIMPLEMENTED();
  }
  void WmStackAtTop(uint32_t change_id, Id window_id) override {
    NOTIMPLEMENTED();
  }
  void WmPerformWmAction(Id window_id, const std::string& action) override {
    NOTIMPLEMENTED();
  }
  void OnAccelerator(uint32_t ack_id,
                     uint32_t accelerator_id,
                     std::unique_ptr<ui::Event> event) override {
    NOTIMPLEMENTED();
  }
  void OnCursorTouchVisibleChanged(bool enabled) override { NOTIMPLEMENTED(); }
  void OnEventBlockedByModalWindow(Id window_id) override { NOTIMPLEMENTED(); }

  TestChangeTracker tracker_;

  mojom::WindowTreePtr tree_;

  // If non-null we're waiting for OnEmbed() using this RunLoop.
  std::unique_ptr<base::RunLoop> embed_run_loop_;

  // If non-null we're waiting for a certain number of change notifications to
  // be encountered.
  std::unique_ptr<WaitState> wait_state_;

  mojo::Binding<WindowTreeClient> binding_;
  Id root_window_id_;
  uint32_t next_change_id_;
  uint32_t waiting_change_id_;
  bool on_change_completed_result_;
  bool track_root_bounds_changes_;
  std::unique_ptr<base::RunLoop> change_completed_run_loop_;

  std::unique_ptr<mojo::AssociatedBinding<mojom::WindowManager>>
      window_manager_binding_;
  mojom::WindowManagerClientAssociatedPtr window_manager_client_;

  DISALLOW_COPY_AND_ASSIGN(TestWindowTreeClient);
};

// -----------------------------------------------------------------------------

// InterfaceFactory for vending TestWindowTreeClients.
class WindowTreeClientFactory {
 public:
  WindowTreeClientFactory() {}
  ~WindowTreeClientFactory() {}

  // Runs a nested MessageLoop until a new instance has been created.
  std::unique_ptr<TestWindowTreeClient> WaitForInstance() {
    if (!client_impl_.get()) {
      DCHECK(!run_loop_);
      run_loop_ = std::make_unique<base::RunLoop>();
      run_loop_->Run();
      run_loop_.reset();
    }
    return std::move(client_impl_);
  }

  void BindWindowTreeClientRequest(
      mojom::WindowTreeClientRequest request) {
    client_impl_ = std::make_unique<TestWindowTreeClient>();
    client_impl_->Bind(std::move(request));
    if (run_loop_.get())
      run_loop_->Quit();
  }

 private:
  std::unique_ptr<TestWindowTreeClient> client_impl_;
  std::unique_ptr<base::RunLoop> run_loop_;

  DISALLOW_COPY_AND_ASSIGN(WindowTreeClientFactory);
};

}  // namespace

class WindowTreeClientTest : public WindowServerServiceTestBase {
 public:
  WindowTreeClientTest() : root_window_id_(0) {}

  ~WindowTreeClientTest() override {}

 protected:
  // Returns the changes from the various clients.
  std::vector<Change>* changes1() { return wt_client1_->tracker()->changes(); }
  std::vector<Change>* changes2() { return wt_client2_->tracker()->changes(); }
  std::vector<Change>* changes3() { return wt_client3_->tracker()->changes(); }

  // Various clients. |wt1()|, being the first client, has special permissions
  // (it's treated as the window manager).
  WindowTree* wt1() { return wt_client1_->tree(); }
  WindowTree* wt2() { return wt_client2_->tree(); }
  WindowTree* wt3() { return wt_client3_->tree(); }

  TestWindowTreeClient* wt_client1() { return wt_client1_.get(); }
  TestWindowTreeClient* wt_client2() { return wt_client2_.get(); }
  TestWindowTreeClient* wt_client3() { return wt_client3_.get(); }

  Id root_window_id() const { return root_window_id_; }

  int client_id_1() const { return client_id_1_; }
  int client_id_2() const { return client_id_2_; }
  int client_id_3() const { return client_id_3_; }

  void EstablishSecondClientWithRoot(Id root_id) {
    ASSERT_TRUE(wt_client2_.get() == nullptr);
    wt_client2_ = EstablishClientViaEmbed(wt1(), root_id);
    ASSERT_GT(client_id_2_, 0);
    ASSERT_TRUE(wt_client2_.get() != nullptr);
  }

  void EstablishSecondClient(bool create_initial_window) {
    Id window_1_1 = 0;
    if (create_initial_window) {
      window_1_1 = wt_client1()->NewWindow(1);
      ASSERT_TRUE(window_1_1);
    }
    ASSERT_NO_FATAL_FAILURE(
        EstablishSecondClientWithRoot(BuildWindowId(client_id_1(), 1)));

    if (create_initial_window) {
      // window_1_1 is created by wt_client1() so its client_id part should be
      // client_id_1() in wt_client2.
      EXPECT_EQ(
          "[" +
              WindowParentToString(
                  BuildWindowId(client_id_1(),
                                ClientWindowIdFromTransportId(window_1_1)),
                  kNullParentId) +
              "]",
          ChangeWindowDescription(*changes2()));
    }
  }

  void EstablishThirdClient(WindowTree* owner, Id root_id) {
    ASSERT_TRUE(wt_client3_.get() == nullptr);
    wt_client3_ = EstablishClientViaEmbed(owner, root_id);
    ASSERT_TRUE(wt_client3_.get() != nullptr);
  }

  std::unique_ptr<TestWindowTreeClient> WaitForWindowTreeClient() {
    return client_factory_->WaitForInstance();
  }

  // Establishes a new client by way of Embed() on the specified WindowTree.
  std::unique_ptr<TestWindowTreeClient> EstablishClientViaEmbed(
      WindowTree* owner,
      Id root_id) {
    return EstablishClientViaEmbedWithPolicyBitmask(owner, root_id);
  }

  std::unique_ptr<TestWindowTreeClient>
  EstablishClientViaEmbedWithPolicyBitmask(WindowTree* owner, Id root_id) {
    if (!EmbedUrl(connector(), owner, test_name(), root_id)) {
      ADD_FAILURE() << "Embed() failed";
      return nullptr;
    }
    std::unique_ptr<TestWindowTreeClient> client =
        client_factory_->WaitForInstance();
    if (!client.get()) {
      ADD_FAILURE() << "WaitForInstance failed";
      return nullptr;
    }
    client->WaitForOnEmbed();

    // TODO(fsamuel): Currently the FrameSinkId maps directly to the server's
    // window ID. This is likely bad from a security perspective and should be
    // fixed.
    EXPECT_EQ("OnEmbed",
              SingleChangeToDescription(*client->tracker()->changes()));
    return client;
  }

  // WindowServerServiceTestBase:
  void OnBindInterface(const service_manager::BindSourceInfo& source_info,
                       const std::string& interface_name,
                       mojo::ScopedMessagePipeHandle interface_pipe) override {
    registry_.BindInterface(interface_name, std::move(interface_pipe));
  }

  void SetUp() override {
    client_factory_ = std::make_unique<WindowTreeClientFactory>();
    registry_.AddInterface(
        base::Bind(&WindowTreeClientFactory::BindWindowTreeClientRequest,
                   base::Unretained(client_factory_.get())));

    WindowServerServiceTestBase::SetUp();

    mojom::WindowTreeHostFactoryPtr factory;
    connector()->BindInterface(ui::mojom::kServiceName, &factory);

    mojom::WindowTreeClientPtr tree_client_ptr;
    wt_client1_ = std::make_unique<TestWindowTreeClient>();
    wt_client1_->Bind(MakeRequest(&tree_client_ptr));

    factory->CreateWindowTreeHost(MakeRequest(&host_),
                                  std::move(tree_client_ptr));

    // Next we should get an embed call on the "window manager" client.
    wt_client1_->WaitForOnEmbed();

    ASSERT_EQ(1u, changes1()->size());
    EXPECT_EQ(CHANGE_TYPE_EMBED, (*changes1())[0].type);
    ASSERT_FALSE((*changes1())[0].windows.empty());
    root_window_id_ = (*changes1())[0].windows[0].window_id;
    ASSERT_EQ(root_window_id_, wt_client1_->root_window_id());
    changes1()->clear();
  }

  void TearDown() override {
    // Destroy these before the message loop is destroyed (happens in
    // WindowServerServiceTestBase::TearDown).
    wt_client1_.reset();
    wt_client2_.reset();
    wt_client3_.reset();
    client_factory_.reset();
    WindowServerServiceTestBase::TearDown();
  }

  std::unique_ptr<TestWindowTreeClient> wt_client1_;
  std::unique_ptr<TestWindowTreeClient> wt_client2_;
  std::unique_ptr<TestWindowTreeClient> wt_client3_;

  mojom::WindowTreeHostPtr host_;

 private:
  std::unique_ptr<WindowTreeClientFactory> client_factory_;
  int client_id_1_ = kWindowServerClientId + 1;
  int client_id_2_ = client_id_1_ + 1;
  int client_id_3_ = client_id_2_ + 1;
  Id root_window_id_;
  service_manager::BinderRegistry registry_;

  DISALLOW_COPY_AND_ASSIGN(WindowTreeClientTest);
};

// Verifies two clients get different ids.
TEST_F(WindowTreeClientTest, TwoClientsGetDifferentClientIds) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));

  ASSERT_EQ(1u, changes2()->size());
  ASSERT_NE(client_id_1(), client_id_2());
}

// Verifies when Embed() is invoked any child windows are removed.
TEST_F(WindowTreeClientTest, WindowsRemovedWhenEmbedding) {
  // Two windows 1 and 2. 2 is parented to 1.
  Id window_1_1 = wt_client1()->NewWindow(1);
  ASSERT_TRUE(window_1_1);
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));

  Id window_1_2 = wt_client1()->NewWindow(2);
  ASSERT_TRUE(window_1_2);
  ASSERT_TRUE(wt_client1()->AddWindow(window_1_1, window_1_2));

  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(false));
  ASSERT_EQ(1u, changes2()->size());
  ASSERT_EQ(1u, (*changes2())[0].windows.size());
  // window_1_1 has a client_id part of client_id_1 in wt2.
  Id window11_in_wt2 =
      BuildWindowId(client_id_1(), ClientWindowIdFromTransportId(window_1_1));
  EXPECT_EQ("[" + WindowParentToString(window11_in_wt2, kNullParentId) + "]",
            ChangeWindowDescription(*changes2()));

  // Embed() removed window 2.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), window_1_2, &windows);
    EXPECT_EQ(WindowParentToString(window_1_2, kNullParentId),
              SingleWindowDescription(windows));
  }

  // ws2 should not see window 2.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt2(), window11_in_wt2, &windows);
    EXPECT_EQ(WindowParentToString(window11_in_wt2, kNullParentId),
              SingleWindowDescription(windows));
  }
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt2(), window_1_2, &windows);
    EXPECT_TRUE(windows.empty());
  }

  // Windows 3 and 4 in client 2.
  Id window_2_3 = wt_client2()->NewWindow(3);
  Id window_2_4 = wt_client2()->NewWindow(4);
  ASSERT_TRUE(window_2_3);
  ASSERT_TRUE(window_2_4);
  ASSERT_TRUE(wt_client2()->AddWindow(window_2_3, window_2_4));

  // Client 3 rooted at 2.
  ASSERT_NO_FATAL_FAILURE(EstablishThirdClient(wt2(), window_2_3));

  // Window 4 should no longer have a parent.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt2(), window_2_3, &windows);
    EXPECT_EQ(WindowParentToString(window_2_3, kNullParentId),
              SingleWindowDescription(windows));

    windows.clear();
    GetWindowTree(wt2(), window_2_4, &windows);
    EXPECT_EQ(WindowParentToString(window_2_4, kNullParentId),
              SingleWindowDescription(windows));
  }

  // And window 4 should not be visible to client 3.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt3(), window_2_3, &windows);
    EXPECT_EQ("no windows", SingleWindowDescription(windows));
  }
}

// Verifies once Embed() has been invoked the parent client can't see any
// children.
TEST_F(WindowTreeClientTest, CantAccessChildrenOfEmbeddedWindow) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));

  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  Id window_2_2 = wt_client2()->NewWindow(2);
  ASSERT_TRUE(window_2_2);
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_2));

  ASSERT_NO_FATAL_FAILURE(EstablishThirdClient(wt2(), window_2_2));

  Id window_3_3 = wt_client3()->NewWindow(3);
  ASSERT_TRUE(window_3_3);
  ASSERT_TRUE(
      wt_client3()->AddWindow(wt_client3()->root_window_id(), window_3_3));

  // Even though 3 is a child of 2 client 2 can't see 3 as it's from a
  // different client.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt2(), window_2_2, &windows);
    EXPECT_EQ(WindowParentToString(window_2_2, window_1_1),
              SingleWindowDescription(windows));
  }

  // Client 2 shouldn't be able to get window 3 at all.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt2(), window_3_3, &windows);
    EXPECT_TRUE(windows.empty());
  }

  // Client 1 should be able to see it all (its the root).
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), window_1_1, &windows);
    ASSERT_EQ(3u, windows.size());
    // window_1_1 is created by wt1() so client_id part would be 0 in wt1().
    EXPECT_EQ(WindowParentToString(ClientWindowIdFromTransportId(window_1_1),
                                   kNullParentId),
              windows[0].ToString());
    // NOTE: we expect a match of WindowParentToString(window_2_2, window_1_1),
    // but the ids are in the id space of client2, which is not the same as
    // the id space of wt1().
    EXPECT_EQ("window=" + std::to_string(client_id_2()) + ",2 parent=0,1",
              windows[1].ToString());
    // Same thing here, we really want to test for
    // WindowParentToString(window_3_3, window_2_2).
    EXPECT_EQ("window=" + std::to_string(client_id_3()) +
                  ",3 parent=" + std::to_string(client_id_2()) + ",2",
              windows[2].ToString());
  }
}

// Verifies once Embed() has been invoked the parent can't mutate the children.
TEST_F(WindowTreeClientTest, CantModifyChildrenOfEmbeddedWindow) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));

  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  Id window_2_1 = wt_client2()->NewWindow(1);
  ASSERT_TRUE(window_2_1);
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_1));

  ASSERT_NO_FATAL_FAILURE(EstablishThirdClient(wt2(), window_2_1));

  Id window_2_2 = wt_client2()->NewWindow(2);
  ASSERT_TRUE(window_2_2);
  // Client 2 shouldn't be able to add anything to the window anymore.
  ASSERT_FALSE(wt_client2()->AddWindow(window_2_1, window_2_2));

  // Create window 3 in client 3 and add it to window 3.
  Id window_3_1 = wt_client3()->NewWindow(1);
  ASSERT_TRUE(window_3_1);
  // window_2_1 should have a client_id of client_id_2 in wt_client3.
  ASSERT_TRUE(wt_client3()->AddWindow(
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_1)),
      window_3_1));

  // Client 2 shouldn't be able to remove window 3.
  ASSERT_FALSE(wt_client2()->RemoveWindowFromParent(
      BuildWindowId(client_id_3(), ClientWindowIdFromTransportId(window_3_1))));
}

// Verifies client gets a valid id.
TEST_F(WindowTreeClientTest, NewWindow) {
  Id window_1_1 = wt_client1()->NewWindow(1);
  ASSERT_TRUE(window_1_1);
  EXPECT_TRUE(changes1()->empty());

  // Can't create a window with the same id.
  ASSERT_EQ(0u, wt_client1()->NewWindowWithCompleteId(window_1_1));
  EXPECT_TRUE(changes1()->empty());

  // Can't create a window with a bogus client id.
  ASSERT_EQ(0u, wt_client1()->NewWindowWithCompleteId(
                    BuildWindowId(client_id_1() + 1, 1)));
  EXPECT_TRUE(changes1()->empty());
}

// Verifies AddWindow fails when window is already in position.
TEST_F(WindowTreeClientTest, AddWindowWithNoChange) {
  // Create the embed point now so that the ids line up.
  ASSERT_TRUE(wt_client1()->NewWindow(1));
  Id window_1_21 = wt_client1()->NewWindow(21);
  Id window_1_31 = wt_client1()->NewWindow(31);
  ASSERT_TRUE(window_1_21);
  ASSERT_TRUE(window_1_31);

  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(false));

  // Make 3 a child of 2.
  ASSERT_TRUE(wt_client1()->AddWindow(window_1_21, window_1_31));

  // Try again, this should fail.
  EXPECT_FALSE(wt_client1()->AddWindow(window_1_21, window_1_31));
}

// Verifies AddWindow fails when window is already in position.
TEST_F(WindowTreeClientTest, AddAncestorFails) {
  // Create the embed point now so that the ids line up.
  ASSERT_TRUE(wt_client1()->NewWindow(1));
  Id window_1_21 = wt_client1()->NewWindow(21);
  Id window_1_31 = wt_client1()->NewWindow(31);
  ASSERT_TRUE(window_1_21);
  ASSERT_TRUE(window_1_31);

  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(false));

  // Make 3 a child of 2.
  ASSERT_TRUE(wt_client1()->AddWindow(window_1_21, window_1_31));

  // Try to make 2 a child of 3, this should fail since 2 is an ancestor of 3.
  EXPECT_FALSE(wt_client1()->AddWindow(window_1_31, window_1_21));
}

// Verifies adding to root sends right notifications.
TEST_F(WindowTreeClientTest, AddToRoot) {
  // Create the embed point now so that the ids line up.
  Id window_1_1 = wt_client1()->NewWindow(1);
  ASSERT_TRUE(window_1_1);
  Id window_1_21 = wt_client1()->NewWindow(21);
  Id window_1_31 = wt_client1()->NewWindow(31);
  ASSERT_TRUE(window_1_21);
  ASSERT_TRUE(window_1_31);

  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(false));
  changes2()->clear();

  // Make 3 a child of 21.
  ASSERT_TRUE(wt_client1()->AddWindow(window_1_21, window_1_31));

  // Make 21 a child of 1.
  ASSERT_TRUE(wt_client1()->AddWindow(window_1_1, window_1_21));

  // Client 2 should not be told anything (because the window is from a
  // different client). Create a window to ensure we got a response from
  // the server.
  ASSERT_TRUE(wt_client2()->NewWindow(100));
  EXPECT_TRUE(changes2()->empty());
}

// Verifies HierarchyChanged is correctly sent for various adds/removes.
TEST_F(WindowTreeClientTest, WindowHierarchyChangedWindows) {
  // Create the embed point now so that the ids line up.
  Id window_1_1 = wt_client1()->NewWindow(1);
  // client_id_1(),2->client_id_1(),11.
  Id window_1_2 = wt_client1()->NewWindow(2);
  ASSERT_TRUE(window_1_2);
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_2, true));
  Id window_1_11 = wt_client1()->NewWindow(11);
  ASSERT_TRUE(window_1_11);
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_11, true));
  ASSERT_TRUE(wt_client1()->AddWindow(window_1_2, window_1_11));

  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(false));
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_1, true));

  ASSERT_TRUE(wt_client2()->WaitForAllMessages());
  changes2()->clear();

  // window_1_1 has a client_id part of client_id_1 in wt2.
  Id window11_in_wt2 =
      BuildWindowId(client_id_1(), ClientWindowIdFromTransportId(window_1_1));

  // client_id_1(),1->client_id_1(),2->client_id_1(),11
  {
    // Client 2 should not get anything (client_id_1(),2 is from another
    // client).
    ASSERT_TRUE(wt_client1()->AddWindow(window_1_1, window_1_2));
    ASSERT_TRUE(wt_client2()->WaitForAllMessages());
    EXPECT_TRUE(changes2()->empty());
  }

  // 0,1->client_id_1(),1->client_id_1(),2->client_id_1(),11.
  {
    // Client 2 is now connected to the root, so it should have gotten a drawn
    // notification.
    ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
    wt_client2_->WaitForChangeCount(1u);
    EXPECT_EQ("DrawnStateChanged window=" + IdToString(window11_in_wt2) +
                  " drawn=true",
              SingleChangeToDescription(*changes2()));
  }

  // client_id_1(),1->client_id_1(),2->client_id_1(),11.
  {
    // Client 2 is no longer connected to the root, should get drawn state
    // changed.
    changes2()->clear();
    ASSERT_TRUE(wt_client1()->RemoveWindowFromParent(window_1_1));
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("DrawnStateChanged window=" + IdToString(window11_in_wt2) +
                  " drawn=false",
              SingleChangeToDescription(*changes2()));
  }

  // client_id_1(),1->client_id_1(),2->client_id_1(),11->client_id_1(),111.
  Id window_1_111 = wt_client1()->NewWindow(111);
  ASSERT_TRUE(window_1_111);
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_111, true));
  {
    changes2()->clear();
    ASSERT_TRUE(wt_client1()->AddWindow(window_1_11, window_1_111));
    ASSERT_TRUE(wt_client2()->WaitForAllMessages());
    EXPECT_TRUE(changes2()->empty());
  }

  // 0,1->client_id_1(),1->client_id_1(),2->client_id_1(),11->client_id_1(),111
  {
    changes2()->clear();
    ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("DrawnStateChanged window=" + IdToString(window11_in_wt2) +
                  " drawn=true",
              SingleChangeToDescription(*changes2()));
  }
}

TEST_F(WindowTreeClientTest, WindowHierarchyChangedAddingKnownToUnknown) {
  // Create the following structure: root -> 1 -> 11 and 2->21 (2 has no
  // parent).
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);

  Id window_2_11 = wt_client2()->NewWindow(11);
  Id window_2_2 = wt_client2()->NewWindow(2);
  Id window_2_21 = wt_client2()->NewWindow(21);
  ASSERT_TRUE(window_2_11);
  ASSERT_TRUE(window_2_2);
  ASSERT_TRUE(window_2_21);
  // window_1_1 has a client_id part of 0 in wt1, while window_2_2 has that of
  // client_id_2.
  Id window11_in_wt1 = ClientWindowIdFromTransportId(window_1_1);
  Id window22_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_2));

  // Set up the hierarchy.
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_11));
  ASSERT_TRUE(wt_client2()->AddWindow(window_2_2, window_2_21));

  // Remove 11, should result in a hierarchy change for the root.
  {
    changes1()->clear();
    ASSERT_TRUE(wt_client2()->RemoveWindowFromParent(window_2_11));

    wt_client1_->WaitForChangeCount(1);
    // client_id_2(),1 should be IdToString(window_2_11), but window_2_11 is in
    // the id space of client2, not client1.
    EXPECT_EQ("HierarchyChanged window=" + std::to_string(client_id_2()) +
                  ",11 old_parent=" + IdToString(window11_in_wt1) +
                  " new_parent=null",
              SingleChangeToDescription(*changes1()));
  }

  // Add 2 to 1.
  {
    changes1()->clear();
    ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_2));
    wt_client1_->WaitForChangeCount(1);
    EXPECT_EQ("HierarchyChanged window=" + IdToString(window22_in_wt1) +
                  " old_parent=null new_parent=" + IdToString(window11_in_wt1),
              SingleChangeToDescription(*changes1()));
    // "window=client_id_2(),3 parent=client_id_2(),2]" should be,
    // WindowParentToString(window_2_21, window_2_2), but isn't because of
    // differing id spaces.
    EXPECT_EQ("[" + WindowParentToString(window22_in_wt1, window11_in_wt1) +
                  "],[window=" + std::to_string(client_id_2()) +
                  ",21 parent=" + std::to_string(client_id_2()) + ",2]",
              ChangeWindowDescription(*changes1()));
  }
}

TEST_F(WindowTreeClientTest, ReorderWindow) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));

  Id window_2_1 = wt_client2()->NewWindow(1);
  Id window_2_2 = wt_client2()->NewWindow(2);
  Id window_2_3 = wt_client2()->NewWindow(3);
  Id window_1_4 = wt_client1()->NewWindow(4);  // Peer to client_id_1(),1
  Id window_1_5 = wt_client1()->NewWindow(5);  // Peer to client_id_1(),1
  Id window_2_6 = wt_client2()->NewWindow(6);  // Child of client_id_1(),2.
  Id window_2_7 = wt_client2()->NewWindow(7);  // Unparented.
  Id window_2_8 = wt_client2()->NewWindow(8);  // Unparented.
  ASSERT_TRUE(window_2_1);
  ASSERT_TRUE(window_2_2);
  ASSERT_TRUE(window_2_3);
  ASSERT_TRUE(window_1_4);
  ASSERT_TRUE(window_1_5);
  ASSERT_TRUE(window_2_6);
  ASSERT_TRUE(window_2_7);
  ASSERT_TRUE(window_2_8);

  ASSERT_TRUE(wt_client2()->AddWindow(window_2_1, window_2_2));
  ASSERT_TRUE(wt_client2()->AddWindow(window_2_2, window_2_6));
  ASSERT_TRUE(wt_client2()->AddWindow(window_2_1, window_2_3));
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_4));
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_5));
  ASSERT_TRUE(
      wt_client2()->AddWindow(BuildWindowId(client_id_1(), 1), window_2_1));

  // window_2_* has client_id part of client_id_2 in wt1.
  Id window22_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_2));
  Id window23_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_3));
  Id window26_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_6));
  Id window27_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_7));
  Id window28_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_8));

  {
    changes1()->clear();
    ASSERT_TRUE(wt_client2()->ReorderWindow(window_2_2, window_2_3,
                                            mojom::OrderDirection::ABOVE));

    wt_client1_->WaitForChangeCount(1);
    EXPECT_EQ("Reordered window=" + IdToString(window22_in_wt1) + " relative=" +
                  IdToString(window23_in_wt1) + " direction=above",
              SingleChangeToDescription(*changes1()));
  }

  {
    changes1()->clear();
    ASSERT_TRUE(wt_client2()->ReorderWindow(window_2_2, window_2_3,
                                            mojom::OrderDirection::BELOW));

    wt_client1_->WaitForChangeCount(1);
    EXPECT_EQ("Reordered window=" + IdToString(window22_in_wt1) + " relative=" +
                  IdToString(window23_in_wt1) + " direction=below",
              SingleChangeToDescription(*changes1()));
  }

  // view2 is already below view3.
  EXPECT_FALSE(wt_client2()->ReorderWindow(window_2_2, window_2_3,
                                           mojom::OrderDirection::BELOW));

  // view4 & 5 are unknown to client 2.
  EXPECT_FALSE(wt_client2()->ReorderWindow(window_1_4, window_1_5,
                                           mojom::OrderDirection::ABOVE));

  // view6 & view3 have different parents.
  EXPECT_FALSE(wt_client1()->ReorderWindow(window23_in_wt1, window26_in_wt1,
                                           mojom::OrderDirection::ABOVE));

  // Non-existent window-ids
  EXPECT_FALSE(wt_client1()->ReorderWindow(BuildWindowId(client_id_1(), 27),
                                           BuildWindowId(client_id_1(), 28),
                                           mojom::OrderDirection::ABOVE));

  // view7 & view8 are un-parented.
  EXPECT_FALSE(wt_client1()->ReorderWindow(window27_in_wt1, window28_in_wt1,
                                           mojom::OrderDirection::ABOVE));
}

// Verifies DeleteWindow works.
TEST_F(WindowTreeClientTest, DeleteWindow) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  Id window_2_1 = wt_client2()->NewWindow(1);
  ASSERT_TRUE(window_2_1);
  // window_2_1 is not created by wt1 so its client_id part is client_id_2,
  // while window_1_1 would have 0 for the client_id part.
  Id window21_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_1));

  // Make 2 a child of 1.
  {
    changes1()->clear();
    ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_1));
    wt_client1_->WaitForChangeCount(1);
    EXPECT_EQ("HierarchyChanged window=" + IdToString(window21_in_wt1) +
                  " old_parent=null new_parent=" +
                  IdToString(ClientWindowIdFromTransportId(window_1_1)),
              SingleChangeToDescription(*changes1()));
  }

  // Delete 2.
  {
    changes1()->clear();
    changes2()->clear();
    ASSERT_TRUE(wt_client2()->DeleteWindow(window_2_1));
    EXPECT_TRUE(changes2()->empty());

    wt_client1_->WaitForChangeCount(1);
    EXPECT_EQ("WindowDeleted window=" + IdToString(window21_in_wt1),
              SingleChangeToDescription(*changes1()));
  }
}

// Verifies DeleteWindow() on the root suceeds.
TEST_F(WindowTreeClientTest, DeleteRoot) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  EXPECT_TRUE(wt_client2()->DeleteWindow(window_1_1));
  // Client1 should get OnEmbeddedAppDisconnected().
  wt_client1_->WaitForChangeCount(1);
  // window_1_1 should have client_id of 0 in wt_client1 because it's created
  // by wt_client1.
  EXPECT_EQ("OnEmbeddedAppDisconnected window=" +
                IdToString(ClientWindowIdFromTransportId(window_1_1)),
            SingleChangeToDescription(*changes1()));

  // Create a new window and try adding to |window_1_1| from client 2, should
  // fail as client 2 no longer knows about |window_1_1|.
  Id window_2_1 = wt_client2()->NewWindow(1);
  ASSERT_TRUE(window_2_1);
  EXPECT_FALSE(wt_client2()->AddWindow(window_1_1, window_2_1));
}

// Verifies DeleteWindow() on the root suceeds.
TEST_F(WindowTreeClientTest, DeleteRootWithChildren) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  Id window_2_1 = wt_client2()->NewWindow(1);
  ASSERT_TRUE(window_2_1);
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_1));
  changes2()->clear();
  EXPECT_TRUE(wt_client2()->DeleteWindow(window_1_1));
  // DeleteWindow() should not result in any calls to client 2.
  EXPECT_TRUE(changes2()->empty());

  // Create a new window parented to 2_1. Should work as 2_1 is still valid.
  Id window_2_2 = wt_client2()->NewWindow(2);
  ASSERT_TRUE(window_2_2);
  ASSERT_TRUE(wt_client2()->AddWindow(window_2_1, window_2_2));
}

// Verifies DeleteWindow isn't allowed from a separate client.
TEST_F(WindowTreeClientTest, DeleteWindowFromAnotherClientDisallowed) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  // This id is unknown, so deletion should fail.
  EXPECT_FALSE(wt_client2()->DeleteWindow(BuildWindowId(client_id_1(), 2)));
}

// Verifies if a window was deleted and then reused that other clients are
// properly notified.
TEST_F(WindowTreeClientTest, ReuseDeletedWindowId) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  Id window_2_1 = wt_client2()->NewWindow(1);
  ASSERT_TRUE(window_2_1);

  // wt1 created window_1_1 but not window_2_1.
  Id window11_in_wt1 = ClientWindowIdFromTransportId(window_1_1);
  Id window21_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_1));

  // Add 2 to 1.
  {
    changes1()->clear();
    ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_1));
    wt_client1_->WaitForChangeCount(1);
    EXPECT_EQ("HierarchyChanged window=" + IdToString(window21_in_wt1) +
                  " old_parent=null new_parent=" + IdToString(window11_in_wt1),
              SingleChangeToDescription(*changes1()));
    EXPECT_EQ(
        "[" + WindowParentToString(window21_in_wt1, window11_in_wt1) + "]",
        ChangeWindowDescription(*changes1()));
  }

  // Delete 2.
  {
    changes1()->clear();
    ASSERT_TRUE(wt_client2()->DeleteWindow(window_2_1));

    wt_client1_->WaitForChangeCount(1);
    EXPECT_EQ("WindowDeleted window=" + IdToString(window21_in_wt1),
              SingleChangeToDescription(*changes1()));
  }

  // Create 2 again, and add it back to 1. Should get the same notification.
  window_2_1 = wt_client2()->NewWindow(2);
  window21_in_wt1 = BuildWindowId(ClientIdFromTransportId(window21_in_wt1),
                                  ClientWindowIdFromTransportId(window_2_1));
  ASSERT_TRUE(window_2_1);
  {
    changes1()->clear();
    ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_1));

    wt_client1_->WaitForChangeCount(1);
    EXPECT_EQ("HierarchyChanged window=" + IdToString(window21_in_wt1) +
                  " old_parent=null new_parent=" + IdToString(window11_in_wt1),
              SingleChangeToDescription(*changes1()));
    EXPECT_EQ(
        "[" + WindowParentToString(window21_in_wt1, window11_in_wt1) + "]",
        ChangeWindowDescription(*changes1()));
  }
}

// Assertions for GetWindowTree.
TEST_F(WindowTreeClientTest, GetWindowTree) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);

  // Create 11 in first client and make it a child of 1.
  Id window_1_11 = wt_client1()->NewWindow(11);
  ASSERT_TRUE(window_1_11);
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  ASSERT_TRUE(wt_client1()->AddWindow(window_1_1, window_1_11));

  // Create two windows in second client, 2 and 3, both children of 1.
  Id window_2_1 = wt_client2()->NewWindow(1);
  Id window_2_2 = wt_client2()->NewWindow(2);
  ASSERT_TRUE(window_2_1);
  ASSERT_TRUE(window_2_2);
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_1));
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_2));

  // wt1 created window_1_1 and window_1_11, but not window_2_1 and window_2_2.
  Id window11_in_wt1 = ClientWindowIdFromTransportId(window_1_1);
  Id window111_in_wt1 = ClientWindowIdFromTransportId(window_1_11);
  Id window21_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_1));
  Id window22_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_2));

  // Verifies GetWindowTree() on the root. The root client sees all.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), root_window_id(), &windows);
    ASSERT_EQ(5u, windows.size());
    EXPECT_EQ(WindowParentToString(root_window_id(), kNullParentId),
              windows[0].ToString());
    EXPECT_EQ(WindowParentToString(window11_in_wt1, root_window_id()),
              windows[1].ToString());
    EXPECT_EQ(WindowParentToString(window111_in_wt1, window11_in_wt1),
              windows[2].ToString());
    EXPECT_EQ(WindowParentToString(window21_in_wt1, window11_in_wt1),
              windows[3].ToString());
    EXPECT_EQ(WindowParentToString(window22_in_wt1, window11_in_wt1),
              windows[4].ToString());
  }

  // Verifies GetWindowTree() on the window client_id_1(),1 from wt2(). wt2()
  // sees client_id_1(),1 as client_id_1(),1 is wt2()'s root and wt2() sees all
  // the windows it created.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt2(), window_1_1, &windows);
    ASSERT_EQ(3u, windows.size());
    EXPECT_EQ(WindowParentToString(window_1_1, kNullParentId),
              windows[0].ToString());
    EXPECT_EQ(WindowParentToString(window_2_1, window_1_1),
              windows[1].ToString());
    EXPECT_EQ(WindowParentToString(window_2_2, window_1_1),
              windows[2].ToString());
  }

  // Client 2 shouldn't be able to get the root tree.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt2(), root_window_id(), &windows);
    ASSERT_EQ(0u, windows.size());
  }
}

TEST_F(WindowTreeClientTest, SetWindowBounds) {
  Id window_1_1 = wt_client1()->NewWindow(1);
  ASSERT_TRUE(window_1_1);
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));

  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(false));

  changes2()->clear();

  wt_client2_->set_track_root_bounds_changes(true);

  viz::ParentLocalSurfaceIdAllocator allocator;
  viz::LocalSurfaceId local_surface_id = allocator.GenerateId();
  wt1()->SetWindowBounds(10, window_1_1, gfx::Rect(0, 0, 100, 100),
                         local_surface_id);
  ASSERT_TRUE(wt_client1()->WaitForChangeCompleted(10));

  wt_client2_->WaitForChangeCount(1);
  // window_1_1 has a client_id part of client_id_1 in wt2.
  Id window11_in_wt2 =
      BuildWindowId(client_id_1(), ClientWindowIdFromTransportId(window_1_1));
  EXPECT_EQ("BoundsChanged window=" + IdToString(window11_in_wt2) +
                " old_bounds=0,0 0x0 new_bounds=0,0 100x100 local_surface_id=" +
                local_surface_id.ToString(),
            SingleChangeToDescription(*changes2()));

  // Should not be possible to change the bounds of a window created by another
  // client.
  wt2()->SetWindowBounds(11, window11_in_wt2, gfx::Rect(0, 0, 0, 0),
                         base::nullopt);
  ASSERT_FALSE(wt_client2()->WaitForChangeCompleted(11));
}

// Verify AddWindow fails when trying to manipulate windows in other roots.
TEST_F(WindowTreeClientTest, CantMoveWindowsFromOtherRoot) {
  // Create 1 and 2 in the first client.
  Id window_1_1 = wt_client1()->NewWindow(1);
  Id window_1_2 = wt_client1()->NewWindow(2);
  ASSERT_TRUE(window_1_1);
  ASSERT_TRUE(window_1_2);

  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(false));

  // Try to move 2 to be a child of 1 from client 2. This should fail as 2
  // should not be able to access 1.
  ASSERT_FALSE(wt_client2()->AddWindow(window_1_1, window_1_2));

  // Try to reparent 1 to the root. A client is not allowed to reparent its
  // roots.
  ASSERT_FALSE(wt_client2()->AddWindow(root_window_id(), window_1_1));
}

// Verify RemoveWindowFromParent fails for windows that are descendants of the
// roots.
TEST_F(WindowTreeClientTest, CantRemoveWindowsInOtherRoots) {
  // Create 1 and 2 in the first client and parent both to the root.
  Id window_1_1 = wt_client1()->NewWindow(1);
  Id window_1_2 = wt_client1()->NewWindow(2);
  ASSERT_TRUE(window_1_1);
  ASSERT_TRUE(window_1_2);

  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_2));

  // Establish the second client and give it the root 1.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(false));

  // Client 2 should not be able to remove window 2 or 1 from its parent.
  ASSERT_FALSE(wt_client2()->RemoveWindowFromParent(window_1_2));
  ASSERT_FALSE(wt_client2()->RemoveWindowFromParent(window_1_1));

  // Create windows 10 and 11 in 2.
  Id window_2_10 = wt_client2()->NewWindow(10);
  Id window_2_11 = wt_client2()->NewWindow(11);
  ASSERT_TRUE(window_2_10);
  ASSERT_TRUE(window_2_11);

  // Parent 11 to 10.
  ASSERT_TRUE(wt_client2()->AddWindow(window_2_10, window_2_11));
  // Remove 11 from 10.
  ASSERT_TRUE(wt_client2()->RemoveWindowFromParent(window_2_11));

  // Verify nothing was actually removed.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), root_window_id(), &windows);
    ASSERT_EQ(3u, windows.size());
    EXPECT_EQ(WindowParentToString(root_window_id(), kNullParentId),
              windows[0].ToString());
    EXPECT_EQ(WindowParentToString(window_1_1, root_window_id()),
              windows[1].ToString());
    EXPECT_EQ(WindowParentToString(window_1_2, root_window_id()),
              windows[2].ToString());
  }
}

// Verify GetWindowTree fails for windows that are not descendants of the roots.
TEST_F(WindowTreeClientTest, CantGetWindowTreeOfOtherRoots) {
  // Create 1 and 2 in the first client and parent both to the root.
  Id window_1_1 = wt_client1()->NewWindow(1);
  Id window_1_2 = wt_client1()->NewWindow(2);
  ASSERT_TRUE(window_1_1);
  ASSERT_TRUE(window_1_2);

  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_2));

  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(false));

  std::vector<TestWindow> windows;

  // Should get nothing for the root.
  GetWindowTree(wt2(), root_window_id(), &windows);
  ASSERT_TRUE(windows.empty());

  // Should get nothing for window 2.
  GetWindowTree(wt2(), window_1_2, &windows);
  ASSERT_TRUE(windows.empty());

  // Should get window 1 if asked for.
  Id window11_in_wt2 =
      BuildWindowId(client_id_1(), ClientWindowIdFromTransportId(window_1_1));
  GetWindowTree(wt2(), window11_in_wt2, &windows);
  ASSERT_EQ(1u, windows.size());
  EXPECT_EQ(WindowParentToString(window11_in_wt2, kNullParentId),
            windows[0].ToString());
}

TEST_F(WindowTreeClientTest, EmbedWithSameWindowId) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  changes2()->clear();

  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  ASSERT_NO_FATAL_FAILURE(EstablishThirdClient(wt1(), window_1_1));

  // Client 2 should have been told of the unembed and delete.
  {
    wt_client2_->WaitForChangeCount(2);
    EXPECT_EQ("OnUnembed window=" + IdToString(window_1_1),
              ChangesToDescription1(*changes2())[0]);
    EXPECT_EQ("WindowDeleted window=" + IdToString(window_1_1),
              ChangesToDescription1(*changes2())[1]);
  }

  // Client 2 has no root. Verify it can't see window client_id_1(),1 anymore.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt2(), window_1_1, &windows);
    EXPECT_TRUE(windows.empty());
  }
}

TEST_F(WindowTreeClientTest, EmbedWithSameWindowId2) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  changes2()->clear();

  ASSERT_NO_FATAL_FAILURE(EstablishThirdClient(wt1(), window_1_1));

  // Client 2 should have been told about the unembed and delete.
  wt_client2_->WaitForChangeCount(2);
  changes2()->clear();

  // Create a window in the third client and parent it to the root.
  Id window_3_1 = wt_client3()->NewWindow(1);
  ASSERT_TRUE(window_3_1);
  // After EstablishThirdClient, window_1_1 should have a ClientWindowId of
  // (client_id_2, 0).
  Id embedded_window_1_1_wt3 = BuildWindowId(client_id_2(), 0);
  ASSERT_TRUE(wt_client3()->AddWindow(embedded_window_1_1_wt3, window_3_1));

  // wt1 created window_1_1 but not window_3_1.
  Id window11_in_wt1 = ClientWindowIdFromTransportId(window_1_1);
  Id window31_in_wt1 =
      BuildWindowId(client_id_3(), ClientWindowIdFromTransportId(window_3_1));

  // Client 1 should have been told about the add (it owns the window).
  {
    wt_client1_->WaitForChangeCount(1);
    EXPECT_EQ("HierarchyChanged window=" + IdToString(window31_in_wt1) +
                  " old_parent=null new_parent=" + IdToString(window11_in_wt1),
              SingleChangeToDescription(*changes1()));
  }

  // Embed client_id_1(),1 again.
  {
    changes3()->clear();

    // We should get a new client for the new embedding.
    std::unique_ptr<TestWindowTreeClient> client4(
        EstablishClientViaEmbed(wt1(), window_1_1));
    Id embedded_window_1_1_wt4 = BuildWindowId(client_id_3(), 0);
    ASSERT_TRUE(client4.get());
    EXPECT_EQ("[" +
                  WindowParentToString(embedded_window_1_1_wt4, kNullParentId) +
                  "]",
              ChangeWindowDescription(*client4->tracker()->changes()));

    // And 3 should get an unembed and delete.
    wt_client3_->WaitForChangeCount(2);
    EXPECT_EQ("OnUnembed window=" + IdToString(embedded_window_1_1_wt3),
              ChangesToDescription1(*changes3())[0]);
    EXPECT_EQ("WindowDeleted window=" + IdToString(embedded_window_1_1_wt3),
              ChangesToDescription1(*changes3())[1]);
  }

  // wt3() has no root. Verify it can't see window client_id_1(),1 anymore.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt3(), window_1_1, &windows);
    EXPECT_TRUE(windows.empty());
  }

  // Verify client_id_3(),1 is no longer parented to client_id_1(),1. We have to
  // do this from client_id_1(),1 as wt3() can no longer see client_id_1(),1.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), window_1_1, &windows);
    ASSERT_EQ(1u, windows.size());
    EXPECT_EQ(WindowParentToString(window11_in_wt1, kNullParentId),
              windows[0].ToString());
  }

  // Verify wt3() can still see the window it created client_id_3(),1.
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt3(), window_3_1, &windows);
    ASSERT_EQ(1u, windows.size());
    EXPECT_EQ(WindowParentToString(window_3_1, kNullParentId),
              windows[0].ToString());
  }
}

// Assertions for SetWindowVisibility.
TEST_F(WindowTreeClientTest, SetWindowVisibility) {
  // Create 1 and 2 in the first client and parent both to the root.
  Id window_1_1 = wt_client1()->NewWindow(1);
  Id window_1_2 = wt_client1()->NewWindow(2);
  ASSERT_TRUE(window_1_1);
  ASSERT_TRUE(window_1_2);

  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), root_window_id(), &windows);
    ASSERT_EQ(2u, windows.size());
    EXPECT_EQ(
        WindowParentToString(root_window_id(), kNullParentId) + " visible=true",
        windows[0].ToString2());
    EXPECT_EQ(
        WindowParentToString(window_1_1, root_window_id()) + " visible=false",
        windows[1].ToString2());
  }

  // Show all the windows.
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_1, true));
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_2, true));
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), root_window_id(), &windows);
    ASSERT_EQ(2u, windows.size());
    EXPECT_EQ(
        WindowParentToString(root_window_id(), kNullParentId) + " visible=true",
        windows[0].ToString2());
    EXPECT_EQ(
        WindowParentToString(window_1_1, root_window_id()) + " visible=true",
        windows[1].ToString2());
  }

  // Hide 1.
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_1, false));
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), window_1_1, &windows);
    ASSERT_EQ(1u, windows.size());
    EXPECT_EQ(
        WindowParentToString(window_1_1, root_window_id()) + " visible=false",
        windows[0].ToString2());
  }

  // Attach 2 to 1.
  ASSERT_TRUE(wt_client1()->AddWindow(window_1_1, window_1_2));
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), window_1_1, &windows);
    ASSERT_EQ(2u, windows.size());
    EXPECT_EQ(
        WindowParentToString(window_1_1, root_window_id()) + " visible=false",
        windows[0].ToString2());
    EXPECT_EQ(WindowParentToString(window_1_2, window_1_1) + " visible=true",
              windows[1].ToString2());
  }

  // Show 1.
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_1, true));
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), window_1_1, &windows);
    ASSERT_EQ(2u, windows.size());
    EXPECT_EQ(
        WindowParentToString(window_1_1, root_window_id()) + " visible=true",
        windows[0].ToString2());
    EXPECT_EQ(WindowParentToString(window_1_2, window_1_1) + " visible=true",
              windows[1].ToString2());
  }
}

// Test that we hear the cursor change in other clients.
TEST_F(WindowTreeClientTest, SetCursor) {
  // Get a second client to listen in.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  changes2()->clear();

  ASSERT_TRUE(wt_client1()->SetCursor(window_1_1,
                                      ui::CursorData(ui::CursorType::kIBeam)));
  wt_client2_->WaitForChangeCount(1u);

  EXPECT_EQ("CursorChanged id=" + IdToString(window_1_1) + " cursor_type=4",
            SingleChangeToDescription(*changes2()));
}

// Assertions for SetWindowVisibility sending notifications.
TEST_F(WindowTreeClientTest, SetWindowVisibilityNotifications) {
  // Create client_id_1(),1 and client_id_1(),2. client_id_1(),2 is made a child
  // of client_id_1(),1 and client_id_1(),1 a child of the root.
  Id window_1_1 = wt_client1()->NewWindow(1);
  ASSERT_TRUE(window_1_1);
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_1, true));
  // Setting to the same value should return true.
  EXPECT_TRUE(wt_client1()->SetWindowVisibility(window_1_1, true));

  Id window_1_2 = wt_client1()->NewWindow(2);
  ASSERT_TRUE(window_1_2);
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_2, true));
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  ASSERT_TRUE(wt_client1()->AddWindow(window_1_1, window_1_2));

  // Establish the second client at client_id_1(),2.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClientWithRoot(window_1_2));

  // Add client_id_2(),3 as a child of client_id_1(),2.
  Id window_2_1 = wt_client2()->NewWindow(1);
  ASSERT_TRUE(window_2_1);
  ASSERT_TRUE(wt_client2()->SetWindowVisibility(window_2_1, true));
  // window_1_2 has a client_id part of client_id_1 in wt2.
  Id window12_in_wt2 =
      BuildWindowId(client_id_1(), ClientWindowIdFromTransportId(window_1_2));
  ASSERT_TRUE(wt_client2()->AddWindow(window12_in_wt2, window_2_1));
  ASSERT_TRUE(wt_client1()->WaitForAllMessages());

  changes2()->clear();
  // Hide client_id_1(),2 from client 1. Client 2 should see this.
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_2, false));
  {
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("VisibilityChanged window=" + IdToString(window12_in_wt2) +
                  " visible=false",
              SingleChangeToDescription(*changes2()));
  }

  changes1()->clear();
  // Show client_id_1(),2 from client 2, client 1 should be notified.
  ASSERT_TRUE(wt_client2()->SetWindowVisibility(window12_in_wt2, true));
  {
    wt_client1_->WaitForChangeCount(1);
    EXPECT_EQ(
        "VisibilityChanged window=" + IdToString(window_1_2) + " visible=true",
        SingleChangeToDescription(*changes1()));
  }

  changes2()->clear();
  // Hide client_id_1(),1, client 2 should be told the draw state changed.
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_1, false));
  {
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("DrawnStateChanged window=" + IdToString(window12_in_wt2) +
                  " drawn=false",
              SingleChangeToDescription(*changes2()));
  }

  changes2()->clear();
  // Show client_id_1(),1 from client 1. Client 2 should see this.
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_1, true));
  {
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("DrawnStateChanged window=" + IdToString(window12_in_wt2) +
                  " drawn=true",
              SingleChangeToDescription(*changes2()));
  }

  // Change visibility of client_id_2(),3, client 1 should see this.
  changes1()->clear();
  ASSERT_TRUE(wt_client2()->SetWindowVisibility(window_2_1, false));
  {
    wt_client1_->WaitForChangeCount(1);
    EXPECT_EQ(
        "VisibilityChanged window=" +
            IdToString(BuildWindowId(
                client_id_2(), ClientWindowIdFromTransportId(window_2_1))) +
            " visible=false",
        SingleChangeToDescription(*changes1()));
  }

  changes2()->clear();
  // Remove client_id_1(),1 from the root, client 2 should see drawn state
  // changed.
  ASSERT_TRUE(wt_client1()->RemoveWindowFromParent(window_1_1));
  {
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("DrawnStateChanged window=" + IdToString(window12_in_wt2) +
                  " drawn=false",
              SingleChangeToDescription(*changes2()));
  }

  changes2()->clear();
  // Add client_id_1(),1 back to the root, client 2 should see drawn state
  // changed.
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  {
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("DrawnStateChanged window=" + IdToString(window12_in_wt2) +
                  " drawn=true",
              SingleChangeToDescription(*changes2()));
  }
}

// Assertions for SetWindowVisibility sending notifications.
TEST_F(WindowTreeClientTest, SetWindowVisibilityNotifications2) {
  // Create client_id_1(),1 and client_id_1(),2. client_id_1(),2 is made a child
  // of client_id_1(),1 and client_id_1(),1 a child of the root.
  Id window_1_1 = wt_client1()->NewWindow(1);
  ASSERT_TRUE(window_1_1);
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_1, true));
  Id window_1_2 = wt_client1()->NewWindow(2);
  ASSERT_TRUE(window_1_2);
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  ASSERT_TRUE(wt_client1()->AddWindow(window_1_1, window_1_2));

  // Establish the second client at client_id_1(),2.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClientWithRoot(window_1_2));
  // window_1_2 has a client_id part of client_id_1 in wt2.
  Id window12_in_wt2 =
      BuildWindowId(client_id_1(), ClientWindowIdFromTransportId(window_1_2));
  EXPECT_EQ("OnEmbed drawn=true", SingleChangeToDescription2(*changes2()));
  changes2()->clear();

  // Show client_id_1(),2 from client 1. Client 2 should see this.
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_2, true));
  {
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("VisibilityChanged window=" + IdToString(window12_in_wt2) +
                  " visible=true",
              SingleChangeToDescription(*changes2()));
  }
}

// Assertions for SetWindowVisibility sending notifications.
TEST_F(WindowTreeClientTest, SetWindowVisibilityNotifications3) {
  // Create client_id_1(),1 and client_id_1(),2. client_id_1(),2 is made a child
  // of client_id_1(),1 and client_id_1(),1 a child of the root.
  Id window_1_1 = wt_client1()->NewWindow(1);
  ASSERT_TRUE(window_1_1);
  Id window_1_2 = wt_client1()->NewWindow(2);
  ASSERT_TRUE(window_1_2);
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  ASSERT_TRUE(wt_client1()->AddWindow(window_1_1, window_1_2));

  // Establish the second client at client_id_1(),2.
  // TODO(fsamuel): Currently the FrameSinkId maps directly to the server's
  // window ID. This is likely bad from a security perspective and should be
  // fixed.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClientWithRoot(window_1_2));
  // window_1_2 has a client_id part of client_id_1 in wt2.
  Id window12_in_wt2 =
      BuildWindowId(client_id_1(), ClientWindowIdFromTransportId(window_1_2));
  EXPECT_EQ("OnEmbed drawn=false", SingleChangeToDescription2(*changes2()));
  changes2()->clear();

  // Show client_id_1(),1, drawn should be true for client_id_1(),2 (as that is
  // all the child sees).
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_1, true));
  {
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("DrawnStateChanged window=" + IdToString(window12_in_wt2) +
                  " drawn=true",
              SingleChangeToDescription(*changes2()));
  }
  changes2()->clear();

  // Show client_id_1(),2, visible should be true.
  ASSERT_TRUE(wt_client1()->SetWindowVisibility(window_1_2, true));
  {
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("VisibilityChanged window=" + IdToString(window12_in_wt2) +
                  " visible=true",
              SingleChangeToDescription(*changes2()));
  }
}

// Tests that when opacity is set on a window, that the calling client is not
// notified, however children are. Also that setting the same opacity is
// rejected and no on eis notifiyed.
TEST_F(WindowTreeClientTest, SetOpacityNotifications) {
  Id window_1_1 = wt_client1()->NewWindow(1);
  ASSERT_TRUE(window_1_1);

  ASSERT_NO_FATAL_FAILURE(EstablishSecondClientWithRoot(window_1_1));
  Id window_2_1 = wt_client2()->NewWindow(1);
  ASSERT_TRUE(window_2_1);
  // window_1_1 has a client_id part of client_id_1 in wt2.
  Id window11_in_wt2 =
      BuildWindowId(client_id_1(), ClientWindowIdFromTransportId(window_1_1));
  ASSERT_TRUE(wt_client2()->AddWindow(window11_in_wt2, window_2_1));
  ASSERT_TRUE(wt_client1()->WaitForAllMessages());

  changes1()->clear();
  changes2()->clear();
  // Change opacity, no notification for calling client.
  ASSERT_TRUE(wt_client1()->SetWindowOpacity(window_1_1, 0.5f));
  EXPECT_TRUE(changes1()->empty());
  wt_client2()->WaitForChangeCount(1);
  EXPECT_EQ("OpacityChanged window_id=" + IdToString(window11_in_wt2) +
                " opacity=0.50",
            SingleChangeToDescription(*changes2()));

  changes2()->clear();
  // Attempting to set the same opacity should succeed, but no notification as
  // there was no actual change.
  ASSERT_TRUE(wt_client1()->SetWindowOpacity(window_1_1, 0.5f));
  EXPECT_TRUE(changes1()->empty());
  wt_client2()->WaitForAllMessages();
  EXPECT_TRUE(changes2()->empty());
}

TEST_F(WindowTreeClientTest, SetWindowProperty) {
  Id window_1_1 = wt_client1()->NewWindow(1);
  ASSERT_TRUE(window_1_1);

  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(false));
  changes2()->clear();

  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), root_window_id(), &windows);
    ASSERT_EQ(2u, windows.size());
    EXPECT_EQ(root_window_id(), windows[0].window_id);
    EXPECT_EQ(window_1_1, windows[1].window_id);
    ASSERT_EQ(0u, windows[1].properties.size());
  }

  // Set properties on 1.
  changes2()->clear();
  std::vector<uint8_t> one(1, '1');
  ASSERT_TRUE(wt_client1()->SetWindowProperty(window_1_1, "one", &one));
  // window_1_1 has a client_id part of client_id_1 in wt2.
  Id window11_in_wt2 =
      BuildWindowId(client_id_1(), ClientWindowIdFromTransportId(window_1_1));
  {
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("PropertyChanged window=" + IdToString(window11_in_wt2) +
                  " key=one value=1",
              SingleChangeToDescription(*changes2()));
  }

  // Test that our properties exist in the window tree
  {
    std::vector<TestWindow> windows;
    GetWindowTree(wt1(), window_1_1, &windows);
    ASSERT_EQ(1u, windows.size());
    ASSERT_EQ(1u, windows[0].properties.size());
    EXPECT_EQ(one, windows[0].properties["one"]);
  }

  changes2()->clear();
  // Set back to null.
  ASSERT_TRUE(wt_client1()->SetWindowProperty(window_1_1, "one", NULL));
  {
    wt_client2_->WaitForChangeCount(1);
    EXPECT_EQ("PropertyChanged window=" + IdToString(window11_in_wt2) +
                  " key=one value=NULL",
              SingleChangeToDescription(*changes2()));
  }
}

TEST_F(WindowTreeClientTest, OnEmbeddedAppDisconnected) {
  // Create client 2 and 3.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  Id window_2_1 = wt_client2()->NewWindow(1);
  ASSERT_TRUE(window_2_1);
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_1));
  changes2()->clear();
  ASSERT_NO_FATAL_FAILURE(EstablishThirdClient(wt2(), window_2_1));

  // Client 1 should get a hierarchy change for window_2_1.
  wt_client1_->WaitForChangeCount(1);
  changes1()->clear();

  // Close client 3. Client 2 (which had previously embedded 3) should
  // be notified of this.
  wt_client3_.reset();
  wt_client2_->WaitForChangeCount(1);
  EXPECT_EQ("OnEmbeddedAppDisconnected window=" + IdToString(window_2_1),
            SingleChangeToDescription(*changes2()));

  // The closing is only interesting to the root that did the embedding. Other
  // clients should not be notified of this.
  wt_client1_->WaitForAllMessages();
  EXPECT_TRUE(changes1()->empty());
}

// Verifies when the parent of an Embed() is destroyed the embedded app gets
// a WindowDeleted (and doesn't trigger a DCHECK).
TEST_F(WindowTreeClientTest, OnParentOfEmbedDisconnects) {
  // Create client 2 and 3.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  Id window_2_1 = wt_client2()->NewWindow(1);
  Id window_2_2 = wt_client2()->NewWindow(2);
  ASSERT_TRUE(window_2_1);
  ASSERT_TRUE(window_2_2);
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_1));
  ASSERT_TRUE(wt_client2()->AddWindow(window_2_1, window_2_2));
  changes2()->clear();
  ASSERT_NO_FATAL_FAILURE(EstablishThirdClient(wt2(), window_2_2));
  changes3()->clear();

  // Close client 2. Client 3 should get a delete (for its root).
  wt_client2_.reset();
  wt_client3_->WaitForChangeCount(1);
  // window_2_2 has a client_id part of client_id_2 in wt3.
  EXPECT_EQ("WindowDeleted window=" +
                IdToString(BuildWindowId(
                    client_id_2(), ClientWindowIdFromTransportId(window_2_2))),
            SingleChangeToDescription(*changes3()));
}

// Verifies WindowTreeImpl doesn't incorrectly erase from its internal
// map when a window from another client with the same window_id is removed.
TEST_F(WindowTreeClientTest, DontCleanMapOnDestroy) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  ASSERT_TRUE(wt_client2()->NewWindow(1));
  changes1()->clear();
  wt_client2_.reset();
  wt_client1_->WaitForChangeCount(1);
  // window_1_1 is created by wt1 so client_id part would be 0.
  EXPECT_EQ("OnEmbeddedAppDisconnected window=" +
                IdToString(ClientWindowIdFromTransportId(window_1_1)),
            SingleChangeToDescription(*changes1()));
  std::vector<TestWindow> windows;
  GetWindowTree(wt1(), window_1_1, &windows);
  EXPECT_FALSE(windows.empty());
}

// Verifies Embed() works when supplying a WindowTreeClient.
TEST_F(WindowTreeClientTest, EmbedSupplyingWindowTreeClient) {
  ASSERT_TRUE(wt_client1()->NewWindow(1));

  TestWindowTreeClient client2;
  mojom::WindowTreeClientPtr client2_ptr;
  mojo::Binding<WindowTreeClient> client2_binding(
      &client2, mojo::MakeRequest(&client2_ptr));
  ASSERT_TRUE(Embed(wt1(), BuildWindowId(client_id_1(), 1),
                    std::move(client2_ptr)));
  client2.WaitForOnEmbed();
  EXPECT_EQ("OnEmbed",
            SingleChangeToDescription(*client2.tracker()->changes()));
}

TEST_F(WindowTreeClientTest, EmbedUsingToken) {
  // Embed client2.
  ASSERT_TRUE(wt_client1()->NewWindow(1));
  TestWindowTreeClient client2;
  mojom::WindowTreeClientPtr client2_ptr;
  mojo::Binding<WindowTreeClient> client2_binding(
      &client2, mojo::MakeRequest(&client2_ptr));
  ASSERT_TRUE(
      Embed(wt1(), BuildWindowId(client_id_1(), 1), std::move(client2_ptr)));
  client2.WaitForOnEmbed();
  EXPECT_EQ("OnEmbed",
            SingleChangeToDescription(*client2.tracker()->changes()));

  // Schedule an embed of |client3| from wt1().
  TestWindowTreeClient client3;
  mojom::WindowTreeClientPtr client3_ptr;
  mojo::Binding<WindowTreeClient> client3_binding(
      &client3, mojo::MakeRequest(&client3_ptr));
  base::UnguessableToken token;
  ScheduleEmbed(wt1(), std::move(client3_ptr), &token);

  // Have |client2| embed using the token scheduled above.
  const Id window_id = client2.NewWindow(121);
  ASSERT_TRUE(window_id);
  ASSERT_TRUE(EmbedUsingToken(client2.tree(), BuildWindowId(client_id_2(), 121),
                              token));
  client3.WaitForOnEmbed();
  EXPECT_EQ("OnEmbed",
            SingleChangeToDescription(*client3.tracker()->changes()));

  // EmbedUsingToken() should fail when passed a token that was already used.
  EXPECT_FALSE(EmbedUsingToken(client2.tree(),
                               BuildWindowId(client_id_2(), 121), token));

  // EmbedUsingToken() should fail when passed a locally generated token.
  EXPECT_FALSE(EmbedUsingToken(client2.tree(),
                               BuildWindowId(client_id_2(), 121),
                               base::UnguessableToken::Create()));
}

TEST_F(WindowTreeClientTest, EmbedUsingTokenFailsWithInvalidWindow) {
  // Embed client2.
  ASSERT_TRUE(wt_client1()->NewWindow(1));
  TestWindowTreeClient client2;
  mojom::WindowTreeClientPtr client2_ptr;
  mojo::Binding<WindowTreeClient> client2_binding(
      &client2, mojo::MakeRequest(&client2_ptr));
  ASSERT_TRUE(
      Embed(wt1(), BuildWindowId(client_id_1(), 1), std::move(client2_ptr)));
  client2.WaitForOnEmbed();
  EXPECT_EQ("OnEmbed",
            SingleChangeToDescription(*client2.tracker()->changes()));

  // Schedule an embed of |client3| from wt1().
  TestWindowTreeClient client3;
  mojom::WindowTreeClientPtr client3_ptr;
  mojo::Binding<WindowTreeClient> client3_binding(
      &client3, mojo::MakeRequest(&client3_ptr));
  base::UnguessableToken token;
  ScheduleEmbed(wt1(), std::move(client3_ptr), &token);

  // This should fail as the window id does not identify a valid window.
  EXPECT_FALSE(EmbedUsingToken(client2.tree(),
                               BuildWindowId(client_id_2(), 121), token));
}

TEST_F(WindowTreeClientTest, EmbedFailsFromOtherClient) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));

  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  Id window_2_1 = wt_client2()->NewWindow(1);
  ASSERT_TRUE(window_2_1);
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_1));
  ASSERT_NO_FATAL_FAILURE(EstablishThirdClient(wt2(), window_2_1));

  Id window_3_3 = wt_client3()->NewWindow(3);
  ASSERT_TRUE(window_3_3);
  // window_2_1 should have client_id of client_id_2 in wt_client3.
  ASSERT_TRUE(wt_client3()->AddWindow(
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_1)),
      window_3_3));

  // 2 should not be able to embed in window_3_3 as window_3_3 was not created
  // by
  // 2.
  EXPECT_FALSE(EmbedUrl(connector(), wt2(), test_name(), window_3_3));
}

// Verifies Embed() from window manager on another clients window works.
TEST_F(WindowTreeClientTest, EmbedFromOtherClient) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));

  Id window_1_1 = BuildWindowId(client_id_1(), 1);
  Id window_2_1 = wt_client2()->NewWindow(1);
  ASSERT_TRUE(window_2_1);
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_1));

  changes2()->clear();

  // Establish a third client in window_2_1. window_2_1 has a client_id of
  // client_id_2 for other clients.
  ASSERT_NO_FATAL_FAILURE(EstablishThirdClient(
      wt1(),
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_1))));

  ASSERT_TRUE(wt_client2()->WaitForAllMessages());
  EXPECT_EQ(std::string(), SingleChangeToDescription(*changes2()));
}

TEST_F(WindowTreeClientTest, CantEmbedFromClientRoot) {
  // Shouldn't be able to embed into the root.
  ASSERT_FALSE(EmbedUrl(connector(), wt1(), test_name(), root_window_id()));

  // Even though the call above failed a WindowTreeClient was obtained. We need
  // to
  // wait for it else we throw off the next connect.
  WaitForWindowTreeClient();

  // Don't allow a client to embed into its own root.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  EXPECT_FALSE(EmbedUrl(connector(), wt2(), test_name(),
                        BuildWindowId(client_id_1(), 1)));

  // Need to wait for a WindowTreeClient for same reason as above.
  WaitForWindowTreeClient();

  Id window_1_2 = wt_client1()->NewWindow(2);
  ASSERT_TRUE(window_1_2);
  ASSERT_TRUE(
      wt_client1()->AddWindow(BuildWindowId(client_id_1(), 1), window_1_2));
  ASSERT_TRUE(wt_client3_.get() == nullptr);
  wt_client3_ = EstablishClientViaEmbedWithPolicyBitmask(wt1(), window_1_2);
  ASSERT_TRUE(wt_client3_.get() != nullptr);

  // window_1_2 is ws3's root, so even though v3 is an embed root it should not
  // be able to Embed into itself.
  ASSERT_FALSE(EmbedUrl(connector(), wt3(), test_name(), window_1_2));
}

// Verifies that a transient window tracks its parent's lifetime.
TEST_F(WindowTreeClientTest, TransientWindowTracksTransientParentLifetime) {
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClient(true));
  Id window_1_1 = BuildWindowId(client_id_1(), 1);

  Id window_2_1 = wt_client2()->NewWindow(1);
  Id window_2_2 = wt_client2()->NewWindow(2);
  Id window_2_3 = wt_client2()->NewWindow(3);
  ASSERT_TRUE(window_2_1);
  // window_2_* has a client_id part of client_id_2 in wt1.
  Id window21_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_1));
  Id window22_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_2));
  Id window23_in_wt1 =
      BuildWindowId(client_id_2(), ClientWindowIdFromTransportId(window_2_3));

  // root -> window_1_1 -> window_2_1
  // root -> window_1_1 -> window_2_2
  // root -> window_1_1 -> window_2_3
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_1));
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_2));
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_1, window_2_3));

  // window_2_2 and window_2_3 now track the lifetime of window_2_1.
  changes1()->clear();
  wt2()->AddTransientWindow(10, window_2_1, window_2_2);
  wt2()->AddTransientWindow(11, window_2_1, window_2_3);
  wt_client1()->WaitForChangeCount(2);
  EXPECT_EQ("AddTransientWindow parent = " + IdToString(window21_in_wt1) +
                " child = " + IdToString(window22_in_wt1),
            ChangesToDescription1(*changes1())[0]);
  EXPECT_EQ("AddTransientWindow parent = " + IdToString(window21_in_wt1) +
                " child = " + IdToString(window23_in_wt1),
            ChangesToDescription1(*changes1())[1]);

  changes1()->clear();
  wt2()->RemoveTransientWindowFromParent(12, window_2_3);
  wt_client1()->WaitForChangeCount(1);
  EXPECT_EQ("RemoveTransientWindowFromParent parent = " +
                IdToString(window21_in_wt1) +
                " child = " + IdToString(window23_in_wt1),
            SingleChangeToDescription(*changes1()));

  changes1()->clear();
  ASSERT_TRUE(wt_client2()->DeleteWindow(window_2_1));
  wt_client1()->WaitForChangeCount(2);
  EXPECT_EQ("WindowDeleted window=" + IdToString(window22_in_wt1),
            ChangesToDescription1(*changes1())[0]);
  EXPECT_EQ("WindowDeleted window=" + IdToString(window21_in_wt1),
            ChangesToDescription1(*changes1())[1]);
}

TEST_F(WindowTreeClientTest, Ids) {
  const Id window_1_100 = wt_client1()->NewWindow(100);
  ASSERT_TRUE(window_1_100);
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_100));

  // Establish the second client at client_id_1(),100.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClientWithRoot(window_1_100));

  // client_id_1(),100 is the id in the wt_client1's id space. The new client
  // should see client_id_2(),1 (the server id).
  const Id window_1_100_in_ws2 = BuildWindowId(client_id_1(), 100);
  EXPECT_EQ(window_1_100_in_ws2, wt_client2()->root_window_id());

  // The first window created in the second client gets a server id of
  // client_id_2(),1 regardless of the id the client uses.
  const Id window_2_101 = wt_client2()->NewWindow(101);
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_100_in_ws2, window_2_101));
  const Id window_2_101_in_ws1 = BuildWindowId(client_id_2(), 101);
  wt_client1()->WaitForChangeCount(1);
  EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_101_in_ws1) +
                " old_parent=null new_parent=" + IdToString(window_1_100),
            SingleChangeToDescription(*changes1()));
  changes1()->clear();

  // Change the bounds of window_2_101 and make sure server gets it.
  wt2()->SetWindowBounds(11, window_2_101, gfx::Rect(1, 2, 3, 4),
                         base::nullopt);
  ASSERT_TRUE(wt_client2()->WaitForChangeCompleted(11));
  wt_client1()->WaitForChangeCount(1);
  EXPECT_EQ(
      "BoundsChanged window=" + IdToString(window_2_101_in_ws1) +
          " old_bounds=0,0 0x0 new_bounds=1,2 3x4 local_surface_id=(none)",
      SingleChangeToDescription(*changes1()));
  changes2()->clear();

  // Remove 2_101 from wm, client1 should see the change.
  wt1()->RemoveWindowFromParent(12, window_2_101_in_ws1);
  ASSERT_TRUE(wt_client1()->WaitForChangeCompleted(12));
  wt_client2()->WaitForChangeCount(1);
  EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_101) +
                " old_parent=" + IdToString(window_1_100_in_ws2) +
                " new_parent=null",
            SingleChangeToDescription(*changes2()));
}

// Tests that setting capture fails when no input event has occurred, and there
// is no notification of lost capture.
TEST_F(WindowTreeClientTest, ExplicitCaptureWithoutInput) {
  Id window_1_1 = wt_client1()->NewWindow(1);

  // Add the window to the root, so that they have a Display to handle input
  // capture.
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  changes1()->clear();

  // Since there has been no input, capture should not succeed. No lost capture
  // message is expected.
  wt1()->SetCapture(1, window_1_1);
  wt_client1_->WaitForAllMessages();
  EXPECT_TRUE(changes1()->empty());

  // Since there is no window with capture, lost capture should not be notified.
  wt1()->ReleaseCapture(3, window_1_1);
  wt_client1_->WaitForAllMessages();
  EXPECT_TRUE(changes1()->empty());
}

// TODO(jonross): Enable this once apptests can send input events to the server.
// Enabling capture requires that the client be processing events.
TEST_F(WindowTreeClientTest, DISABLED_ExplicitCapturePropagation) {
  Id window_1_1 = wt_client1()->NewWindow(1);
  Id window_1_2 = wt_client1()->NewWindow(2);

  // Add the windows to the root, so that they have a Display to handle input
  // capture.
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_1));
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_2));

  changes1()->clear();
  // Window 1 takes capture then Window 2 takes capture.
  // Verify that window 1 has lost capture.
  wt1()->SetCapture(1, window_1_1);
  wt1()->SetCapture(2, window_1_2);
  wt_client1_->WaitForChangeCount(1);

  EXPECT_EQ("OnLostCapture window=" + IdToString(window_1_1),
            SingleChangeToDescription(*changes1()));

  changes1()->clear();
  // Explicitly releasing capture should not notify of lost capture.
  wt1()->ReleaseCapture(3, window_1_2);
  wt_client1_->WaitForAllMessages();

  EXPECT_TRUE(changes1()->empty());
}

TEST_F(WindowTreeClientTest, SurfaceIdPropagation) {
  const Id window_1_100 = wt_client1()->NewWindow(100);
  ASSERT_TRUE(window_1_100);
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_100));

  // Establish the second client at client_id_1(),100.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClientWithRoot(window_1_100));
  changes2()->clear();

  // client_id_1(),100 is the id in the wt_client1's id space. The new client
  // should see client_id_2(),1 (the server id).
  const Id window_1_100_in_ws2 = BuildWindowId(client_id_1(), 100);
  EXPECT_EQ(window_1_100_in_ws2, wt_client2()->root_window_id());

  // Submit a CompositorFrame to window_1_100_in_ws2 (the embedded window in
  // wt2) and make sure the server gets it.
  {
    viz::mojom::CompositorFrameSinkPtr surface_ptr;
    viz::mojom::CompositorFrameSinkClientRequest client_request;
    viz::mojom::CompositorFrameSinkClientPtr surface_client_ptr;
    client_request = mojo::MakeRequest(&surface_client_ptr);
    wt2()->AttachCompositorFrameSink(window_1_100_in_ws2,
                                     mojo::MakeRequest(&surface_ptr),
                                     std::move(surface_client_ptr));
    viz::CompositorFrame compositor_frame;
    std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create();
    gfx::Rect frame_rect(0, 0, 100, 100);
    render_pass->SetNew(1, frame_rect, frame_rect, gfx::Transform());
    compositor_frame.render_pass_list.push_back(std::move(render_pass));
    compositor_frame.metadata.device_scale_factor = 1.f;
    compositor_frame.metadata.begin_frame_ack = viz::BeginFrameAck(0, 1, true);
    viz::LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create());
    surface_ptr->SubmitCompositorFrame(local_surface_id,
                                       std::move(compositor_frame), nullptr, 0);
  }
  // Make sure the parent connection gets the surface ID.
  wt_client1()->WaitForChangeCount(1);
  // Verify that the submitted frame is for |window_2_101|.
  viz::FrameSinkId frame_sink_id =
      changes1()->back().surface_id.frame_sink_id();
  // FrameSinkId is based on window's ClientWindowId.
  EXPECT_EQ(static_cast<size_t>(client_id_2()), frame_sink_id.client_id());
  EXPECT_EQ(0u, frame_sink_id.sink_id());
  changes1()->clear();

  // The first window created in the second client gets a server id of
  // client_id_2(),1 regardless of the id the client uses.
  const Id window_2_101 = wt_client2()->NewWindow(101);
  ASSERT_TRUE(wt_client2()->AddWindow(window_1_100_in_ws2, window_2_101));
  const Id window_2_101_in_ws2 = BuildWindowId(client_id_2(), 101);
  wt_client1()->WaitForChangeCount(1);
  EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_101_in_ws2) +
                " old_parent=null new_parent=" + IdToString(window_1_100),
            SingleChangeToDescription(*changes1()));
  // Submit a CompositorFrame to window_2_101_in_ws2 (a regular window in
  // wt2) and make sure client gets it.
  {
    viz::mojom::CompositorFrameSinkPtr surface_ptr;
    viz::mojom::CompositorFrameSinkClientRequest client_request;
    viz::mojom::CompositorFrameSinkClientPtr surface_client_ptr;
    client_request = mojo::MakeRequest(&surface_client_ptr);
    wt2()->AttachCompositorFrameSink(window_2_101,
                                     mojo::MakeRequest(&surface_ptr),
                                     std::move(surface_client_ptr));
    viz::CompositorFrame compositor_frame;
    std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create();
    gfx::Rect frame_rect(0, 0, 100, 100);
    render_pass->SetNew(1, frame_rect, frame_rect, gfx::Transform());
    compositor_frame.render_pass_list.push_back(std::move(render_pass));
    compositor_frame.metadata.device_scale_factor = 1.f;
    compositor_frame.metadata.begin_frame_ack = viz::BeginFrameAck(0, 1, true);
    viz::LocalSurfaceId local_surface_id(2, base::UnguessableToken::Create());
    surface_ptr->SubmitCompositorFrame(local_surface_id,
                                       std::move(compositor_frame), nullptr, 0);
  }
  // Make sure the parent connection gets the surface ID.
  wt_client2()->WaitForChangeCount(1);
  // Verify that the submitted frame is for |window_2_101|.
  viz::FrameSinkId frame_sink_id2 =
      changes2()->back().surface_id.frame_sink_id();
  // FrameSinkId is based on window's ClientWindowId.
  EXPECT_NE(0u, frame_sink_id2.client_id());
  EXPECT_EQ(ClientWindowIdFromTransportId(window_2_101),
            frame_sink_id2.sink_id());
}

// Verifies when an unknown window with a known child is added to a hierarchy
// the known child is identified in the WindowData.
TEST_F(WindowTreeClientTest, AddUnknownWindowKnownParent) {
  const Id window_1_100 = wt_client1()->NewWindow(100);
  ASSERT_TRUE(window_1_100);
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window_1_100));

  // Establish the second client at client_id_1(),100.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClientWithRoot(window_1_100));
  const Id window_2_1 = wt_client2()->NewWindow(1000);
  const Id window_2_2 = wt_client2()->NewWindow(2000);
  // Add 2_1 to the root, remove 2_1, add 2_1 to 2_2 and then 2_2 to the parent.
  ASSERT_TRUE(
      wt_client2()->AddWindow(wt_client2()->root_window_id(), window_2_1));
  ASSERT_TRUE(wt_client2()->RemoveWindowFromParent(window_2_1));
  ASSERT_TRUE(wt_client2()->AddWindow(window_2_2, window_2_1));
  wt_client1()->WaitForChangeCount(2);
  changes1()->clear();
  ASSERT_TRUE(
      wt_client2()->AddWindow(wt_client2()->root_window_id(), window_2_2));
  wt_client1()->WaitForChangeCount(1);
  const Id window_2_1_in_wm = BuildWindowId(client_id_2(), 1000);
  const Id window_2_2_in_wm = BuildWindowId(client_id_2(), 2000);
  EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_2_in_wm) +
                " old_parent=null new_parent=" + IdToString(window_1_100),
            SingleChangeToDescription(*changes1()));
  EXPECT_EQ("[window=" + IdToString(window_2_2_in_wm) + " parent=" +
                IdToString(window_1_100) + "],[window=" +
                IdToString(window_2_1_in_wm) + " parent=" +
                IdToString(window_2_2_in_wm) + "]",
            ChangeWindowDescription(*changes1()));
}

TEST_F(WindowTreeClientTest, Transform) {
  const Id window1 = wt_client1()->NewWindow(100);
  ASSERT_TRUE(window1);
  ASSERT_TRUE(wt_client1()->AddWindow(root_window_id(), window1));

  // Establish the second client at |window1|.
  ASSERT_NO_FATAL_FAILURE(EstablishSecondClientWithRoot(window1));

  // The first window created in the second client gets a server id of
  // client_id_2(),1 regardless of the id the client uses.
  const Id window1_in_client2 = BuildWindowId(client_id_1(), 100);
  const Id window2 = wt_client2()->NewWindow(11);
  ASSERT_TRUE(wt_client2()->AddWindow(window1_in_client2, window2));
  const Id window2_in_client1 = BuildWindowId(client_id_2(), 11);
  wt_client1()->WaitForChangeCount(1);
  changes1()->clear();

  // Change the transform of |window2| and make sure server gets it.
  gfx::Transform transform;
  transform.Scale(SkIntToMScalar(2), SkIntToMScalar(2));
  const uint32_t transform_change_id = 12;
  wt2()->SetWindowTransform(transform_change_id, window2, transform);
  ASSERT_TRUE(wt_client2()->WaitForChangeCompleted(transform_change_id));
  wt_client1()->WaitForChangeCount(1);
  EXPECT_EQ("TransformChanged window_id=" + IdToString(window2_in_client1),
            SingleChangeToDescription(*changes1()));
}

// TODO(sky): need to better track changes to initial client. For example,
// that SetBounsdWindows/AddWindow and the like don't result in messages to the
// originating client.

// TODO(sky): make sure coverage of what was
// WindowManagerTest.SecondEmbedRoot_InitService and
// WindowManagerTest.MultipleEmbedRootsBeforeWTHReady gets added to window
// manager
// tests.

}  // namespace test
}  // namespace ws
}  // namespace ui
