diff options
Diffstat (limited to 'en/devices/architecture/configstore')
-rw-r--r-- | en/devices/architecture/configstore/add-class-item.html | 236 | ||||
-rw-r--r-- | en/devices/architecture/configstore/client.html | 166 | ||||
-rw-r--r-- | en/devices/architecture/configstore/index.html | 108 | ||||
-rw-r--r-- | en/devices/architecture/configstore/interface.html | 186 | ||||
-rw-r--r-- | en/devices/architecture/configstore/service.html | 128 |
5 files changed, 824 insertions, 0 deletions
diff --git a/en/devices/architecture/configstore/add-class-item.html b/en/devices/architecture/configstore/add-class-item.html new file mode 100644 index 00000000..319462b7 --- /dev/null +++ b/en/devices/architecture/configstore/add-class-item.html @@ -0,0 +1,236 @@ +<html devsite> + <head> + <title>Adding ConfigStore Classes & Items</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>You can add new ConfigStore items</a> (i.e., interface methods) for an +existing interface class. If the interface class is not defined, you must add a +new class before you can add a ConfigStore item for that class. This section +uses the example of a <code>disableInitBlank</code> configuration item for +<code>healthd</code> being added to the <code>IChargerConfigs</code> interface +class.</p> + +<p class=note><strong>Note:</strong> Before continuing, ensure you are familiar +with <a href="/devices/architecture/hidl/index.html">general HIDL concepts</a>, +<a href="/devices/architecture/hidl-cpp/index.html">HIDL C++ development +workflow</a>, <a href="/devices/architecture/hidl/code-style.html">HIDL Code +Style</a>, and <a href="/devices/architecture/configstore/index.html"> +ConfigStore design</a>.</p> + +<h2 id=add-class>Adding interface classes</h2> +<p>If no interface class is defined for the interface method you want to add, +you must first add the interface class before you can add the associated +ConfigStore items.</p> + +<ol> +<li>Create a HAL interface file. The ConfigStore version is 1.0, so define +ConfigStore interfaces in <code>hardware/interfaces/configstore/1.0</code>. For +example, in +<strong><code>hardware/interfaces/configstore/1.0/IChargerConfigs.hal</code></strong>: + +<pre class="devsite-click-to-copy"> +package android.hardware.configstore@1.0; + +interface IChargerConfigs { + // TO-BE-FILLED-BELOW +}; +</pre></li> + +<li>Update <code>Android.bp</code> and <code>Android.mk</code> for ConfigStore +shared library and header files to include the new interface HAL. For example: + +<pre class="devsite-click-to-copy"> +<code class=devsite-terminal>hidl-gen -o hardware/interfaces/configstore/1.0/default -Lmakefile -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.0::IChargerConfigs</code> +<code class=devsite-terminal>hidl-gen -o hardware/interfaces/configstore/1.0/default -Landroidbp -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.0::IChargerConfigs</code> +</pre> +These commands update <code>Android.bp</code> and <code>Android.mk</code> in +<code>hardware/interfaces/configstore/1.0</code>.</li> + +<li>Generate the C++ stub for implementing the server code. For example: + +<pre class="devsite-terminal devsite-click-to-copy"> +hidl-gen -o hardware/interfaces/configstore/1.0/default -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.configstore@1.0::IChargerConfigs +</pre> +This command creates two files, <code>ChargerConfigs.h</code> and +<code>ChargerConfigs.cpp</code>, in +<code>hardware/interfaces/configstore/1.0/default</code>.</li> + +<li>Open the .h and .cpp implementation files and remove code related to the +function <code>HIDL_FETCH_<em>name</code></em> (e.g., +<code>HIDL_FETCH_IChargerConfigs</code>). This function is needed for HIDL +passthrough mode, which is unused by ConfigStore.</li> + +<li>Register the implementation to the ConfigStore service. For example, in +<strong><code>hardware/interfaces/configstore/1.0/default/service.cpp</code></strong>: + +<pre class="devsite-click-to-copy"> +#include <android/hardware/configstore/1.0/IChargerConfigs.h> +#include "ChargerConfigs.h" + +using android::hardware::configstore::V1_0::IChargerConfigs; +using android::hardware::configstore::V1_0::implementation::ChargerConfigs; + +int main() { + ... // other code + sp<IChargerConfigs> chargerConfigs = new ChargerConfigs; + status = chargerConfigs->registerAsService(); + LOG_ALWAYS_FATAL_IF(status != OK, "Could not register IChargerConfigs"); + ... // other code +} +</pre></li> + +<li>Modify <code>Android.mk</code> file to add implementation file +(<em>modulename</em>Configs.cpp) to LOCAL_SRC_FILES and to map build flags into +macro definitions. For example, in +<strong><code>hardware/interfaces/configstore/1.0/default/Android.mk</code></strong>: + +<pre class="devsite-click-to-copy"> +LOCAL_SRC_FILES += ChargerConfigs.cpp + +ifeq ($(strip $(BOARD_CHARGER_DISABLE_INIT_BLANK)),true) +LOCAL_CFLAGS += -DCHARGER_DISABLE_INIT_BLANK +endif +</pre></li> + +<li>(Optional) Add manifest entry. If it doesn't exist, default to the "default" +instance name of ConfigStore. For example, in +<strong><code>device/google/marlin/manifest.xml</code></strong>: + +<pre class="devsite-click-to-copy"> + <hal format="hidl"> + <name>android.hardware.configstore</name> + ... + <interface> + <name>IChargerConfigs</name> + <instance>default</instance> + </interface> + </hal> +</pre></li> + +<li>Add the sepolicy rule if needed (i.e., if the client does not have +permissions for making hwbinder calls to the <code>hal_configstore</code>). For +example, in <strong><code>system/sepolicy/private/healthd.te</code></strong>: + +<pre class="devsite-click-to-copy"> +... // other rules +binder_call(healthd, hal_configstore) +</pre></li> +</ol> + + +<h2 id=add-item>Adding new ConfigStore items</h2> +<p>To add a new ConfigStore item:</p> +<ol> +<li>Open the HAL file and add required interface method for the item. (The .hal +files for ConfigStore reside in +<code>hardware/interfaces/configstore/1.0</code>.) For example, in +<strong><code>hardware/interfaces/configstore/1.0/IChargerConfigs.hal</code></strong>: + +<pre class="devsite-click-to-copy"> +package android.hardware.configstore@1.0; + +interface IChargerConfigs { + ... // Other interfaces + disableInitBlank() generates(OptionalBool value); +}; +</pre></li> + +<li>Implement the method in the corresponding interface HAL implementation files +(.h and .cpp). Place default implementations in +<code>hardware/interfaces/configstore/1.0/default</code>. + +<p class=note><strong>Note:</strong> Running <code>hidl-gen</code> with +<code>-Lc++-impl</code> generates skeleton code for the newly added interface +method. However, as it also overwrites implementations for all existing +interface methods, use the <code>-o</code> option appropriately.</p> + +For example, in +<strong><code>hardware/interfaces/configstore/1.0/default/ChargerConfigs.h</code></strong>: + +<pre class="devsite-click-to-copy"> +struct ChargerConfigs : public IChargerConfigs { + ... // Other interfaces + Return<void> disableInitBlank(disableInitBlank_cb _hidl_cb) override; +}; +</pre> + +And in +<strong><code>hardware/interfaces/configstore/1.0/default/ChargerConfigs.cpp</code></strong>: + +<pre class="devsite-click-to-copy"> +Return<void> ChargerConfigs::disableInitBlank(disableInitBlank_cb _hidl_cb) { + bool value = false; +#ifdef CHARGER_DISABLE_INIT_BLANK + value = true; +#endif + _hidl_cb({true, value}); + return Void(); +} +</pre></li> +</ol> + +<h2 id=using>Using ConfigStore items</h2> +<p>To use a ConfigStore item:</p> + +<ol> +<li>Include required header files. For example, in +<strong><code>system/core/healthd/healthd.cpp</code></strong>: + +<pre class="devsite-click-to-copy"> +#include <android/hardware/configstore/1.0/IChargerConfigs.h> +#include <configstore/Utils.h> +</pre></li> + +<li>Access the ConfigStore item using the appropriate template function in +<code>android.hardware.configstore-utils</code>. For example, in +<strong><code>system/core/healthd/healthd.cpp</code></strong>: + +<pre class="devsite-click-to-copy"> +using namespace android::hardware::configstore; +using namespace android::hardware::configstore::V1_0; + +static int64_t disableInitBlank = getBool< + IChargerConfigs, + &IChargerConfigs::disableInitBlank>(false); +</pre> +In this example, the ConfigStore item <code>disableInitBlank</code> is retrieved +and stored to a variable (useful when the variable needs to be accessed multiple +times). The value retrieved from the ConfigStore is cached inside the +instantiated template function so it can be retrieved quickly from the cached +value without contacting the ConfigStore service for later calls to the +instantiated template function. +</li> + +<li>Add the dependency on ConfigStore and <code>configstore-utils</code> library +in <code>Android.mk</code> or <code>Android.bp</code>. For example, in +<strong><code>system/core/healthd/Android.mk</code></strong>: + +<pre class="devsite-click-to-copy"> +LOCAL_SHARED_LIBRARIES := \ + android.hardware.configstore@1.0 \ + android.hardware.configstore-utils \ + ... (other libraries) \ +</pre></li> +</ol> + + </body> +</html> diff --git a/en/devices/architecture/configstore/client.html b/en/devices/architecture/configstore/client.html new file mode 100644 index 00000000..7b691994 --- /dev/null +++ b/en/devices/architecture/configstore/client.html @@ -0,0 +1,166 @@ +<html devsite> + <head> + <title>Client-Side Usage</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>You can refactor conditionally-compiled code to read values dynamically from +the HAL interface. For example:</p> + +<pre class="devsite-click-to-copy"> +#ifdef TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS +//some code fragment +#endif +</pre> + +<p>Framework code can then call an appropriate utility function defined in +<code><configstore/Utils.h></code> depending on its type.</p> + +<h2 id=example>ConfigStore example</h2> +<p>This example shows reading +<code>TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS</code>, defined in ConfigStore HAL +as <code>forceHwcForVirtualDisplays()</code> with return type +<code>OptionalBool</code>:</p> + +<pre class="devsite-click-to-copy"> +#include <configstore/Utils.h> +using namespace android::hardware::configstore; +using namespace android::hardware::configstore::V1_0; + +static bool vsyncPhaseOffsetNs = getBool<ISurfaceFlingerConfigs, + ISurfaceFlingerConfigs::forceHwcForVirtualDisplays>(false); +</pre> + +<p>The utility function (<code>getBool</code> in the example above) contacts the +<code>configstore</code> service to get the handle for the proxy of the +interface function, then retrieves the value by invoking the handle via +HIDL/hwbinder.</p> + +<h2 id=utility-functions>Utility functions</h2> +<p><code><configstore/Utils.h></code> +(<code>configstore/1.0/include/configstore/Utils.h</code>) provides utility +functions for each primitive return type, including +<code>Optional[Bool|String|Int32|UInt32|Int64|UInt64]</code>, as listed +below:</p> + +<table> + +<tr> +<th>Type</th> +<th>Function <em>(template parameters omitted)</em></th> +</tr> + +<tr> +<td><code>OptionalBool</code></td> +<td><code>bool getBool(const bool defValue)</code></td> +</tr> + +<tr> +<td><code>OptionalInt32</code></td> +<td><code>int32_t getInt32(const int32_t defValue)</code></td> +</tr> + +<tr> +<td><code>OptionalUInt32</code></td> +<td><code>uint32_t getUInt32(const uint32_t defValue)</code></td> +</tr> + +<tr> +<td><code>OptionalInt64</code></td> +<td><code>int64_t getInt64(const int64_t defValue)</code></td> +</tr> + +<tr> +<td><code>OptionalUInt64</code></td> +<td><code>uint64_t getUInt64(const uint64_t defValue)</code></td> +</tr> + +<tr> +<td><code>OptionalString</code></td> +<td><code>std::string getString(const std::string &defValue)</code></td> +</tr> + +</table> + +<p><code>defValue</code> is a default value returned when the HAL implementation +does not specify a value for the configuration item. Each function takes two +template parameters:</p> +<ul> +<li><code><strong>I</code></strong>. Interface class name.</li> +<li><code><strong>Func</code></strong>. Member function pointer for getting the +configuration item.</li> +</ul> +<p>Because the configuration value is read-only and does not change, the utility +function internally caches the configuration value. Subsequent calls are +serviced more efficiently using the cached value in the same linking unit.</p> + +<h2 id=utils>Using configstore-utils</h2> +<p>The ConfigStore HAL is designed to be forward-compatible for minor version +upgrades, meaning that when the HAL is up-revisioned and some framework code +uses the newly-introduced items, the ConfigStore service with older minor +version in <code>/vendor</code> can still be used.</p> + +<p>For forward-compatibility, ensure your implementation adheres to the +following guidelines:</p> + +<ol> +<li>New items use the default value when <em>only</em> the old version service +is available. Example: + +<pre class="devsite-click-to-copy"> +service = V1_1::IConfig::getService(); // null if V1_0 is installed +value = DEFAULT_VALUE; + if(service) { + value = service->v1_1API(DEFAULT_VALUE); + } +</pre> + +</li> + +<li>Client uses the earliest interface in which the ConfigStore item was +introduced. Example: + +<pre class="devsite-click-to-copy"> +V1_1::IConfig::getService()->v1_0API(); // NOT ALLOWED + +V1_0::IConfig::getService()->v1_0API(); // OK +</pre> +</li> +<li>New version service can be retrieved for old version interface. In the +following example, if the installed version is v1_1, the v1_1 service must be +returned for getService(): + +<pre class="devsite-click-to-copy"> +V1_0::IConfig::getService()->v1_0API(); +</pre> + +<p class=note><strong>Note:</strong> The +<a href="https://android-review.googlesource.com/c/393736/">current AOSP +implementation</a> satisfies this requirement.</p> +</li> +</ol> + +<p>When the access functions in <code>configstore-utils</code> library are used +for accessing the ConfigStore item, #1 is guaranteed by the implementation and +#2 is guaranteed by compiler errors. For these reasons we strongly recommend +using <code>configstore-utils</code> wherever possible.</p> + + </body> +</html> diff --git a/en/devices/architecture/configstore/index.html b/en/devices/architecture/configstore/index.html new file mode 100644 index 00000000..45dcb9e7 --- /dev/null +++ b/en/devices/architecture/configstore/index.html @@ -0,0 +1,108 @@ +<html devsite> + <head> + <title>Configstore HAL</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>Android O splits the monolithic Android OS into generic (system.img) +and hardware-specific (vendor.img and odm.img) partitions. As a result of this +change, conditional compilation must be removed from modules installed to the +system partition and such modules must now determine the configuration of the +system at runtime (and behave differently depending on that configuration).</p> + +<p>The ConfigStore HAL provides a set of APIs for accessing read-only +configuration items used to configure the Android framework. This page describes +the design of ConfigStore HAL (and why system properties were not used for this +purpose); other pages in this section detail the +<a href="/devices/architecture/configstore/interface.html">HAL interface</a>, +<a href="/devices/architecture/configstore/service.html">service +implementation</a>, and +<a href="/devices/architecture/configstore/client.html">client-side usage</a>, +all using <code>surfaceflinger</code> as an example. For help with ConfigStore +interface classes, see +<a href="/devices/architecture/configstore/add-class-item.html">Adding Interface +Classes & Items</a>.</p> + +<h2 id=system-properties>Why not use system properties?</h2> +<p>We considered using system properties but found several fundamental issues, +including: </p> +<ul> +<li><strong>Length limits on values</strong>. System properties have +tight limits on the length of their values (92 bytes). In addition, as these +limits have been directly exposed to Android apps as C macros, increasing the +length can cause backwards-compatibility issues.</li> +<li><strong>No type support</strong>. All values are essentially strings, and +APIs simply parse the string into an <code>int</code> or <code>bool</code>. +Other compound data types (array, struct, etc.) should be encoded/decoded by +the clients (e.g. "aaa,bbb,ccc" can be decoded as an array of three strings). +</li> +<li><strong>Overwrites</strong>. Because read-only system properties are +implemented as write-once properties, vendors/ODMs that want to override +AOSP-defined read-only values must import their own read-only values prior to +AOSP-defined read-only values, which in turn results in vendor-defined +re-writable values being overridden by AOSP-defined values.</li> +<li><strong>Address space requirements</strong>. System properties take a +relatively large amount of address space in each process. System properties are +grouped in <code>prop_area</code> units with a fixed size of 128KB, all of which +is allocated to a process address space even if only a single system property in +it is being accessed. This can cause problems on 32-bit devices where address +space is precious.</li> +</ul> +<p>We attempted to overcome these limitations without sacrificing compatibility +but continued to be concerned that system properties were not designed to +support accessing read-only configuration items. Eventually we decided that +system properties are better suited for sharing a few dynamically-updated items +across all of Android in real time, and that a need existed for a new system +dedicated to accessing read-only configuration items.</p> + +<h2>ConfigStore HAL design</h2> +<p>The basic design is simple:</p> +<p><img src="../images/treble_configstore_design.png"></p> +<p><strong>Figure 1.</strong> ConfigStore HAL design</p> + +<ul> +<li>Describe build flags (currently used for conditionally compiling the +framework) in HIDL.</li> +<li>Vendors and OEMs provide SoC and device-specific values for build flags by +implementing the HAL service.</li> +<li>Modify the framework to use the HAL service to find the value of a +configuration item at runtime.</li> +</ul> + +<p>Configuration items currently referenced by the framework are included in a +versioned HIDL package (<code>android.hardware.configstore@1.0</code>). Vendors +and/or OEMs provide values to the configuration items by implementing interfaces +in this package, and the framework uses the interfaces when it needs to get a +value for a configuration item.</p> + +<h2 id=security>Security considerations</h2> +<p>Build flags defined in the same interface are affected by same SELinux +policy. If one or more build flags should have different SELinux policies, +<strong>they must be separated to another interface</strong>. This can require +major uprev of <code>android.hardware.configstore package</code> as the +separated interfaces are no longer backwards-compatible.</p> + +<aside class="note"><strong>Note:</strong> For details on Android 8.0 SELinux, +see <a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android +8.0</a>.</aside> + + </body> +</html> diff --git a/en/devices/architecture/configstore/interface.html b/en/devices/architecture/configstore/interface.html new file mode 100644 index 00000000..6c735feb --- /dev/null +++ b/en/devices/architecture/configstore/interface.html @@ -0,0 +1,186 @@ +<html devsite> + <head> + <title>Creating the HAL Interface</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>You must use HIDL to describe all build flags used for conditionally +compiling the framework. Relevant build flags must be grouped and included in a +single <code>.hal</code> file. Using HIDL for specifying configuration items +includes the following benefits:</p> +<ul> +<li>Versioned (to add new config items, vendors/OEMs must explicitly extend the +HAL)</li> +<li>Well-documented</li> +<li>Access control using SELinux</li> +<li>Sanity check for configuration items via +<a href="/devices/tech/test_infra/tradefed/fundamentals/vts">Vendor Test +Suite</a> (range check, inter-dependency check among items, etc.)</li> +<li>Auto-generated APIs in both C++ and Java</li> +</ul> + +<h2 id=identify-flags>Identifying build flags used by the framework</h2> +<p>Start by identifying the build configs used to conditionally compile the +framework, then abandon obsolete configs to make the set smaller. For example, +the following set of build flags are identified for <code>surfaceflinger</code>: +</p> +<ul> +<li><code>TARGET_USES_HWC2</code> (will be obsoleted)</li> +<li><code>TARGET_BOARD_PLATFORM</code></li> +<li><code>TARGET_DISABLE_TRIPLE_BUFFERING</code></li> +<li><code>TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS</code></li> +<li><code>NUM_FRAMEBUFFER_SURFACE_BUFFERS</code></li> +<li><code>TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK</code></li> +<li><code>VSYNC_EVENT_PHASE_OFFSET_NS</code></li> +<li><code>SF_VSYNC_EVENT_PHASE_OFFSET_NS</code> (will be obsoleted)</li> +<li><code>PRESENT_TIME_OFFSET_FROM_VSYNC_NS</code></li> +<li><code>MAX_VIRTUAL_DISPLAY_DIMENSION</code></li> +</ul> + +<h2 id="create-interface">Creating a HAL interface</h2> +<p>Build configs for a subsystem are accessed via a HAL interface, while +interfaces for giving configuration values are grouped in the HAL package <code>android.hardware.configstore</code> (currently at version 1.0). For example, to +create a HAL interface file for <code>surfaceflinger</code>, in +<strong><code>hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal</code></strong>: +</p> + +<pre class="devsite-click-to-copy"> +package android.hardware.configstore@1.0; + +interface ISurfaceFlingerConfigs { + // TO-BE-FILLED-BELOW +}; +</pre> + +<p>After creating the <code>.hal</code> file, run +<code>hardware/interfaces/update-makefiles.sh</code> to add the new +<code>.hal</code> file to the <code>Android.bp</code> and +<code>Android.mk</code> files.</p> + +<h2 id="add-functions">Adding functions for build flags</h2> +<p>For each build flag, add a new function to the interface. For example, in +<strong><code>hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal</code></strong>: +</p> + +<pre class="devsite-click-to-copy"> +interface ISurfaceFlingerConfigs { + disableTripleBuffering() generates(OptionalBool ret); + forceHwcForVirtualDisplays() generates(OptionalBool ret); + enum NumBuffers: uint8_t { + USE_DEFAULT = 0, + TWO = 2, + THREE = 3, + }; + numFramebufferSurfaceBuffers() generates(NumBuffers ret); + runWithoutSyncFramework() generates(OptionalBool ret); + vsyncEventPhaseOffsetNs generates (OptionalUInt64 ret); + presentTimeOffsetFromSyncNs generates (OptionalUInt64 ret); + maxVirtualDisplayDimension() generates(OptionalInt32 ret); +}; +</pre> + +<p>When adding a function:</p> +<ul> +<li><strong>Be concise with names</strong>. Avoid converting makefile variable +names into function names and keep in mind that <code>TARGET_</code> and +<code>BOARD_</code> prefixes are no longer necessary.</li> +<li><strong>Add comments</strong>. Help developers understand the purpose of the +config item, how it changes framework behavior, valid values, etc.</li> +</ul> +<p>Function return types can be +<code>Optional[Bool|String|Int32|UInt32|Int64|UInt64]</code>. Types are defined +in <code>types.hal</code> in the same directory and wrap primitive values with a +field that indicates if the value is specified by the HAL; if not, the default +value is used.</p> + +<pre class="devsite-click-to-copy"> +struct OptionalString { + bool specified; + string value; +}; +</pre> + +<p>When appropriate, define the enum that best represents the type of the +configuration item and use that enum as the return type. In the example above, +the <code>NumBuffers</code> enum is defined to limit the number of valid +values. When defining such custom data types, add a field or a enum value (e.g., +<code>USE_DEFAULT</code>) for denoting if the value is/is not specified by +HAL.</p> + +<p>It is not mandatory for a single build flag to become a single function in +HIDL. Module owners can alternatively aggregate closely-related build flags into +a struct and have a function that returns that struct (doing so can reduce +number of function calls).</p> + +<p>For example, an option for aggregating two build flags into a single struct +in <strong><code>hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal</code></strong> +is:</p> + +<pre class="devsite-click-to-copy"> + interface ISurfaceFlingerConfigs { + // other functions here + struct SyncConfigs { + OptionalInt64 vsyncEventPhaseoffsetNs; + OptionalInt64 presentTimeoffsetFromSyncNs; + }; + getSyncConfigs() generates (SyncConfigs ret); + // other functions here +}; +</pre> + +<h2 id=alternatives>Alternatives to a single HAL function</h2> + +<p>As an alternative to using a single HAL function for all build flags, the HAL +interface also provides simple functions such as <code>getBoolean(string +key)</code> and <code>getInteger(string key)</code>. The actual +<code>key=value</code> pairs are stored in separate files and the HAL service +provides values by reading/parsing those files.</p> + +<p>While this approach is easy to define, it does not include the benefits +provided by HIDL (enforced versioning, ease of documentation, access control) +and is therefore not recommended.</p> + +<p class=note><strong>Note:</strong> When using simple functions, access +control is almost impossible as HAL cannot identify clients by itself.</p> + +<h2 id=single-multiple>Single vs. multiple interfaces</h2> +<p>The design of the HAL interface for configuration items presents two +choices:</p> + +<ol> +<li>Single interface that covers all configuration items</li> +<li>Multiple interfaces, each of which covers a set of related configuration +items</li> +</ol> +<p>A single interface is easier but can become unmaintainable as more +configuration items are added to the single file. In addition, access control +is not fine-grained, so a process granted access to the interface can read all +configuration items (access to a partial set of configuration items cannot be +granted). Alternatively, if access is not granted, no configuration item can be +read.</p> + +<p>Because of these issues, Android uses multiple interfaces with a single HAL +interface for a group of related configuration items. For example, +<code>ISurfaceflingerConfigs</code> for <code>surfaceflinger</code>-related +configuration items, <code>IBluetoothConfigs</code> for Bluetooth-related +configuration items, etc.</p> + + </body> +</html> diff --git a/en/devices/architecture/configstore/service.html b/en/devices/architecture/configstore/service.html new file mode 100644 index 00000000..09874b4d --- /dev/null +++ b/en/devices/architecture/configstore/service.html @@ -0,0 +1,128 @@ +<html devsite> + <head> + <title>Implementing the Service</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>To prepare for the HAL implementation, you can generate basic configstore +interface code then modify it to meet your needs.</p> + +<h2 id=generate-boilerplate>Generating interface code</h2> +<p>To generate boilerplate code for the interface, run <code>hidl-gen</code>. +For example, to generate code for <code>surfaceflinger</code>:</p> + +<pre class="devsite-terminal devsite-click-to-copy"> +hidl-gen -o hardware/interfaces/configstore/1.0/default \ + -Lc++-impl \ + -randroid.hardware:hardware/interfaces \ + -randroid.hidl:system/libhidl/transport \ + android.hardware.config@1.0::ISurfaceFlingerConfigs +</pre> + +<p class="note"><strong>Note:</strong> Don't run <code>hidl-gen</code> with +<code>-Landroidbp-impl</code> as this generates <code>Android.bp</code>. The +module must be built with <code>Android.mk</code> to access build flags.</p> + +<h2 id=modify-androidmk>Modifying Android.mk</h2> +<p>Next, modify <code>Android.mk</code> file to add implementation file +(<code><modulename>Configs.cpp</code>) to <code>LOCAL_SRC_FILES</code> and +to map build flags into macro definitions. For example, you can modify +<code>surfaceflinger</code> in +<strong><code>hardware/interface/configstore/1.0/default/Android.mk</code></strong>: +</p> + +<pre class="devsite-click-to-copy"> +LOCAL_SRC_FILES += SurfaceFlingerConfigs.cpp +ifneq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),) + LOCAL_CFLAGS += -DNUM_FRAMEBUFFER_SURFACE_BUFFERS=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS) +endif + +ifeq ($(TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK),true) + LOCAL_CFLAGS += -DRUNNING_WITHOUT_SYNC_FRAMEWORK +endif +</pre> + +<p>If <code>Android.mk</code> includes several <code>ifeq-endif</code> blocks, +consider moving your code into a new file (i.e., <code>surfaceflinger.mk</code>) +then include that file from <code>Android.mk</code>.</p> + +<h2 id=implement-functions>Implementing functions</h2> +<p>To fill the functions to implement the HAL, call back the +<code>_hidl_cb</code> function with different values (conditioned on build +flags). For example, you can fill the functions for <code>surfaceflinger</code> +in <strong><code>hardware/interfaces/configstore/1.0/default/SurfaceFlingerConfigs.cpp</code></strong>:</p> + +<pre class="devsite-click-to-copy"> +Return<void> SurfaceFlingerConfigs::numFramebufferSurfaceBuffers( + numFramebufferSurfaceBuffers_cb _hidl_cb) { + #if NUM_FRAMEBUFFER_SURFACE_BUFFERS 2 + _hidl_cb(NumBuffers.TWO); + #else if NUM_FRAMEBUFFER_SURFACE_BUFFERS 3 + _hidl_cb(NumBuffers.THREE); + #else + _hidl_cb(NumBuffers.USE_DEFAULT); + #endif +} + +Return<void> SurfaceFlingerConfigs::runWithoutSyncFramework( + runWithoutSyncFramework_cb _hidl_cb) { + #ifdef RUNNING_WITHOUT_SYNC_FRAMEWORK + _hidl_cb({true /* specified */, true /* value */}); + #else + // when macro not defined, we can give any value to the second argument. + // It will simply be ignored in the framework side. + _hidl_cb({false /* specified */, false /* value */}); + #endif +} +</pre> + +<p>Ensure the implementation does not contain a function named +<code>HIDL_FETCH_<interface name></code> (e.g., +<code>HIDL_FETCH_ISurfaceFlingerConfigs</code>). This function is needed for +HIDL passthrough mode, which is unused (and prohibited) by +<code>configstore</code>. ConfigStore must always run in binderized mode.</p> + +<h2 id=register-service>Registering as a service</h2> +<p>Finally, register all interface implementations to the +<code>configstore</code> service. For example, you can register +<code>surfaceflinger</code> implementations in +<strong><code>hardware/interfaces/configstore/1.0/default/service.cpp</code></strong>: +</p> + +<pre class="devsite-click-to-copy"> +configureRpcThreadpool(maxThreads, true); +sp<ISurfaceFlingerConfigs> surfaceFlingerConfigs = new SurfaceFlingerConfigs; +status_t status = surfaceFlingerConfigs->registerAsService(); + +sp<IBluetoothConfigs> bluetoothConfigs = new BluetoothConfigs; +status = bluetoothConfigs->registerAsService(); + +// register more interfaces here +joinRpcThreadpool(); +</pre> + +<h2 id=bootstrapping>Ensuring early access</h2> +<p>To ensure a framework module can get early access the HAL service, the config +HAL service should start as early as possible, just after +<code>hwservicemanager</code> is ready. As the config HAL service does not read +external files, it is expected to be ready quickly after it is launched.</p> + + </body> +</html> |