aboutsummaryrefslogtreecommitdiff
path: root/en/devices/architecture/hidl-cpp/functions.html
blob: 5d52b31d9e4035bd5e71d7a6d23b3452fc3bd0cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<html devsite>
  <head>
    <title>Functions</title>
    <meta name="project_path" value="/_project.yaml" />
    <meta name="book_path" value="/_book.yaml" />
  </head>
  <body>
  <!--
      Copyright 2017 The Android Open Source Project

      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
  -->

<p>Functions in a HIDL interface are mapped to methods in the autogenerated
<code>IFoo</code> C++ class declaration. The name of each function remains the
same in C++; the following sections describe how HIDL arguments and return
values are translated to C++.</p>

<h2 id=parameters>Function parameters</h2>
<p>The arguments listed in the <code>.hal</code> file map to C++ data types.
Arguments that do not map to a primitive C++ type are passed by const
reference.</p>

<p>For every HIDL function that has a return value (has a <code>generates</code>
statement), the C++ parameter list for that function has an additional argument:
a callback function that is called with the return values of the HIDL function.
There is <strong>one exception</strong>: If the <code>generates</code> clause
contains a single parameter that directly maps to a C++ primitive, callback
<em>elision</em> is used (the callback is removed and the return value is
returned from the function through a normal <code>return</code> statement).</p>

<h2 id=return-values>Function return values</h2>
<p>The following functions have return values.</p>

<h3 id=transport>Transport errors and return type</h3>
<p>The <code>generates</code> statement can result in three types of function
signatures:</p>

<ul>
<li>For only one return value that is a C++ primitive, the
<code>generates</code> return value is returned by value from the function in a
<code>Return&lt;T&gt;</code> object.</li>
<li>For more complicated cases, the <code>generates</code> return value(s) are
returned through the callback parameter provided with the function call itself,
and the function returns <code>Return&lt;void&gt;</code>.</li>
<li>For when no <code>generates</code> statement exists, the function returns
<code>Return&lt;void&gt;</code>.</li>
</ul>

<p>RPC calls can occasionally encounter transport errors, e.g. when the server
dies, when transport resources are insufficient to complete the call, or when
the parameters passed do not permit completing the call (such as missing a
required callback function). <code>Return</code> objects store transport error
indications as well as a <code>T</code> value (except
<code>Return&lt;void&gt;</code>).</p>

<p>As the client-side and server-side functions have the same signature, the
server-side function must return a <code>Return</code> type even though its
implementation does not signal transport errors. <code>Return&lt;T&gt;</code>
objects are constructed with <code>Return(myTValue)</code> (or can be implicitly
constructed from <code>mTValue</code>, such as in <code>return</code>
statements) and <code>Return&lt;void&gt;</code> objects are constructed with
<code>Void()</code>.</p>

<p><code>Return&lt;T&gt;</code> objects have implicit conversion to and from
their <code>T</code> value. The <code>Return</code> object can be checked for
transport errors by calling its <code>isOk()</code> method. This check is not
required; however, if an error occurs and is not checked by the time the
<code>Return</code> object is destroyed, or a <code>T</code> value conversion is
attempted, the client process will be killed and an error logged. If
<code>isOk()</code> indicates a transport error or a call failure due to a logic
error in developer code (such as passing <code>nullptr</code> as a synchronous
callback), then <code>description()</code> can be called on the Return object to
return a string suitable for logging. In such cases, there is no way to
determine how much code may have executed on the server as a result of the
failed call. The method <code>isDeadObject()</code> is also provided. This
method indicates that <code>!isOk()</code> is because the remote object has
crashed or no longer exists. <code>isDeadObject()</code> always implies
<code>!isOk()</code>.</p>

<h3 id=return-by>Return by value</h3>
<p>If the <code>generates</code> statement maps to a single C++ primitive, no
callback parameter is in the parameter list. Instead, an implementation provides
the return value <code>T</code> in a <code>Return&lt;T&gt;</code> object, which
can be implicitly generated from the primitive type <code>T</code>. For
example:</p>

<pre class="prettyprint">
Return&lt;uint32_t&gt; someMethod() {
    uint32_t return_data = ...; // Compute return_data
    return return_data;
};
</pre>

<p>The method <code>Return&lt;*&gt;::withDefault</code> is also provided. This
method provides a value in cases where the return value is <code>!isOk()</code>.
This method also automatically marks the return object as okay so the client
process will not be killed.</p>

<h3 id=return-callback>Return using callback parameter</h3>
<p>A callback can pass the return value of the HIDL function back to the caller.
The prototype of the callback is a <code>std::function</code> object with
parameters (taken from the <code>generates</code> statement) mapped to C++
types. Its return value is void—the callback itself doesn't return a value.</p>

<p>The return value of a C++ function with a callback parameter has type
<code>Return&lt;void&gt;</code>. The server implementation is responsible only
for providing the return value. As the return values are already transferred
using the callback, the <code>T</code> template parameter is <code>void</code>:
</p>

<pre class="prettyprint">
Return&lt;void&gt; someMethod(someMethod_cb _cb);
</pre>

<p>From their C++ implementation, server implementations should return
<code>Void()</code>, which is a static inlined function returning a
<code>Return&lt;void&gt;</code> object. Example of a typical server method
implementation with a callback parameter:</p>

<pre class="prettyprint">
Return&lt;void&gt; someMethod(someMethod_cb _cb) {
    // Do some processing, then call callback with return data
    hidl_vec&lt;uint32_t&gt; vec = ...
    _cb(vec);
    return Void();
};
</pre>

<h2 id=no-return>Functions without return values</h2>
<p>The C++ signature of a function without a <code>generates</code> statement
will not have a callback parameter in the parameter list. Its return type will
be <code>Return&lt;void&gt;.</code></p>

<h2 id=oneway>Oneway functions</h2>
<p>Functions marked with the <code>oneway</code> keyword are asynchronous
functions (clients won't block on their execution) and do not have return
values. The C++ signature of a <code>oneway</code> function will not have a
callback parameter in the parameter list, and its C++ return value will be
<code>Return&lt;void&gt;</code>.</p>

  </body>
</html>