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 31 namespace { 32 33 // Implements ITrunksClient and forwards response data to a ResponseCallback. 34 class 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 59 namespace trunks { 60 61 bool 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 73 void 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 95 std::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