1// 2// Copyright (C) 2016 The Android Open Source Project 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include "trunks/trunks_binder_proxy.h" 18 19#include <base/bind.h> 20#include <base/callback.h> 21#include <base/logging.h> 22#include <binderwrapper/binder_wrapper.h> 23#include <utils/Errors.h> 24 25#include "android/trunks/BnTrunksClient.h" 26#include "android/trunks/BpTrunks.h" 27#include "trunks/binder_interface.h" 28#include "trunks/error_codes.h" 29#include "trunks/interface.pb.h" 30 31namespace { 32 33// Implements ITrunksClient and forwards response data to a ResponseCallback. 34class ResponseObserver : public android::trunks::BnTrunksClient { 35 public: 36 ResponseObserver(const trunks::CommandTransceiver::ResponseCallback& callback) 37 : callback_(callback) {} 38 39 // ITrunksClient interface. 40 android::binder::Status OnCommandResponse( 41 const std::vector<uint8_t>& response_proto_data) override { 42 trunks::SendCommandResponse response_proto; 43 if (!response_proto.ParseFromArray(response_proto_data.data(), 44 response_proto_data.size())) { 45 LOG(ERROR) << "TrunksBinderProxy: Bad response data."; 46 callback_.Run( 47 trunks::CreateErrorResponse(trunks::SAPI_RC_MALFORMED_RESPONSE)); 48 } 49 callback_.Run(response_proto.response()); 50 return android::binder::Status::ok(); 51 } 52 53 private: 54 trunks::CommandTransceiver::ResponseCallback callback_; 55}; 56 57} // namespace 58 59namespace trunks { 60 61bool TrunksBinderProxy::Init() { 62 android::sp<android::IBinder> service_binder = 63 android::BinderWrapper::GetOrCreateInstance()->GetService( 64 kTrunksServiceName); 65 if (!service_binder.get()) { 66 LOG(ERROR) << "TrunksBinderProxy: Trunks service does not exist."; 67 return false; 68 } 69 trunks_service_ = new android::trunks::BpTrunks(service_binder); 70 return true; 71} 72 73void TrunksBinderProxy::SendCommand(const std::string& command, 74 const ResponseCallback& callback) { 75 SendCommandRequest command_proto; 76 command_proto.set_command(command); 77 std::vector<uint8_t> command_proto_data; 78 command_proto_data.resize(command_proto.ByteSize()); 79 if (!command_proto.SerializeToArray(command_proto_data.data(), 80 command_proto_data.size())) { 81 LOG(ERROR) << "TrunksBinderProxy: Failed to serialize protobuf."; 82 callback.Run(CreateErrorResponse(TRUNKS_RC_IPC_ERROR)); 83 return; 84 } 85 android::sp<ResponseObserver> observer(new ResponseObserver(callback)); 86 android::binder::Status status = 87 trunks_service_->SendCommand(command_proto_data, observer); 88 if (!status.isOk()) { 89 LOG(ERROR) << "TrunksBinderProxy: Binder error: " << status.toString8(); 90 callback.Run(CreateErrorResponse(TRUNKS_RC_IPC_ERROR)); 91 return; 92 } 93} 94 95std::string TrunksBinderProxy::SendCommandAndWait(const std::string& command) { 96 SendCommandRequest command_proto; 97 command_proto.set_command(command); 98 std::vector<uint8_t> command_proto_data; 99 command_proto_data.resize(command_proto.ByteSize()); 100 if (!command_proto.SerializeToArray(command_proto_data.data(), 101 command_proto_data.size())) { 102 LOG(ERROR) << "TrunksBinderProxy: Failed to serialize protobuf."; 103 return CreateErrorResponse(TRUNKS_RC_IPC_ERROR); 104 } 105 std::vector<uint8_t> response_proto_data; 106 android::binder::Status status = trunks_service_->SendCommandAndWait( 107 command_proto_data, &response_proto_data); 108 if (!status.isOk()) { 109 LOG(ERROR) << "TrunksBinderProxy: Binder error: " << status.toString8(); 110 return CreateErrorResponse(TRUNKS_RC_IPC_ERROR); 111 } 112 trunks::SendCommandResponse response_proto; 113 if (!response_proto.ParseFromArray(response_proto_data.data(), 114 response_proto_data.size())) { 115 LOG(ERROR) << "TrunksBinderProxy: Bad response data."; 116 return trunks::CreateErrorResponse(trunks::SAPI_RC_MALFORMED_RESPONSE); 117 } 118 return response_proto.response(); 119} 120 121} // namespace trunks 122