| // Copyright 2016 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "libwebserv/binder_server.h" |
| |
| #include <utils/String16.h> |
| |
| #include "libwebserv/binder_constants.h" |
| |
| #include <string> |
| #include <vector> |
| |
| using android::String16; |
| using android::sp; |
| using android::IBinder; |
| using std::string; |
| using std::vector; |
| |
| namespace libwebserv { |
| |
| BinderServer::BinderServer(brillo::MessageLoop* message_loop, |
| const base::Closure& on_server_online, |
| const base::Closure& on_server_offline, |
| android::BinderWrapper* binder_wrapper) |
| : message_loop_{message_loop}, |
| on_server_online_{on_server_online}, |
| on_server_offline_{on_server_offline}, |
| binder_wrapper_{binder_wrapper} { |
| message_loop_->PostTask(FROM_HERE, |
| base::Bind(&BinderServer::TryConnecting, |
| weak_ptr_factory_.GetWeakPtr())); |
| } |
| |
| void BinderServer::TryConnecting() { |
| ClearLocalState(); |
| android::sp<android::IBinder> binder = binder_wrapper_->GetService( |
| libwebserv::kWebserverBinderServiceName); |
| if (!binder.get()) { |
| LOG(INFO) << "Webservd has not registered with service manager."; |
| } else if (!BuildLocalState(binder)) { |
| ClearLocalState(); |
| } else { |
| // Got a binder, built up appropriate local state, our job is done. |
| return; |
| } |
| message_loop_->PostDelayedTask(FROM_HERE, |
| base::Bind(&BinderServer::TryConnecting, |
| weak_ptr_factory_.GetWeakPtr()), |
| base::TimeDelta::FromSeconds(1)); |
| } |
| |
| |
| void BinderServer::ClearLocalState() { |
| // Remove all references to remote protocol handlers from our local wrappers. |
| |
| // TODO(wiley) Define this method |
| //for (auto& local_handler: local_protocol_handlers_) { |
| // local_handler.second->ResetRemoteProtocolHandlers(); |
| //} |
| |
| remote_server_.clear(); |
| } |
| |
| bool BinderServer::BuildLocalState(android::sp<android::IBinder> server) { |
| remote_server_ = android::interface_cast<RemoteServer>(server); |
| vector<sp<IBinder>> remote_raw_binders; |
| if (!remote_server_->GetProtocolHandlers(&remote_raw_binders).isOk()) { |
| // Possibly the server died, this is not necessarily an error. |
| LOG(INFO) << "Webservd failed to tell us about protocol handlers."; |
| return false; |
| } |
| |
| // Tell the local wrappers about the remote handlers that exist now. |
| for (auto& raw_binder: remote_raw_binders) { |
| sp<RemoteProtocolHandler> remote_handler = |
| android::interface_cast<RemoteProtocolHandler>(raw_binder); |
| String16 name; |
| if (!remote_handler->GetName(&name).isOk()) { |
| LOG(INFO) << "Remote handler could not report its name."; |
| return false; |
| } |
| // TODO(wiley) Look for a BinderPHGroup by that name in local_handlers_ |
| // Create a new BinderPHGroup if necessary |
| // Add it to the map under |name| |
| // Update |it| appropriately |
| // Tell |it| about |remote_handler| |
| } |
| return true; |
| } |
| |
| } // namespace libwebserv |