Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "services/ui/view_manager/view_associate_table.h" | 5 #include "services/ui/view_manager/view_associate_table.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 11 #include "mojo/public/cpp/application/connect.h" | 11 #include "mojo/public/cpp/application/connect.h" |
| 12 #include "mojo/services/ui/views/cpp/formatting.h" | 12 #include "mojo/services/ui/views/cpp/formatting.h" |
| 13 | 13 |
| 14 namespace view_manager { | 14 namespace view_manager { |
| 15 | 15 |
| 16 template <typename T> | 16 template <typename T> |
| 17 static bool Contains(const mojo::Array<T>& array, const T& value) { | 17 static bool Contains(const mojo::Array<T>& array, const T& value) { |
| 18 return std::find(array.storage().cbegin(), array.storage().cend(), value) != | 18 return std::find(array.storage().cbegin(), array.storage().cend(), value) != |
| 19 array.storage().cend(); | 19 array.storage().cend(); |
| 20 } | 20 } |
| 21 | 21 |
| 22 ViewAssociateTable::ViewAssociateTable() {} | 22 ViewAssociateTable::ViewAssociateTable() {} |
| 23 | 23 |
| 24 ViewAssociateTable::~ViewAssociateTable() {} | 24 ViewAssociateTable::~ViewAssociateTable() {} |
| 25 | 25 |
| 26 void ViewAssociateTable::ConnectAssociates( | 26 void ViewAssociateTable::RegisterViewAssociate( |
| 27 mojo::ApplicationImpl* app_impl, | |
| 28 mojo::ui::ViewInspector* inspector, | 27 mojo::ui::ViewInspector* inspector, |
| 29 const std::vector<std::string>& urls, | 28 mojo::ui::ViewAssociatePtr associate, |
| 30 const AssociateConnectionErrorCallback& connection_error_callback) { | 29 mojo::InterfaceRequest<mojo::ui::ViewAssociateOwner> |
| 31 DCHECK(app_impl); | 30 view_associate_owner_request, |
| 31 const mojo::String& label) { | |
| 32 DCHECK(inspector); | 32 DCHECK(inspector); |
| 33 DCHECK(associate.is_bound()); | |
| 33 | 34 |
| 34 for (auto& url : urls) { | 35 associates_.emplace_back( |
| 35 DVLOG(1) << "Connecting to view associate: url=" << url; | 36 new AssociateData(label, associate.Pass(), this, inspector)); |
| 36 associates_.emplace_back(new AssociateData(url, inspector)); | 37 AssociateData* data = associates_.back().get(); |
| 37 AssociateData* data = associates_.back().get(); | |
| 38 | 38 |
| 39 mojo::ConnectToService(app_impl->shell(), url, GetProxy(&data->associate)); | 39 data->BindOwner(view_associate_owner_request.Pass()); |
| 40 data->associate.set_connection_error_handler( | |
| 41 base::Bind(connection_error_callback, url)); | |
| 42 | 40 |
| 43 mojo::ui::ViewInspectorPtr inspector; | 41 // Set it to use our error handler. |
| 44 data->inspector_binding.Bind(GetProxy(&inspector)); | 42 data->associate.set_connection_error_handler( |
| 45 data->associate->Connect( | 43 base::Bind(&ViewAssociateTable::OnAssociateConnectionError, |
| 46 inspector.Pass(), | 44 base::Unretained(this), data)); |
| 47 base::Bind(&ViewAssociateTable::OnConnected, base::Unretained(this), | |
| 48 pending_connection_count_)); | |
| 49 | 45 |
| 50 pending_connection_count_++; | 46 data->associate_owner.set_connection_error_handler( |
| 51 } | 47 base::Bind(&ViewAssociateTable::OnAssociateOwnerConnectionError, |
| 48 base::Unretained(this), data)); | |
| 49 | |
| 50 // Connect the associate to our view inspector. | |
| 51 mojo::ui::ViewInspectorPtr inspector_ptr; | |
| 52 data->inspector_binding.Bind(GetProxy(&inspector_ptr)); | |
| 53 data->associate->Connect( | |
| 54 inspector_ptr.Pass(), | |
| 55 base::Bind(&ViewAssociateTable::OnConnected, base::Unretained(this), | |
| 56 pending_connection_count_)); | |
| 57 | |
| 58 // Wait for the associate to connect to our view inspector. | |
| 59 pending_connection_count_++; | |
| 60 } | |
| 61 | |
| 62 void ViewAssociateTable::FinishedRegisteringViewAssociates() { | |
| 63 waiting_to_register_associates_ = false; | |
|
jeffbrown
2016/05/18 18:07:16
This needs to kick deferred work in the same way t
mikejurka
2016/05/18 19:09:10
Done.
| |
| 52 } | 64 } |
| 53 | 65 |
| 54 void ViewAssociateTable::ConnectToViewService( | 66 void ViewAssociateTable::ConnectToViewService( |
| 55 mojo::ui::ViewTokenPtr view_token, | 67 mojo::ui::ViewTokenPtr view_token, |
| 56 const mojo::String& service_name, | 68 const mojo::String& service_name, |
| 57 mojo::ScopedMessagePipeHandle client_handle) { | 69 mojo::ScopedMessagePipeHandle client_handle) { |
| 58 if (pending_connection_count_) { | 70 if (waiting_to_register_associates_ || pending_connection_count_) { |
| 59 deferred_work_.push_back( | 71 deferred_work_.push_back( |
| 60 base::Bind(&ViewAssociateTable::ConnectToViewService, | 72 base::Bind(&ViewAssociateTable::ConnectToViewService, |
| 61 base::Unretained(this), base::Passed(view_token.Pass()), | 73 base::Unretained(this), base::Passed(view_token.Pass()), |
| 62 service_name, base::Passed(client_handle.Pass()))); | 74 service_name, base::Passed(client_handle.Pass()))); |
| 63 return; | 75 return; |
| 64 } | 76 } |
| 65 | 77 |
| 66 for (auto& data : associates_) { | 78 for (auto& data : associates_) { |
| 67 DCHECK(data->info); | 79 DCHECK(data->info); |
| 68 if (Contains(data->info->view_service_names, service_name)) { | 80 if (Contains(data->info->view_service_names, service_name)) { |
| 69 DVLOG(2) << "Connecting to view service: view_token=" << view_token | 81 DVLOG(2) << "Connecting to view service: view_token=" << view_token |
| 70 << ", service_name=" << service_name | 82 << ", service_name=" << service_name |
| 71 << ", associate_url=" << data->url; | 83 << ", associate_label=" << data->label; |
| 72 DCHECK(data->associate); | 84 DCHECK(data->associate); |
| 73 data->associate->ConnectToViewService(view_token.Pass(), service_name, | 85 data->associate->ConnectToViewService(view_token.Pass(), service_name, |
| 74 client_handle.Pass()); | 86 client_handle.Pass()); |
| 75 return; | 87 return; |
| 76 } | 88 } |
| 77 } | 89 } |
| 78 | 90 |
| 79 DVLOG(2) << "Requested view service not available: view_token=" << view_token | 91 DVLOG(2) << "Requested view service not available: view_token=" << view_token |
| 80 << ", service_name=" << service_name; | 92 << ", service_name=" << service_name; |
| 81 // Allow pipe to be closed as an indication of failure. | 93 // Allow pipe to be closed as an indication of failure. |
| 82 } | 94 } |
| 83 | 95 |
| 96 void ViewAssociateTable::OnAssociateConnectionError( | |
| 97 AssociateData* associate_data) { | |
| 98 // Remove associate from our list. | |
| 99 for (auto it = associates_.begin(); it != associates_.end(); it++) { | |
| 100 AssociateData* data = it->get(); | |
| 101 if (associate_data == data) { | |
| 102 DVLOG(2) << "ViewAssociate disconnected, removing from table" | |
| 103 << ", associate_label=" << data->label; | |
| 104 associates_.erase(it); | |
| 105 break; | |
| 106 } | |
| 107 } | |
|
jeffbrown
2016/05/18 18:07:16
nit: if we fail to find the associate then there's
mikejurka
2016/05/18 19:09:10
Done.
| |
| 108 } | |
| 109 | |
| 110 void ViewAssociateTable::OnAssociateOwnerConnectionError( | |
| 111 AssociateData* associate_data) { | |
| 112 // Remove associate from our list. | |
| 113 for (auto it = associates_.begin(); it != associates_.end(); it++) { | |
| 114 AssociateData* data = it->get(); | |
| 115 if (associate_data == data) { | |
| 116 DVLOG(2) << "ViewAssociateOwner disconnected, removing from table" | |
| 117 << ", associate_label=" << data->label; | |
| 118 associates_.erase(it); | |
| 119 break; | |
| 120 } | |
| 121 } | |
| 122 } | |
| 123 | |
| 84 void ViewAssociateTable::ConnectToViewTreeService( | 124 void ViewAssociateTable::ConnectToViewTreeService( |
| 85 mojo::ui::ViewTreeTokenPtr view_tree_token, | 125 mojo::ui::ViewTreeTokenPtr view_tree_token, |
| 86 const mojo::String& service_name, | 126 const mojo::String& service_name, |
| 87 mojo::ScopedMessagePipeHandle client_handle) { | 127 mojo::ScopedMessagePipeHandle client_handle) { |
| 88 if (pending_connection_count_) { | 128 if (waiting_to_register_associates_ || pending_connection_count_) { |
| 89 deferred_work_.push_back( | 129 deferred_work_.push_back( |
| 90 base::Bind(&ViewAssociateTable::ConnectToViewTreeService, | 130 base::Bind(&ViewAssociateTable::ConnectToViewTreeService, |
| 91 base::Unretained(this), base::Passed(view_tree_token.Pass()), | 131 base::Unretained(this), base::Passed(view_tree_token.Pass()), |
| 92 service_name, base::Passed(client_handle.Pass()))); | 132 service_name, base::Passed(client_handle.Pass()))); |
| 93 return; | 133 return; |
| 94 } | 134 } |
| 95 | 135 |
| 96 for (auto& data : associates_) { | 136 for (auto& data : associates_) { |
| 97 DCHECK(data->info); | 137 DCHECK(data->info); |
| 98 if (Contains(data->info->view_tree_service_names, service_name)) { | 138 if (Contains(data->info->view_tree_service_names, service_name)) { |
| 99 DVLOG(2) << "Connecting to view tree service: view_tree_token=" | 139 DVLOG(2) << "Connecting to view tree service: view_tree_token=" |
| 100 << view_tree_token << ", service_name=" << service_name | 140 << view_tree_token << ", service_name=" << service_name |
| 101 << ", associate_url=" << data->url; | 141 << ", associate_label=" << data->label; |
| 102 DCHECK(data->associate); | 142 DCHECK(data->associate); |
| 103 data->associate->ConnectToViewTreeService( | 143 data->associate->ConnectToViewTreeService( |
| 104 view_tree_token.Pass(), service_name, client_handle.Pass()); | 144 view_tree_token.Pass(), service_name, client_handle.Pass()); |
| 105 return; | 145 return; |
| 106 } | 146 } |
| 107 } | 147 } |
| 108 | 148 |
| 109 DVLOG(2) << "Requested view tree service not available: view_tree_token=" | 149 DVLOG(2) << "Requested view tree service not available: view_tree_token=" |
| 110 << view_tree_token << ", service_name=" << service_name; | 150 << view_tree_token << ", service_name=" << service_name; |
| 111 // Allow pipe to be closed as an indication of failure. | 151 // Allow pipe to be closed as an indication of failure. |
| 112 } | 152 } |
| 113 | 153 |
| 114 void ViewAssociateTable::OnConnected(uint32_t index, | 154 void ViewAssociateTable::OnConnected(uint32_t index, |
| 115 mojo::ui::ViewAssociateInfoPtr info) { | 155 mojo::ui::ViewAssociateInfoPtr info) { |
| 116 DCHECK(info); | 156 DCHECK(info); |
| 117 DCHECK(pending_connection_count_); | 157 DCHECK(pending_connection_count_); |
| 118 DCHECK(!associates_[index]->info); | 158 DCHECK(!associates_[index]->info); |
| 119 | 159 |
| 120 DVLOG(1) << "Connected to view associate: url=" << associates_[index]->url | 160 DVLOG(1) << "Connected to view associate: label=" << associates_[index]->label |
| 121 << ", info=" << info; | 161 << ", info=" << info; |
| 122 associates_[index]->info = info.Pass(); | 162 associates_[index]->info = info.Pass(); |
| 123 | 163 |
| 124 pending_connection_count_--; | 164 pending_connection_count_--; |
| 125 if (!pending_connection_count_) | 165 if (!waiting_to_register_associates_ && !pending_connection_count_) |
|
jeffbrown
2016/05/18 18:07:16
Consider renaming CompleteDeferredWork to Complete
mikejurka
2016/05/18 19:09:10
Done.
| |
| 126 CompleteDeferredWork(); | 166 CompleteDeferredWork(); |
| 127 } | 167 } |
| 128 | 168 |
| 129 void ViewAssociateTable::CompleteDeferredWork() { | 169 void ViewAssociateTable::CompleteDeferredWork() { |
| 130 DCHECK(!pending_connection_count_); | 170 DCHECK(!pending_connection_count_); |
| 171 DCHECK(!waiting_to_register_associates_); | |
| 131 | 172 |
| 132 for (auto& work : deferred_work_) | 173 for (auto& work : deferred_work_) |
| 133 work.Run(); | 174 work.Run(); |
| 134 deferred_work_.clear(); | 175 deferred_work_.clear(); |
| 135 } | 176 } |
| 136 | 177 |
| 178 size_t ViewAssociateTable::associate_count() { | |
| 179 return associates_.size(); | |
| 180 } | |
| 181 | |
| 137 ViewAssociateTable::AssociateData::AssociateData( | 182 ViewAssociateTable::AssociateData::AssociateData( |
| 138 const std::string& url, | 183 const std::string& label, |
| 184 mojo::ui::ViewAssociatePtr associate, | |
| 185 mojo::ui::ViewAssociateOwner* associate_owner_impl, | |
| 139 mojo::ui::ViewInspector* inspector) | 186 mojo::ui::ViewInspector* inspector) |
| 140 : url(url), inspector_binding(inspector) {} | 187 : label(label), |
| 188 associate(associate.Pass()), | |
| 189 associate_owner(associate_owner_impl), | |
| 190 inspector_binding(inspector) {} | |
| 141 | 191 |
| 142 ViewAssociateTable::AssociateData::~AssociateData() {} | 192 ViewAssociateTable::AssociateData::~AssociateData() {} |
| 143 | 193 |
| 194 void ViewAssociateTable::AssociateData::BindOwner( | |
| 195 mojo::InterfaceRequest<mojo::ui::ViewAssociateOwner> | |
| 196 view_associate_owner_request) { | |
| 197 associate_owner.Bind(view_associate_owner_request.Pass()); | |
| 198 } | |
| 199 | |
| 144 } // namespace view_manager | 200 } // namespace view_manager |
| OLD | NEW |