• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ResponseObserver(const trunks::CommandTransceiver::ResponseCallback & callback)36   explicit ResponseObserver(
37       const trunks::CommandTransceiver::ResponseCallback& callback)
38       : callback_(callback) {}
39 
40   // ITrunksClient interface.
OnCommandResponse(const std::vector<uint8_t> & response_proto_data)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 
Init()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 
SendCommand(const std::string & command,const ResponseCallback & callback)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 
SendCommandAndWait(const std::string & command)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