blob: 148bfae8088b6665e90b070678620ad8f2405599 [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/soma_connection.h"
#include <utility>
#include <base/logging.h>
#include <protobinder/binder_proxy.h>
#include <protobinder/iinterface.h>
#include <soma/constants.h>
#include "psyche/proto_bindings/soma.pb.h"
#include "psyche/proto_bindings/soma.pb.rpc.h"
#include "psyche/proto_bindings/soma_container_spec.pb.h"
using protobinder::BinderProxy;
using protobinder::BinderToInterface;
using soma::ContainerSpec;
using soma::ISoma;
namespace psyche {
// static
const char* SomaConnection::ResultToString(Result result) {
switch (result) {
case Result::SUCCESS:
return "SUCCESS";
case Result::NO_SOMA_CONNECTION:
return "NO_SOMA_CONNECTION";
case Result::RPC_ERROR:
return "RPC_ERROR";
case Result::UNKNOWN_SERVICE:
return "UNKNOWN_SERVICE";
}
NOTREACHED() << "Invalid result " << static_cast<int>(result);
return "INVALID";
}
SomaConnection::SomaConnection() : service_(soma::kSomaServiceName) {
service_.AddObserver(this);
}
SomaConnection::~SomaConnection() {
service_.RemoveObserver(this);
}
bool SomaConnection::HasProxy() const {
return service_.GetProxy();
}
void SomaConnection::SetProxy(std::unique_ptr<protobinder::BinderProxy> proxy) {
// TODO(derat): Verify that the transaction is coming from the proper UID and
// report failure if not.
service_.SetProxy(std::move(proxy));
}
SomaConnection::Result SomaConnection::GetContainerSpecForService(
const std::string& service_name,
ContainerSpec* spec_out) {
DCHECK(spec_out);
if (!interface_)
return Result::NO_SOMA_CONNECTION;
soma::GetContainerSpecRequest request;
request.set_service_name(service_name);
soma::GetContainerSpecResponse response;
int result = interface_->GetContainerSpec(&request, &response);
if (result != 0) {
LOG(ERROR) << "GetContainerSpec RPC to somad returned " << result;
return Result::RPC_ERROR;
}
if (!response.has_container_spec())
return Result::UNKNOWN_SERVICE;
*spec_out = response.container_spec();
return Result::SUCCESS;
}
SomaConnection::Result SomaConnection::GetPersistentContainerSpecs(
std::vector<soma::ContainerSpec>* specs_out) {
DCHECK(specs_out);
specs_out->clear();
if (!interface_)
return Result::NO_SOMA_CONNECTION;
soma::GetPersistentContainerSpecsRequest request;
soma::GetPersistentContainerSpecsResponse response;
int result = interface_->GetPersistentContainerSpecs(&request, &response);
if (result != 0) {
LOG(ERROR) << "GetPersistentContainerSpecs RPC to somad returned "
<< result;
return Result::RPC_ERROR;
}
specs_out->reserve(response.container_specs_size());
for (const auto& spec : response.container_specs())
specs_out->push_back(spec);
return Result::SUCCESS;
}
void SomaConnection::OnServiceProxyChange(ServiceInterface* service) {
DCHECK_EQ(service, &service_);
if (service->GetProxy()) {
LOG(INFO) << "Got connection to somad";
interface_.reset(BinderToInterface<ISoma>(service->GetProxy()));
} else {
LOG(WARNING) << "Lost connection to somad";
interface_.reset();
}
}
} // namespace psyche