122 lines
4.4 KiB
C++
122 lines
4.4 KiB
C++
//
|
|
// Copyright (C) 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 "trunks/trunks_binder_proxy.h"
|
|
|
|
#include <base/bind.h>
|
|
#include <base/callback.h>
|
|
#include <base/logging.h>
|
|
#include <binderwrapper/binder_wrapper.h>
|
|
#include <utils/Errors.h>
|
|
|
|
#include "android/trunks/BnTrunksClient.h"
|
|
#include "android/trunks/BpTrunks.h"
|
|
#include "trunks/binder_interface.h"
|
|
#include "trunks/error_codes.h"
|
|
#include "trunks/interface.pb.h"
|
|
|
|
namespace {
|
|
|
|
// Implements ITrunksClient and forwards response data to a ResponseCallback.
|
|
class ResponseObserver : public android::trunks::BnTrunksClient {
|
|
public:
|
|
explicit ResponseObserver(
|
|
const trunks::CommandTransceiver::ResponseCallback& callback)
|
|
: callback_(callback) {}
|
|
|
|
// ITrunksClient interface.
|
|
android::binder::Status OnCommandResponse(
|
|
const std::vector<uint8_t>& response_proto_data) override {
|
|
trunks::SendCommandResponse response_proto;
|
|
if (!response_proto.ParseFromArray(response_proto_data.data(),
|
|
response_proto_data.size())) {
|
|
LOG(ERROR) << "TrunksBinderProxy: Bad response data.";
|
|
callback_.Run(
|
|
trunks::CreateErrorResponse(trunks::SAPI_RC_MALFORMED_RESPONSE));
|
|
}
|
|
callback_.Run(response_proto.response());
|
|
return android::binder::Status::ok();
|
|
}
|
|
|
|
private:
|
|
trunks::CommandTransceiver::ResponseCallback callback_;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
namespace trunks {
|
|
|
|
bool TrunksBinderProxy::Init() {
|
|
android::sp<android::IBinder> service_binder =
|
|
android::BinderWrapper::GetOrCreateInstance()->GetService(
|
|
kTrunksServiceName);
|
|
if (!service_binder.get()) {
|
|
LOG(ERROR) << "TrunksBinderProxy: Trunks service does not exist.";
|
|
return false;
|
|
}
|
|
trunks_service_ = new android::trunks::BpTrunks(service_binder);
|
|
return true;
|
|
}
|
|
|
|
void TrunksBinderProxy::SendCommand(const std::string& command,
|
|
const ResponseCallback& callback) {
|
|
SendCommandRequest command_proto;
|
|
command_proto.set_command(command);
|
|
std::vector<uint8_t> command_proto_data;
|
|
command_proto_data.resize(command_proto.ByteSize());
|
|
if (!command_proto.SerializeToArray(command_proto_data.data(),
|
|
command_proto_data.size())) {
|
|
LOG(ERROR) << "TrunksBinderProxy: Failed to serialize protobuf.";
|
|
callback.Run(CreateErrorResponse(TRUNKS_RC_IPC_ERROR));
|
|
return;
|
|
}
|
|
android::sp<ResponseObserver> observer(new ResponseObserver(callback));
|
|
android::binder::Status status =
|
|
trunks_service_->SendCommand(command_proto_data, observer);
|
|
if (!status.isOk()) {
|
|
LOG(ERROR) << "TrunksBinderProxy: Binder error: " << status.toString8();
|
|
callback.Run(CreateErrorResponse(TRUNKS_RC_IPC_ERROR));
|
|
return;
|
|
}
|
|
}
|
|
|
|
std::string TrunksBinderProxy::SendCommandAndWait(const std::string& command) {
|
|
SendCommandRequest command_proto;
|
|
command_proto.set_command(command);
|
|
std::vector<uint8_t> command_proto_data;
|
|
command_proto_data.resize(command_proto.ByteSize());
|
|
if (!command_proto.SerializeToArray(command_proto_data.data(),
|
|
command_proto_data.size())) {
|
|
LOG(ERROR) << "TrunksBinderProxy: Failed to serialize protobuf.";
|
|
return CreateErrorResponse(TRUNKS_RC_IPC_ERROR);
|
|
}
|
|
std::vector<uint8_t> response_proto_data;
|
|
android::binder::Status status = trunks_service_->SendCommandAndWait(
|
|
command_proto_data, &response_proto_data);
|
|
if (!status.isOk()) {
|
|
LOG(ERROR) << "TrunksBinderProxy: Binder error: " << status.toString8();
|
|
return CreateErrorResponse(TRUNKS_RC_IPC_ERROR);
|
|
}
|
|
trunks::SendCommandResponse response_proto;
|
|
if (!response_proto.ParseFromArray(response_proto_data.data(),
|
|
response_proto_data.size())) {
|
|
LOG(ERROR) << "TrunksBinderProxy: Bad response data.";
|
|
return trunks::CreateErrorResponse(trunks::SAPI_RC_MALFORMED_RESPONSE);
|
|
}
|
|
return response_proto.response();
|
|
}
|
|
|
|
} // namespace trunks
|