Index: services/ui/view_manager/view_associate_table.cc |
diff --git a/services/ui/view_manager/view_associate_table.cc b/services/ui/view_manager/view_associate_table.cc |
index 2088696f1a0193f8360a95b8d90c75dacd150a61..4acb4715b824652b43ca8abe458ebc056e7d897a 100644 |
--- a/services/ui/view_manager/view_associate_table.cc |
+++ b/services/ui/view_manager/view_associate_table.cc |
@@ -23,39 +23,56 @@ ViewAssociateTable::ViewAssociateTable() {} |
ViewAssociateTable::~ViewAssociateTable() {} |
-void ViewAssociateTable::ConnectAssociates( |
- mojo::ApplicationImpl* app_impl, |
+void ViewAssociateTable::RegisterViewAssociate( |
mojo::ui::ViewInspector* inspector, |
- const std::vector<std::string>& urls, |
- const AssociateConnectionErrorCallback& connection_error_callback) { |
- DCHECK(app_impl); |
+ mojo::ui::ViewAssociatePtr associate, |
+ mojo::InterfaceRequest<mojo::ui::ViewAssociateOwner> |
+ view_associate_owner_request, |
+ const mojo::String& label) { |
DCHECK(inspector); |
+ DCHECK(associate.is_bound()); |
+ |
+ std::string sanitized_label = |
+ label.get().substr(0, mojo::ui::kLabelMaxLength); |
+ associates_.emplace_back( |
+ new AssociateData(sanitized_label, associate.Pass(), this, inspector)); |
+ AssociateData* data = associates_.back().get(); |
+ |
+ data->BindOwner(view_associate_owner_request.Pass()); |
+ |
+ // Set it to use our error handler. |
+ data->associate.set_connection_error_handler( |
+ base::Bind(&ViewAssociateTable::OnAssociateConnectionError, |
+ base::Unretained(this), data)); |
+ |
+ data->associate_owner.set_connection_error_handler( |
+ base::Bind(&ViewAssociateTable::OnAssociateOwnerConnectionError, |
+ base::Unretained(this), data)); |
+ |
+ // Connect the associate to our view inspector. |
+ mojo::ui::ViewInspectorPtr inspector_ptr; |
+ data->inspector_binding.Bind(GetProxy(&inspector_ptr)); |
+ data->associate->Connect( |
+ inspector_ptr.Pass(), |
+ base::Bind(&ViewAssociateTable::OnConnected, base::Unretained(this), |
+ pending_connection_count_)); |
+ |
+ // Wait for the associate to connect to our view inspector. |
+ pending_connection_count_++; |
+} |
- for (auto& url : urls) { |
- DVLOG(1) << "Connecting to view associate: url=" << url; |
- associates_.emplace_back(new AssociateData(url, inspector)); |
- AssociateData* data = associates_.back().get(); |
- |
- mojo::ConnectToService(app_impl->shell(), url, GetProxy(&data->associate)); |
- data->associate.set_connection_error_handler( |
- base::Bind(connection_error_callback, url)); |
- |
- mojo::ui::ViewInspectorPtr inspector; |
- data->inspector_binding.Bind(GetProxy(&inspector)); |
- data->associate->Connect( |
- inspector.Pass(), |
- base::Bind(&ViewAssociateTable::OnConnected, base::Unretained(this), |
- pending_connection_count_)); |
+void ViewAssociateTable::FinishedRegisteringViewAssociates() { |
+ waiting_to_register_associates_ = false; |
- pending_connection_count_++; |
- } |
+ // If no more pending connections, kick off deferred work |
+ CompleteDeferredWorkIfReady(); |
} |
void ViewAssociateTable::ConnectToViewService( |
mojo::ui::ViewTokenPtr view_token, |
const mojo::String& service_name, |
mojo::ScopedMessagePipeHandle client_handle) { |
- if (pending_connection_count_) { |
+ if (waiting_to_register_associates_ || pending_connection_count_) { |
deferred_work_.push_back( |
base::Bind(&ViewAssociateTable::ConnectToViewService, |
base::Unretained(this), base::Passed(view_token.Pass()), |
@@ -68,7 +85,7 @@ void ViewAssociateTable::ConnectToViewService( |
if (Contains(data->info->view_service_names, service_name)) { |
DVLOG(2) << "Connecting to view service: view_token=" << view_token |
<< ", service_name=" << service_name |
- << ", associate_url=" << data->url; |
+ << ", associate_label=" << data->label; |
DCHECK(data->associate); |
data->associate->ConnectToViewService(view_token.Pass(), service_name, |
client_handle.Pass()); |
@@ -81,11 +98,42 @@ void ViewAssociateTable::ConnectToViewService( |
// Allow pipe to be closed as an indication of failure. |
} |
+bool ViewAssociateTable::RemoveAssociateData(AssociateData* associate_data, |
+ std::string& label) { |
+ for (auto it = associates_.begin(); it != associates_.end(); it++) { |
+ AssociateData* data = it->get(); |
+ if (associate_data == data) { |
+ label = data->label; |
+ associates_.erase(it); |
+ return true; |
+ } |
+ } |
+ return false; |
+} |
+ |
+void ViewAssociateTable::OnAssociateConnectionError( |
+ AssociateData* associate_data) { |
+ std::string label; |
+ bool removed = RemoveAssociateData(associate_data, label); |
+ DCHECK(removed); |
+ DVLOG(2) << "ViewAssociate disconnected, removing from table" |
+ << ", associate_label=" << label; |
+} |
+ |
+void ViewAssociateTable::OnAssociateOwnerConnectionError( |
+ AssociateData* associate_data) { |
+ std::string label; |
+ bool removed = RemoveAssociateData(associate_data, label); |
+ DCHECK(removed); |
+ DVLOG(2) << "ViewAssociateOwner disconnected, removing from table" |
+ << ", associate_label=" << label; |
+} |
+ |
void ViewAssociateTable::ConnectToViewTreeService( |
mojo::ui::ViewTreeTokenPtr view_tree_token, |
const mojo::String& service_name, |
mojo::ScopedMessagePipeHandle client_handle) { |
- if (pending_connection_count_) { |
+ if (waiting_to_register_associates_ || pending_connection_count_) { |
deferred_work_.push_back( |
base::Bind(&ViewAssociateTable::ConnectToViewTreeService, |
base::Unretained(this), base::Passed(view_tree_token.Pass()), |
@@ -98,7 +146,7 @@ void ViewAssociateTable::ConnectToViewTreeService( |
if (Contains(data->info->view_tree_service_names, service_name)) { |
DVLOG(2) << "Connecting to view tree service: view_tree_token=" |
<< view_tree_token << ", service_name=" << service_name |
- << ", associate_url=" << data->url; |
+ << ", associate_label=" << data->label; |
DCHECK(data->associate); |
data->associate->ConnectToViewTreeService( |
view_tree_token.Pass(), service_name, client_handle.Pass()); |
@@ -117,28 +165,44 @@ void ViewAssociateTable::OnConnected(uint32_t index, |
DCHECK(pending_connection_count_); |
DCHECK(!associates_[index]->info); |
- DVLOG(1) << "Connected to view associate: url=" << associates_[index]->url |
+ DVLOG(1) << "Connected to view associate: label=" << associates_[index]->label |
<< ", info=" << info; |
associates_[index]->info = info.Pass(); |
pending_connection_count_--; |
- if (!pending_connection_count_) |
- CompleteDeferredWork(); |
+ CompleteDeferredWorkIfReady(); |
} |
-void ViewAssociateTable::CompleteDeferredWork() { |
- DCHECK(!pending_connection_count_); |
+void ViewAssociateTable::CompleteDeferredWorkIfReady() { |
+ // We check to see if all the ViewAssociates have been registered, and if |
+ // they connected to us. Otherwise, we keep the work deferred. |
+ if (!waiting_to_register_associates_ && !pending_connection_count_) { |
+ for (auto& work : deferred_work_) |
+ work.Run(); |
+ deferred_work_.clear(); |
+ } |
+} |
- for (auto& work : deferred_work_) |
- work.Run(); |
- deferred_work_.clear(); |
+size_t ViewAssociateTable::associate_count() { |
+ return associates_.size(); |
} |
ViewAssociateTable::AssociateData::AssociateData( |
- const std::string& url, |
+ const std::string& label, |
+ mojo::ui::ViewAssociatePtr associate, |
+ mojo::ui::ViewAssociateOwner* associate_owner_impl, |
mojo::ui::ViewInspector* inspector) |
- : url(url), inspector_binding(inspector) {} |
+ : label(label), |
+ associate(associate.Pass()), |
+ associate_owner(associate_owner_impl), |
+ inspector_binding(inspector) {} |
ViewAssociateTable::AssociateData::~AssociateData() {} |
+void ViewAssociateTable::AssociateData::BindOwner( |
+ mojo::InterfaceRequest<mojo::ui::ViewAssociateOwner> |
+ view_associate_owner_request) { |
+ associate_owner.Bind(view_associate_owner_request.Pass()); |
+} |
+ |
} // namespace view_manager |