1 /*
2  * Copyright (C) 2017 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 <nos/CitadeldProxyClient.h>
18 
19 #include <android-base/logging.h>
20 #include <binder/IServiceManager.h>
21 #include <binder/ProcessState.h>
22 
23 #include <application.h>
24 
25 using ::android::defaultServiceManager;
26 using ::android::sp;
27 using ::android::IServiceManager;
28 using ::android::ProcessState;
29 
30 using ::android::binder::Status;
31 
32 using ::android::hardware::citadel::ICitadeld;
33 
34 namespace nos {
35 
~CitadeldProxyClient()36 CitadeldProxyClient::~CitadeldProxyClient() {
37     Close();
38 }
39 
Open()40 void CitadeldProxyClient::Open() {
41     // Ensure this process is using the vndbinder
42     ProcessState::initWithDriver("/dev/vndbinder");
43     _citadeld = ICitadeld::asInterface(defaultServiceManager()->getService(ICitadeld::descriptor));
44 }
45 
Close()46 void CitadeldProxyClient::Close() {
47     _citadeld.clear();
48 }
49 
IsOpen() const50 bool CitadeldProxyClient::IsOpen() const {
51     return _citadeld != nullptr;
52 }
53 
CallApp(uint32_t appId,uint16_t arg,const std::vector<uint8_t> & request,std::vector<uint8_t> * _response)54 uint32_t CitadeldProxyClient::CallApp(uint32_t appId, uint16_t arg,
55                                       const std::vector<uint8_t>& request,
56                                       std::vector<uint8_t>* _response) {
57     // Binder doesn't pass a nullptr or the capacity so resolve the response
58     // buffer size before making the call. The response vector may be the same
59     // as the request vector so the response cannot be directly resized.
60     std::vector<uint8_t> response(_response == nullptr ? 0 : _response->capacity());
61 
62     uint32_t appStatus;
63     Status status = _citadeld->callApp(appId, arg, request, &response,
64                                        reinterpret_cast<int32_t*>(&appStatus));
65     if (status.isOk()) {
66         if (_response != nullptr) {
67             *_response = std::move(response);
68         }
69         return appStatus;
70     }
71     LOG(ERROR) << "Failed to call app via citadeld: " << status.toString8();
72     return APP_ERROR_IO;
73 }
74 
Citadeld()75 ICitadeld& CitadeldProxyClient::Citadeld() {
76     return *_citadeld.get();
77 }
78 
79 } // namespace nos
80