summaryrefslogtreecommitdiff
path: root/chromium/content/renderer/mus/mus_embedded_frame.cc
blob: f6b3d1e439f0aa1a8a346a4d0cad3ac3b33f2a08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/renderer/mus/mus_embedded_frame.h"

#include <map>

#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "cc/base/switches.h"
#include "components/viz/client/client_layer_tree_frame_sink.h"
#include "components/viz/client/hit_test_data_provider.h"
#include "components/viz/client/local_surface_id_provider.h"
#include "content/renderer/mus/renderer_window_tree_client.h"
#include "services/ui/public/cpp/property_type_converters.h"
#include "services/ui/public/interfaces/window_manager.mojom.h"

namespace content {
namespace {

// Callback from embedding a child frame.
void OnEmbedAck(bool success) {
  DCHECK(success);
}

}  // namespace

MusEmbeddedFrame::~MusEmbeddedFrame() {
  renderer_window_tree_client_->OnEmbeddedFrameDestroyed(this);

  // If the tree changed the old tree the window was created in was dropped and
  // the server implictly cleaned up. As such, no need to do cleanup here (and
  // we don't have a handle to the right WindowTree at this point).
  if (tree_changed_)
    return;

  // If there is |pending_state_| it means we didn't actually create the window
  // yet and there is nothing to do.
  if (pending_state_)
    return;

  window_tree()->DeleteWindow(GetAndAdvanceNextChangeId(), window_id_);
}

void MusEmbeddedFrame::SetWindowBounds(
    const viz::LocalSurfaceId& local_surface_id,
    const gfx::Rect& bounds) {
  if (tree_changed_)
    return;

  if (!window_tree()) {
    DCHECK(pending_state_);
    pending_state_->bounds = bounds;
    pending_state_->local_surface_id = local_surface_id;
    pending_state_->was_set_window_bounds_called = true;
    return;
  }

  window_tree()->SetWindowBounds(GetAndAdvanceNextChangeId(), window_id_,
                                 bounds, local_surface_id);
}

MusEmbeddedFrame::MusEmbeddedFrame(
    RendererWindowTreeClient* renderer_window_tree_client,
    MusEmbeddedFrameDelegate* delegate,
    ui::ClientSpecificId window_id,
    const base::UnguessableToken& token)
    : renderer_window_tree_client_(renderer_window_tree_client),
      delegate_(delegate),
      window_id_(window_id) {
  if (!window_tree()) {
    pending_state_ = std::make_unique<PendingState>();
    pending_state_->token = token;
    return;
  }
  CreateChildWindowAndEmbed(token);
}

void MusEmbeddedFrame::CreateChildWindowAndEmbed(
    const base::UnguessableToken& token) {
  // Set a name for debugging.
  std::unordered_map<std::string, std::vector<uint8_t>> properties;
  properties[ui::mojom::WindowManager::kName_Property] =
      mojo::ConvertTo<std::vector<uint8_t>>(std::string("RendererFrame"));
  window_tree()->NewWindow(GetAndAdvanceNextChangeId(), window_id_, properties);
  window_tree()->AddWindow(GetAndAdvanceNextChangeId(),
                           renderer_window_tree_client_->root_window_id_,
                           window_id_);
  window_tree()->EmbedUsingToken(window_id_, token, 0,
                                 base::BindOnce(&OnEmbedAck));
}

void MusEmbeddedFrame::OnTreeAvailable() {
  // See header for description, always called before OnTreeWillChange().
  DCHECK(!tree_changed_);
  std::unique_ptr<PendingState> pending_state = std::move(pending_state_);
  CreateChildWindowAndEmbed(pending_state->token);
  if (pending_state->was_set_window_bounds_called)
    SetWindowBounds(pending_state->local_surface_id, pending_state->bounds);
}

void MusEmbeddedFrame::OnTreeWillChange() {
  tree_changed_ = true;
}

uint32_t MusEmbeddedFrame::GetAndAdvanceNextChangeId() {
  return renderer_window_tree_client_->GetAndAdvanceNextChangeId();
}

ui::mojom::WindowTree* MusEmbeddedFrame::window_tree() {
  // Once |tree_changed_| is true the WindowTree this instance used has changed
  // and it no longer makes sense to use it (the original window was deleted).
  return tree_changed_ ? nullptr : renderer_window_tree_client_->tree_.get();
}

MusEmbeddedFrame::PendingState::PendingState() = default;

MusEmbeddedFrame::PendingState::~PendingState() = default;

}  // namespace content