trunks_binder_proxy.cc revision 655d35e67b7cf5c0ea273de8a9bb2606476e53f8
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