aboutsummaryrefslogtreecommitdiff
path: root/en/devices/architecture/hal/framework-testing.html
blob: 8eb311a9c6b256d4e8b48e2438168d8f3530bc96 (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
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&lt;int64_t&gt; doFoo(int32_t a) {
        return this-&gt;mImpl-&gt;doFoo(a);
    }

    Return&lt;V1_0::ICallback&gt; 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-&gt;mImpl-&gt;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>