You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
3.5 KiB
95 lines
3.5 KiB
// |
|
// 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
|
|
|