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 "HandleType.h"
18
19#include "HidlTypeAssertion.h"
20
21#include <hidl-util/Formatter.h>
22#include <android-base/logging.h>
23
24namespace android {
25
26HandleType::HandleType() {}
27
28void HandleType::addNamedTypesToSet(std::set<const FQName> &) const {
29    // do nothing
30}
31
32bool HandleType::isHandle() const {
33    return true;
34}
35
36std::string HandleType::getCppType(StorageMode mode,
37                                   bool specifyNamespaces) const {
38    const std::string base =
39          std::string(specifyNamespaces ? "::android::hardware::" : "")
40        + "hidl_handle";
41
42    switch (mode) {
43        case StorageMode_Stack:
44            return base;
45
46        case StorageMode_Argument:
47            return "const " + base + "&";
48
49        case StorageMode_Result:
50            return base;
51    }
52}
53
54std::string HandleType::getVtsType() const {
55    return "TYPE_HANDLE";
56}
57
58void HandleType::emitReaderWriter(
59        Formatter &out,
60        const std::string &name,
61        const std::string &parcelObj,
62        bool parcelObjIsPointer,
63        bool isReader,
64        ErrorMode mode) const {
65    const std::string parcelObjDeref =
66        parcelObj + (parcelObjIsPointer ? "->" : ".");
67
68    if (isReader) {
69        out << "const native_handle_t *"
70            << name << "_ptr;\n\n";
71
72        out << "_hidl_err = "
73            << parcelObjDeref
74            << "readNullableNativeHandleNoDup("
75            << "&" << name << "_ptr"
76            << ");\n\n";
77
78        handleError(out, mode);
79
80        out << name << " = " << name << "_ptr;\n";
81    } else {
82        out << "_hidl_err = ";
83        out << parcelObjDeref
84            << "writeNativeHandleNoDup("
85            << name
86            << ");\n";
87
88        handleError(out, mode);
89    }
90}
91
92bool HandleType::useNameInEmitReaderWriterEmbedded(bool isReader) const {
93    return !isReader;
94}
95
96void HandleType::emitReaderWriterEmbedded(
97        Formatter &out,
98        size_t /* depth */,
99        const std::string &name,
100        const std::string &sanitizedName,
101        bool nameIsPointer,
102        const std::string &parcelObj,
103        bool parcelObjIsPointer,
104        bool isReader,
105        ErrorMode mode,
106        const std::string &parentName,
107        const std::string &offsetText) const {
108    if (isReader) {
109        const std::string ptrName = "_hidl_" + sanitizedName  + "_ptr";
110
111        out << "const native_handle_t *"
112            << ptrName << ";\n"
113            << "_hidl_err = "
114            << parcelObj
115            << (parcelObjIsPointer ? "->" : ".")
116            << "readNullableEmbeddedNativeHandle(\n";
117
118        out.indent();
119        out.indent();
120
121        out << parentName
122            << ",\n"
123            << offsetText
124            << ",\n"
125            << "&" << ptrName
126            << "\n"
127            << ");\n\n";
128
129        out.unindent();
130        out.unindent();
131
132        handleError(out, mode);
133    } else {
134        out << "_hidl_err = "
135            << parcelObj
136            << (parcelObjIsPointer ? "->" : ".")
137            << "writeEmbeddedNativeHandle(\n";
138
139        out.indent();
140        out.indent();
141
142        out << (nameIsPointer ? ("*" + name) : name)
143            << ",\n"
144            << parentName
145            << ",\n"
146            << offsetText
147            << ");\n\n";
148
149        out.unindent();
150        out.unindent();
151
152        handleError(out, mode);
153    }
154}
155
156bool HandleType::needsEmbeddedReadWrite() const {
157    return true;
158}
159
160bool HandleType::isJavaCompatible() const {
161    return false;
162}
163
164static HidlTypeAssertion assertion("hidl_handle", 16 /* size */);
165void HandleType::getAlignmentAndSize(size_t *align, size_t *size) const {
166    *align = 8;  // hidl_handle
167    *size = assertion.size();
168}
169
170status_t HandleType::emitVtsTypeDeclarations(Formatter &out) const {
171    out << "type: " << getVtsType() << "\n";
172    return OK;
173}
174
175}  // namespace android
176
177