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 explicit ResponseObserver( 37 const trunks::CommandTransceiver::ResponseCallback& callback) 38 : callback_(callback) {} 39 40 // ITrunksClient interface. 41 android::binder::Status OnCommandResponse( 42 const std::vector<uint8_t>& response_proto_data) override { 43 trunks::SendCommandResponse response_proto; 44 if (!response_proto.ParseFromArray(response_proto_data.data(), 45 response_proto_data.size())) { 46 LOG(ERROR) << "TrunksBinderProxy: Bad response data."; 47 callback_.Run( 48 trunks::CreateErrorResponse(trunks::SAPI_RC_MALFORMED_RESPONSE)); 49 } 50 callback_.Run(response_proto.response()); 51 return android::binder::Status::ok(); 52 } 53 54 private: 55 trunks::CommandTransceiver::ResponseCallback callback_; 56 }; 57 58 } // namespace 59 60 namespace trunks { 61 62 bool TrunksBinderProxy::Init() { 63 android::sp<android::IBinder> service_binder = 64 android::BinderWrapper::GetOrCreateInstance()->GetService( 65 kTrunksServiceName); 66 if (!service_binder.get()) { 67 LOG(ERROR) << "TrunksBinderProxy: Trunks service does not exist."; 68 return false; 69 } 70 trunks_service_ = new android::trunks::BpTrunks(service_binder); 71 return true; 72 } 73 74 void TrunksBinderProxy::SendCommand(const std::string& command, 75 const ResponseCallback& callback) { 76 SendCommandRequest command_proto; 77 command_proto.set_command(command); 78 std::vector<uint8_t> command_proto_data; 79 command_proto_data.resize(command_proto.ByteSize()); 80 if (!command_proto.SerializeToArray(command_proto_data.data(), 81 command_proto_data.size())) { 82 LOG(ERROR) << "TrunksBinderProxy: Failed to serialize protobuf."; 83 callback.Run(CreateErrorResponse(TRUNKS_RC_IPC_ERROR)); 84 return; 85 } 86 android::sp<ResponseObserver> observer(new ResponseObserver(callback)); 87 android::binder::Status status = 88 trunks_service_->SendCommand(command_proto_data, observer); 89 if (!status.isOk()) { 90 LOG(ERROR) << "TrunksBinderProxy: Binder error: " << status.toString8(); 91 callback.Run(CreateErrorResponse(TRUNKS_RC_IPC_ERROR)); 92 return; 93 } 94 } 95 96 std::string TrunksBinderProxy::SendCommandAndWait(const std::string& command) { 97 SendCommandRequest command_proto; 98 command_proto.set_command(command); 99 std::vector<uint8_t> command_proto_data; 100 command_proto_data.resize(command_proto.ByteSize()); 101 if (!command_proto.SerializeToArray(command_proto_data.data(), 102 command_proto_data.size())) { 103 LOG(ERROR) << "TrunksBinderProxy: Failed to serialize protobuf."; 104 return CreateErrorResponse(TRUNKS_RC_IPC_ERROR); 105 } 106 std::vector<uint8_t> response_proto_data; 107 android::binder::Status status = trunks_service_->SendCommandAndWait( 108 command_proto_data, &response_proto_data); 109 if (!status.isOk()) { 110 LOG(ERROR) << "TrunksBinderProxy: Binder error: " << status.toString8(); 111 return CreateErrorResponse(TRUNKS_RC_IPC_ERROR); 112 } 113 trunks::SendCommandResponse response_proto; 114 if (!response_proto.ParseFromArray(response_proto_data.data(), 115 response_proto_data.size())) { 116 LOG(ERROR) << "TrunksBinderProxy: Bad response data."; 117 return trunks::CreateErrorResponse(trunks::SAPI_RC_MALFORMED_RESPONSE); 118 } 119 return response_proto.response(); 120 } 121 122 } // namespace trunks 123