| // |
| // 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 |