blob: b0e21eb937bdb8228f4d1fca0d2a9767c4ddf12d [file] [log] [blame]
// Copyright 2015 The Chromium OS 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 "psyche/psyched/client.h"
#include <utility>
#include <protobinder/binder_proxy.h>
#include <protobinder/proto_util.h>
#include "psyche/proto_bindings/psyche.pb.h"
#include "psyche/proto_bindings/psyche.pb.rpc.h"
#include "psyche/psyched/service.h"
using protobinder::BinderProxy;
using protobinder::BinderToInterface;
namespace psyche {
Client::Client(std::unique_ptr<BinderProxy> client_proxy)
: proxy_(std::move(client_proxy)),
interface_(BinderToInterface<IPsycheClient>(proxy_.get())) {
}
Client::~Client() {
while (!services_.empty())
RemoveService(*(services_.begin()));
}
const ClientInterface::ServiceSet& Client::GetServices() const {
return services_;
}
void Client::ReportServiceRequestFailure(const std::string& service_name) {
SendServiceProxy(service_name, nullptr);
}
void Client::AddService(ServiceInterface* service) {
DCHECK(services_.find(service) == services_.end())
<< "Service \"" << service->GetName() << "\" already registered for "
<< "client with handle " << proxy_->handle();
service->AddObserver(this);
services_.insert(service);
if (service->GetProxy())
SendServiceProxy(service->GetName(), service->GetProxy());
}
void Client::RemoveService(ServiceInterface* service) {
service->RemoveObserver(this);
services_.erase(service);
}
void Client::OnServiceProxyChange(ServiceInterface* service) {
DCHECK(service);
CHECK(services_.count(service)) << "Service \"" << service->GetName()
<< "\" not registered for client "
<< "with handle " << proxy_->handle();
if (service->GetProxy())
SendServiceProxy(service->GetName(), service->GetProxy());
}
void Client::SendServiceProxy(const std::string& service_name,
const protobinder::BinderProxy* service_proxy) {
ReceiveServiceRequest request;
request.set_name(service_name);
if (service_proxy)
protobinder::StoreBinderInProto(*service_proxy, request.mutable_binder());
int result = interface_->ReceiveService(&request);
if (result != 0) {
LOG(WARNING) << "Failed to pass service \"" << service_name
<< "\" to client with handle " << proxy_->handle()
<< "; got " << result;
}
}
} // namespace psyche