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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
<html devsite="">
<head>
<title>HIDL Framework Backwards Compatibility Verification</title>
<meta name="project_path" value="/_project.yaml">
<meta name="book_path" value="/_book.yaml">
</head>
<body>
{% include "_versions.html" %}
<!--
Copyright 2018 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><a href="/devices/architecture/#hidl">HIDL HALs</a>
guarantee the Android core system (aka system.img or the framework) is
backwards compatible. While <a href="/compatibility/vts">Vendor Test Suite (VTS)</a>
tests ensure that HALs work as expected (e.g. 1.1 HAL tests are run on all
1.2 implementations), framework testing is needed to ensure that when a
supported HAL (1.0, 1.1, or 1.2) is provided, the framework works properly
with that HAL.</p>
<p>For details on HAL interface definition language (HIDL), refer to <a href=
"/devices/architecture/hidl">HIDL</a>, <a href=
"/devices/architecture/hidl/versioning">HIDL
versioning</a>, and <a href=
"/devices/architecture/vintf/fcm#hal-version-deprecation">HIDL HAL
Deprecation</a>.</p>
<h2 id="about-HAL-upgrades">About HAL upgrades</h2>
<p>There are two types of HAL upgrades: <em>major</em> and <em>minor</em>.
Most systems include only one HAL implementation, but multiple
implementations are supported. For example:</p>
<pre>android.hardware.teleport@1.0 # initial interface
android.hardware.teleport@1.1 # minor version upgrade
android.hardware.teleport@1.2 # another minor version upgrade
...
android.hardware.teleport@2.0 # major version upgrade
...</pre>
<p>The system partition typically includes a framework daemon (such as
<code>teleportd</code>) that manages communication with a specific group of
HAL implementations. Alternatively, systems might instead
include a system library (such as
<code>android.hardware.configstore-utils</code>) that implements convenient
client behavior. In the example above, <code>teleportd</code> must work no
matter what version of the HAL is installed on the device.</p>
<h2 id="google-maintained-versions">Google-maintained versions</h2>
<p>If major version upgrades (1.0, 2.0, 3.0, etc.) exist, at least one
Google-maintained device must maintain an implementation of each major
version until that version is deprecated. If no Google-maintained device
ships with a specific major version, Google continues to maintain an old
implementation of that major version.</p>
<p>Such maintenance adds minor additional overhead because the old
implementation (e.g. 1.2) can be kept and not used by default when a new
implementation (e.g. 2.0) is created.</p>
<h2 id="testing-minor-version-upgrades">Testing minor version upgrades</h2>
<p>Testing the backwards compatibility of minor versions in the framework
requires a way to automatically generate minor version implementations. Given
the restrictions around Google-maintained versions, <code>hidl-gen</code>
will only (and can only) generate adapters that take a 1.(x+n) implementation
and provide a 1.x implementation; it cannot generate a 1.0 implementation
from a 2.0 implementation (by definition of a major version).</p>
<p>For example, to run 1.1 tests on a 1.2 implementation, you must be able to
simulate having a 1.1 implementation. The 1.2 interfaces can automatically be
used as 1.1 implementation with some slight differences in behavior (such as
the framework manually checking what version something is or calling
<code>castFrom</code> on it).</p>
<p>The basic idea is this:</p>
<ol>
<li>Install an x.(y+n) interface on an Android mobile device.</li>
<li>Install and activate an x.y-target adapter.</li>
<li>Test the device to verify it works as expected when running an older
minor version.</li>
</ol>
<p>These adapters completely hide the fact that the implementation is
actually backed by a 1.2 interface and only provides the 1.1 interface (the
adapter takes a 1.2 interface and makes it look like a 1.1 interface).</p>
<h3 id="example-workflow">Example workflow</h3>
<p>In this example, the Android device runs
<code>android.hardware.foo@1.1::IFoo/default</code>. To ensure a client works
properly with <code>android.hardware.foo@1.0::IFoo/default</code>:</p>
<ol>
<li>In a terminal, run the following:
<pre>$ PACKAGE=android.hidl.allocator@1.0-adapter
$ INTERFACE=IAllocator
$ INSTANCE=ashmem
$ THREAD_COUNT=1 # can see current thread use on `lshal -i -e`
$ m -j $PACKAGE
$ /data/nativetest64/$PACKAGE/$PACKAGE $INTERFACE $INSTANCE $THREAD_COUNT
Trying to adapt down android.hidl.allocator@1.0-adapter/default
Press any key to disassociate adapter.</pre>
</li>
<li>Restart the client using <code>adb shell stop</code> (or
<code>start</code>) or simply kill the process.</li>
<li>After the test completes, disassociate the adapter.</li>
<li>Restore system state by restarting the device OR by restarting the
client.</li>
</ol>
<h3 id="additional-targets">Additional targets</h3>
<p><code>hidl-gen</code> automatically adds additional build targets for the
adapters for every interface specified with <code>hidl_interface</code> in
the build system. For package <code>a.b.c@x.y</code>, there is an additional
C++ target <code>a.b.c@x.y-adapter</code>.</p>
<aside class="note"><strong>Note:</strong> No java adapter needs to be made because a C++
adapter can always be used to wrap a Java service.</aside>
<p>An adapter for <code>a.b.c@x.y</code> takes as an input some
implementation, <code>a.b.c@x.(y+n)::ISomething/instance-name</code>, and
must register <code>a.b.c@x.y::ISomething/instance-name</code> which must
also unregister the <code>y+n</code> implementation.</p>
<p>Given the following sample interface:</p>
<pre>// IFoo.hal
package a.b.c@1.0;
interface IFoo {
doFoo(int32_t a) generates (int64_t b);
doSubInterface() generates (IFoo a);
};</pre>
<p>The code provided by <code>a.b.c@1.0-adapter</code> is similar to the
sample below:</p>
<pre>// autogenerated code
// in namespace a::b::c::V1_0::IFoo
struct MockFoo {
// takes some subclass of V1_0. May be V1_1, V1_2, etc...
MockFoo(V1_0::IFoo impl) mImpl(impl) {}
Return<int64_t> doFoo(int32_t a) {
return this->mImpl->doFoo(a);
}
Return<V1_0::ICallback> doSubInterface() {
// getMockForBinder returns MockCallback instance
// that corresponds to a particular binder object
// It can't return a new object every time or
// clients using interfacesSame will have
// divergent behavior when using the mock.
auto _hidl_out = this->mImpl->doSubInterface();
return getMockForBinder(_hidl_out);
}
};</pre>
<p>Data values are forwarded exactly into and out of the auto-generated mock
class, except for sub interfaces, which are returned. These interfaces must
be wrapped in the corresponding most recent callback object.</p>
</body>
</html>
|