blob: ad4b7bc22a94a100bad4a81fdfda061be772c755 [file] [log] [blame]
//
// 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.
//
namespace tpm_manager {
// Handles protobuf conversions for a binder proxy. Implements ITpmManagerClient
// and acts as a response observer for async requests it sends out. The
// |RequestProtobufType| and |ResponseProtobufType| types can be any protobufs.
template<typename RequestProtobufType, typename ResponseProtobufType>
class BinderProxyHelper {
public:
using CallbackType = base::Callback<void(const ResponseProtobufType&)>;
using GetErrorResponseCallbackType =
base::Callback<void(ResponseProtobufType*)>;
using BinderMethodType = base::Callback<android::binder::Status(
const std::vector<uint8_t>& command_proto,
const android::sp<android::tpm_manager::ITpmManagerClient>& client)>;
BinderProxyHelper(const BinderMethodType& method,
const CallbackType& callback,
const GetErrorResponseCallbackType& get_error_response)
: method_(method),
callback_(callback),
get_error_response_(get_error_response) {}
void SendErrorResponse() {
ResponseProtobufType response_proto;
get_error_response_.Run(&response_proto);
callback_.Run(response_proto);
}
void SendRequest(const RequestProtobufType& request) {
VLOG(2) << __func__;
android::sp<ResponseObserver> observer(
new ResponseObserver(callback_, get_error_response_));
std::vector<uint8_t> request_bytes;
request_bytes.resize(request.ByteSize());
if (!request.SerializeToArray(request_bytes.data(), request_bytes.size())) {
LOG(ERROR) << "BinderProxyHelper: Failed to serialize protobuf.";
SendErrorResponse();
return;
}
android::binder::Status status = method_.Run(request_bytes, observer);
if (!status.isOk()) {
LOG(ERROR) << "BinderProxyHelper: Binder error: " << status.toString8();
SendErrorResponse();
return;
}
}
private:
class ResponseObserver : public android::tpm_manager::BnTpmManagerClient {
public:
ResponseObserver(const CallbackType& callback,
const GetErrorResponseCallbackType& get_error_response)
: callback_(callback), get_error_response_(get_error_response) {}
// ITpmManagerClient interface.
android::binder::Status OnCommandResponse(
const std::vector<uint8_t>& response_proto_data) override {
VLOG(2) << __func__;
ResponseProtobufType response_proto;
if (!response_proto.ParseFromArray(response_proto_data.data(),
response_proto_data.size())) {
LOG(ERROR) << "BinderProxyHelper: Bad response data.";
get_error_response_.Run(&response_proto);
}
callback_.Run(response_proto);
return android::binder::Status::ok();
}
private:
CallbackType callback_;
GetErrorResponseCallbackType get_error_response_;
};
BinderMethodType method_;
CallbackType callback_;
GetErrorResponseCallbackType get_error_response_;
};
} // tpm_manager