#include "mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h"
#include "base/bind.h"
+#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
-#include "mojo/public/cpp/application/application.h"
+#include "base/stl_util.h"
+#include "mojo/public/cpp/application/application_connection.h"
#include "mojo/public/cpp/application/connect.h"
-#include "mojo/public/interfaces/service_provider/service_provider.mojom.h"
-#include "mojo/services/public/cpp/view_manager/lib/node_private.h"
+#include "mojo/public/cpp/application/service_provider_impl.h"
+#include "mojo/public/interfaces/application/service_provider.mojom.h"
#include "mojo/services/public/cpp/view_manager/lib/view_private.h"
-#include "mojo/services/public/cpp/view_manager/node_observer.h"
#include "mojo/services/public/cpp/view_manager/util.h"
#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
#include "mojo/services/public/cpp/view_manager/view_observer.h"
+#include "mojo/services/public/cpp/view_manager/window_manager_delegate.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/codec/png_codec.h"
namespace mojo {
-namespace view_manager {
Id MakeTransportId(ConnectionSpecificId connection_id,
ConnectionSpecificId local_id) {
return (connection_id << 16) | local_id;
}
-// Helper called to construct a local node/view object from transport data.
-Node* AddNodeToViewManager(ViewManagerClientImpl* client,
- Node* parent,
- Id node_id,
+// Helper called to construct a local view object from transport data.
+View* AddViewToViewManager(ViewManagerClientImpl* client,
+ View* parent,
Id view_id,
const gfx::Rect& bounds) {
// We don't use the ctor that takes a ViewManager here, since it will call
- // back to the service and attempt to create a new node.
- Node* node = NodePrivate::LocalCreate();
- NodePrivate private_node(node);
- private_node.set_view_manager(client);
- private_node.set_id(node_id);
- private_node.LocalSetBounds(gfx::Rect(), bounds);
+ // back to the service and attempt to create a new view.
+ View* view = ViewPrivate::LocalCreate();
+ ViewPrivate private_view(view);
+ private_view.set_view_manager(client);
+ private_view.set_id(view_id);
+ client->AddView(view);
+ private_view.LocalSetBounds(gfx::Rect(), bounds);
if (parent)
- NodePrivate(parent).LocalAddChild(node);
- client->AddNode(node);
-
- // View.
- if (view_id != 0) {
- View* view = ViewPrivate::LocalCreate();
- ViewPrivate private_view(view);
- private_view.set_view_manager(client);
- private_view.set_id(view_id);
- private_view.set_node(node);
- // TODO(beng): this broadcasts notifications locally... do we want this? I
- // don't think so. same story for LocalAddChild above!
- private_node.LocalSetActiveView(view);
- client->AddView(view);
- }
- return node;
-}
-
-Node* BuildNodeTree(ViewManagerClientImpl* client,
- const Array<NodeDataPtr>& nodes) {
- std::vector<Node*> parents;
- Node* root = NULL;
- Node* last_node = NULL;
- for (size_t i = 0; i < nodes.size(); ++i) {
- if (last_node && nodes[i]->parent_id == last_node->id()) {
- parents.push_back(last_node);
+ ViewPrivate(parent).LocalAddChild(view);
+ return view;
+}
+
+View* BuildViewTree(ViewManagerClientImpl* client,
+ const Array<ViewDataPtr>& views,
+ View* initial_parent) {
+ std::vector<View*> parents;
+ View* root = NULL;
+ View* last_view = NULL;
+ if (initial_parent)
+ parents.push_back(initial_parent);
+ for (size_t i = 0; i < views.size(); ++i) {
+ if (last_view && views[i]->parent_id == last_view->id()) {
+ parents.push_back(last_view);
} else if (!parents.empty()) {
- while (parents.back()->id() != nodes[i]->parent_id)
+ while (parents.back()->id() != views[i]->parent_id)
parents.pop_back();
}
- Node* node = AddNodeToViewManager(
+ View* view = AddViewToViewManager(
client,
!parents.empty() ? parents.back() : NULL,
- nodes[i]->node_id,
- nodes[i]->view_id,
- nodes[i]->bounds.To<gfx::Rect>());
- if (!last_node)
- root = node;
- last_node = node;
+ views[i]->view_id,
+ views[i]->bounds.To<gfx::Rect>());
+ if (!last_view)
+ root = view;
+ last_view = view;
}
return root;
}
-// Responsible for removing a root from the ViewManager when that node is
+// Responsible for removing a root from the ViewManager when that view is
// destroyed.
-class RootObserver : public NodeObserver {
+class RootObserver : public ViewObserver {
public:
- explicit RootObserver(Node* root) : root_(root) {}
+ explicit RootObserver(View* root) : root_(root) {}
virtual ~RootObserver() {}
private:
- // Overridden from NodeObserver:
- virtual void OnNodeDestroy(Node* node,
- DispositionChangePhase phase) OVERRIDE {
- DCHECK_EQ(node, root_);
- if (phase != NodeObserver::DISPOSITION_CHANGED)
- return;
+ // Overridden from ViewObserver:
+ virtual void OnViewDestroyed(View* view) OVERRIDE {
+ DCHECK_EQ(view, root_);
static_cast<ViewManagerClientImpl*>(
- NodePrivate(root_).view_manager())->RemoveRoot(root_);
+ ViewPrivate(root_).view_manager())->RemoveRoot(root_);
+ view->RemoveObserver(this);
delete this;
}
- Node* root_;
+ View* root_;
DISALLOW_COPY_AND_ASSIGN(RootObserver);
};
-class ViewManagerTransaction {
- public:
- virtual ~ViewManagerTransaction() {}
-
- void Commit() {
- DCHECK(!committed_);
- DoCommit();
- committed_ = true;
- }
-
- bool committed() const { return committed_; }
-
- protected:
- explicit ViewManagerTransaction(ViewManagerClientImpl* client)
- : committed_(false),
- client_(client) {
- }
-
- // Overridden to perform transaction-specific commit actions.
- virtual void DoCommit() = 0;
-
- // Overridden to perform transaction-specific cleanup on commit ack from the
- // service.
- virtual void DoActionCompleted(bool success) = 0;
-
- ViewManagerService* service() { return client_->service_; }
-
- Id GetAndAdvanceNextServerChangeId() {
- return client_->next_server_change_id_++;
- }
-
- base::Callback<void(bool)> ActionCompletedCallback() {
- return base::Bind(&ViewManagerTransaction::OnActionCompleted,
- base::Unretained(this));
- }
-
- private:
- // General callback to be used for commits to the service.
- void OnActionCompleted(bool success) {
- DCHECK(success);
- DoActionCompleted(success);
- client_->RemoveFromPendingQueue(this);
- }
-
- bool committed_;
- ViewManagerClientImpl* client_;
-
- DISALLOW_COPY_AND_ASSIGN(ViewManagerTransaction);
-};
-
-class CreateViewTransaction : public ViewManagerTransaction {
- public:
- CreateViewTransaction(Id view_id, ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- view_id_(view_id) {}
- virtual ~CreateViewTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- service()->CreateView(view_id_, ActionCompletedCallback());
- }
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): failure.
- }
-
- const Id view_id_;
-
- DISALLOW_COPY_AND_ASSIGN(CreateViewTransaction);
-};
-
-class DestroyViewTransaction : public ViewManagerTransaction {
- public:
- DestroyViewTransaction(Id view_id, ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- view_id_(view_id) {}
- virtual ~DestroyViewTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- service()->DeleteView(view_id_, ActionCompletedCallback());
- }
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): recovery?
- }
-
- const Id view_id_;
-
- DISALLOW_COPY_AND_ASSIGN(DestroyViewTransaction);
-};
-
-class CreateNodeTransaction : public ViewManagerTransaction {
- public:
- CreateNodeTransaction(Id node_id, ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- node_id_(node_id) {}
- virtual ~CreateNodeTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- service()->CreateNode(node_id_, ActionCompletedCallback());
- }
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): Failure means we tried to create with an extant id for this
- // connection. It also could mean we tried to do something
- // invalid, or we tried applying a change out of order. Figure
- // out what to do.
- }
-
- const Id node_id_;
-
- DISALLOW_COPY_AND_ASSIGN(CreateNodeTransaction);
-};
-
-class DestroyNodeTransaction : public ViewManagerTransaction {
- public:
- DestroyNodeTransaction(Id node_id, ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- node_id_(node_id) {}
- virtual ~DestroyNodeTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- service()->DeleteNode(node_id_,
- GetAndAdvanceNextServerChangeId(),
- ActionCompletedCallback());
- }
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): recovery?
- }
-
- const Id node_id_;
- DISALLOW_COPY_AND_ASSIGN(DestroyNodeTransaction);
-};
-
-class AddChildTransaction : public ViewManagerTransaction {
- public:
- AddChildTransaction(Id child_id,
- Id parent_id,
- ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- child_id_(child_id),
- parent_id_(parent_id) {}
- virtual ~AddChildTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- service()->AddNode(parent_id_,
- child_id_,
- GetAndAdvanceNextServerChangeId(),
- ActionCompletedCallback());
- }
-
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): recovery?
- }
-
- const Id child_id_;
- const Id parent_id_;
-
- DISALLOW_COPY_AND_ASSIGN(AddChildTransaction);
-};
-
-class RemoveChildTransaction : public ViewManagerTransaction {
- public:
- RemoveChildTransaction(Id child_id, ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- child_id_(child_id) {}
- virtual ~RemoveChildTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- service()->RemoveNodeFromParent(
- child_id_,
- GetAndAdvanceNextServerChangeId(),
- ActionCompletedCallback());
- }
-
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): recovery?
- }
-
- const Id child_id_;
-
- DISALLOW_COPY_AND_ASSIGN(RemoveChildTransaction);
-};
-
-class ReorderNodeTransaction : public ViewManagerTransaction {
- public:
- ReorderNodeTransaction(Id node_id,
- Id relative_id,
- OrderDirection direction,
- ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- node_id_(node_id),
- relative_id_(relative_id),
- direction_(direction) {}
- virtual ~ReorderNodeTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- service()->ReorderNode(node_id_,
- relative_id_,
- direction_,
- GetAndAdvanceNextServerChangeId(),
- ActionCompletedCallback());
- }
-
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): recovery?
- }
-
- const Id node_id_;
- const Id relative_id_;
- const OrderDirection direction_;
-
- DISALLOW_COPY_AND_ASSIGN(ReorderNodeTransaction);
-};
-
-class SetActiveViewTransaction : public ViewManagerTransaction {
- public:
- SetActiveViewTransaction(Id node_id,
- Id view_id,
- ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- node_id_(node_id),
- view_id_(view_id) {}
- virtual ~SetActiveViewTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- service()->SetView(node_id_, view_id_, ActionCompletedCallback());
- }
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): recovery?
- }
-
- const Id node_id_;
- const Id view_id_;
-
- DISALLOW_COPY_AND_ASSIGN(SetActiveViewTransaction);
-};
-
-class SetBoundsTransaction : public ViewManagerTransaction {
- public:
- SetBoundsTransaction(Id node_id,
- const gfx::Rect& bounds,
- ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- node_id_(node_id),
- bounds_(bounds) {}
- virtual ~SetBoundsTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- service()->SetNodeBounds(
- node_id_, Rect::From(bounds_), ActionCompletedCallback());
- }
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): recovery?
- }
-
- const Id node_id_;
- const gfx::Rect bounds_;
-
- DISALLOW_COPY_AND_ASSIGN(SetBoundsTransaction);
-};
-
-class SetViewContentsTransaction : public ViewManagerTransaction {
- public:
- SetViewContentsTransaction(Id view_id,
- const SkBitmap& contents,
- ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- view_id_(view_id),
- contents_(contents) {}
- virtual ~SetViewContentsTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- std::vector<unsigned char> data;
- gfx::PNGCodec::EncodeBGRASkBitmap(contents_, false, &data);
-
- void* memory = NULL;
- ScopedSharedBufferHandle duped;
- bool result = CreateMapAndDupSharedBuffer(data.size(),
- &memory,
- &shared_state_handle_,
- &duped);
- if (!result)
- return;
-
- memcpy(memory, &data[0], data.size());
-
- service()->SetViewContents(view_id_, duped.Pass(),
- static_cast<uint32_t>(data.size()),
- ActionCompletedCallback());
- }
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): recovery?
- }
-
- bool CreateMapAndDupSharedBuffer(size_t size,
- void** memory,
- ScopedSharedBufferHandle* handle,
- ScopedSharedBufferHandle* duped) {
- MojoResult result = CreateSharedBuffer(NULL, size, handle);
- if (result != MOJO_RESULT_OK)
- return false;
- DCHECK(handle->is_valid());
-
- result = DuplicateBuffer(handle->get(), NULL, duped);
- if (result != MOJO_RESULT_OK)
- return false;
- DCHECK(duped->is_valid());
-
- result = MapBuffer(
- handle->get(), 0, size, memory, MOJO_MAP_BUFFER_FLAG_NONE);
- if (result != MOJO_RESULT_OK)
- return false;
- DCHECK(*memory);
-
- return true;
- }
-
- const Id view_id_;
- const SkBitmap contents_;
- ScopedSharedBufferHandle shared_state_handle_;
-
- DISALLOW_COPY_AND_ASSIGN(SetViewContentsTransaction);
-};
-
-class EmbedTransaction : public ViewManagerTransaction {
- public:
- EmbedTransaction(const String& url,
- Id node_id,
- ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- url_(url),
- node_id_(node_id) {}
- virtual ~EmbedTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- std::vector<Id> ids;
- ids.push_back(node_id_);
- service()->Embed(url_, Array<Id>::From(ids), ActionCompletedCallback());
- }
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): recovery?
- }
+bool CreateMapAndDupSharedBuffer(size_t size,
+ void** memory,
+ ScopedSharedBufferHandle* handle,
+ ScopedSharedBufferHandle* duped) {
+ MojoResult result = CreateSharedBuffer(NULL, size, handle);
+ if (result != MOJO_RESULT_OK)
+ return false;
+ DCHECK(handle->is_valid());
- const String url_;
- const Id node_id_;
-
- DISALLOW_COPY_AND_ASSIGN(EmbedTransaction);
-};
-
-class SetFocusTransaction : public ViewManagerTransaction {
- public:
- SetFocusTransaction(Id node_id, ViewManagerClientImpl* client)
- : ViewManagerTransaction(client),
- node_id_(node_id) {}
- virtual ~SetFocusTransaction() {}
-
- private:
- // Overridden from ViewManagerTransaction:
- virtual void DoCommit() OVERRIDE {
- service()->SetFocus(node_id_, ActionCompletedCallback());
- }
- virtual void DoActionCompleted(bool success) OVERRIDE {
- // TODO(beng): recovery?
- }
+ result = DuplicateBuffer(handle->get(), NULL, duped);
+ if (result != MOJO_RESULT_OK)
+ return false;
+ DCHECK(duped->is_valid());
- const Id node_id_;
+ result = MapBuffer(
+ handle->get(), 0, size, memory, MOJO_MAP_BUFFER_FLAG_NONE);
+ if (result != MOJO_RESULT_OK)
+ return false;
+ DCHECK(*memory);
- DISALLOW_COPY_AND_ASSIGN(SetFocusTransaction);
-};
+ return true;
+}
-ViewManagerClientImpl::ViewManagerClientImpl(ViewManagerDelegate* delegate)
+ViewManagerClientImpl::ViewManagerClientImpl(
+ ViewManagerDelegate* delegate,
+ ApplicationConnection* app_connection)
: connected_(false),
connection_id_(0),
next_id_(1),
- next_server_change_id_(0),
- delegate_(delegate) {}
+ delegate_(delegate),
+ window_manager_delegate_(NULL) {
+ // TODO(beng): Come up with a better way of establishing a configuration for
+ // what the active window manager is.
+ std::string window_manager_url = "mojo:mojo_window_manager";
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch("window-manager")) {
+ window_manager_url =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ "window-manager");
+ }
+ app_connection->ConnectToService(window_manager_url, &window_manager_);
+ window_manager_.set_client(this);
+}
ViewManagerClientImpl::~ViewManagerClientImpl() {
- while (!nodes_.empty()) {
- IdToNodeMap::iterator it = nodes_.begin();
- if (OwnsNode(it->second->id()))
- it->second->Destroy();
- else
- nodes_.erase(it);
- }
+ std::vector<View*> non_owned;
while (!views_.empty()) {
IdToViewMap::iterator it = views_.begin();
- if (OwnsView(it->second->id()))
+ if (OwnsView(it->second->id())) {
it->second->Destroy();
- else
+ } else {
+ non_owned.push_back(it->second);
views_.erase(it);
+ }
}
-}
-
-Id ViewManagerClientImpl::CreateNode() {
- DCHECK(connected_);
- const Id node_id(MakeTransportId(connection_id_, ++next_id_));
- pending_transactions_.push_back(new CreateNodeTransaction(node_id, this));
- Sync();
- return node_id;
-}
-
-void ViewManagerClientImpl::DestroyNode(Id node_id) {
- DCHECK(connected_);
- pending_transactions_.push_back(new DestroyNodeTransaction(node_id, this));
- Sync();
+ // Delete the non-owned views last. In the typical case these are roots. The
+ // exception is the window manager, which may know aboutother random views
+ // that it doesn't own.
+ // NOTE: we manually delete as we're a friend.
+ for (size_t i = 0; i < non_owned.size(); ++i)
+ delete non_owned[i];
+ delegate_->OnViewManagerDisconnected(this);
}
Id ViewManagerClientImpl::CreateView() {
DCHECK(connected_);
- const Id view_id(MakeTransportId(connection_id_, ++next_id_));
- pending_transactions_.push_back(new CreateViewTransaction(view_id, this));
- Sync();
+ const Id view_id = MakeTransportId(connection_id_, ++next_id_);
+ service_->CreateView(view_id, ActionCompletedCallbackWithErrorCode());
return view_id;
}
void ViewManagerClientImpl::DestroyView(Id view_id) {
DCHECK(connected_);
- pending_transactions_.push_back(new DestroyViewTransaction(view_id, this));
- Sync();
+ service_->DeleteView(view_id, ActionCompletedCallback());
}
-void ViewManagerClientImpl::AddChild(Id child_id,
- Id parent_id) {
+void ViewManagerClientImpl::AddChild(Id child_id, Id parent_id) {
DCHECK(connected_);
- pending_transactions_.push_back(
- new AddChildTransaction(child_id, parent_id, this));
- Sync();
+ service_->AddView(parent_id, child_id, ActionCompletedCallback());
}
void ViewManagerClientImpl::RemoveChild(Id child_id, Id parent_id) {
DCHECK(connected_);
- pending_transactions_.push_back(new RemoveChildTransaction(child_id, this));
- Sync();
+ service_->RemoveViewFromParent(child_id, ActionCompletedCallback());
}
void ViewManagerClientImpl::Reorder(
- Id node_id,
- Id relative_node_id,
+ Id view_id,
+ Id relative_view_id,
OrderDirection direction) {
DCHECK(connected_);
- pending_transactions_.push_back(
- new ReorderNodeTransaction(node_id, relative_node_id, direction, this));
- Sync();
-}
-
-bool ViewManagerClientImpl::OwnsNode(Id id) const {
- return HiWord(id) == connection_id_;
+ service_->ReorderView(view_id, relative_view_id, direction,
+ ActionCompletedCallback());
}
bool ViewManagerClientImpl::OwnsView(Id id) const {
return HiWord(id) == connection_id_;
}
-void ViewManagerClientImpl::SetActiveView(Id node_id, Id view_id) {
+void ViewManagerClientImpl::SetBounds(Id view_id, const gfx::Rect& bounds) {
DCHECK(connected_);
- pending_transactions_.push_back(
- new SetActiveViewTransaction(node_id, view_id, this));
- Sync();
-}
-
-void ViewManagerClientImpl::SetBounds(Id node_id, const gfx::Rect& bounds) {
- DCHECK(connected_);
- pending_transactions_.push_back(
- new SetBoundsTransaction(node_id, bounds, this));
- Sync();
+ service_->SetViewBounds(view_id, Rect::From(bounds),
+ ActionCompletedCallback());
}
void ViewManagerClientImpl::SetViewContents(Id view_id,
const SkBitmap& contents) {
DCHECK(connected_);
- pending_transactions_.push_back(
- new SetViewContentsTransaction(view_id, contents, this));
- Sync();
+ std::vector<unsigned char> data;
+ gfx::PNGCodec::EncodeBGRASkBitmap(contents, false, &data);
+
+ void* memory = NULL;
+ ScopedSharedBufferHandle duped, shared_state_handle;
+ bool result = CreateMapAndDupSharedBuffer(data.size(),
+ &memory,
+ &shared_state_handle,
+ &duped);
+ if (!result)
+ return;
+
+ memcpy(memory, &data[0], data.size());
+
+ service_->SetViewContents(view_id, duped.Pass(),
+ static_cast<uint32_t>(data.size()),
+ ActionCompletedCallback());
}
-void ViewManagerClientImpl::SetFocus(Id node_id) {
- DCHECK(connected_);
- pending_transactions_.push_back(new SetFocusTransaction(node_id, this));
- Sync();
+void ViewManagerClientImpl::SetFocus(Id view_id) {
+ window_manager_->FocusWindow(view_id, ActionCompletedCallback());
}
-void ViewManagerClientImpl::Embed(const String& url, Id node_id) {
+void ViewManagerClientImpl::SetVisible(Id view_id, bool visible) {
DCHECK(connected_);
- pending_transactions_.push_back(new EmbedTransaction(url, node_id, this));
- Sync();
+ service_->SetViewVisibility(view_id, visible, ActionCompletedCallback());
}
-void ViewManagerClientImpl::AddNode(Node* node) {
- DCHECK(nodes_.find(node->id()) == nodes_.end());
- nodes_[node->id()] = node;
+void ViewManagerClientImpl::Embed(const String& url, Id view_id) {
+ ServiceProviderPtr sp;
+ BindToProxy(new ServiceProviderImpl, &sp);
+ Embed(url, view_id, sp.Pass());
}
-void ViewManagerClientImpl::RemoveNode(Id node_id) {
- IdToNodeMap::iterator it = nodes_.find(node_id);
- if (it != nodes_.end())
- nodes_.erase(it);
+void ViewManagerClientImpl::Embed(
+ const String& url,
+ Id view_id,
+ ServiceProviderPtr service_provider) {
+ DCHECK(connected_);
+ service_->Embed(url, view_id, service_provider.Pass(),
+ ActionCompletedCallback());
}
void ViewManagerClientImpl::AddView(View* view) {
////////////////////////////////////////////////////////////////////////////////
// ViewManagerClientImpl, ViewManager implementation:
+void ViewManagerClientImpl::SetWindowManagerDelegate(
+ WindowManagerDelegate* window_manager_delegate) {
+ CHECK(NULL != GetViewById(1));
+ CHECK(!window_manager_delegate_);
+ window_manager_delegate_ = window_manager_delegate;
+}
+
+void ViewManagerClientImpl::DispatchEvent(View* target, EventPtr event) {
+ CHECK(window_manager_delegate_);
+ service_->DispatchOnViewInputEvent(target->id(), event.Pass());
+}
+
const std::string& ViewManagerClientImpl::GetEmbedderURL() const {
return creator_url_;
}
-const std::vector<Node*>& ViewManagerClientImpl::GetRoots() const {
+const std::vector<View*>& ViewManagerClientImpl::GetRoots() const {
return roots_;
}
-Node* ViewManagerClientImpl::GetNodeById(Id id) {
- IdToNodeMap::const_iterator it = nodes_.find(id);
- return it != nodes_.end() ? it->second : NULL;
-}
-
View* ViewManagerClientImpl::GetViewById(Id id) {
IdToViewMap::const_iterator it = views_.find(id);
return it != views_.end() ? it->second : NULL;
////////////////////////////////////////////////////////////////////////////////
// ViewManagerClientImpl, ViewManagerClient implementation:
-void ViewManagerClientImpl::OnViewManagerConnectionEstablished(
+void ViewManagerClientImpl::OnEmbed(
ConnectionSpecificId connection_id,
const String& creator_url,
- Id next_server_change_id,
- Array<NodeDataPtr> nodes) {
- connected_ = true;
- connection_id_ = connection_id;
- creator_url_ = TypeConverter<String, std::string>::ConvertFrom(creator_url);
- next_server_change_id_ = next_server_change_id;
-
- DCHECK(pending_transactions_.empty());
- AddRoot(BuildNodeTree(this, nodes));
-}
+ ViewDataPtr root_data,
+ InterfaceRequest<ServiceProvider> service_provider) {
+ if (!connected_) {
+ connected_ = true;
+ connection_id_ = connection_id;
+ creator_url_ = TypeConverter<String, std::string>::ConvertFrom(creator_url);
+ } else {
+ DCHECK_EQ(connection_id_, connection_id);
+ DCHECK_EQ(creator_url_, creator_url);
+ }
-void ViewManagerClientImpl::OnRootsAdded(Array<NodeDataPtr> nodes) {
- AddRoot(BuildNodeTree(this, nodes));
-}
+ // A new root must not already exist as a root or be contained by an existing
+ // hierarchy visible to this view manager.
+ View* root = AddViewToViewManager(this, NULL, root_data->view_id,
+ root_data->bounds.To<gfx::Rect>());
+ roots_.push_back(root);
+ root->AddObserver(new RootObserver(root));
-void ViewManagerClientImpl::OnServerChangeIdAdvanced(
- Id next_server_change_id) {
- next_server_change_id_ = next_server_change_id;
+ // BindToRequest() binds the lifetime of |exported_services| to the pipe.
+ ServiceProviderImpl* exported_services = new ServiceProviderImpl;
+ BindToRequest(exported_services, &service_provider);
+ scoped_ptr<ServiceProvider> remote(
+ exported_services->CreateRemoteServiceProvider());
+ delegate_->OnEmbed(this, root, exported_services, remote.Pass());
}
-void ViewManagerClientImpl::OnNodeBoundsChanged(Id node_id,
+void ViewManagerClientImpl::OnViewBoundsChanged(Id view_id,
RectPtr old_bounds,
RectPtr new_bounds) {
- Node* node = GetNodeById(node_id);
- NodePrivate(node).LocalSetBounds(old_bounds.To<gfx::Rect>(),
+ View* view = GetViewById(view_id);
+ ViewPrivate(view).LocalSetBounds(old_bounds.To<gfx::Rect>(),
new_bounds.To<gfx::Rect>());
}
-void ViewManagerClientImpl::OnNodeHierarchyChanged(
- Id node_id,
+void ViewManagerClientImpl::OnViewHierarchyChanged(
+ Id view_id,
Id new_parent_id,
Id old_parent_id,
- Id server_change_id,
- mojo::Array<NodeDataPtr> nodes) {
- next_server_change_id_ = server_change_id + 1;
+ mojo::Array<ViewDataPtr> views) {
+ View* initial_parent = views.size() ?
+ GetViewById(views[0]->parent_id) : NULL;
- BuildNodeTree(this, nodes);
+ BuildViewTree(this, views, initial_parent);
- Node* new_parent = GetNodeById(new_parent_id);
- Node* old_parent = GetNodeById(old_parent_id);
- Node* node = GetNodeById(node_id);
+ View* new_parent = GetViewById(new_parent_id);
+ View* old_parent = GetViewById(old_parent_id);
+ View* view = GetViewById(view_id);
if (new_parent)
- NodePrivate(new_parent).LocalAddChild(node);
+ ViewPrivate(new_parent).LocalAddChild(view);
else
- NodePrivate(old_parent).LocalRemoveChild(node);
-}
-
-void ViewManagerClientImpl::OnNodeReordered(Id node_id,
- Id relative_node_id,
- OrderDirection direction,
- Id server_change_id) {
- next_server_change_id_ = server_change_id + 1;
-
- Node* node = GetNodeById(node_id);
- Node* relative_node = GetNodeById(relative_node_id);
- if (node && relative_node) {
- NodePrivate(node).LocalReorder(relative_node, direction);
- }
-}
-
-void ViewManagerClientImpl::OnNodeDeleted(Id node_id, Id server_change_id) {
- next_server_change_id_ = server_change_id + 1;
-
- Node* node = GetNodeById(node_id);
- if (node)
- NodePrivate(node).LocalDestroy();
+ ViewPrivate(old_parent).LocalRemoveChild(view);
}
-void ViewManagerClientImpl::OnNodeViewReplaced(Id node_id,
- Id new_view_id,
- Id old_view_id) {
- Node* node = GetNodeById(node_id);
- View* new_view = GetViewById(new_view_id);
- if (!new_view && new_view_id != 0) {
- // This client wasn't aware of this View until now.
- new_view = ViewPrivate::LocalCreate();
- ViewPrivate private_view(new_view);
- private_view.set_view_manager(this);
- private_view.set_id(new_view_id);
- private_view.set_node(node);
- AddView(new_view);
- }
- View* old_view = GetViewById(old_view_id);
- DCHECK_EQ(old_view, node->active_view());
- NodePrivate(node).LocalSetActiveView(new_view);
+void ViewManagerClientImpl::OnViewReordered(Id view_id,
+ Id relative_view_id,
+ OrderDirection direction) {
+ View* view = GetViewById(view_id);
+ View* relative_view = GetViewById(relative_view_id);
+ if (view && relative_view)
+ ViewPrivate(view).LocalReorder(relative_view, direction);
}
void ViewManagerClientImpl::OnViewDeleted(Id view_id) {
ack_callback.Run();
}
-void ViewManagerClientImpl::DispatchOnViewInputEvent(Id view_id,
- EventPtr event) {
- // For now blindly bounce the message back to the server. Doing this means the
- // event is sent to the correct target (|view_id|).
- // Note: This function is only invoked on the window manager.
- service_->DispatchOnViewInputEvent(view_id, event.Pass());
+void ViewManagerClientImpl::Embed(
+ const String& url,
+ InterfaceRequest<ServiceProvider> service_provider) {
+ window_manager_delegate_->Embed(url, service_provider.Pass());
+}
+
+void ViewManagerClientImpl::DispatchOnViewInputEvent(EventPtr event) {
+ if (window_manager_delegate_)
+ window_manager_delegate_->DispatchEvent(event.Pass());
}
////////////////////////////////////////////////////////////////////////////////
-// ViewManagerClientImpl, private:
+// ViewManagerClientImpl, WindowManagerClient implementation:
-void ViewManagerClientImpl::Sync() {
- // The service connection may not be set up yet. OnConnectionEstablished()
- // will schedule another sync when it is.
- if (!connected_)
- return;
+void ViewManagerClientImpl::OnWindowManagerReady() {}
- Transactions::const_iterator it = pending_transactions_.begin();
- for (; it != pending_transactions_.end(); ++it) {
- if (!(*it)->committed())
- (*it)->Commit();
+void ViewManagerClientImpl::OnCaptureChanged(Id old_capture_view_id,
+ Id new_capture_view_id) {}
+
+void ViewManagerClientImpl::OnFocusChanged(Id old_focused_view_id,
+ Id new_focused_view_id) {
+ View* focused = GetViewById(new_focused_view_id);
+ View* blurred = GetViewById(old_focused_view_id);
+ if (blurred) {
+ FOR_EACH_OBSERVER(ViewObserver,
+ *ViewPrivate(blurred).observers(),
+ OnViewFocusChanged(focused, blurred));
+ }
+ if (focused) {
+ FOR_EACH_OBSERVER(ViewObserver,
+ *ViewPrivate(focused).observers(),
+ OnViewFocusChanged(focused, blurred));
}
}
-void ViewManagerClientImpl::RemoveFromPendingQueue(
- ViewManagerTransaction* transaction) {
- DCHECK_EQ(transaction, pending_transactions_.front());
- pending_transactions_.erase(pending_transactions_.begin());
- if (pending_transactions_.empty() && !changes_acked_callback_.is_null())
- changes_acked_callback_.Run();
-}
+void ViewManagerClientImpl::OnActiveWindowChanged(Id old_focused_window,
+ Id new_focused_window) {}
-void ViewManagerClientImpl::AddRoot(Node* root) {
- // A new root must not already exist as a root or be contained by an existing
- // hierarchy visible to this view manager.
- std::vector<Node*>::const_iterator it = roots_.begin();
- for (; it != roots_.end(); ++it) {
- if (*it == root || (*it)->Contains(root))
- return;
- }
- roots_.push_back(root);
- root->AddObserver(new RootObserver(root));
- delegate_->OnRootAdded(this, root);
-}
+////////////////////////////////////////////////////////////////////////////////
+// ViewManagerClientImpl, private:
-void ViewManagerClientImpl::RemoveRoot(Node* root) {
- std::vector<Node*>::iterator it =
+void ViewManagerClientImpl::RemoveRoot(View* root) {
+ std::vector<View*>::iterator it =
std::find(roots_.begin(), roots_.end(), root);
if (it != roots_.end())
roots_.erase(it);
}
-////////////////////////////////////////////////////////////////////////////////
-// ViewManager, public:
+void ViewManagerClientImpl::OnActionCompleted(bool success) {
+ if (!change_acked_callback_.is_null())
+ change_acked_callback_.Run();
+}
+
+void ViewManagerClientImpl::OnActionCompletedWithErrorCode(ErrorCode code) {
+ OnActionCompleted(code == ERROR_CODE_NONE);
+}
+
+base::Callback<void(bool)> ViewManagerClientImpl::ActionCompletedCallback() {
+ return base::Bind(&ViewManagerClientImpl::OnActionCompleted,
+ base::Unretained(this));
+}
-// static
-void ViewManager::Create(Application* application,
- ViewManagerDelegate* delegate) {
- application->AddService<ViewManagerClientImpl>(delegate);
+base::Callback<void(ErrorCode)>
+ ViewManagerClientImpl::ActionCompletedCallbackWithErrorCode() {
+ return base::Bind(&ViewManagerClientImpl::OnActionCompletedWithErrorCode,
+ base::Unretained(this));
}
-} // namespace view_manager
} // namespace mojo